What “Zero-Knowledge” Means
Zero-knowledge in this context means the server has zero knowledge of message content. All encryption and decryption happens exclusively on client devices (the owner’s app and the agent’s plugin). The server never possesses private keys, never performs decryption, and cannot read messages.
The Server Cannot See
| Data | Protection |
|---|---|
| Message content | Encrypted client-side with XChaCha20-Poly1305 before transmission. Stored as BYTEA (binary) in PostgreSQL. |
| Private keys | Generated locally on each device. Never transmitted to the server. |
| Invite tokens (raw) | Only the BLAKE2b hash is stored. The raw token is returned to the owner once and never persisted server-side. |
| Key exchange material | X3DH agreement computed locally on both sides. The shared secret never touches the wire. |
| Ratchet state | Chain keys, message keys, and DH ratchet keys live exclusively in client memory/storage. |
The Server Can See
Transparency about what the server does know is essential for honest security claims:| Data | Why | Mitigation |
|---|---|---|
| Ciphertext blobs | Must store and relay encrypted messages | Content is indistinguishable from random bytes without the key |
| Public keys | Required for enrollment coordination | Public keys reveal nothing about private keys |
| Message metadata | Timestamps, sender/receiver device IDs, conversation IDs | Metadata is tenant-scoped via RLS; cross-tenant correlation is prevented at the database level |
| Connection metadata | IP addresses, WebSocket session timing | Standard for any network service; Cloudflare provides an additional proxy layer |
| Device fingerprints | Displayed to owner for manual verification during enrollment | Derived from public key via BLAKE2b; not sensitive |
Cryptographic Guarantees
End-to-End Encryption
Every message is encrypted with XChaCha20-Poly1305 using a unique message key derived from the Double Ratchet:Forward Secrecy
The Double Ratchet protocol provides forward secrecy: every message advances the chain key, and old message keys are deleted after decryption. What this means in practice: If an attacker compromises a device’s current keys, they cannot decrypt past messages. The ratchet has already moved forward, and the old keys no longer exist.Post-Compromise Security
The DH ratchet rotates the key agreement with every exchange direction change. If an attacker compromises current keys but the compromise is later resolved (e.g., device is revoked and re-enrolled), future messages become secure again after a single round trip.Key Agreement (X3DH)
During enrollment, both parties perform a triple Diffie-Hellman key agreement:AEAD Encryption
XChaCha20-Poly1305 is an Authenticated Encryption with Associated Data (AEAD) cipher. This means:- Confidentiality — message content is encrypted
- Integrity — any modification to the ciphertext is detected
- Authentication — the recipient can verify the message was encrypted by someone holding the correct key
Database-Level Protections
Ciphertext-Only Storage
Themessages table contains exactly two content columns, both BYTEA:
plaintext, preview, subject, or body TEXT columns. This is by design and enforced at the schema level.
Row-Level Security
Every table has RLS enabled with tenant isolation policies:Invite Token Hashing
Raw invite tokens are never stored. The server stores only the BLAKE2b hash:Compromise Scenarios
Scenario: Full backend database breach
Scenario: Full backend database breach
What the attacker gets: Ciphertext blobs, public keys, message metadata, hashed invite tokens.What the attacker cannot do: Decrypt any messages. Derive private keys from public keys. Use hashed invite tokens to enroll new devices.Why: Private keys exist only on client devices. The ciphertext is encrypted with keys derived from the Double Ratchet, which the server never possesses.
Scenario: Backend server code compromise
Scenario: Backend server code compromise
What the attacker gets: The ability to intercept ciphertext in transit, modify relay behavior, or inject messages.What the attacker cannot do: Decrypt messages in transit (no keys). Forge messages (Ed25519 signatures verify sender identity). Read historical messages (ciphertext-only storage).Why: The backend never handles plaintext or private keys, so there is nothing to intercept even with full code control.
Scenario: Compromised client device
Scenario: Compromised client device
What the attacker gets: Access to the device’s private keys, ratchet state, and the ability to decrypt messages for that device.What the attacker cannot do: Access messages from other tenants. Decrypt messages from before the compromise began (forward secrecy). Continue access after the device is revoked.Mitigation: Device revocation immediately terminates WebSocket connections and prevents further authentication. The owner re-enrolls with a new device, establishing fresh keys.
Scenario: Network eavesdropper (MITM)
Scenario: Network eavesdropper (MITM)
What the attacker gets: Encrypted WebSocket traffic (TLS + E2E encrypted payloads).What the attacker cannot do: Decrypt the TLS layer (Cloudflare-managed certificates). Decrypt the E2E layer inside TLS (XChaCha20-Poly1305). Forge messages (Ed25519 signatures).Why: Two layers of encryption — TLS for transport, E2E for content. Breaking TLS still leaves the attacker with indecipherable ciphertext.
Honest Limitations
AgentVault does not protect against:| Limitation | Explanation |
|---|---|
| Compromised host OS | An attacker with root access to the machine running the owner app or agent plugin can extract keys from memory. This is true of all software-based encryption. |
| Malicious tenant administrator | In single-owner deployments (the common case), this is N/A. In multi-user tenants, a malicious admin could revoke and re-enroll devices but cannot decrypt existing messages. |
| Screenshots / screen recording | Once a message is decrypted and displayed, screen capture is outside the encryption boundary. |
| Traffic analysis | An observer can determine that communication is occurring, its timing, and approximate volume. Content remains protected. |
| Metadata correlation | Message timestamps, sender/receiver pairs, and conversation patterns are visible to the server (within tenant scope). |
These limitations are shared by virtually all E2E encrypted messaging systems, including Signal. Documenting them honestly is a deliberate choice — transparency about what we do and do not protect against builds trust.
Comparison with Signal’s Architecture
AgentVault follows the same zero-knowledge relay model as Signal with adaptations for agent communications:| Property | Signal | AgentVault |
|---|---|---|
| E2E encryption | Double Ratchet | Double Ratchet |
| Symmetric cipher | AES-256-CBC + HMAC-SHA256 | XChaCha20-Poly1305 (AEAD, 192-bit nonce) |
| Key exchange | X3DH with signed prekeys | X3DH (synchronous enrollment) |
| Server role | Encrypted relay | Encrypted relay |
| Forward secrecy | Yes | Yes |
| Post-compromise security | Yes | Yes |
| Group protocol | Sender Keys | Room-scoped Double Ratchet (Sender Keys on roadmap) |
| Nonce safety | Counter-managed | Random-safe (192-bit) |