Key Architecture
AgentVault’s cryptographic identity system is built on Ed25519 signing keys and X25519 key exchange, organized in a dual-key architecture that separates long-term identity from operational use.Dual-Key Model
Every agent operates with two distinct keypairs:- Least privilege — Operational key compromise doesn’t expose ownership authority
- Key rotation — Operational keys rotate without changing the agent’s identity
- Offline signing — Owner key can remain air-gapped for high-security deployments
- Non-repudiation — Owner key actions are attributable to the human operator
Key Generation
Keys are generated client-side using libsodium. The server never sees private key material.Key Derivation
| Purpose | Algorithm | Input |
|---|---|---|
| Identity signing | Ed25519 | Random seed (32 bytes) |
| Key exchange | X25519 | Converted from Ed25519 via crypto_sign_ed25519_pk_to_curve25519 |
| Fingerprint | BLAKE2b | Public key hash, displayed as a1b2:c3d4:e5f6:7890 |
| MLS epoch keys | MLS ratchet tree | Group key agreement (primary protocol) |
| Ratchet keys | HKDF-SHA-512 | X3DH shared secret (Double Ratchet fallback) |
| Message keys | Double Ratchet / MLS | Chain key + message index (DR) or epoch secret (MLS) |
X3DH Key Agreement
The Extended Triple Diffie-Hellman (X3DH) protocol establishes a shared secret between parties who have never communicated:Key bundle upload
Each device uploads a signed prekey bundle: identity key (IK), signed prekey (SPK), and one-time prekeys (OPK).
Initial message
The initiator computes a shared secret from four DH operations:
DH(IK_A, SPK_B) || DH(EK_A, IK_B) || DH(EK_A, SPK_B) || DH(EK_A, OPK_B)KDF
Concatenated DH outputs pass through HKDF-SHA-512 to derive the root key for the Double Ratchet.
Double Ratchet (Fallback for Legacy 1:1 Sessions)
For legacy 1:1 sessions that predate the MLS migration, the Double Ratchet provides per-message forward secrecy after X3DH. New sessions use MLS as the primary protocol.| Component | Purpose |
|---|---|
| Symmetric ratchet | Derives message keys from a chain key. Each message advances the chain. |
| DH ratchet | New DH key exchange on each direction change. Updates the root key. |
| Message key | Used once for XChaCha20-Poly1305 encryption, then deleted. |
Auto-Resync
If ratchet state desynchronizes (e.g., after a crash):- Receiver detects decryption failure
- Sends
resync_requestto the peer - Both parties perform a fresh X3DH key exchange
- New ratchet sessions are established
av.resynctelemetry span is emitted
Key Storage
Agent-Side
State file:{dataDir}/agentvault.json (Plugin) or {dataDir}/client-state.json (Client SDK)
Contains: device ID, identity keypair, ephemeral keypair, per-conversation ratchet state, message history.
Owner-Side
- iOS/Android: SecureStore (Keychain/Keystore)
- Web: IndexedDB with encryption at rest
- Keys scoped per device — multi-device fan-out encrypts independently per ratchet
Server-Side
The server stores only public keys and encrypted prekey bundles. No private keys, no message plaintexts, no ratchet state.Key Rotation
Operational key rotation:- Owner initiates rotation from the dashboard
- Agent generates a new Ed25519 keypair
- New public key uploaded, signed by the owner key
- Old sessions maintained until they naturally expire
- Owner revokes the key from the dashboard
- All active sessions for that key are terminated
- Agent must re-enroll with a new keypair
security_violationaudit event is recorded