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

# Architecture Overview

> How AgentVault's zero-knowledge architecture keeps your agent communications private.

AgentVault is a secure enclave communications platform where AI agent owners communicate with their agents through end-to-end encrypted channels. The server acts solely as an encrypted relay -- it never sees plaintext.

## Core Security Properties

<Note>
  These four properties are enforced at every layer of the stack -- cryptographic, application, and database.
</Note>

1. **Server never sees plaintext.** All encryption and decryption happens client-side.
2. **Closed, invite-only enrollment.** No public discovery. Every device is explicitly approved by the owner.
3. **Device-bound keys.** Private keys are generated locally and never leave the device.
4. **Strict tenant isolation via RLS.** Row-Level Security policies on every database table prevent cross-tenant access.

## System Architecture

```
OWNER (Browser / Mobile)
  Expo App + libsodium (MLS + Double Ratchet fallback)
  ├── Auth UI (Clerk)
  ├── Chat UI (E2E encrypted)
  └── Device Enrollment UI
        │
        ▼
AGENTVAULT BACKEND (FastAPI)
  Stores and relays ciphertext only
  ├── Enrollment Service
  ├── Message Store (BYTEA columns)
  └── WebSocket Relay (Redis pub/sub)
        │
        ▼
AGENT (OpenClaw / Third-Party)
  Node.js Plugin (@agentvault/agentvault)
  ├── libsodium (MLS + Double Ratchet fallback)
  └── OpenClaw Skill Interface
```

## Components

### Clients

AgentVault supports three client types, all sharing the same cryptographic library (`@agentvault/crypto`):

<Accordion title="Owner App (Expo Universal)">
  The owner app runs on iOS, Android, and web from a single Expo codebase. It handles:

  * **Authentication** via Clerk (JWT issuance, session management)
  * **Key generation** (Ed25519 identity + X25519 ephemeral keypairs)
  * **MLS/Double Ratchet encryption** for every outbound message
  * **Device management** (invite, approve, revoke)
  * **Key storage** in platform-appropriate secure storage (SecureStore on native, IndexedDB on web)
</Accordion>

<Accordion title="Agent Plugin (@agentvault/agentvault)">
  The Node.js plugin integrates with OpenClaw and other agent frameworks:

  * **3-line configuration** in the agent's config file
  * **Automatic enrollment** on first run (key generation, invite consumption, fingerprint display)
  * **Persistent encrypted state** on disk for subsequent runs
  * **WebSocket connection** for real-time bidirectional messaging
  * **Message handler** that decrypts inbound messages, passes them to agent logic, and encrypts responses
</Accordion>

<Accordion title="Client SDK (@agentvault/client)">
  A standalone TypeScript SDK for third-party integrations:

  * **API key authentication** (no Clerk dependency)
  * **TOFU key exchange** (Trust On First Use)
  * **MLS/Double Ratchet E2E encryption** via the shared crypto library
  * **Programmatic access** to all AgentVault APIs
</Accordion>

### Backend (FastAPI)

The backend is a Python FastAPI application that handles:

| Responsibility       | Details                                                                       |
| -------------------- | ----------------------------------------------------------------------------- |
| **Enrollment**       | Invite generation, token validation (BLAKE2b hashes only), device approval    |
| **Message relay**    | Stores ciphertext in PostgreSQL BYTEA columns, relays via WebSocket           |
| **WebSocket**        | Real-time bidirectional relay using Redis pub/sub for horizontal scaling      |
| **Tenant isolation** | RLS policies on every tenant-scoped table, `tenant_id` scoping on every query |
| **Rate limiting**    | Redis-backed limits (enrollment: 5/IP/10min, messaging: 60/min)               |

<Warning>
  The backend has no access to private keys, no decryption capabilities, and no plaintext columns. Even a complete backend compromise exposes only ciphertext.
</Warning>

### Database (PostgreSQL)

All data is stored in PostgreSQL 18 with Row-Level Security enabled on every tenant-scoped table:

* **tenants** -- Tenant identity and status
* **users** -- Clerk-authenticated users with RBAC roles
* **devices** -- Device identity keys (public only), fingerprints, status
* **invites** -- BLAKE2b hashed tokens (raw tokens never stored)
* **conversations** -- Owner-to-agent session metadata
* **messages** -- `header_blob` (BYTEA) + `ciphertext` (BYTEA). No plaintext columns exist.

Every query passes through RLS enforcement:

```sql theme={null}
CREATE POLICY tenant_isolation ON messages
  USING (tenant_id = NULLIF(current_setting('app.current_tenant_id', true), '')::uuid);
```

### Cache and Pub/Sub (Redis)

Redis 7 serves two functions:

1. **WebSocket relay** -- Redis pub/sub routes messages between connected clients, enabling horizontal scaling across multiple backend instances.
2. **Rate limiting** -- Sliding window counters for enrollment, polling, and messaging endpoints.

