apple: fall back to non-userPresence storage when the keychain rejects the ACL#80
Merged
jgowdy-godaddy merged 1 commit intomainfrom Apr 24, 2026
Merged
Conversation
…s the ACL On macOS unsigned builds (cargo, Homebrew) `SecItemAdd` with `kSecAttrAccessControl(.userPresence)` fails in both routing paths: - Data Protection keychain returns `errSecMissingEntitlement` (-34018) because the caller isn't code-signed with the required entitlement. - Legacy keychain returns `errSecParam` (-50) because it doesn't honor `.userPresence` on `SecAccessControl`. Since PR #77 made userPresence the default for sshenc, this silently broke `sshenc keygen` (and every e2e scenario that creates a new key) on unsigned installs. The old comment at the top of this section specifically called the entitlement issue out — the userPresence path just bypassed the safeguard. Detect those two OSStatuses and retry the add without `kSecAttrAccessControl`, falling back to plain `kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly`. Log a one-line stderr warning so the config downgrade is visible instead of silent. Behavior on signed builds that reach the Data Protection keychain is unchanged — the fallback branch only runs after the primary add has already failed. Verified with sshenc e2e suite: all 36 scenarios now pass in SE mode on my unsigned dev build.
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.
Summary
errSecMissingEntitlement(-34018) anderrSecParam(-50) responses fromSecItemAddon the userPresence path and retry withoutkSecAttrAccessControlMotivation
Since #77 made userPresence the default in sshenc (#50),
sshenc keygenfails on every unsigned macOS build (cargo, Homebrew) because neither keychain can honor the.userPresenceSecAccessControl flag:errSecMissingEntitlement(-34018) — caller isn't code-signed with the DP-keychain entitlementerrSecParam(-50) — doesn't support.userPresenceon SecAccessControl at allThe existing top-of-section comment explicitly calls the entitlement problem out ("on unsigned builds … the modern Data Protection keychain returns errSecMissingEntitlement"), but the userPresence code path skipped over it.
Impact
Before this change, on my unsigned dev build:
After:
The user keeps Secure Enclave's AccessPolicy-driven prompts at signing time (independent of the wrapping-key ACL). They lose the additional userPresence gate on wrapping-key decrypt until they sign the binary. The warning is loud enough to not be silent security-config drift.
Test plan
cargo test --workspace— cleancargo clippy --workspace --all-targets -- -D warnings— cleancargo fmt --all -- --check— clean