2.1 KiB
Password-store repository core
crates/storage::repository maps logical entry names directly to the upstream
password-store layout: team/service is stored as team/service.gpg and no
IronStorage-specific metadata is added. Discovery inventories ordinary
directories, encrypted entries, .gpg-id, .gpg-id.sig, auxiliary regular
files, and .git directory boundaries. Git contents are not mistaken for
password-store objects, and the innermost boundary applies to a nested entry.
Logical paths are relative component sequences. Absolute paths, . and ..,
empty entry paths, and entry paths with a trailing slash are rejected before
filesystem access. A trailing slash in display-path resolution explicitly
selects a directory. If both name.gpg and name/ exist, the unadorned name is
reported as ambiguous and mutations through the collision are rejected.
The repository is opened as a capability-scoped directory. All subsequent discovery, reads, temporary files, renames, and cleanup remain relative to that handle. Symlinks are rejected, and the capability layer prevents a raced link from escaping the selected vault. FIFOs, sockets, devices, and other special file types are also rejected; unrelated regular files remain visible as auxiliary repository objects.
Encrypted replacements are written to a temporary file in the destination directory, assigned private permissions on Unix, flushed to stable storage, atomically renamed over the destination, and followed by a directory sync. Before the rename, any error leaves the old entry intact and removes newly created empty directories. After the rename, the only possible observable state is the complete new entry; an interrupted directory sync is reported as durability-uncertain rather than pretending that rollback occurred. Empty ancestor cleanup uses directory-only removal and therefore stops at the store root, content, or a recipient-policy boundary.
Decrypted bytes use SecretBytes, which takes ownership without an additional
copy, redacts Debug, exposes data only through explicit methods, and zeroes
its allocation on drop.