We have a macOS Authorization Plugin that reads and writes data from login.keychain-db during the login flow (logout→login scenario).
On macOS 26.6, SecKeychainUnlock consistently fails in the pre-session context — before the user session is established.
Error returned:
Error Domain=NSOSStatusErrorDomain Code=-25293 "errSecAuthFailed: The username or passphrase you entered is not correct."
However, the error message is misleading. We tested four combinations on macOS 26.6 to isolate the exact cause:
- Active session + correct password → Success
- Active session + wrong password → -25293
- Pre-session + correct password → -25293
- Pre-session + wrong password → -25293
In the pre-session context, macOS 26.6 returns -25293 for both correct and wrong passwords identically. This strongly suggests macOS is not evaluating the password at all in that context — the failure happens before password validation, likely because the session-bound material required to unlock login.keychain-db does not exist yet when the auth plugin runs.
Key observations:
- The same code works correctly on macOS 26.3.1 and 26.5.1 — SecKeychainUnlock succeeds with the correct password in the pre-session context on those versions. The issue is specific to macOS 26.6.
- The file path /Users/<username>/Library/Keychains/login.keychain-db is unchanged — we get -25293 (auth failed), not -25294 (no such keychain), confirming the file is found and opened correctly.
- SecKeychainUnlock(ref, 0, NULL, NO) also fails for login.keychain-db in both pre-session and active session contexts.
- System.keychain with SecKeychainUnlock(ref, 0, NULL, NO) continues to work correctly in the pre-session context on macOS 26.6.
Questions:
- Has the protection model for login.keychain-db changed in macOS 26.6 such that it can no longer be unlocked viaSecKeychainUnlock in a pre-session authorization plugin context?
- Is this an intentional security hardening change, or a regression?
- Is there a supported API or entitlement for authorization plugins to access login.keychain-db before the user session is established?
- Does the modern Data Protection Keychain (SecItemCopyMatching/SecItemAdd with kSecUseDataProtectionKeychain: @YES) work correctly in the authorization plugin pre-session context on macOS 26.6? If yes, is migrating to that API the recommended approach?
Note: We are aware that SecKeychainUnlock is deprecated. We are actively evaluating migration to the modern Data Protection Keychain API, but understanding whether this is an intentional change, would help us choose the right fix approach.
Recent versions of macOS 26 have additional security hardening for the login keychain. I plan to update TN3137 to discuss these changes (r. 184510296) but that might take a while. Prior to that, I’m reluctant to discuss specifics because, in a security critical area like this, I want to make sure that any info I share is properly reviewed.
One thing I’m happy to share is that macOS logs information about this to the system log in the dp_login category (that’s category, not subsystem). So if you monitor the system log for log entries with that category, you can see a bunch of implementation details. For lots of hints and tips about the system log, see Your Friend the System Log.
As to what you can do about your product, that’s hard to say. I think it’s reasonable for the system to prevent you from unlocking a user’s login keychain from outside of the login session. That’s not really a supported use case. Indeed, the system doesn’t expect an authorisation plug-in to use the keychain. That’s because the system uses the user name and password — things that the authorisation machinery generates and puts in the authorisation context — to unlock the keychain at the end of the login process.
If you cast your mind back to FileVault 1, you’ll note that the user’s home directory wasn’t mounted prior to a login. So, if an authorisation plug-in tried to access the user’s login keychain, it’d fail because the file is not available.
Likewise for users with network home directories.
Does the modern Data Protection Keychain … work correctly in the authorization plugin pre-session context on macOS 26.6?
No.
There’s some subtlety here. Access to the data protection keychain is mediated by entitlements. An authorisation plug-in is an in-process plug-in, so it doesn’t have its own entitlements. Rather, it uses the entitlements of whatever host process it’s loaded into. The programs that load authorisation plug-ins aren’t signed with entitlements that allow access to the data protection keychain.
In theory you could this keychain work in a separate process and have your authorisation plug-in use an IPC mechanism (ideally XPC) to request that this separate process perform keychain operations on its behalf. However:
- The separate process can’t be a
launchddaemon becauselaunchddaemons don’t have access to the data protection keychain. See TN3137. - The separate process can’t be
launchdagent either, becauselaunchdagents don’t run until the login process is complete (well, you have pre-login agents, but those aren’t running in the user’s context and that can’t possibly access the user’s data protection keychain).
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"