Make CLI OpenPGP passphrase retrieval use the canonical application identity and provide a complete interactive fallback when no passphrase exists in secure storage.
Problem
The CLI currently only retrieves the org.ironstorage.openpgp-passphrase record for a key fingerprint (observed with fingerprint beginning 3B98 and ending 5429). It never creates that record, and a missing secret is flattened to Unavailable in crates/storage/src/secret_store.rs.
The org.ironstorage service prefix is not this application identity. The bundle identifier is de.rfc1437.ironstorage, and related secure-storage service and account identifiers must align with it.
Scope
Replace the incorrect OpenPGP secure-storage service identity with de.rfc1437.ironstorage.openpgp-passphrase everywhere, including tests and platform bridges.
Preserve a typed missing-secret condition instead of flattening it to general unavailability.
When the CLI needs an OpenPGP passphrase and none exists in secure storage, prompt for it securely on the terminal without echoing it.
Define and implement persistence through the storage-owned secure-secret orchestration so future CLI invocations can retrieve the passphrase.
Keep passphrases out of logs, errors, debug output, command arguments, and ordinary terminal output.
Acceptance criteria
A missing passphrase causes an interactive hidden terminal prompt in the CLI and successful encrypted-entry access when the supplied passphrase is correct.
The supplied passphrase is stored under the canonical de.rfc1437.ironstorage.openpgp-passphrase service and fingerprint account, then reused without prompting.
Cancellation, incorrect passphrases, secure-storage denial or unavailability, and persistence failures are typed, redacted, and do not corrupt existing records.
All password-store and secure-secret decisions remain in crates/storage; the CLI only collects terminal input and invokes the Rust API.
No external process is launched and no unsafe Rust is introduced.
## Objective
Make CLI OpenPGP passphrase retrieval use the canonical application identity and provide a complete interactive fallback when no passphrase exists in secure storage.
## Problem
The CLI currently only retrieves the org.ironstorage.openpgp-passphrase record for a key fingerprint (observed with fingerprint beginning 3B98 and ending 5429). It never creates that record, and a missing secret is flattened to Unavailable in crates/storage/src/secret_store.rs.
The org.ironstorage service prefix is not this application identity. The bundle identifier is de.rfc1437.ironstorage, and related secure-storage service and account identifiers must align with it.
## Scope
- Replace the incorrect OpenPGP secure-storage service identity with de.rfc1437.ironstorage.openpgp-passphrase everywhere, including tests and platform bridges.
- Preserve a typed missing-secret condition instead of flattening it to general unavailability.
- When the CLI needs an OpenPGP passphrase and none exists in secure storage, prompt for it securely on the terminal without echoing it.
- Define and implement persistence through the storage-owned secure-secret orchestration so future CLI invocations can retrieve the passphrase.
- Keep passphrases out of logs, errors, debug output, command arguments, and ordinary terminal output.
## Acceptance criteria
- A missing passphrase causes an interactive hidden terminal prompt in the CLI and successful encrypted-entry access when the supplied passphrase is correct.
- The supplied passphrase is stored under the canonical de.rfc1437.ironstorage.openpgp-passphrase service and fingerprint account, then reused without prompting.
- Cancellation, incorrect passphrases, secure-storage denial or unavailability, and persistence failures are typed, redacted, and do not corrupt existing records.
- Tests cover missing, prompt-and-store, reuse, cancellation, wrong passphrase, and storage failure paths.
- All password-store and secure-secret decisions remain in crates/storage; the CLI only collects terminal input and invokes the Rust API.
- No external process is launched and no unsafe Rust is introduced.
hugo
added this to the 02 - Mutt-style terminal UI milestone 2026-08-10 07:22:24 +00:00
hugo
added the bug label 2026-08-10 07:22:24 +00:00
Replaced every native secret-store service prefix from org.ironstorage to the canonical bundle identity: de.rfc1437.ironstorage.openpgp-passphrase and de.rfc1437.ironstorage.https-git.
Preserved missing, denied, cancelled, unavailable, and persistence failure as distinct secret-provider outcomes.
Added storage-owned interactive passphrase provisioning. The CLI terminal adapter collects a hidden passphrase only when stdin is a terminal; storage decides when prompting is needed.
Added crypto provider lifecycle callbacks so a prompted passphrase is created in secure storage only after it successfully decrypts or signs. Rejected passphrases are zeroized and never persisted.
Kept existing canonical records immutable on races and failures; create errors do not overwrite any record.
Added real fixture tests for prompt, successful decrypt, persistence, no-prompt reuse, wrong passphrase, cancellation, denial, and create failure, plus a complete CLI show/reuse integration test and canonical service-name assertions.
Review confirmed passphrases remain absent from logs, debug output, arguments, and ordinary prompt output. No process launch or unsafe Rust was introduced.
Implemented in c82c792 and pushed to main.
Implementation:
- Replaced every native secret-store service prefix from org.ironstorage to the canonical bundle identity: de.rfc1437.ironstorage.openpgp-passphrase and de.rfc1437.ironstorage.https-git.
- Preserved missing, denied, cancelled, unavailable, and persistence failure as distinct secret-provider outcomes.
- Added storage-owned interactive passphrase provisioning. The CLI terminal adapter collects a hidden passphrase only when stdin is a terminal; storage decides when prompting is needed.
- Added crypto provider lifecycle callbacks so a prompted passphrase is created in secure storage only after it successfully decrypts or signs. Rejected passphrases are zeroized and never persisted.
- Kept existing canonical records immutable on races and failures; create errors do not overwrite any record.
- Added real fixture tests for prompt, successful decrypt, persistence, no-prompt reuse, wrong passphrase, cancellation, denial, and create failure, plus a complete CLI show/reuse integration test and canonical service-name assertions.
Review confirmed passphrases remain absent from logs, debug output, arguments, and ordinary prompt output. No process launch or unsafe Rust was introduced.
Verification passed:
- cargo fmt --all -- --check
- RUSTFLAGS=-D warnings cargo check --workspace --all-targets
- cargo clippy --workspace --all-targets -- -D warnings
- cargo test --workspace
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Objective
Make CLI OpenPGP passphrase retrieval use the canonical application identity and provide a complete interactive fallback when no passphrase exists in secure storage.
Problem
The CLI currently only retrieves the org.ironstorage.openpgp-passphrase record for a key fingerprint (observed with fingerprint beginning 3B98 and ending 5429). It never creates that record, and a missing secret is flattened to Unavailable in crates/storage/src/secret_store.rs.
The org.ironstorage service prefix is not this application identity. The bundle identifier is de.rfc1437.ironstorage, and related secure-storage service and account identifiers must align with it.
Scope
Acceptance criteria
Implemented in
c82c792and pushed to main.Implementation:
Review confirmed passphrases remain absent from logs, debug output, arguments, and ordinary prompt output. No process launch or unsafe Rust was introduced.
Verification passed: