Files
safetynet/docs/evidence-pq-channel.md
T

23 lines
3.1 KiB
Markdown

# Protected evidence upload channel
Automatic browser evidence now uses a dedicated `safetynet-evidence-mlkem1024-mldsa87-v1` channel. It shares the enrollment-pinned management signing identity while separating its protocol version, HKDF domain, AES-GCM AAD and pending challenges from policy delivery. Existing policy wire format remains compatible.
The browser verifies the signed device/expiry/KEM challenge using Ed25519 and ML-DSA-87, encapsulates an ephemeral ML-KEM-1024 secret, derives separate request/response AES-256-GCM keys with HKDF-SHA384, and encrypts the evidence object. The acknowledgement is encrypted and bound to the same challenge and random request ID. Unauthenticated status/body cannot become a delivery acknowledgement. Application plaintext is limited to 64 KiB plus envelope overhead; plaintext buffers and response keys are wiped on completion and failure.
Routes (device authentication required):
- `POST /api/device/channel/evidence/challenge` with an empty JSON object.
- `POST /api/device/channel/evidence` with the KEM/AEAD envelope.
Challenges expire after 60 seconds and are consumed before decryption, including invalid ciphertext submissions. Other devices cannot use or consume a device's pending challenge. The server rechecks current evidence policy at storage, verifies the source event and preserves exact-payload idempotency. Thus a lost acknowledgement can be retried with a fresh challenge without creating another evidence row.
The automatic browser has no plaintext fallback. Production/required-PQ configurations reject `/api/device/evidence`. Legacy raw submission is limited to local development when the configured URL and actual socket are loopback and protected management is not required. Official startup binds development HTTP to loopback. Central collection disablement aborts pending evidence protocol requests and preserves ordinary audit events. Already accepted records retain their investigation access/retention rules.
## Operational limits
Authenticated HTTPS is still required for remote deployment. Device bearer tokens remain protected by TLS, not individually signed by a device PQ key. Server signing keys currently remain in the existing SQLite-backed management key store; external key custody, rotation and independently deployed initial pins need production hardening. `SAFETYNET_CHANNEL_SIGNATURE_KEY_FILE` and `SAFETYNET_REQUIRE_CHANNEL_PIN` provide the existing deployment pin controls. A compromised authorized server can decrypt evidence by design.
Pending challenges are process-local. A restart discards them and clients obtain fresh challenges; existing stored evidence supports idempotent retry. Multiple management instances require request affinity or a suitable shared challenge service. Global authenticated rate limits and a 10,000-pending challenge ceiling bound the current service, but this is not a completed HA design.
OpenTelemetry records `evidence.challenge`, `evidence.decrypt`, `evidence.store` and `evidence.encrypt` with timing/outcome under the HTTP request span. Evidence contents, ciphertexts, credentials and key material are not trace attributes.