ADR-0003. Mandatory ECDH + AES-256-GCM payload encryption on /stream
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-03-28 |
| Deciders | signal-team |
| Supersedes | — |
Context
- TLS terminates at Traefik; beyond it, traffic crosses the internal network and a shared Redis bus.
- WebSocket payloads carry order/payment data that should not be readable at the bus or by other co-tenant connections.
- We want per-connection key isolation and forward secrecy without a key-management service.
Decision
We will require end-to-end payload encryption for every /stream connection (requireEncryption: true):
- During the handshake the client sends
clientPublicKey; the server generates an ephemeral ECDH P-256 key pair, derives an AES-256 key via HKDF-SHA-256, and stores it in an in-memory_clientAesKeysmap keyed by client id. - The server returns
{ serverPublicKey, salt }inside theconnectedevent so the client derives the same key. - All subsequent messages are AES-256-GCM
{ iv, ct }. Onlyconnectedanderrorare sent in plaintext. - Keys are deleted on disconnect and lost on restart (clients reconnect to re-derive).
Consequences
| Pros | Cons |
|---|---|
| Payloads opaque on the wire, bus, and to other connections | No persistence — restart forces all clients to reconnect |
| Forward secrecy (ephemeral key per connection) | clientPublicKey is mandatory — clients without ECDH are rejected |
| No external KMS needed | In-memory key map limits a single process; relies on sticky socket + Redis for scale |
Alternatives Considered
| Option | Pros | Cons | Why rejected |
|---|---|---|---|
| TLS only (no payload encryption) | Simplest | Plaintext past Traefik + on Redis bus | Insufficient for payment data |
| Shared static AES key | No handshake | No forward secrecy; one leak compromises all | Unacceptable blast radius |
| mTLS per client | Strong identity | Heavy cert lifecycle on POS/Tauri clients | Operationally impractical for client fleet |
References
signal/src/components/websocket.component.ts(ECDH, handshake, outbound transformer, message handler)- Encryption
- Operations — security