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:
FileProtocolStateStoragekeeps 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.SealedFileMlsStoragekeeps 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 aStoreKeyProvider, 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
Okimmediately (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:Teamandgroup:teamonto 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::openrefuses 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.
closereleases 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§
- EnvStore
Key - A store key read from an environment variable, as 64 hex digits or as standard base64 (padded or not).
- File
Protocol State Storage - Protocol-state storage in plain files, in the format the Python, Swift and Kotlin providers write.
- File
Store Pair - The MLS store and the protocol-state store of one account, opened together.
- Sealed
File MlsStorage - MLS storage in files, every record sealed under a key derived from the operator’s store key.
- Static
Store Key - A store key the host already holds.
Enums§
- File
Store Error - Why a built-in file store could not be opened, or could not answer a question about its directory.
- Sealed
State - What the record key an MLS store holds makes of the sealed records in a protocol-state store.
- Store
KeyError - Why a
StoreKeyProviderproduced no key.
Constants§
- STORE_
KEY_ BYTES - Length of a store key.
Traits§
- Store
KeyProvider - Supplies the store key that
super::SealedFileMlsStorageseals under.
Functions§
- account_
storage_ namespace - Returns the opaque, filesystem-safe namespace for one protocol account.
- is_
account_ storage_ namespace - Whether
valueis a well-formed account namespace.