Skip to main content

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:
Owner (human)                    Agent (machine)
┌─────────────────┐              ┌─────────────────┐
│  Owner Key      │              │  Operational Key │
│  (Ed25519)      │              │  (Ed25519)       │
│                 │              │                  │
│  Signs:         │              │  Signs:          │
│  - DID document │              │  - Messages      │
│  - SPTs         │              │  - Heartbeats    │
│  - Key rotation │              │  - Telemetry     │
│  - Attestations │              │  - A2A handshakes│
│                 │              │                  │
│  Storage:       │              │  Storage:        │
│  Device keychain│              │  dataDir on disk │
└─────────────────┘              └─────────────────┘
Why two keys?
  • 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

PurposeAlgorithmInput
Identity signingEd25519Random seed (32 bytes)
Key exchangeX25519Converted from Ed25519 via crypto_sign_ed25519_pk_to_curve25519
FingerprintBLAKE2bPublic key hash, displayed as a1b2:c3d4:e5f6:7890
MLS epoch keysMLS ratchet treeGroup key agreement (primary protocol)
Ratchet keysHKDF-SHA-512X3DH shared secret (Double Ratchet fallback)
Message keysDouble Ratchet / MLSChain 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:
1

Key bundle upload

Each device uploads a signed prekey bundle: identity key (IK), signed prekey (SPK), and one-time prekeys (OPK).
2

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)
3

KDF

Concatenated DH outputs pass through HKDF-SHA-512 to derive the root key for the Double Ratchet.
4

Ratchet initialization

Both parties initialize a Double Ratchet session from the shared secret.
Security properties: Forward secrecy, deniability, asynchronous setup.

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.
Root Key ──────────────────────────────────────────────────►
    │              │              │
    ▼              ▼              ▼
Chain Key 1    Chain Key 2    Chain Key 3
    │              │              │
    ▼              ▼              ▼
Message Key    Message Key    Message Key
(encrypt msg)  (encrypt msg)  (encrypt msg)
ComponentPurpose
Symmetric ratchetDerives message keys from a chain key. Each message advances the chain.
DH ratchetNew DH key exchange on each direction change. Updates the root key.
Message keyUsed once for XChaCha20-Poly1305 encryption, then deleted.

Auto-Resync

If ratchet state desynchronizes (e.g., after a crash):
  1. Receiver detects decryption failure
  2. Sends resync_request to the peer
  3. Both parties perform a fresh X3DH key exchange
  4. New ratchet sessions are established
  5. av.resync telemetry 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.
State files contain private key material. Ensure dataDir has restrictive file permissions (chmod 700). A backup is automatically maintained at agentvault.json.bak.

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:
  1. Owner initiates rotation from the dashboard
  2. Agent generates a new Ed25519 keypair
  3. New public key uploaded, signed by the owner key
  4. Old sessions maintained until they naturally expire
Emergency revocation:
  1. Owner revokes the key from the dashboard
  2. All active sessions for that key are terminated
  3. Agent must re-enroll with a new keypair
  4. security_violation audit event is recorded

Fingerprint Verification

Key fingerprints are BLAKE2b hashes displayed as colon-separated hex:
a1b2:c3d4:e5f6:7890:abcd:ef01:2345:6789
Owners verify their agent’s fingerprint by comparing values shown in the app, the agent’s CLI output during enrollment, and the DID document. This out-of-band verification prevents man-in-the-middle attacks.