pub struct PasswordStore<S: Store> { /* private fields */ }Expand description
Password-encrypted store wrapper.
Wraps any Store type with transparent AES-256-GCM encryption using
password-derived keys (Argon2id). The type parameter S specifies the
wrapped store type, and PasswordStore<S> delegates Store::Data to
S::Data — encryption is a transport-level concern invisible at the type level.
§Type Parameter
S- The wrapped store type (e.g.,DocStore,Table<T>)
§State Machine
PasswordStore has three states (derived from internal fields):
- Uninitialized - Created via
get_store(), no encryption configured - Locked - Has encryption config, not yet decrypted
- Unlocked - Decrypted and ready to use
State transitions:
get_store()→ Uninitialized (new) or Locked (existing)initialize()→ Unlocked (from Uninitialized only)open()→ Unlocked (from Locked only)
§Security
- Encryption: AES-256-GCM authenticated encryption
- Key Derivation: Argon2id memory-hard password hashing
- Nonces: Unique random nonce per encryption operation
- Zeroization: Passwords cleared from memory on drop
§Limitations
- Password Loss: Losing the password means permanent data loss
- Performance: Encryption/decryption overhead on every operation
§Examples
Creating a new encrypted store:
let tx = db.new_transaction().await?;
let mut encrypted = tx.get_store::<PasswordStore<DocStore>>("secrets").await?;
encrypted.initialize("my_password", Doc::new()).await?;
let docstore = encrypted.inner().await?;
docstore.set("key", "secret value").await?;
tx.commit().await?;Opening an existing encrypted store:
let tx = db.new_transaction().await?;
let mut store = tx.get_store::<PasswordStore<DocStore>>("secrets").await?;
store.open("my_password")?;
let docstore = store.inner().await?;
let value = docstore.get("key").await?;Implementations§
Source§impl<S: Store> PasswordStore<S>
impl<S: Store> PasswordStore<S>
Sourcepub async fn initialize(
&mut self,
password: impl Into<String>,
wrapped_config: Doc,
) -> Result<()>
pub async fn initialize( &mut self, password: impl Into<String>, wrapped_config: Doc, ) -> Result<()>
Initialize encryption on an uninitialized store
This configures encryption for a PasswordStore that was obtained via
get_store(). The wrapped store’s type (derived from S) and config
are encrypted and stored in the PasswordStore’s configuration in _index.
After calling this method, the store transitions to the Unlocked state and is ready to use.
§Arguments
password- Password for encryption (will be zeroized after use)wrapped_config- Configuration for wrapped store
§Returns
Ok(()) on success, the store is now unlocked
§Errors
- Returns error if store is not in Uninitialized state
- Returns error if encryption fails
§Examples
let tx = db.new_transaction().await?;
let mut encrypted = tx.get_store::<PasswordStore<DocStore>>("secrets").await?;
encrypted.initialize("my_password", Doc::new()).await?;
let docstore = encrypted.inner().await?;
docstore.set("key", "secret value").await?;
tx.commit().await?;Sourcepub fn open(&mut self, password: impl Into<String>) -> Result<()>
pub fn open(&mut self, password: impl Into<String>) -> Result<()>
Open (unlock) the encrypted store with a password
This decrypts the wrapped store configuration and caches the password for subsequent encrypt/decrypt operations.
§Arguments
password- Password to decrypt the store
§Returns
Ok(()) if password is correct, Err otherwise
§Errors
- Returns error if store is Uninitialized (use
initialize()first) - Returns error if store is already Unlocked
- Returns error if password is incorrect
§Security
The password is cached in memory (with zeroization on drop) for convenience.
Sourcepub fn is_initialized(&self) -> bool
pub fn is_initialized(&self) -> bool
Check if the store is initialized (has encryption configuration)
Sourcepub async fn inner(&self) -> Result<S>
pub async fn inner(&self) -> Result<S>
Get the wrapped store, providing transparent encryption.
Returns the inner S store instance that transparently encrypts data
on write and decrypts on read. The wrapped store is unaware of
encryption — all crypto operations are handled by an encryptor
registered with the transaction during open() or initialize().
§Errors
- Returns error if store is not opened (call
open()first)
§Examples
let mut encrypted = tx2.get_store::<PasswordStore<DocStore>>("test").await?;
encrypted.open("pass")?;
let docstore = encrypted.inner().await?;
docstore.set("key", "value").await?; // Automatically encryptedTrait Implementations§
Source§impl<S: Store> Registered for PasswordStore<S>
impl<S: Store> Registered for PasswordStore<S>
Source§impl<S: Store> Store for PasswordStore<S>
impl<S: Store> Store for PasswordStore<S>
Source§type Data = <S as Store>::Data
type Data = <S as Store>::Data
Source§fn new<'life0, 'async_trait>(
txn: &'life0 Transaction,
subtree_name: String,
) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn new<'life0, 'async_trait>(
txn: &'life0 Transaction,
subtree_name: String,
) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Store handle associated with a specific transaction. Read moreSource§fn init<'life0, 'async_trait>(
txn: &'life0 Transaction,
subtree_name: String,
) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn init<'life0, 'async_trait>(
txn: &'life0 Transaction,
subtree_name: String,
) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
_index. Read moreSource§fn transaction(&self) -> &Transaction
fn transaction(&self) -> &Transaction
Source§fn default_config() -> Doc
fn default_config() -> Doc
Source§fn get_config<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Doc>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_config<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Doc>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
_index subtree. Read moreSource§fn set_config<'life0, 'async_trait>(
&'life0 self,
config: Doc,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn set_config<'life0, 'async_trait>(
&'life0 self,
config: Doc,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
_index subtree. Read moreSource§fn get_height_strategy<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<HeightStrategy>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_height_strategy<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<HeightStrategy>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
_index subtree. Read moreAuto Trait Implementations§
impl<S> Freeze for PasswordStore<S>
impl<S> !RefUnwindSafe for PasswordStore<S>
impl<S> Send for PasswordStore<S>
impl<S> Sync for PasswordStore<S>
impl<S> Unpin for PasswordStore<S>where
S: Unpin,
impl<S> !UnwindSafe for PasswordStore<S>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CompatExt for T
impl<T> CompatExt for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more