Encryption Architecture
Client-side encryption for complete data protection.
Overview
Raven implements client-side encryption for all memory blobs stored on Walrus. This protects conversation data from unauthorized access while allowing agents to autonomously retrieve and decrypt data for context assembly.
Threat Model
Protected Against
- - External discovery layers scanning Walrus data
- - Unauthorized blob retrieval via leaked IDs
- - Data exposure from compromised storage nodes
- - Accidental public disclosure of blob contents
- - Cross-tenant data access
Not Protected Against
- - Compromised API service with key access
- - Sui registry metadata (tenant_id, timestamps)
- - Blob IDs registered on-chain (discoverable)
Encryption Algorithm
AES-256-GCM (Authenticated Encryption with Associated Data) provides both confidentiality and integrity. The authentication tag ensures any tampering is detected during decryption.
Encrypted Payload Format
interface EncryptedPayload {
algorithm: 'AES-256-GCM'; // Algorithm identifier
version: number; // Key version (for rotation)
iv: string; // Base64-encoded IV (12 bytes)
auth_tag: string; // Base64-encoded auth tag (16 bytes)
ciphertext: string; // Base64-encoded encrypted data
key_id?: string; // Optional key identifier
}Encryption Flow
How data is encrypted during ingestion:
User Interaction
↓
Memory Ingestion Service
↓
Serialize MemoryBlob → JSON
↓
Hash (SHA-256) ← for integrity verification
↓
Encrypt (AES-256-GCM) ← tenant-scoped key
↓
Serialize EncryptedPayload → JSON
↓
Store to Walrus (encrypted bytes)
↓
Register metadata on Sui (blob_id, content_hash)Decryption Flow
How data is decrypted during retrieval:
Query from Agent (with API Key)
↓
Auth Middleware (validate tenant)
↓
Memory Retrieval Service
↓
Fetch blob_id from Tier2 (tenant-scoped)
↓
Retrieve encrypted bytes from Walrus
↓
Deserialize EncryptedPayload ← JSON
↓
Decrypt (AES-256-GCM) ← tenant-scoped key
↓
Parse MemoryBlob ← JSON
↓
Validate schema
↓
Return conversation contextKey Management
Encryption keys are scoped by tenant and user for complete isolation:
// Key identifier format
const keyId = `${tenant_id}:${user_id}`;
// Example: "ten_abc123:usr_xyz789"
// This ensures:
// - Tenant isolation: Different tenants can't decrypt each other's data
// - User isolation: Different users have separate keys
// - Key rotation: Keys can be rotated per-tenantKey Storage Options
Development (In-Memory)
Keys auto-generated per user, stored in memory. Lost on restart.
ENCRYPTION_KEY_STORAGE=memoryEnvironment-Based (Simple Production)
Master key from environment, per-user keys derived.
ENCRYPTION_KEY_STORAGE=env
ENCRYPTION_MASTER_KEY=your-256-bit-hex-keyExternal KMS (Recommended for Production)
Integration with AWS KMS, Google Cloud KMS, Azure Key Vault, or HashiCorp Vault.
ENCRYPTION_KEY_STORAGE=kms
KMS_PROVIDER=aws
KMS_KEY_ID=arn:aws:kms:us-east-1:123456789:key/...Key Rotation
The version field in EncryptedPayload supports key rotation:
Security Properties
| Property | Status | Details |
|---|---|---|
| Confidentiality | Provided | AES-256 provides ~2^256 security level |
| Integrity | Provided | GCM auth tag + SHA-256 content hash |
| Authenticity | Provided | Tampering causes decryption failure |
| Forward Secrecy | Optional | Can be achieved with per-conversation keys |
Privacy Considerations
What Remains Public (on Sui)
- •
blob_id- The Walrus blob identifier - •
user_id- The user owning the blob - •
blob_type- episodic, semantic, or embeddings - •
created_at- Timestamp - •
expires_at- Expiration timestamp - •
owner- Sui address of blob owner
Metadata Leakage Mitigation
Configuration
# Enable/disable encryption (default: true)
ENCRYPTION_ENABLED=true
# Key storage backend (memory | env | kms)
ENCRYPTION_KEY_STORAGE=env
# Master key for env-based storage (256-bit hex)
ENCRYPTION_MASTER_KEY=your-master-key-hex
# KMS Configuration (if using KMS)
KMS_PROVIDER=aws
KMS_KEY_ID=arn:aws:kms:region:account:key/id
KMS_REGION=us-east-1