1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 Craton Software Company
//! HTTP serverless API gateway built on axum 0.7.
//!
//! Exposes deploy/invoke/metrics/healthz endpoints with structured JSON
//! errors. Application state is a `DashMap<Uuid, FunctionRecord>` shared
//! via `Arc<AppState>`. The synchronous and async invoke paths both drive
//! `tensor_wasm_exec::executor::TensorWasmExecutor`.
//!
//! ## Security surface
//!
//! * **Body limit.** Every request is capped at 64 MiB by
//! [`axum::extract::DefaultBodyLimit::max`]; oversized bodies are
//! rejected with `413 Payload Too Large` before any handler runs.
//! * **CORS.** The gateway installs an explicit-allowlist
//! [`tower_http::cors::CorsLayer`]; the allowlist is empty by default
//! (every cross-origin request rejected). Widen by setting
//! `TENSOR_WASM_API_CORS_ALLOWED_ORIGINS` to a comma-separated list of
//! origins. See [`middleware::CorsConfig`].
//! * **Bearer auth.** Reads `TENSOR_WASM_API_TOKENS` (comma-separated allowlist)
//! at startup. Empty/unset means dev mode (pass-through with warning);
//! otherwise requests must carry `Authorization: Bearer <token>`.
//! * **Scoped tokens.** Each entry in `TENSOR_WASM_API_TOKENS` may carry a
//! `:tenant=` scope clause (`token:tenant=1,2,3` or `token:tenant=*`).
//! Routes that bind to a tenant return `403 tenant_scope_denied` when the
//! caller's bearer token is not scoped to that tenant. Bare entries are
//! treated as wildcard with a one-shot deprecation warning at startup
//! (removal targeted for v1.0). See [`token_scope`].
//! * **Tenant scoping.** The `X-TensorWasm-Tenant: <u64>` header is parsed and
//! threaded through to the executor. Set `TENSOR_WASM_API_REQUIRE_TENANT=1`
//! to make the header mandatory.
//! * **Per-token rate limiting.** Configurable QPS + burst per bearer token,
//! enforced behind bearer auth. Reads
//! `TENSOR_WASM_API_RATE_LIMIT_QPS` and `TENSOR_WASM_API_RATE_LIMIT_BURST`;
//! either zero or unset disables the limiter. Rejections return
//! `429 Too Many Requests` with a `Retry-After` header. See
//! [`rate_limit`].
//! * **Audit log.** Every state-mutating call (`POST /functions`,
//! `DELETE /functions/{id}`, `POST /functions/{id}/invoke[-async]`)
//! emits a structured JSON record to the sink selected by
//! `TENSOR_WASM_API_AUDIT_LOG` (default: stdout). Read-only routes
//! emit nothing. See [`audit`] and `docs/AUDIT-LOG.md`.
//! * **XFCC spoofing gate via `TENSOR_WASM_API_TRUSTED_XFCC_PROXIES`.**
//! Comma-separated allowlist of IPv4/IPv6 addresses or CIDR ranges
//! whose `X-Forwarded-Client-Cert` headers the audit middleware will
//! honour. Empty / unset = trust nobody (safe default — every inbound
//! XFCC is dropped). Deployments behind an mTLS-terminating proxy
//! should set this to the proxy's IP(s); operators not running an
//! XFCC-stripping proxy should leave it unset. See
//! [`audit::TrustedProxies`].
//! * **Snapshot HMAC key.** When
//! `TENSOR_WASM_API_SNAPSHOT_HMAC_KEY` is set (64-char hex, 32 bytes)
//! the `/snapshot/save` route HMAC-SHA256-signs the snapshot blob it
//! returns and `/snapshot/restore` verifies the signature (always
//! requiring a signature on restore). Set
//! `TENSOR_WASM_API_SNAPSHOT_REQUIRE_SIGNATURE=true` for the matching
//! strict-restore posture. The routes are wired into the protected
//! stack (bearer auth + tenant scope + per-tenant ownership) by
//! [`build_router`], which reads the key via
//! [`AppConfig::from_env`](config::AppConfig::from_env); when the key is
//! unset both routes return `503 snapshot_signing_not_configured`. See
//! [`routes::snapshot_save`] / [`routes::snapshot_restore`] and
//! [`config`] for the schema.
//! * **HTTP request metrics.** A tower middleware emits
//! `tensor_wasm_http_requests_total`,
//! `tensor_wasm_http_request_duration_seconds`, and
//! `tensor_wasm_http_requests_in_flight` per `(route, method, status)`,
//! labelled with the axum route template (never the substituted id).
//! The layer sits OUTSIDE bearer auth so `401`/`429` responses are
//! counted too — required by the `availability_http` SLI in
//! `docs/SLO.md`. See [`http_metrics`].
//!
//! See [`API.md`](../API.md) for the wire-format contract.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;