Architecture
Understanding how DCP components work together to provide secure delegated access.
System Overview
┌─────────────────────────────────────────────────────────────┐
│ USER INTERFACES │
├────────────────┬────────────────┬───────────────────────────┤
│ CLI (Human) │ REST (Local) │ MCP (AI Agents) │
│ dcp init │ localhost:8420 │ Claude Desktop/Cursor │
└────────────────┴────────┬───────┴───────────────────────────┘
│
┌─────────────────────────┴────────────────────────────────────┐
│ DCP CORE │
├────────────┬─────────────┬─────────────┬────────────────────┤
│ Crypto │ Wallet │ Budget │ Storage │
│ Engine │ Manager │ Engine │ Layer │
│ │ │ │ │
│ XChaCha20 │ Solana │ Rate limits │ SQLite DB │
│ Argon2id │ Ethereum │ Budgets │ Encrypted records │
│ Envelope │ Base │ Approvals │ Sessions │
│ encryption │ Signing │ │ Audit log │
└────────────┴─────────────┴─────────────┴────────────────────┘
│
┌─────────────────────────┴────────────────────────────────────┐
│ STORAGE │
├──────────────────────────────────────────────────────────────┤
│ SQLite Database (~/.dcp/vault.db) │
│ • vault_records: Encrypted data (wallets, personal info) │
│ • sessions: Active agent sessions │
│ • pending_consents: Awaiting approval │
│ • spend_events: Transaction history │
│ • audit_events: Immutable operation log │
│ • config: Vault settings │
├──────────────────────────────────────────────────────────────┤
│ Master Key Storage │
│ • Primary: OS Keychain (macOS/Windows/Linux) │
│ • Fallback: Encrypted file (~/.dcp/master.key) │
└──────────────────────────────────────────────────────────────┘Data Flow: Transaction Signing
Understanding how a transaction signing request flows through the system:
┌─────────────┐
│ AI Agent │ 1. Request to sign 1.5 SOL transaction
└──────┬──────┘
│
▼
┌──────────────┐
│ MCP/REST │ 2. Check if session exists with sign:solana scope
│ Interface │
└──────┬───────┘
│
▼
┌──────────────┐
│ Vault │ 3. No session? → Create consent request
│ Storage │ Session exists? → Check budget
└──────┬───────┘
│
▼
┌──────────────┐
│ Budget │ 4. Check:
│ Engine │ • Per-tx limit (5 SOL) ✓
└──────┬───────┘ • Daily budget (20 SOL, 15 used) ✓
│ • Amount: 1.5 SOL ✓
│ • Under auto-approve threshold (2 SOL)? ✓
▼
┌──────────────┐
│ Consent │ 5. Below threshold → Auto-approved
│ System │ OR Above threshold → User popup
└──────┬───────┘
│
▼
┌──────────────┐
│ Crypto │ 6. Decrypt private key from storage
│ Engine │ • Key exists in memory for ~5ms
└──────┬───────┘ • Sign transaction
│ • Zeroize key from memory immediately
▼
┌──────────────┐
│ Audit Log │ 7. Record event:
└──────┬───────┘ • Agent: TradingBot
│ • Action: SIGN
│ • Amount: 1.5 SOL
▼ • Status: APPROVED
┌──────────────┐
│ Response │ 8. Return signed transaction to agent
│ │ • Agent receives: signature + signed_tx
└──────────────┘ • Agent NEVER sees: private keyEncryption Architecture
Master Key Storage
The master key is protected by Argon2id key derivation:
User Passphrase ──▶ Argon2id (64MB RAM, 3 iter) ──▶ Wrapping Key
│
▼
┌───────────────┐
│ Master Key │
│ (encrypted) │
└───────────────┘
│
Storage Priority: │
1. OS Keychain (macOS Keychain, Windows Credential Mgr) │
2. Encrypted file (~/.dcp/master.key) ◀────────────────────┘Envelope Encryption
Every record uses two-layer envelope encryption:
┌──────────────────────────────────────────────────────┐ │ Encrypted Record Structure │ ├──────────────────────────────────────────────────────┤ │ │ │ 1. DEK Nonce (24 bytes) ──────────────┐ │ │ │ │ │ 2. DEK Ciphertext ◀─── Master Key ────┘ │ │ (32 bytes encrypted DEK + 16 byte tag) │ │ │ │ 3. Data Nonce (24 bytes) ─────────────┐ │ │ │ │ │ 4. Data Ciphertext ◀─── DEK ───────────┘ │ │ (variable length + 16 byte tag) │ │ │ └──────────────────────────────────────────────────────┘ Decryption: 1. Use Master Key to decrypt DEK 2. Use DEK to decrypt actual data 3. Zeroize DEK from memory immediately
Cryptographic Algorithms
| Component | Algorithm | Parameters |
|---|---|---|
| Symmetric encryption | XChaCha20-Poly1305 | 256-bit key, 192-bit nonce, AEAD |
| Key derivation | Argon2id | 64MB memory, 3 iterations, 4 parallelism |
| Recovery phrase | BIP-39 | 128-bit entropy, 12 words |
| Master key derivation | PBKDF2 (via BIP-39) | SHA-512, 2048 iterations |
| Wallet (Solana) | Ed25519 | 32-byte seed |
| Wallet (EVM) | secp256k1 | ECDSA signing |
Session Management
Sessions allow agents to make multiple requests without repeated consent prompts:
┌─────────────────┐
│ Created │
│ (via consent) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Active │◀──────┐
│ │ │ Activity
└────────┬────────┘ │ updates
│ │ last_used_at
┌──────────────┼──────────────┘
│ │
▼ ▼
┌───────────────┐ ┌──────────┐
│ Idle Timeout │ │ Max TTL │
│ (30 min) │ │ (4 hour) │
└───────┬───────┘ └────┬─────┘
│ │
└──────┬───────┘
│
▼
┌─────────────────┐
│ Expired │
└─────────────────┘Scope Matching
Sessions grant access to specific scopes with wildcard support:
| Granted Scope | Request Scope | Match? |
|---|---|---|
sign:solana | sign:solana | ✅ Yes |
read:identity.* | read:identity.email | ✅ Yes |
read:identity.* | read:identity.passport | ✅ Yes |
read:identity.email | read:identity.passport | ❌ No |
sign:* | sign:ethereum | ✅ Yes |
Budget Enforcement
Budget checks happen before every transaction signing:
Request: Sign 0.5 SOL transaction
│
▼
┌─────────────────────────┐
│ Check per-tx limit │ Default: 5 SOL
│ Requested: 0.5 SOL │ ✓ Under limit
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Check daily budget │ Daily: 20 SOL
│ Already spent: 15 SOL │ Remaining: 5 SOL
│ Requested: 0.5 SOL │ ✓ Within budget
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Check approval threshold│ Threshold: 2 SOL
│ Requested: 0.5 SOL │ ✓ Below threshold
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ AUTO-APPROVED │ Transaction signed
│ (no user popup needed) │ without user interaction
└─────────────────────────┘Remote Access Architecture
For agents running on remote servers (VPS), DCP uses an encrypted relay system:
┌─────────────────────────────────────────────────────────────┐
│ REMOTE VPS SERVER │
│ ┌────────────┐ ┌─────────────────┐ │
│ │ AI Agent │──────────▶│ DCP Proxy │ │
│ │ │ localhost │ (localhost:8420)│ │
│ └────────────┘ :8420 └────────┬────────┘ │
│ │ │
│ Encrypts with │
│ vault's HPKE │
│ public key │
└─────────────────────────────────────┼────────────────────────┘
│
│ WSS (TLS)
▼
┌───────────────────────┐
│ Relay Server │
│ relay.dcp.1ly.store │
│ │
│ • Transport only │
│ • Can't decrypt data │
│ • Routes messages │
└───────────┬───────────┘
│ WSS (TLS)
▼
┌─────────────────────────────────────┼────────────────────────┐
│ LOCAL MACHINE │
│ ┌─────────────┐ ┌────────────┐ │
│ │ DCP Vault │◀──────────│ Relay │ │
│ │ │ Decrypts │ Client │ │
│ │ • Signs tx │ with │ │ │
│ │ • Logs │ private │ │ │
│ │ • Enforces │ HPKE key │ │ │
│ └─────────────┘ └────────────┘ │
└──────────────────────────────────────────────────────────────┘
Security:
✓ End-to-end encryption (HPKE)
✓ Relay sees only encrypted blobs
✓ Private keys never leave local machine
✓ Budget/consent enforced locallyDatabase Schema
vault_records
Stores encrypted data (wallets, personal information):
| Column | Type | Description |
|---|---|---|
| id | TEXT | UUID primary key |
| scope | TEXT | Hierarchical scope (e.g., wallet:solana) |
| item_type | TEXT | WALLET_KEY | PERSONAL_DATA |
| sensitivity | TEXT | standard | sensitive | critical |
| chain | TEXT | Blockchain (for wallets): solana | ethereum | base |
| public_address | TEXT | Public wallet address (for wallets) |
| encrypted_payload | BLOB | Envelope-encrypted data |
| created_at | TEXT | ISO timestamp |
| updated_at | TEXT | ISO timestamp |
sessions
Active agent sessions with granted permissions:
| Column | Type | Description |
|---|---|---|
| id | TEXT | UUID session ID |
| agent_name | TEXT | Agent identifier |
| granted_scopes | TEXT | JSON array of scopes |
| consent_mode | TEXT | once | session |
| expires_at | TEXT | Session expiry timestamp |
| created_at | TEXT | Creation timestamp |
| last_used_at | TEXT | Last activity timestamp |
Security Guarantees
What DCP Guarantees
- ✅ Private keys exist in plaintext for <5ms during signing operations
- ✅ Keys are immediately zeroized from memory after use
- ✅ No export function exists - keys cannot be extracted
- ✅ Budget limits are enforced at the vault level (agents cannot bypass)
- ✅ All operations are logged immutably
- ✅ Encryption uses battle-tested algorithms (XChaCha20, Argon2id)
What DCP Doesn't Protect Against
- ❌ Physical device compromise (assumes trusted execution environment)
- ❌ Operating system compromise (assumes OS security is maintained)
- ❌ Recovery phrase theft (phrase = full vault access)
- ❌ User approving malicious requests (you must review consent popups)