fix(desktop): store dev secrets in a 0o600 file instead of the keychain - #6727
Open
Maxwellimus wants to merge 2 commits into
Open
fix(desktop): store dev secrets in a 0o600 file instead of the keychain#6727Maxwellimus wants to merge 2 commits into
Maxwellimus wants to merge 2 commits into
Conversation
Unsigned dev binaries get a new code identity on every rebuild, which invalidates the keychain item's Always-Allow ACL and made macOS demand the login password on every tauri dev relaunch. Debug builds now default SecretStore to a file backend: secrets.<service>.json (0o600, atomic tmp+rename writes) in the app-data dir, guarded by the existing per-service flock. Release builds are keyring-only by construction (the File variant is cfg(debug_assertions)). BUZZ_DEV_USE_KEYCHAIN=1 opts a debug build back into the keychain. The file store deliberately starts empty — no migration from the old buzz-desktop-dev keychain item (dev keys are cheap to re-import, and a one-shot migration would live on as dead code). Every legacy-keychain path short-circuits in file mode, including the prod->dev agent-key copy, so the OS keychain is never touched. First launch after this change shows the identity-recovery screen once; re-import the dev nsec or use BUZZ_PRIVATE_KEY. BUZZ_SHARE_IDENTITY now reads the secrets file first (skipped when BUZZ_DEV_USE_KEYCHAIN=1 to avoid exporting a stale identity), and the in-app reset wipes the file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Max Lampert <maxwell@squareup.com>
…ize ratchet secret_store.rs (1307 lines pre-change) and app_state.rs (1055) are inherited-oversize files the CI ratchet forbids growing. Move the interprocess lock to secret_store_lock.rs, the debug file backend to secret_store_file.rs (each with their tests), and the migration-marker helpers to app_state_keyring.rs where the marker naming already lives. No behavior change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Max Lampert <maxwell@squareup.com>
Chessing234
suggested changes
Aug 25, 2026
Chessing234
left a comment
Contributor
There was a problem hiding this comment.
0o600 has to be applied at create (OpenOptions.mode), not chmod after write, or there's a window the file is 0644. also please drop the CONTRIBUTING.md hunk from this pr.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Unsigned dev binaries get a new code identity on every rebuild, which invalidates the macOS keychain item's "Always Allow" ACL — so every
just devrelaunch demanded the login password. Painful when an agent is iterating on the app.The keychain held exactly one item per dev build (service
buzz-desktop-dev, accountsecrets): a JSON blob with the identity nsec, one nsec per managed agent, and a migration sentinel. Nothing else.Change
Debug builds now default
SecretStoreto a file backend:secrets.<service>.json(0o600, atomic tmp+rename writes) in the app-data dir, guarded by the existing per-service flock. Release builds are keyring-only by construction — theFilevariant iscfg(debug_assertions).BUZZ_DEV_USE_KEYCHAIN=1opts a debug build back into the keychain.Deliberately no migration from the old dev keychain item: dev keys are cheap to re-import, and a one-shot migration would live on as dead code. Every legacy-keychain path short-circuits in file mode — including the prod→dev agent-key copy, whose prod-keychain read would otherwise reintroduce the prompt. Old dev keychain items are never read again; clean up manually with
security delete-generic-password -s buzz-desktop-dev -a secrets.Also:
BUZZ_SHARE_IDENTITYreads the secrets file first (skipped whenBUZZ_DEV_USE_KEYCHAIN=1so a stale file identity is never exported)verify_fully_wipedchecks its absencelocal-fileno longer claims the keychain "wasn't available"Heads-up for existing devs
First launch after this lands shows the identity-recovery screen once (file store starts empty, migration marker exists). Re-import your dev nsec there or set
BUZZ_PRIVATE_KEY. Managed agents mint fresh keys.Verification
Known cosmetic:
cargo check --no-default-featureshas dead-code warnings insecret_store.rs(mostly pre-existing; one new for the unusedFilepayload). No CI config builds that combo.🤖 Generated with Claude Code