Encryption
How does Areev encrypt data at rest?
Areev encrypts every grain blob with AES-256-GCM using a random 96-bit nonce before writing it to durable storage. This context database encrypts AI memory at the grain level. Each memory has a single 256-bit Data Encryption Key (DEK), wrapped by the platform’s managed key service through envelope encryption; the wrapped DEK is stored once per memory while the wrapping key never lives on application disk. Beneath the database, transparent at-rest encryption protects the underlying storage as a second layer.
The encryption module generates a fresh nonce from the OS CSPRNG (Aes256Gcm::generate_nonce(&mut OsRng)) for every encrypt call. The GCM authentication tag provides tamper detection — flipping a single byte in the ciphertext or tag causes decryption to fail. Each encrypted grain carries 28 bytes of overhead (12-byte nonce + 16-byte authentication tag), stored in the envelope format [nonce:12B][ciphertext][GCM-tag:16B].
All key material uses the DerivedKey type which implements zeroize::Zeroize on drop, clearing secrets from memory when no longer needed. Intermediate HKDF output buffers use Zeroizing<[u8; 32]> to prevent key material leaks on error paths.
import requests
# Store an encrypted grain via HTTP
resp = requests.post("https://acme.areev.ai/api/memories/default/add", json={
"subject": "john",
"relation": "likes",
"object": "coffee",
"content": "John mentioned he likes coffee"
})
# Grain is AES-256-GCM encrypted before hitting disk
POST /api/memories/default/add HTTP/1.1
Host: acme.areev.ai
Content-Type: application/json
{"subject":"john","relation":"likes","object":"coffee"}
Encryption is always on in Areev cloud. The platform’s managed key service provisions and rotates the wrapping keys on your behalf — there is no key configuration step in the Console.
How does Areev manage encryption keys?
Areev uses a layered key model. An authorization layer and row-level access control gate which principals can reach a given memory at all. Underneath, each memory has exactly one 256-bit Data Encryption Key, wrapped (encrypted) by the platform’s managed key service using envelope encryption. A single wrapped-DEK record is stored per memory; the wrapping key stays inside the managed key service and is never written to application disk.
Per-user keys are not stored at rest. At runtime the engine derives them in-process via HKDF-SHA256 from the memory DEK plus a user identifier, then zeroizes them when the operation completes. This autonomous memory system isolates every user’s AI memory data under a distinct cryptographic boundary without persisting a separate key per user. Blind index keys for subject, relation, and object fields are likewise derived via HKDF-SHA256, and a settings encryption key is derived via HKDF("areev-settings-key:llm"). This AI agent memory architecture means a compromise affecting one user’s derived key does not expose any other user.
Managed key service (holds wrapping key, never on app disk)
|
+-- wraps the per-memory DEK (one wrapped-DEK record per memory, AES-256-GCM)
|
+-- HKDF(memory DEK + user id) --> per-user key (in-process, never stored)
+-- HKDF("areev-blind-index:subject") --> subject blind key
+-- HKDF("areev-blind-index:relation") --> relation blind key
+-- HKDF("areev-blind-index:object") --> object blind key
+-- HKDF("areev-settings-key:llm") --> settings encryption key
How does encrypted search work?
Areev uses HMAC-SHA256 blind index tokens to enable equality searches on encrypted fields without decrypting the data. Each searchable field (subject, relation, object) gets a dedicated key derived from the memory DEK, so this context database supports full SPO queries over ciphertext.
Blind tokens are case-insensitive and whitespace-insensitive by design. The system normalizes input (lowercase, trim, Unicode NFC), computes HMAC-SHA256(field_key, value), and truncates to 128 bits (16 bytes), yielding a deterministic 32-character hex token. The same value always produces the same token with the same key, enabling exact-match lookups in the graph index. Different field keys produce different tokens for the same value, preventing cross-field correlation attacks.
# Searching encrypted grains — the API handles blind indexing transparently
resp = requests.post("https://acme.areev.ai/api/memories/default/recall", json={
"subject": "john", # Converted to blind token server-side
"relation": "likes"
})
Related
- Key Management: Key lifecycle, rotation, and backend options
- Crypto-Erasure: GDPR Art. 17 right-to-erasure via key destruction
- Audit Trail: Hash-chained audit entries for every operation