Skip to main content

Crate tensor_wasm_api

Crate tensor_wasm_api 

Source
Expand description

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; 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 for the wire-format contract.

Re-exports§

pub use audit::audit_log_middleware;
pub use audit::AuditAction;
pub use audit::AuditActor;
pub use audit::AuditActorKind;
pub use audit::AuditConfig;
pub use audit::AuditOutcome;
pub use audit::AuditRecord;
pub use audit::AuditResource;
pub use audit::AuditSink;
pub use audit::FileJsonSink;
pub use audit::NoopSink;
pub use audit::StdoutJsonSink;
pub use audit::TokenScopeView;
pub use audit::TrustedProxies;
pub use audit::ENV_AUDIT_LOG;
pub use audit::ENV_TRUSTED_XFCC_PROXIES;
pub use audit::HEADER_XFCC;
pub use config::AppConfig;
pub use config::ConfigError;
pub use config::HexParseReason;
pub use config::ENV_SNAPSHOT_HMAC_KEY;
pub use config::ENV_SNAPSHOT_REQUIRE_SIGNATURE;
pub use config::SNAPSHOT_HMAC_KEY_LEN;
pub use http_metrics::http_metrics_middleware;
pub use http_metrics::HttpMetricsLayerConfig;
pub use http_metrics::RouteAllowList;
pub use http_metrics::DEFAULT_ROUTE_ALLOWLIST;
pub use http_metrics::UNKNOWN_ROUTE;
pub use middleware::normalize_method;
pub use middleware::sanitize_path;
pub use middleware::AuthConfig;
pub use middleware::CorsConfig;
pub use middleware::KernelPublishTokens;
pub use middleware::TenantConfig;
pub use middleware::TrustedHosts;
pub use middleware::ENV_API_TOKENS;
pub use middleware::ENV_CORS_ALLOWED_ORIGINS;
pub use middleware::ENV_KERNEL_PUBLISH_TOKENS;
pub use middleware::ENV_REQUIRE_TENANT;
pub use middleware::ENV_TRUSTED_HOSTS;
pub use middleware::HEADER_TENANT;
pub use middleware::MAX_AUTH_HEADER_BYTES;
pub use middleware::MAX_PATH_LEN;
pub use middleware::MAX_REQUEST_BODY_BYTES;
pub use openai::ChatCompletionsRequest;
pub use openai::ChatMessage;
pub use openai::CompletionsRequest;
pub use openai::OpenAiError;
pub use openai::OpenAiErrorBody;
pub use openai_translator::assemble_chat_prompt;
pub use openai_translator::model_map_from_env;
pub use openai_translator::parse_model_map_env;
pub use openai_translator::translate_chat_completions_request;
pub use openai_translator::translate_completions_request;
pub use openai_translator::ModelMap;
pub use openai_translator::TranslatedRequest;
pub use openai_translator::ENV_OPENAI_MODEL_MAP;
pub use rate_limit::AuthContext;
pub use rate_limit::PerTenantRateLimitConfig;
pub use rate_limit::RateLimitConfig;
pub use rate_limit::RateLimiter;
pub use rate_limit::TokenId;
pub use routes::snapshot_restore;
pub use routes::snapshot_save;
pub use routes::ApiError;
pub use routes::AppState;
pub use routes::FunctionRecord;
pub use routes::JobRecord;
pub use routes::JobStatus;
pub use routes::SnapshotRestoreRequest;
pub use routes::SnapshotRestoreResponse;
pub use routes::SnapshotSaveRequest;
pub use routes::SnapshotSaveResponse;
pub use server::build_router;
pub use server::build_router_with_audit;
pub use server::build_router_with_config;
pub use server::build_router_with_full_config;
pub use server::build_router_with_kernel_publish_tokens;
pub use server::build_router_with_trusted_proxies;
pub use server::serve;
pub use token_scope::parse_token_entry;
pub use token_scope::parse_tokens_env;
pub use token_scope::ParsedTokens;
pub use token_scope::ScopeParseError;
pub use token_scope::TenantScope;
pub use token_scope::TokenScope;
pub use trace_propagation::current_trace_id;
pub use trace_propagation::extract_parent_context;
pub use trace_propagation::inject_trace_id_header;
pub use trace_propagation::install_w3c_propagator;
pub use trace_propagation::HeaderMapExtractor;
pub use trace_propagation::HEADER_TRACE_ID;

Modules§

audit
Structured audit log for state-mutating API calls.
config
Top-level application config knobs that don’t fit naturally into any single middleware-scoped config struct.
http_metrics
HTTP request metrics middleware.
kernels
/kernels HTTP endpoints (roadmap feature #3 — server-side path).
middleware
Tower middleware helpers: timeouts, concurrency limits, body limits, authentication, tenant scoping, and tracing spans.
openai
OpenAI-compatible inference gateway shim.
openai_translator
OpenAI request → internal invoke translation (T41, v0.4 wire-up).
rate_limit
Per-token QPS + burst rate limiting (token-bucket).
routes
REST route handlers (deploy, invoke, metrics, healthz).
server
Axum router builder and listener.
token_scope
Per-tenant scoped bearer tokens.
trace_propagation
W3C Trace Context propagation helpers.