StorageKeyProvider

Supplies storage encryption keys. Key storage is the provider's job, never the database's: a key kept next to the records it protects protects nothing. Platform providers (Android Keystore, Apple Keychain, an application secret store) implement this interface.

A provider holds key material only. Which key is current, and whether a storage key rotation is running, is recorded in the database (docs/storage-key-rotation.md); the database also allocates key IDs.

A provider must never hand out a replacement for a key it lost: storage that was encrypted before then fails closed (see key).

Inheritors

Functions

Link copied to clipboard
abstract suspend fun createKey(id: StorageKeyId): StorageEncryptionKey

Creates key id for a storage key rotation and returns it once it is persisted and read back. If the provider already has key id, returns that key unchanged: a key is never overwritten or replaced, so a repeated or concurrent call yields the same key. Other keys are not touched. Throws StorageEncryptionException.KeyUnavailable if the provider holds no key yet (rotation needs provisioned storage) or its state cannot be read; nothing is changed then.

Link copied to clipboard
abstract suspend fun hasKeys(): Boolean

Whether the provider holds any key. Never creates, rotates, repairs or replaces a key, and changes nothing. Throws StorageEncryptionException.KeyUnavailable if the provider's state exists but cannot be read (it never reports such state as empty).

Link copied to clipboard
abstract suspend fun key(id: StorageKeyId): StorageEncryptionKey?

The existing key id, or null if the provider does not have it. Never creates a key: this is called for storage that is already encrypted with id.

Link copied to clipboard
abstract suspend fun loadOrCreateKey(): StorageEncryptionKey

The key for storage that has no key bound yet: a new database, or a database from before record encryption that is about to be encrypted. Returns the provider's only key, or creates and persists key ID 1 if the provider has none. Throws StorageEncryptionException.KeyUnavailable if the provider holds several keys (its namespace belongs to a database in or after a storage key rotation) or no key can be provided.

Link copied to clipboard
abstract suspend fun removeKey(id: StorageKeyId): Boolean

Removes key id, for retiring a storage key after a rotation proved that no record uses it. Returns true if this call removed it and false if the provider did not have it. Other keys are not touched. Throws IllegalStateException and changes nothing if id is the provider's last key: a provider never removes all of its keys.