Implement the safe password-store repository core #3

Closed
opened 2026-08-09 18:54:51 +00:00 by hugo · 1 comment
Owner

Objective

Implement the safe password-store repository and entry model in crates/storage.

Scope

  • Map logical entry paths to the ordinary pass tree and .gpg files without introducing a new on-disk format.
  • Discover directories, entries, .gpg-id, .gpg-id.sig, and the innermost applicable Git repository.
  • Reject traversal, absolute-entry paths, symlink escapes, unsupported file types, and collisions between entries and directories.
  • Provide atomic writes, durable rename/replace behavior, cleanup of empty directories, and rollback on failed operations.
  • Keep decrypted data in secret-aware types and minimize copies and lifetime.

Acceptance criteria

  • Fixture tests cover normal trees, nested trees, Unicode names, entry/directory ambiguity, hostile paths and symlinks, interrupted writes, and empty cleanup.
  • No partial encrypted entry or repository mutation remains after an error.
  • All storage-derived objects live in crates/storage.

Prerequisites

Compatibility fixture harness.

## Objective Implement the safe password-store repository and entry model in `crates/storage`. ## Scope - Map logical entry paths to the ordinary pass tree and `.gpg` files without introducing a new on-disk format. - Discover directories, entries, `.gpg-id`, `.gpg-id.sig`, and the innermost applicable Git repository. - Reject traversal, absolute-entry paths, symlink escapes, unsupported file types, and collisions between entries and directories. - Provide atomic writes, durable rename/replace behavior, cleanup of empty directories, and rollback on failed operations. - Keep decrypted data in secret-aware types and minimize copies and lifetime. ## Acceptance criteria - Fixture tests cover normal trees, nested trees, Unicode names, entry/directory ambiguity, hostile paths and symlinks, interrupted writes, and empty cleanup. - No partial encrypted entry or repository mutation remains after an error. - All storage-derived objects live in `crates/storage`. ## Prerequisites Compatibility fixture harness.
hugo added this to the 01 - Full Rust pass CLI parity milestone 2026-08-09 18:54:51 +00:00
hugo added the enhancement label 2026-08-09 18:54:51 +00:00
Author
Owner

Implemented in commit 8e4c939 (pushed to main).

Added the storage-owned, capability-scoped password-store repository core. Logical entries map directly to upstream .gpg paths with no new format. Deterministic discovery covers directories, encrypted entries, .gpg-id/.gpg-id.sig policies, auxiliary regular files, and innermost nested .git boundaries. Typed validation rejects absolute/traversal paths, entry/directory ambiguity, symlinks, special file types, invalid Git boundaries, and mutation collisions.

Encrypted writes use same-directory capability temporary files, private Unix permissions, file sync, atomic replacement, and directory sync. Pre-rename failures retain the old entry and roll back newly created empty directories; post-rename interruption reports durability uncertainty while retaining a complete new entry. Empty ancestor cleanup stops at content, policy, or root boundaries. SecretBytes owns decrypted bytes, redacts Debug, and zeroes memory on drop.

Related verification:

  • cargo test -p ironstorage --test repository_core (9 fixture-backed core tests)
  • cargo test -p ironstorage repository::tests (3 interruption/rollback unit tests tied to layouts.toml recipes)
  • cargo fmt --all -- --check
  • RUSTFLAGS=-D warnings cargo check --workspace --all-targets
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace

All unrelated and compatibility fixture tests remained green.

Implemented in commit 8e4c939 (pushed to main). Added the storage-owned, capability-scoped password-store repository core. Logical entries map directly to upstream .gpg paths with no new format. Deterministic discovery covers directories, encrypted entries, .gpg-id/.gpg-id.sig policies, auxiliary regular files, and innermost nested .git boundaries. Typed validation rejects absolute/traversal paths, entry/directory ambiguity, symlinks, special file types, invalid Git boundaries, and mutation collisions. Encrypted writes use same-directory capability temporary files, private Unix permissions, file sync, atomic replacement, and directory sync. Pre-rename failures retain the old entry and roll back newly created empty directories; post-rename interruption reports durability uncertainty while retaining a complete new entry. Empty ancestor cleanup stops at content, policy, or root boundaries. SecretBytes owns decrypted bytes, redacts Debug, and zeroes memory on drop. Related verification: - cargo test -p ironstorage --test repository_core (9 fixture-backed core tests) - cargo test -p ironstorage repository::tests (3 interruption/rollback unit tests tied to layouts.toml recipes) - cargo fmt --all -- --check - RUSTFLAGS=-D warnings cargo check --workspace --all-targets - cargo clippy --workspace --all-targets -- -D warnings - cargo test --workspace All unrelated and compatibility fixture tests remained green.
hugo closed this issue 2026-08-09 21:42:01 +00:00
Sign in to join this conversation.