feat: pin keychain item ACLs to the app's code signature (macOS) #21

Merged
adrianbonpin merged 1 commits from feat/keychain-acl into prod 2026-09-04 03:41:55 +00:00
Owner

What

After every successful keychain write (save_connection_password, save_connection_ssh_password, save_connection_ssh_passphrase), replace the stored item's ACL with an explicit SecAccess whose trusted-application list contains exactly this app, resolved by its code-signature requirement (SecTrustedApplicationCreateFromPath(NULL)).

Why

Legacy keychain items get a default ACL granting the creating app's signature access. Ad-hoc (dev) builds change signature every build; upgrading users from pre-signing builds keep ACLs pointing at the old ad-hoc identity — so the new Developer-ID-signed app prompts once. This change makes the result permanent and clean:

  • New installs: items are ACL-pinned from the first save; Developer ID requirement is stable, so upgrades never prompt.
  • Upgraders: the one-time "Always Allow" now permanently replaces the ACL (removing stale ad-hoc entries) instead of appending.
  • Safety: item lookup is ref-only (kSecReturnRef) — never prompts; all failures are swallowed so keychain writes never fail because of ACL work. Non-macOS: no-op.

Verification

  • cargo check (lib + tests) clean; cargo test 358 passed / 0 failed (16 pre-existing ignored).
  • Real-keychain integration test (added, #[ignore]-gated so CI never touches the login keychain): creates an item via the same legacy API the plugin uses → ACL normalize → read back → delete. Passes against the live login keychain.

Notes

  • Uses SecAccessCreate/SecTrustedApplication FFI (deprecated-but-functional API family — same family the keyring store's legacy backend already relies on).
  • Dev builds (tauri:dev) still prompt between rebuilds — unavoidable (ad-hoc DR changes per build); release builds are stable.
## What After every successful keychain write (`save_connection_password`, `save_connection_ssh_password`, `save_connection_ssh_passphrase`), replace the stored item's ACL with an explicit `SecAccess` whose trusted-application list contains exactly this app, resolved by its code-signature requirement (`SecTrustedApplicationCreateFromPath(NULL)`). ## Why Legacy keychain items get a default ACL granting the *creating app's signature* access. Ad-hoc (dev) builds change signature every build; upgrading users from pre-signing builds keep ACLs pointing at the old ad-hoc identity — so the new Developer-ID-signed app prompts once. This change makes the result permanent and clean: - **New installs**: items are ACL-pinned from the first save; Developer ID requirement is stable, so upgrades never prompt. - **Upgraders**: the one-time "Always Allow" now permanently *replaces* the ACL (removing stale ad-hoc entries) instead of appending. - **Safety**: item lookup is ref-only (`kSecReturnRef`) — never prompts; all failures are swallowed so keychain writes never fail because of ACL work. Non-macOS: no-op. ## Verification - `cargo check` (lib + tests) clean; `cargo test` 358 passed / 0 failed (16 pre-existing ignored). - Real-keychain integration test (added, `#[ignore]`-gated so CI never touches the login keychain): creates an item via the same legacy API the plugin uses → ACL normalize → read back → delete. Passes against the live login keychain. ## Notes - Uses `SecAccessCreate`/`SecTrustedApplication` FFI (deprecated-but-functional API family — same family the keyring store's legacy backend already relies on). - Dev builds (`tauri:dev`) still prompt between rebuilds — unavoidable (ad-hoc DR changes per build); release builds are stable.
adrianbonpin added 1 commit 2026-09-04 03:41:51 +00:00
After every keychain write, replace the item's ACL with an explicit
SecAccess whose trusted-application list is this app's code-signature
requirement (SecTrustedApplicationCreateFromPath(NULL)):

- New installs: items are ACL-pinned from the first save, so future
  upgrades never prompt (Developer ID requirement is stable).
- Upgraders from ad-hoc builds: the first access shows the standard
  one-time prompt; 'Always Allow' now permanently rewrites the ACL
  instead of just appending, so stale ad-hoc entries are cleaned up.
- Ref-only item lookup (kSecReturnRef) never prompts, and failures are
  swallowed so keychain writes never fail because of ACL work.
adrianbonpin merged commit fd451d219d into prod 2026-09-04 03:41:55 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adrianbonpin/gridline#21