> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentvault.chat/llms.txt
> Use this file to discover all available pages before exploring further.

# Key Architecture

> Ed25519 dual-key model, X3DH key agreement, and key lifecycle management for agent identities.

# 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

| 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)](https://signal.org/docs/specifications/x3dh/) protocol establishes a shared secret between parties who have never communicated:

<Steps>
  <Step title="Key bundle upload">
    Each device uploads a signed prekey bundle: identity key (IK), signed prekey (SPK), and one-time prekeys (OPK).
  </Step>

  <Step title="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)`
  </Step>

  <Step title="KDF">
    Concatenated DH outputs pass through HKDF-SHA-512 to derive the root key for the Double Ratchet.
  </Step>

  <Step title="Ratchet initialization">
    Both parties initialize a Double Ratchet session from the shared secret.
  </Step>
</Steps>

**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)
```

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

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.

<Warning>
  State files contain private key material. Ensure `dataDir` has restrictive file permissions (`chmod 700`). A backup is automatically maintained at `agentvault.json.bak`.
</Warning>

### 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.
