Skip to main content

Module file_store

Module file_store 

Source
Expand description

Built-in file-backed stores, for a host with a filesystem and no platform keystore.

The engine takes its two stores from the host (crate::OfflineProtocol::initialize_mls). The mobile bindings hand in the Keychain or Keystore and an app-container directory; a headless host on Linux has neither a keystore the SDK can assume nor a binding that writes files for it. These two stores are that host’s defaults:

  • FileProtocolStateStorage keeps restartable delivery state. It writes the same on-disk format as the Python, Swift and Kotlin providers, byte for byte, so a state directory is portable across bindings. Its values arrive already sealed by the engine for every sensitive category, exactly as they do for those providers.
  • SealedFileMlsStorage keeps identity keys, group state and the record key that seals the other store. It seals every record under a key derived from a store key the operator supplies through a StoreKeyProvider, and names its files with a keyed digest.

§Invariants

  • A write the store acknowledged survives a crash. Every store writes a temporary file, flushes it, renames it into place and flushes the directory. The engine writes state that depends on a returned Ok immediately (the record key is the sharp case), so an acknowledged write that is only staged is a data-loss bug, not a performance choice.
  • A load never allocates more than the ceiling. The file size is checked before the read and the read itself is capped, so a planted multi-gigabyte file costs a stat.
  • File names are fixed-length digests, never an encoding of the key. Case-insensitive volumes (APFS, NTFS by default) fold group:Team and group:team onto one file, and group ids are chosen by peers. A digest is lowercase hex whatever the key, so the key is compared byte for byte.
  • The sealed store never deletes on a read. A record that does not authenticate is reported as corrupt, with its path, and left in place. The common cause is the operator supplying the wrong store key, and deleting on that would destroy the identity. SealedFileMlsStorage::open refuses a wrong key before any record is read, so a record that fails afterwards is damaged, and the error names the file so the operator can decide.
  • One store per directory. Each store holds an exclusive lock on its account directory until it is closed or dropped, and a second store over the same directory, in this process or another, is refused with FileStoreError::InUse. Two stores over one MLS directory would each advance ratchet state the other never sees, and the groups would diverge without an error.
  • Releasing a directory never depends on who still holds the store. close releases the lock at once and makes every later operation an error. A host whose runtime decides when an object is freed (a garbage collector, a reference cycle through a callback) would otherwise hold the directory for as long as anything, anywhere, kept a reference.

§Layout

Each store owns <root>/<namespace>/, where the namespace is account_storage_namespace of the application id and profile, the same derivation every binding uses. The two stores use different directory prefixes and different lock files, so they do not collide if given one root, but they should not share one: protocol state is scoped to an installation and is meant to be removed with it, while MLS material may outlive it.

Structs§

EnvStoreKey
A store key read from an environment variable, as 64 hex digits or as standard base64 (padded or not).
FileProtocolStateStorage
Protocol-state storage in plain files, in the format the Python, Swift and Kotlin providers write.
FileStorePair
The MLS store and the protocol-state store of one account, opened together.
SealedFileMlsStorage
MLS storage in files, every record sealed under a key derived from the operator’s store key.
StaticStoreKey
A store key the host already holds.

Enums§

FileStoreError
Why a built-in file store could not be opened, or could not answer a question about its directory.
SealedState
What the record key an MLS store holds makes of the sealed records in a protocol-state store.
StoreKeyError
Why a StoreKeyProvider produced no key.

Constants§

STORE_KEY_BYTES
Length of a store key.

Traits§

StoreKeyProvider
Supplies the store key that super::SealedFileMlsStorage seals under.

Functions§

account_storage_namespace
Returns the opaque, filesystem-safe namespace for one protocol account.
is_account_storage_namespace
Whether value is a well-formed account namespace.