## Cryptographic Primitives

| Function             | Primitive               | Why                                                                       |
| -------------------- | ----------------------- | ------------------------------------------------------------------------- |
| Key exchange         | X25519 (Diffie-Hellman) | Industry standard via libsodium `crypto_scalarmult`                       |
| Signing              | Ed25519                 | Device identity keys, proof-of-possession during enrollment               |
| Symmetric encryption | XChaCha20-Poly1305      | 192-bit nonce eliminates nonce reuse risk (unlike AES-GCM's 96-bit nonce) |
| Group key agreement  | MLS (RFC 9420)          | Scalable group encryption with per-epoch forward secrecy                  |
| KDF                  | HKDF-SHA-512            | Ratchet key derivation                                                    |
| Hashing              | BLAKE2b                 | Invite token hashing, device fingerprints                                 |

<Note>
  XChaCha20-Poly1305 was chosen over AES-256-GCM specifically because its 192-bit nonce is safe to generate randomly with negligible collision probability. In a high-volume messaging system, AES-GCM's 96-bit nonce creates a reuse risk that would result in full plaintext recovery. If FIPS compliance is later required, AES-256-GCM is a swap, not a rewrite.
</Note>

## Protocol Stack

### Encryption: MLS Primary, Double Ratchet Fallback

AgentVault uses **MLS (Messaging Layer Security, RFC 9420)** as the primary encryption protocol for all conversation types -- 1:1, rooms, and A2A channels. MLS provides scalable group key agreement with per-epoch forward secrecy via a ratchet tree structure.

The **Double Ratchet protocol** (with X3DH key exchange) remains as a fallback for legacy 1:1 sessions and backward compatibility with older clients. Both protocols use XChaCha20-Poly1305 as the underlying AEAD cipher.

**MLS flow:**

1. **Key package upload** during enrollment establishes the device's MLS credentials
2. **Group creation** builds a ratchet tree for all conversation participants
3. **Commit messages** advance the group epoch on membership changes
4. **Per-epoch forward secrecy** -- old epoch secrets are deleted after processing

**Double Ratchet fallback (legacy 1:1):**

1. **X3DH key agreement** during enrollment establishes a shared secret
2. **Symmetric ratchet** advances the chain key with every message
3. **DH ratchet** rotates the key agreement with every reply
4. **Forward secrecy** -- old message keys are deleted after decryption

### Message Flow

```
Owner types a message:
  1. Advance sending chain key
  2. Derive message key via KDF
  3. Generate random 24-byte nonce
  4. Encrypt with XChaCha20-Poly1305
  5. Sign header with Ed25519 identity key
  6. Send {header, signature, ciphertext} via WebSocket

Backend:
  7. Store ciphertext in PostgreSQL (BYTEA)
  8. Relay via Redis pub/sub to recipient

Agent receives:
  9. Verify header signature
  10. Advance receiving chain, derive message key
  11. Decrypt ciphertext
  12. Pass plaintext to agent logic
```

## Infrastructure

| Component    | Service                   | Notes                                           |
| ------------ | ------------------------- | ----------------------------------------------- |
| App server   | DigitalOcean Droplet      | 2 vCPU / 4GB, Docker deployment                 |
| Database     | DO Managed PostgreSQL 18  | Automated backups, SSL, connection pooling      |
| Cache/PubSub | DO Managed Redis 7        | TLS (`rediss://`), pub/sub for WebSocket relay  |
| Auth         | Clerk                     | JWT issuance, session management, custom domain |
| Frontend     | Expo (EAS Build) + Vercel | Native apps via EAS, web SPA on Vercel          |
| DNS/SSL      | Cloudflare                | Free tier, DDoS protection                      |

## Monorepo Structure

```
packages/
├── crypto/     # Shared TypeScript: MLS, Double Ratchet, X3DH, key generation
├── web/        # Expo universal app (iOS, Android, Web)
├── plugin/     # OpenClaw Node.js plugin
├── client/     # Third-party SDK
├── verify/     # Verification SDK (VCs, DID resolution)
├── site/       # Marketing site (Next.js)
└── backend/    # FastAPI Python backend (never decrypts)
```

The crypto library is the shared foundation -- both the web app and the plugin import it for identical encryption behavior. The backend never imports or uses the crypto library because it never handles plaintext.

## What's Next

<Card title="Zero-Knowledge Architecture" icon="lock" href="/architecture/zero-knowledge">
  Deep dive into what the server can and cannot see.
</Card>

<Card title="Threat Model" icon="shield" href="/architecture/threat-model">
  Security goals, threat actors, and mitigations.
</Card>

<Card title="Protocol Flows" icon="diagram-project" href="/architecture/sequence-diagrams">
  Visual sequence diagrams for enrollment, messaging, and device management.
</Card>
