Encryption
Envelope encryption with Ed25519 signing for end-to-end data protection across devices.
Envelope encryption
Persist uses envelope encryption to protect data at rest and in transit. Each record is encrypted with a unique data encryption key (DEK). The DEK itself is encrypted with a key-encryption key (KEK) derived from your master key. This two-layer approach means rotating the master key does not require re-encrypting every record.
Plaintext → [DEK] → Ciphertext
DEK → [KEK] → Encrypted DEK
KEK ← Master Key
Enabling encryption
Pass an encryption configuration when creating a store. Persist generates and manages DEKs automatically.
import { createStore } from "@cuitty/persist";
const store = await createStore("secrets", {
adapter: "sqlite",
path: "./secrets.db",
encryption: {
algorithm: "aes-256-gcm",
masterKey: process.env.PERSIST_MASTER_KEY,
},
});
// Writes are encrypted transparently
await store.records.put("api-key:stripe", {
key: "sk_live_...",
created: Date.now(),
});
Ed25519 signing
Every sync payload is signed with an Ed25519 keypair. The receiving device verifies the signature before applying changes. This prevents tampered data from being merged into the local store.
import { createStore, enableSync, generateKeyPair } from "@cuitty/persist";
const keypair = await generateKeyPair();
await enableSync(store, {
remote: "https://sync.persist.one",
signing: {
algorithm: "ed25519",
publicKey: keypair.publicKey,
privateKey: keypair.privateKey,
},
});
Key management
Persist provides utilities for key generation, rotation, and export. Keys can be stored in environment variables, OS keychains, or external vaults.
import { generateKeyPair, exportKey, importKey } from "@cuitty/persist";
// Generate a new keypair
const kp = await generateKeyPair();
// Export for backup
const exported = exportKey(kp.privateKey, "base64");
// Import from backup
const restored = importKey(exported, "base64");
Key rotation re-wraps existing DEKs under a new KEK without decrypting and re-encrypting the underlying data. This operation is atomic and safe to run while the store is in use.
Threat model
Encryption protects against unauthorized access to the storage backend (a stolen device, a compromised database server). It does not protect against a compromised application process that holds the master key in memory.