The 'WebTransport proxy' concept was conflating two distinct things; this pass separates them: 1. In-process ALPN-stream-proxy (ADR-040, in alknet-http): the h3 handler hands a WebTransport stream to another ALPN handler (SshAdapter, GitAdapter, etc.) as a Connection, so a browser with a WASM parser can reach any ALPN service via WebTransport. Path-based routing (the CONNECT path declares the target: /alknet/ssh -> SshAdapter). HttpAdapter gains Arc<HandlerRegistry> for the lookup. The browser's WASM parser implements BiStream (ADR-007) over the WebTransport stream. SSH-over-WebTransport is HTTPS-shaped at the network layer (anti-censorship: the 'VPN-like without being a VPN' use case on a clean foundation). russh-sftp demonstrates WASM targeting is feasible; SSH is the next target. 2. Standalone relay service (OQ-38, future alknet-relay crate): a full relay - fork of iroh-relay - with WebTransport proxy fallback for NAT traversal. This is infrastructure, not a mode of the h3 handler. OQ-38 reframed to be the standalone-relay scope question (distinct from the in-process proxy now resolved by ADR-040). webtransport.md updated: three stream destinations (call protocol, ALPN-handler proxy, other sub-protocols) with path-based routing; new 'ALPN-stream-proxy' section covering the WASM client side, auth model (bearer token gates the session; protocol's own auth gates the protocol session), and the HandlerRegistry reference. README/overview ADR tables and OQ summaries updated for ADR-040.
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-06-29 |
alknet-http
HTTP interface for alknet: serves HTTP/1.1, HTTP/2, and HTTP/3 (WebTransport)
on standard ALPNs, and hosts the HTTP-backed call-protocol adapters
(from_openapi, to_openapi, from_mcp, to_mcp).
Documents
| Document | Status | Description |
|---|---|---|
| overview.md | draft | Crate purpose, two roles (server + client host), dependencies, adapter location map |
| http-server.md | draft | HttpAdapter (ProtocolHandler for h2/http/1.1), axum over QUIC, Bearer auth, stealth, /healthz |
| http-adapters.md | draft | from_openapi (reqwest client) and to_openapi (OpenAPI projection); no-env-vars invariant point |
| http-mcp.md | draft | from_mcp / to_mcp (feature-gated), streamable-HTTP-only, stdio exclusion |
| webtransport.md | draft | h3/WebTransport handler — the browser streaming path |
Applicable ADRs
| ADR | Title | Relevance |
|---|---|---|
| 001 | ALPN-Based Protocol Dispatch | HttpAdapter registers on standard HTTP ALPNs |
| 002 | ProtocolHandler Trait | HttpAdapter implements ProtocolHandler |
| 003 | Crate Decomposition | alknet-http depends on alknet-core + alknet-call (protocol-foundation exception, Amendment 1) |
| 004 | Auth as Shared Core | Bearer → resolve_from_token |
| 007 | BiStream Type Definition | HttpAdapter receives Connection, accepts a stream for hyper |
| 010 | ALPN Router and Endpoint | Stealth mode = HTTP handler on standard ALPNs |
| 014 | Secret Material Flow | from_openapi/from_mcp are the credential injection point |
| 015 | Privilege Model | Adapter-registered ops are Internal by default |
| 017 | Call Protocol Client and Adapter Contract | OperationAdapter trait; to_* are projections; published-spec contract |
| 022 | Handler Registration, Provenance, Composition Authority | from_openapi/from_mcp produce leaf bundles |
| 023 | Operation Error Schemas | from_openapi/to_openapi error fidelity; HTTP_<status> error codes |
| 027 | TLS Identity Redesign | Browsers require X.509; WebTransport requires X.509 |
| 034 | Outgoing-Only X.509 and Three Peer Roles | Browsers are not alknet peers; WebTransport relay-as-proxy recorded |
| 036 | HTTP-to-Call Operation Mapping | Direct path mapping; to_openapi is projection, not router |
| 037 | MCP Stdio Transport Exclusion | Streamable HTTP only; stdio not built |
| 038 | HTTP/3 and WebTransport as First-Class HTTP Transports | h3 in scope, not deferred |
| 039 | HTTP Server and Client Host Colocated in alknet-http | One crate for server + client host (shared HTTP deps, shared mapping) |
| 040 | WebTransport ALPN-Stream-Proxy | Browser → WebTransport stream → any ALPN handler (SSH, git, SFTP) via WASM parser |
Relevant Open Questions
| OQ | Title | Status | Relevance |
|---|---|---|---|
| OQ-11 | Handler-level auth resolution observability | resolved | HTTP handler stores resolved identity on Connection via set_identity |
| OQ-12 | TLS identity provisioning | resolved | Browsers require X.509 (gates the entire h3 feature) |
| OQ-13 | Operation path format | resolved | /{service}/{op} is the HTTP path (ADR-036) |
| OQ-17 | Call protocol client and adapter contract | resolved | OperationAdapter trait; to_* projections |
| OQ-24 | Operation error schemas | resolved | from_openapi/to_openapi error fidelity |
| OQ-26 | OperationAdapter error type | resolved | AdapterError variants reused by HTTP adapters |
| OQ-37 | X.509 outgoing-only / three peer roles | resolved | Browsers are not peers; hub with mixed fingerprints |
| OQ-38 | WebTransport standalone relay service scope | open (scope, not deferral) | The standalone relay (future alknet-relay, fork of iroh-relay) — distinct from the in-process ALPN-stream-proxy (ADR-040) |
| OQ-39 | to_openapi published-spec versioning |
open | Versioning strategy for generated OpenAPI specs |
| OQ-40 | reqwest client config and connection pooling | open | Two-way-door: pooling/retry config shape |
Key Design Principles
- HTTP is both a server surface and a client transport for adapters.
Inbound HTTP (
h2/http/1.1/h3) is served byaxumover a QUIC stream; outbound HTTP (from_openapi/from_mcpforwarding) usesreqwest. Both directions share the same HTTP dependencies, which is why they live in one crate rather than being split. See overview.md. - The HTTP surface is a projection of the call protocol. An HTTP
request at
POST /fs/readFilebecomes acall.requestedfor/fs/readFile. The HTTP path IS the operation path;to_openapidescribes this surface, it does not define a second one. See ADR-036. - Standard ALPNs, not alknet ALPNs.
h2,http/1.1,h3are IANA-registered ALPN strings. Any HTTP client (browser, curl, axios) connects without knowing about alknet — the TLS handshake negotiatesh2orhttp/1.1normally. This is the stealth mapping (ADR-010). from_openapi/from_mcpare the no-env-vars injection point. The forwarding handlers readcontext.capabilities, notstd::env::var. This is the architectural mechanism that makes aisdk's env-var reads unreachable. See ADR-014, client-and-adapters.md.- MCP streamable HTTP only; stdio is not built. stdio = spawn arbitrary executable = RCE. Streamable HTTP is network-isolated, auth-gatable, and runs under alknet's auth model. See ADR-037.
- HTTP/3 + WebTransport is a first-class transport, not a deferral. The browser streaming path uses QUIC streams directly. See ADR-038.
- The
h3handler is an ALPN-stream-proxy for browsers. A browser with a WASM parser can reach any ALPN handler (SSH, git, SFTP) via WebTransport — no install, no native client, no VPN. SSH-over- WebTransport is HTTPS-shaped at the network layer (anti-censorship). See ADR-040. h3requires X.509. Browsers don't support RFC 7250 raw keys (ADR-027). A node serving WebTransport must have an X.509 identity. This is a browser limitation, not an alknet decision.
References
docs/research/alknet-http/phase-0-findings.md— Phase 0 research (directionally close; DH-2's deferral framing is corrected by ADR-038)docs/research/alknet-call-completion/gap-analysis.md— adapter location map, no-env-vars invariant/workspace/@alkdev/operations/src/from_openapi.ts,/workspace/@alkdev/operations/src/from_mcp.ts— TypeScript prior art/workspace/rust-sdk/— MCP Rust SDK (rmcp v1.8.0); streamable HTTP transport examples/workspace/wtransport/— pure-Rust WebTransport reference implementation (theh3feature's candidate dependency)