Encryption
SwirlDB provides pluggable encryption at multiple levels through the EncryptionProvider trait.
All encryption works on all platforms (browser + server).
Encryption Architecture
Encryption Layers
- At-Rest Encryption: Data encrypted before storage (localStorage, IndexedDB, redb)
- Over-the-Wire: CRDT changes encrypted during sync between clients
- Field-Level: Selective encryption based on field patterns
Built-in Providers
UnencryptedProvider (Default)
No-op provider that passes data through unchanged. Use when encryption is handled externally (encrypted filesystem, TLS, etc.) or not required.
// Rust
use swirldb_core::encryption::UnencryptedProvider;
let provider = UnencryptedProvider::new();
// TypeScript
const provider = new UnencryptedProvider(); AesGcmProvider (AES-256-GCM)
Authenticated encryption with 256-bit keys. Provides confidentiality and authenticity.
// Rust
use swirldb_core::encryption::AesGcmProvider;
// Random key
let provider = AesGcmProvider::new_random();
// Fixed key (32 bytes)
let key = [0u8; 32]; // In production: use secure random
let provider = AesGcmProvider::new(&key);
// Derive from password
let provider = AesGcmProvider::from_password(
b"user-password",
b"unique-salt-12345"
).unwrap();
// TypeScript
const provider = await AesGcmProvider.fromPassword('password', 'salt'); FieldEncryptionProvider
Pattern-based selective encryption. Encrypts matching fields while leaving others in plaintext.
// Rust
use swirldb_core::encryption::{FieldEncryptionProvider, AesGcmProvider};
let mut provider = FieldEncryptionProvider::new();
// Encrypt all SSN fields
provider.add_pattern("*.ssn", Box::new(AesGcmProvider::new_random()));
// Encrypt all password fields
provider.add_pattern("user.*.password", Box::new(AesGcmProvider::new_random()));
// Everything else remains unencrypted Encryption At Rest
Browser Example
import { SwirlDB, AesGcmProvider } from '@swirldb/js';
// Create encrypted storage
const encryption = await AesGcmProvider.fromPassword(
'user-password',
'app-salt'
);
const db = await SwirlDB.withLocalStorage('my-app', {
encryption
});
// All data automatically encrypted before localStorage
db.data.user.ssn = '123-45-6789'; // Encrypted in storage
db.data.user.name = 'Alice'; // Encrypted in storage Server Example
use swirldb_core::{SwirlDB, encryption::AesGcmProvider};
use swirldb_server::storage::RedbAdapter;
// Create encrypted storage
let encryption = AesGcmProvider::new_random();
let storage = RedbAdapter::new("./data")
.with_encryption(encryption);
let db = SwirlDB::with_storage(storage, "db-key").await;
// All saves encrypted on disk
db.set_path("user.ssn", "123-45-6789".into())?;
db.persist().await?; // Encrypted to redb Encryption Over the Wire
For end-to-end encrypted sync, wrap CRDT changes before transmission. The server never sees plaintext data.
Encrypted Sync Example
use swirldb_core::encryption::AesGcmProvider;
// Shared encryption key (use key exchange in production)
let sync_key = [0u8; 32];
let provider = AesGcmProvider::new(&sync_key);
// Get local changes
let changes = db.get_changes();
// Encrypt each change
let encrypted_changes: Vec<Vec<u8>> = changes
.iter()
.map(|change| provider.encrypt(change).await.unwrap())
.collect();
// Send encrypted changes to server
sync_client.push(encrypted_changes).await?; Architecture
┌─────────┐ ┌─────────┐
│ Client │ │ Server │
│ │ │ │
│ CRDT │ │ CRDT │
│ ↓ │ │ ↓ │
│ Encrypt │ ──── Encrypted Wire ────→ │ Decrypt │
│ ↓ │ │ ↓ │
│ Storage │ │ Storage │
└─────────┘ └─────────┘
Server never sees plaintext data Security Best Practices
Key Management
- Browser: Store keys in IndexedDB, protect with Web Crypto API
- Server: Store keys in secure vault (HashiCorp Vault, AWS KMS)
- Never: Hard-code keys in source code or commit to git
Nonce Reuse
AES-GCM uses random nonces per encryption. Never reuse nonces with the same key. SwirlDB automatically generates fresh nonces for each encryption operation.
Authentication
AES-GCM provides authenticated encryption (AEAD). Tampering with ciphertext will fail decryption. This protects against data corruption and malicious modification.
Performance
- AES-GCM throughput: ~1GB/s on modern hardware
- Field-level encryption encrypts only matching fields
- Transport encryption (TLS/WSS) provides additional protection
- Encryption overhead: typically <5% for document operations
Future Enhancements
- X25519 key exchange for multi-party encryption
- RSA-OAEP for asymmetric encryption
- Automatic key rotation support
- Hardware security module (HSM) integration
- Pattern matching for field-level encryption