Status: draft Last updated: 2026-05-24 Owner: asupersync-umelq.14.2
This document covers security risks and mitigations for the Asupersync runtime and its protocol stack, with focus on:
- Runtime core (scheduler, cancellation, obligations, trace)
- TLS integration and crypto hygiene
- HTTP/1.1, HTTP/2, gRPC, WebSocket protocol handling
- Messaging clients (Redis, NATS, Kafka)
- Deterministic lab runtime and replay tooling
- OS kernel security, CPU micro-architecture attacks
- Supply-chain policy beyond basic dependency hygiene
- Full formal verification (tracked separately)
Primary assets and goals:
- Correctness invariants: structured concurrency, no orphan tasks, no obligation leaks
- Cancellation correctness: request -> drain -> finalize, bounded cleanup
- Protocol safety: no uncontrolled memory/CPU growth, fail-safe parsing
- Integrity of traces and diagnostics (no corrupted replay data)
- Confidentiality of TLS sessions and protected data in transit
- Deterministic testing: reproducible traces, no ambient randomness
- Untrusted network input: all protocol decoders, stream parsers, and framing
- Runtime boundary: user code is untrusted and may misbehave
- Cancellation boundary: drop-based cancellation is not trusted to be safe
- External dependencies: crates with unsafe internals may contain vulnerabilities
- Remote unauthenticated attacker: malformed protocol inputs, DoS via resource exhaustion
- Remote authenticated attacker: protocol misuse, request smuggling, stream abuse
- Local attacker (same host): abuse of file paths, permissions, or local sockets
- Malicious library user: misuse of APIs, intentional invariant violations
This addendum defines browser-specific security assumptions and controls for the
wasm-browser-preview surface.
- Browser host and JavaScript environment are untrusted from the runtime point of view.
- Network authority must be explicit (
Cx+IoCap) and never ambient. - Fetch capability authority is default-deny; every origin/method/credential grant is explicit.
- Replay artifacts are potentially exfiltratable unless treated as sensitive outputs.
- Dependency compromise remains possible; policy gates must prevent forbidden runtime surfaces.
| Category | Browser Abuse Case | Required Control |
|---|---|---|
| Spoofing | Untrusted origin impersonates approved backend | Default-deny origin policy + explicit origin allowlist in FetchAuthority |
| Tampering | Script mutates request shape to bypass policy | Method allowlist + header-count cap + invalid URL rejection |
| Repudiation | Missing provenance for security decisions | Structured security diagnostics + deterministic test replay commands |
| Information Disclosure | Replay/log artifacts expose secrets/tokens | Redaction requirements + no secret-bearing stdout/stderr |
| Denial of Service | Oversized headers/bodies or hostile request patterns | Hard policy bounds (max_header_count, protocol size limits) |
| Elevation of Privilege | Ambient fetch/credentials escalation without capability | Capability-gated IoCap::fetch_cap() + default-deny grants (origin/method/credentials) |
tests/security_invariants.rs(browser_fetch_securitymodule) enforces:- default authority deny-all behavior,
- untrusted origin denial,
- method escalation denial,
- credential-default-deny behavior,
- header-count bound enforcement,
- malformed URL rejection.
src/io/cap.rsunit tests enforce authority and policy wiring throughBrowserFetchIoCap..github/workflows/ci.ymlruns full test gates; failures include deterministic test names and replayable commands.
For local reproduction with remote offload:
rch exec -- env CARGO_TARGET_DIR=${TMPDIR:-/tmp}/rch_target_security_docs cargo test --test security_invariants browser_fetch_security -- --nocapture
rch exec -- env CARGO_TARGET_DIR=${TMPDIR:-/tmp}/rch_target_security_docs cargo test --lib io::cap -- --nocapture
rch exec -- env CARGO_TARGET_DIR=${TMPDIR:-/tmp}/rch_target_security_docs cargo test --test security -- --nocaptureFor CI parity checks:
python3 scripts/check_wasm_dependency_policy.py --policy .github/wasm_dependency_policy.json
rch exec -- env CARGO_TARGET_DIR=${TMPDIR:-/tmp}/rch_target_security_docs cargo test --test security_invariants browser_fetch_security -- --nocapture| Risk | Why Residual | Current Mitigation | Closure Trigger |
|---|---|---|---|
| Third-party package compromise in JS toolchains | Rust-level controls cannot fully govern npm/bundler supply chain | Dependency policy gate + lockfile review + reproducible CI artifacts | Signed provenance + policy-enforced package allowlist for browser SDK distribution |
| Replay artifact over-collection | Traces can capture sensitive operational context if emitted too broadly | Redaction guidance + scoped diagnostics + no secret stdout/stderr | Automated artifact redaction validation gate in CI |
| Host bridge misuse by integrators | Browser embedding layer can accidentally widen authority in app code | Explicit FetchAuthority contract with default-deny grants (origin/method/credentials) |
Contract tests for all host adapters plus policy check in release gate |
Normative policy source: .github/security_release_policy.json section
trace_telemetry_privacy (trace-telemetry-privacy-v1).
Data minimization classes:
secret: credentials/tokens/password-like material; never persisted in replay/telemetry artifacts.sensitive: potentially identifying payload/log details; allowed only in redacted form.metadata: routing + reproducibility metadata (suite,scenario_id,seed, replay command) retained for forensics.
Redaction modes and opt-in levels:
metadata_only(default): keeps deterministic reproduction metadata, strips sensitive payload fields.strict: stronger minimization with the same replay contract guarantees.none: local-only opt-in for debugging; forbidden in CI.
Retention and storage scope:
- Local default/max: 14 days.
- CI default/max: 30 days.
- Approved artifact path fragments:
/target/e2e-results//target/phase6-e2e/target/test-results//test_logs
Release-blocking privacy assertions:
artifact_lifecycle_policy.jsonmust declare CI-safe redaction mode (metadata_onlyorstrict).- Required redacted fields must include
suite_log. - Retention days must be numeric and within CI cap.
- Every suite must keep replay and artifact routing enabled.
CI enforcement:
.github/workflows/ci.ymlD4 gate validates lifecycle artifacts against.github/security_release_policy.json.trace_telemetry_privacy.- Security release gate (
scripts/check_security_release_gate.py) and CI report artifacts provide audit evidence for incident review.
Offline ATP mailbox relays are untrusted store-and-forward infrastructure. The relay may enforce storage policy and prove custody, but it must not need access to private payload bytes. Receiver safety is based on policy metadata, stable digests, expiry, monotonic sequence evidence, and proof-bundle linkage.
- Relay operators can observe timing, object sizes, mailbox ids, source and receiver routing metadata, quota pressure, and expiry timestamps.
- Relay operators cannot be trusted to preserve payload confidentiality unless bytes are encrypted before relay custody.
- Authenticated peers can still attempt replay, quota exhaustion, storage spam, stale retrieval, truncation, or equivocation across receivers.
- Receivers may be offline long enough for entries to expire, so expiry and non-delivery evidence must remain explicit instead of inferred from absence.
| Risk | Required control | Code surface |
|---|---|---|
| Private payload disclosure | Stored mailbox objects must be end-to-end encrypted before relay custody unless they carry an explicit public-data policy id. | MailboxPrivacyPolicy::validate |
| Metadata leakage | Diagnostics redact peer/object identifiers and cap visible peer metadata by policy. | MailboxPrivacyPolicy::redact_peer, InboxJsonRow |
| Quota exhaustion / spam | Mailbox entries are charged to the Mailbox quota bucket before acceptance and expire through mailbox retention policy. |
QuotaBucket::Mailbox, QuotaLedger, RetentionPolicy |
| Tampering / equivocation | Retrieval must match manifest root, stored-object digest, manifest epoch, and mailbox sequence evidence. | MailboxTamperEvidence::validate_retrieval |
| Replay | Receivers reject sequence numbers at or below the last accepted mailbox sequence. | MailboxTamperEvidence::validate_retrieval |
| Truncation | Receivers compare returned byte count with the committed mailbox content length. | MailboxTamperEvidence::validate_retrieval |
| Stale entries | Receivers reject retrieval after the committed mailbox expiry. | MailboxTamperEvidence::validate_retrieval |
| Risk | Why Residual | Current Mitigation | Closure Trigger |
|---|---|---|---|
| Relay traffic analysis | Size/timing/routing metadata remains visible even with encrypted payloads | Metadata redaction and explicit relay-visibility documentation | Padding/batching policy with deterministic quota impact tests |
| Non-delivery ambiguity | A receiver cannot distinguish deletion, expiry, and malicious withholding without relay evidence | Expiry is explicit and proof bundles can attach mailbox storage/retrieval evidence | Signed non-delivery receipts and independent relay quorum evidence |
| Abuse across federated relays | A malicious sender can distribute spam across operators | Per-relay quota bucket and retention controls | Federated reputation/rate-limit protocol with replayable abuse evidence |
Threats:
- Task starvation or scheduler deadlock (lost wakeups, cancel lane monopoly)
- Obligation leaks causing resource retention
- Budget bypass leading to unbounded work
Mitigations:
- Scheduler invariants and tests (lost wakeup, duplicate scheduling)
- Obligation tracking (reserve/commit/abort) with leak detection
- Budget propagation and checkpoint enforcement
Threats:
- Silent drops of in-flight effects
- Unbounded cleanup on cancel
Mitigations:
- Two-phase effects for critical primitives
- Cancellation protocol: request -> drain -> finalize
- Lab runtime oracles: quiescence, obligation leak, loser drain
Threats:
- Weak cipher negotiation or missing ALPN
- Invalid certificate acceptance
- Missing client auth options (mTLS)
Mitigations:
- rustls integration with explicit configuration
- ALPN negotiation required for HTTP/2 and gRPC
- Separate tasks for TLS conformance and mTLS
Threats:
- HPACK memory/CPU exhaustion
- Incomplete CONTINUATION sequences (connection-level DoS)
- PUSH_PROMISE abuse (resource leaks, stream ID exhaustion)
- Stream dependency violations
Mitigations:
- HPACK bounds, Huffman validation, recursion limits
- Continuation deadline and header block size caps
- Strict stream state machine checks
- Tests for flow control, SETTINGS, and GOAWAY
Threats:
- Oversized frames or metadata
- Stream reset abuse
- Inconsistent status mapping
Mitigations:
- Frame size caps and strict header validation
- Explicit status mapping from Outcome to gRPC codes
- Conformance and interop tests
Threats:
- Incomplete close handshake leading to resource leaks
- Missing masking validation for client -> server frames
- Fragmentation abuse
Mitigations:
- RFC 6455 close handshake implementation
- Masking enforcement
- Message size caps and fragmentation limits
Threats:
- Unbounded buffer growth in codecs
- Protocol state desync on partial frames
- Cancel-sensitive operations leaking resources
Mitigations:
- Incremental decoders with size limits
- Connection pool health checks
- Cancel-correct send/recv semantics
- No unbounded allocations from untrusted input
- Protocol parsers are total: reject invalid input without panics
- All obligations resolved before task completion
- Cancellation does not drop committed effects
- Trace and replay must be deterministic and tamper-evident
Unit tests:
- Parser boundary tests for HTTP/2, HPACK, WebSocket, gRPC
- Obligation leak detection on task completion
- TLS configuration validation
Fuzz tests:
- HTTP/2 frame sequences
- HPACK header blocks
- WebSocket frame parser
- gRPC frame decoder
E2E tests:
- Protocol conformance suites where available
- Cancellation under load with structured logging
Lab runtime tests:
- Deterministic scheduling + oracle verification for security invariants
The table below maps key security invariants to existing tests and fuzz targets. Gaps are listed in the "Open Items" section.
| Invariant / Threat | Current Coverage | Notes |
|---|---|---|
| Structured concurrency, region close => quiescence | tests/region_lifecycle_conformance.rs, tests/integration_e2e.rs |
Region + task lifecycle invariants |
| No obligation leaks | tests/integration_e2e.rs, tests/io_e2e.rs, tests/e2e/combinator/cancel_correctness/obligation_cleanup.rs |
Obligation safety across join/race + I/O |
| Losers are drained after races | tests/e2e/combinator/cancel_correctness/loser_drain.rs, tests/e2e_combinator.rs |
Race cancellation + drain behavior |
| Cancellation protocol (request -> drain -> finalize) | tests/cancellation_conformance.rs, tests/cancel_attribution.rs, tests/integration_e2e.rs |
Cancellation correctness in core flows |
| Deterministic lab runtime | tests/lab_determinism.rs, tests/lab_execution.rs, tests/dpor_exploration.rs |
Determinism + schedule exploration |
| HTTP/1 parsing safety | tests/http_verification.rs, fuzz/fuzz_targets/http1_request.rs, fuzz/fuzz_targets/http1_response.rs |
Parser bounds + fuzzing |
| HTTP/2 frame safety | src/http/h2/connection.rs (unit tests), fuzz/fuzz_targets/http2_frame.rs |
Frame-level robustness |
| HPACK decoding safety | fuzz/fuzz_targets/hpack_decode.rs |
Size bounds + parser totality |
| WebSocket correctness | tests/e2e_websocket.rs, src/web/debug.rs (stub) |
Protocol tests, more needed |
| gRPC framing and status safety | tests/grpc_verification.rs |
Mapping + framing checks |
| Network primitives hardening | tests/net_tcp.rs, tests/net_udp.rs, tests/net_unix.rs, tests/net_verification.rs |
Nonblocking and error paths |
| File system safety | tests/fs_verification.rs, tests/io_cancellation.rs |
File ops + cancel behavior |
| Security primitives | tests/security/*.rs |
Auth/context/key/tag/property tests |
| Browser fetch authority boundaries | tests/security_invariants.rs (browser_fetch_security), src/io/cap.rs (unit tests) |
Origin/method/credentials/header policy enforcement |
| Trace/replay integrity | tests/replay_debugging.rs |
Trace format + replay sanity |
Documented size limits should be enforced at the codec or framing layer and be configurable where appropriate. Current defaults:
- HTTP/1.1:
src/http/h1/codec.rs:DEFAULT_MAX_HEADERS_SIZE= 64 KiB,DEFAULT_MAX_BODY_SIZE= 16 MiBsrc/http/h1/codec.rs:MAX_HEADERS= 128,MAX_REQUEST_LINE= 8192 bytessrc/http/h1/client.rs: same defaults for client decode
- HTTP/2:
src/http/h2/settings.rs:DEFAULT_MAX_FRAME_SIZE= 16384src/http/h2/settings.rs:DEFAULT_MAX_HEADER_LIST_SIZE= 65536src/http/h2/settings.rs:DEFAULT_CONTINUATION_TIMEOUT_MS= 5000src/http/h2/stream.rs:HEADER_FRAGMENT_MULTIPLIER= 4 (fragment limit = 4x header list)src/http/h2/connection.rs: HPACK decoder max header list size set from settings
- gRPC:
src/grpc/codec.rs:DEFAULT_MAX_MESSAGE_SIZE= 4 MiBsrc/grpc/server.rs+src/grpc/client.rs:max_recv_message_size/max_send_message_sizedefault 4 MiB
- WebSocket:
src/net/websocket/frame.rs:FrameCodec::DEFAULT_MAX_PAYLOAD_SIZE= 16 MiBsrc/net/websocket/client.rs:WebSocketConfigdefaults:max_frame_size= 16 MiB,max_message_size= 64 MiB
Fuzz targets are documented in fuzz/README.md and wired into
.github/workflows/fuzz.yml for scheduled runs:
fuzz_http1_request(HTTP/1 request parser)fuzz_http1_response(HTTP/1 response parser)fuzz_hpack_decode(HPACK decoder)fuzz_http2_frame(HTTP/2 frame parser)fuzz_interest_flags(reactor interest flags)
CI should run at least the critical targets with a bounded time budget, e.g.:
cargo +nightly fuzz run fuzz_http2_frame -- -max_total_time=300
cargo +nightly fuzz run fuzz_hpack_decode -- -max_total_time=300
Missing fuzz targets to add: WebSocket frame parser and gRPC message framing.
- Define explicit size limits (frame/header/message) with safe defaults
- Validate all state transitions; reject invalid sequences early
- Bound allocations derived from untrusted input
- Ensure cancellation-safe cleanup for in-flight operations
- Add deterministic lab tests covering edge cases
- Add a fuzz target + seeds and wire into CI
- Emit structured trace events for protocol errors (no stdout/stderr)
- Emit structured trace events for security-relevant failures
- Record reasons for protocol errors (without leaking secrets)
- Never write to stdout/stderr in core runtime paths
The security release gate validates policy compliance in CI before every release.
- Policy:
.github/security_release_policy.json - Gate script:
scripts/check_security_release_gate.py - Report artifact:
artifacts/security_release_gate_report.json - Event log:
artifacts/security_release_gate_events.ndjson
Release-blocking checks (SEC-BLOCK-01 through SEC-BLOCK-06):
- Dependency audit: No forbidden runtime crates in WASM profiles.
- Capability authority: FetchAuthority/StorageAuthority default-deny enforcement.
- Protocol bounds: All protocol parsers enforce documented size limits.
- Telemetry redaction: Sensitive data scrubbed before emission.
- Structured concurrency: No orphan tasks or obligation leaks.
- Supply chain: All conditional dependencies have non-expired transition plans.
Warning checks (non-blocking): fuzz target coverage, credential escalation prevention.
Adversarial scenarios (ADV-01 through ADV-06) are validated for test coverage against
tests/security_invariants.rs.
Validator commands:
python3 scripts/check_security_release_gate.py --self-test
python3 scripts/check_security_release_gate.py \
--policy .github/security_release_policy.json- Add fuzz targets for WebSocket frame parsing and gRPC message framing
- Tracked in
bd-1p2e(WebSocket conformance + fuzz) - Tracked in
bd-27sd(gRPC conformance + interop)
- Tracked in