Database Encryption
| This is an Enterprise Edition feature. |
Couchbase Lite JavaScript includes the ability to encrypt databases stored in IndexedDB. This allows browser applications to secure data at rest. The encryption uses the Web Crypto API with AES-GCM algorithm.
Encryption Limitations
Unlike native Couchbase Lite SDKs, browser-based encryption has limitations due to IndexedDB:
-
Indexed properties cannot be encrypted: IndexedDB requires these properties to remain accessible for indexing
-
Document IDs and metadata are not encrypted: IndexedDB uses these for document lookup
-
Field-level encryption: By default, all document properties are encrypted. Properties specified in the
indexesarray are automatically left unencrypted to allow indexing
-
All document properties except those specified in the
indexesarray -
All blobs (binary attachments)
-
Document IDs and revision IDs
-
Properties listed in the
indexesarray -
Database metadata
Enabling Encryption
To enable encryption, provide a password in the DatabaseConfig when opening the database. Provide this encryption password every time the database is opened — see Example 1.
const database = await Database.open({
name: 'secure-app',
password: 'my-secure-password',
collections: {
users: {
// Index properties are not encrypted by default
indexes: ['username', 'email', 'createdAt']
}
}
});
// Get the users collection
const users = database.getCollection("users");
await users.save({
username: 'alice', // Not encrypted (indexed property)
email: 'alice@example.com', // Not encrypted (indexed property)
createdAt: '2025-01-15', // Not encrypted (indexed property)
ssn: '123-45-6789', // Encrypted
creditCard: '4111-1111', // Encrypted
address: { // Encrypted (entire object)
street: '123 Main St',
city: 'Springfield'
}
});
Persisting the Encryption Key
Couchbase Lite does not persist the encryption key. It is the application’s responsibility to manage the key.
| There is no secure cross-session storage available in browsers. The encryption password must be obtained from the user each time the application loads, or stored using browser-specific mechanisms with appropriate security considerations. |
Opening Encrypted Databases
An encrypted database must be opened with the correct password:
try {
const database = await Database.open({
name: 'secure-app',
password: userEnteredPassword,
collections: { users: {} }
});
} catch (error) {
if (error instanceof EncryptionError) {
console.error('Incorrect password');
}
}
Changing the Encryption Key
To change an existing encryption key, open the database with its current password and use Database.changeEncryptionKey():
// Open database with current password
const database = await Database.open('secure-app', {
password: 'old-password',
collections: { users: {} }
});
// Change to new password
await database.changeEncryptionKey('new-password');
console.log('Encryption key changed');
Removing Encryption
To remove encryption, open the database with its current password and call changeEncryptionKey() with undefined:
// Open encrypted database
const database = await Database.open('secure-app', {
password: 'current-password',
collections: { users: {} }
});
// Remove encryption
await database.changeEncryptionKey(undefined);
console.log('Encryption removed');
Security Best Practices
When using database encryption in browser applications:
-
Password Management: Never hardcode encryption passwords. Always obtain them from user input or secure key management systems.
-
HTTPS Only: Always serve encrypted database applications over HTTPS to prevent password interception.
-
Memory Considerations: Be aware that decrypted data exists in browser memory during use.
-
Storage Clearing: Educate users that clearing browser data will delete encrypted databases.
-
Indexed Properties: Be aware that indexed properties are not encrypted. Only index properties that don’t contain sensitive data.