E2E chat
End-to-end messaging on a blind relay — identity, delivery, and the hosted demo.
E2E chat
Chat is the final layer on the passkey-centered Vault stack: X3DH + Double Ratchet primitives (@railman/zero-e2e) with a session-authenticated blind relay in @railman/auth-zero-access.
hardened passkey → PRF-backed Vault unlock → identity seed → zero-e2ezero-e2e accepts an identity seed instead of importing WebAuthn code. That is a library boundary, not an independent product path.
Composition
Wire Chat with Chat composition. This page covers identity, relay visibility, and the hosted demo.
Live demo: Chat lab
What the server sees
| Server stores | Server never sees |
|---|---|
| Sealed envelopes | Message plaintext |
| Identity fingerprints (for change detection) | Identity private keys |
| Delivery metadata | MEK / ratchet roots |
Identity
Product identity material is derived client-side from a grant-capable Vault unlock. The same Vault material yields the same identity; rotation uses an epoch bump.
Users should compare safety numbers / fingerprints out of band before trusting a new peer. Product callers must use initiateSessionPinned (or verify a bundle pin themselves). Unpinned initiateSession is denied unless ZERO_E2E_ALLOW_UNPINNED=1 (tests only).
Hosted lab notes
- Open delivery may be relaxed so demos can message without mutual contacts — turn contact gates on in production.
- The hosted lab may use a password-derived identity shortcut. It demonstrates messaging behavior, not the production passkey/Vault identity architecture.
- WebSocket wakes the peer to fetch mail; polling is the fallback.
- Reset clears local state and best-effort relay identity when a demo gets stuck.
Related
- Crypto primitives
- WebAuthn and PRF
- Vault guide
- Security model
- Monorepo:
docs/E2E_CHAT.mdfor engineer depth