Some checks failed
Dependency security audit / rustsec (push) Has been cancelled
89 lines
4.3 KiB
Markdown
89 lines
4.3 KiB
Markdown
# Repository instructions
|
|
|
|
## Architecture boundary
|
|
|
|
`crates/storage` owns all password-store behavior and all objects stored in or
|
|
derived from a password-store repository. This includes filesystem layout,
|
|
`.gpg-id` handling, GPG-compatible encryption and key handling, Git,
|
|
synchronization, conflict handling, entry parsing, password generation, OTP,
|
|
QR payloads, server/application identities, HTTPS Git credentials, and
|
|
secure-secret-storage orchestration. Git remotes are typed HTTPS or optional
|
|
SSH endpoints; reject local, helper, executable, and unknown transports before
|
|
entering Git transport code. Builds without the `ssh` feature must still parse
|
|
SSH endpoints and return a typed unsupported-transport error before connection
|
|
or repository mutation.
|
|
|
|
The SSH feature must keep its algorithm allowlist, strict known-host checking,
|
|
single configured identity, bounded channel/diagnostic limits, and ambiguous
|
|
push outcome rules in `crates/storage`. Do not add OpenSSH configuration,
|
|
proxy commands, password or keyboard-interactive authentication, host-key
|
|
bypasses, or frontend transport policy.
|
|
|
|
The CLI, Ratatui, Iced, Swift, SwiftUI, AutoFill, and watchOS code may collect
|
|
input, invoke the Rust API, and present Rust-provided state. They must not
|
|
duplicate storage rules, derive domain state from display strings, or directly
|
|
read or mutate a password-store repository.
|
|
|
|
Application code must not launch external processes. Do not invoke `pass`,
|
|
`git`, `gpg`, shell commands, or helper executables. Use pure Rust libraries.
|
|
Use FFI only where an operating-system API has no feasible Rust interface,
|
|
such as Apple authentication and secure-storage APIs; keep domain decisions in
|
|
`crates/storage`.
|
|
|
|
Keep project crates free of `unsafe` Rust. Isolate any unavoidable future FFI
|
|
implementation in the smallest platform-specific module and document its
|
|
safety contract.
|
|
|
|
## Compatibility
|
|
|
|
Compatibility means the upstream `pass` repository format and observable
|
|
behavior, including `pass-otp`; IronStorage must not introduce a competing
|
|
on-disk format. Prove new behavior with fixtures usable by both upstream tools
|
|
and `crates/storage` without executing those tools at application runtime.
|
|
|
|
## Required checks
|
|
|
|
Run these from the repository root before committing:
|
|
|
|
```sh
|
|
cargo fmt --all -- --check
|
|
RUSTFLAGS="-D warnings" cargo check --workspace --all-targets
|
|
cargo clippy --workspace --all-targets -- -D warnings
|
|
cargo test --workspace
|
|
```
|
|
|
|
For Apple project changes, also run `xcodegen generate` from `apple/` and build
|
|
the affected simulator targets.
|
|
|
|
### Updating the Simulator app
|
|
|
|
Treat the booted simulator and its app container as persistent test state. To
|
|
update IronStorage, build for that simulator and install the new `.app` over
|
|
the existing installation with `xcrun simctl install <device-udid> <app-path>`.
|
|
Keep the same device UDID and bundle identifier.
|
|
|
|
Do not uninstall IronStorage, erase or recreate the simulator, reset its
|
|
keychain, install app-data packages, or delete its app container during an app
|
|
update. Those are destructive reset operations, not update steps, and can
|
|
remove preferences, repositories, credentials, and biometric enrollment state.
|
|
|
|
### Simulator biometric validation
|
|
|
|
For initial setup only, select **Features > Face ID > Enrolled** before enabling
|
|
Biometric Unlock in the iPhone app. The user must then enable Biometric Unlock
|
|
and enter the GPG passphrase once so the protected passphrase is enrolled.
|
|
|
|
For normal validation, do not toggle **Enrolled** again. Tap the entry's
|
|
**Unlock** control first so an authentication request is active, then select
|
|
**Features > Face ID > Matching Face** and verify the app changes from locked to
|
|
unlocked. A matching face presented before **Unlock** does nothing. Use
|
|
**Non-matching Face** to test rejection without changing enrollment.
|
|
|
|
Apple's `biometryCurrentSet` access control invalidates a protected Keychain
|
|
item when Face ID is re-enrolled. Clearing or toggling **Enrolled** is therefore
|
|
a destructive negative test, not part of the normal unlock sequence. Only do it
|
|
when the issue explicitly requires changed-enrollment coverage and the user is
|
|
available to enter the GPG passphrase again. When deliberately returning to a
|
|
manual baseline, disable Biometric Unlock in IronStorage while the protected
|
|
record is still valid, then clear **Enrolled**.
|