Repeated login Keychain prompts and securityd crash after app upgrade on macOS 26.6.x

Overview

We are investigating repeated "login" Keychain prompts affecting our macOS application on macOS 26.6.x.

The issue appears after upgrading an existing installation. A clean uninstall/reinstall of the same version resolves it.

Changing the affected Keychain item's Access Control from "Confirm before allowing access" to explicitly allowing our application/process also stops the prompts.

On one affected machine, Apple Support observed a securityd crash followed by:

SecKeyCreateSignature failed
CSSMERR_DL_INVALID_DB_HANDLE

Our code uses some legacy SecKeychain* APIs, so we are currently investigating whether this is related.

Questions

  • Were there any changes in macOS 26.6.x around securityd, Keychain ACL handling, or legacy SecKeychain* APIs that could explain this?
  • Could an existing Keychain ACL become stale after an application upgrade, even when both versions are signed with the same Developer ID?
Answered by DTS Engineer in 904056022

Thanks for all that additional info. Most interesting.

securityd is a bit like the kernel. You shouldn’t be able to crash it just by calling its API. Rather, if you make a mistake like this, securityd should start returning errors or, in extreme circumstances, kill you.

Given that, this failure is automatically bugworthy, and I’d appreciate you filing a bug report about it, including a sysdiagnose log taken shortly after reproducing the problem. Please post your bug number, just for the record.

Looking at the crash report I have some theories as to why it actually crashed, but I don’t want to go too far down that rabbit hole. Rather, I’d like to stay focused on what you’re doing.

1- Is our root cause plausible from your side?

It’s certainly plausible. Regardless, the current behaviour of your keychain code is clearly wrong, and thus you should fix that.

2- Is fully moving to SecItem the right long-term direction … ?

Yes, but…

or is there extra guidance for apps that still need to scope lookups to a specific keychain?

There are likely to be exceptions in your case.

I suspect you’ve already read TN3137 On Mac keychain APIs and implementations but, if not, I encourage you to take a look at it now. The key takeaways are:

  • Keychain has two implementations (file-based and data protection).
  • The file-based keychain implementation is deprecated.

Moving to the SecItem API is a necessary to get off the file-based keychain, but it’s not sufficient. To start, you have to explicitly opt in, but there are further complications. If parts of your product run outside of a user context then the data protection keychain isn’t an option. You have to stick with the file-based keychain, and specifically the System keychain.

So:

  • It definitely makes sense to move to the SecItem API.
  • And avoid the deprecated file-based keychain APIs as much as possible (more on this below).
  • Moving to the data protection may not be possible.
  • Even if it is, it’s a non-trivial task and not something I’d recommend for a bug fix release.

When working with the file-based keychain my general advice is:

  • Stick with the SecItem API as much as possible.
  • If you need control over which file-based keychain you act on, use kSecMatchItemList (for queries) and kSecUseKeychain (for adds).
  • Try to avoid using custom keychains.
  • Rather, target the standard login keychain (assuming you’re in a user context) and system keychain (in any context).
  • Which you can get to via SecKeychainCopyDefault. Or, in the rare cases where it doesn’t do the right thing, SecKeychainCopyDomainDefault.
Where we still need user-vs-system scoping, we build the search list via SecKeychainCopyDomainSearchList

Yeah, that’ll work too (-:


It turns out Apple's own airportd triggers the exact same [problem]

Well, that’s not good. Make sure to mention that in your bug report.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Were there any changes in macOS 26.6.x around securityd, Keychain ACL handling, or legacy SecKeychain* APIs that could explain this?

Anything involving security should be assumed to be constantly in flux.

Our code uses some legacy SecKeychain* APIs, so we are currently investigating whether this is related.

That sounds logical.

There have been significant keychain changes to the file-based keychain starting in macOS 26.4, but I’m not aware of any that would cause this sort of problem. Before we go further I’d like to clarify what exact alert you’re seeing. Please reply here with either a screenshot or the exact wording, including the button names [1].

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] See Resolving errSecInternalComponent errors during code signing for same examples of the latter.

Since multiple unrelated apps/services are affected, it seems unlikely our app triggered it.

Agreed. But not impossible. If you were, for example, developing an endpoint security product then it’s possible that this is being triggered by that.

Could macOS 26.6.x have changed how access to the login keychain is handled?

Well, as I mentioned above, macOS 26.4 kicked off a process for changing how the system handles the file-based keychain, and so this is definitely a possibility.

Are you able to reproduce this on a ‘clean’ install, that is, one that’s never had your software installed?

Oh, and earlier you wrote:

Apple Support observed a securityd crash followed by

Did you capture the resulting crash report? If so, please post it here. See Posting a Crash Report for advice on how to do that. Or, if it went into a bug then please post the bug number.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks Quinn - answering your questions and sharing what we've since found.

The alert is the standard macOS login keychain prompt, here's an example from an unrelated app to our app:

Regarding the crash report: yes, Apple Support captured a securityd crash on an affected machine (securityd-2026-08-20-105000.ips). The key frames:

`Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
(Security) [com.apple.security:seckey] SecKeyCreateSignature failed:
Error Domain=NSOSStatusErrorDomain Code=-67680
"CSSM Exception: -2147413942 CSSMERR_DL_INVALID_DB_HANDLE"
(Security) [com.apple.securityd:integrity] dbBlobVersion() failed
for a CssmError: 1 unknown error 1=1`

Here are two example .ips crash files after reproducing the issue on my own machine.

We believe we identified the root cause and would like you to confirm.

Our cert-lookup code used the legacy CSSM APIs: SecKeychainOpen (and SecKeychainCreate in one path) to open keychains by file path, then queried with kSecMatchSearchList. The opened keychain refs were never released (no CFRelease), so each lookup leaked a DL/DB handle into securityd.

Our theory is that those leaked/stale DB handles are what surface as CSSMERR_DL_INVALID_DB_HANDLE and eventually crash securityd. Once securityd is down, macOS falls back to prompting for the login keychain password - which explains why unrelated apps got hit too (they weren't the cause, they were just the next thing to touch the keychain after the crash).

This lines up with our two workarounds: a clean reinstall resets the state and delays the buildup, and setting the item ACL to "allow all applications" removes the repeated per-app access checks that were driving the lookups.

We believe this issue is tied to 26.6.x specifically because it's the same binary, unchanged for a long time - we only started seeing this after machines moved to 26.6.x. That also matches Apple's release notes on macOS 26.6 mentioning Keychain CVEs specifically. On earlier macOS the same code didn't crash securityd.

To be clear on your endpoint-security question: we're a network/VPN agent (with a system/network extension), not doing anything that should be poking securityd on a loop - the keychain calls are only our own client-cert lookups.

We currently applied a fix that migrated every cert-lookup path off SecKeychain*/CSSM to SecItemCopyMatching. Where we still need user-vs-system scoping, we build the search list via SecKeychainCopyDomainSearchList rather than opening keychains by path, so no keychain refs are held or leaked. After this, the leak is gone and we no longer reproduce the crash or the prompts.

What we'd like confirmed:

  1. Is our root cause plausible from your side? Do the leaked legacy SecKeychain* DB handles driving CSSMERR_DL_INVALID_DB_HANDLE / the securityd SIGSEGV, made fatal by the macOS 26.4/26.6 keychain changes?
  2. Is fully moving to SecItem* (default keychain, no SecKeychain*) the right long-term direction, or is there extra guidance for apps that still need to scope lookups to a specific keychain?

Thanks again.

Quick follow-up with a new data point that I think matters for root cause.

After migrating our app fully off the legacy SecKeychain*/CSSM path, we still saw securityd crash on this machine, so I went digging into who else was hitting it.

It turns out Apple's own airportd triggers the exact same CSSMERR_DL_INVALID_DB_HANDLE and takes securityd down, with our app completely out of the picture.

Here's a clean example from this machine (macOS 26.6.2, 25G83). In this window our agent logged nothing at all - the only thing hitting the error was airportd (pid 634):

04:26:44.933  airportd[634]  (Security) [com.apple.securityd:security_exception] CSSM Exception: -2147413942 CSSMERR_DL_INVALID_DB_HANDLE
04:26:53.249  airportd[634]  (Security) [com.apple.securityd:security_exception] CSSM Exception: -2147413942 CSSMERR_DL_INVALID_DB_HANDLE
04:27:03.883  airportd[634]  (Security) [com.apple.securityd:security_exception] CSSM Exception: -2147413942 CSSMERR_DL_INVALID_DB_HANDLE
04:27:15.110  airportd[634]  (Security) [com.apple.securityd:security_exception] CSSM Exception: -2147413942 CSSMERR_DL_INVALID_DB_HANDLE

securityd was then corpsed at 04:27:20 and relaunched at 04:27:26. We've counted 22 securityd crashes on this machine this week, crash-looping (consecutiveCrashCount reached 17), all EXC_BAD_ACCESS (SIGSEGV) at 0x0.

This reframes the root cause a bit: our leaked legacy handles were a contributor, but they aren't required to crash securityd on 26.6.x — a first-party daemon (airportd) hits the identical error on its own. That fits the theory that the 26.4/26.6 file-based-keychain changes made stale/invalid DL/DB handle use fatal for any CSSM client, Apple's included. It also explains why our fix removed our contribution but didn't fully stop the prompts/crashes: something else on the system keeps knocking securityd over.

Does the airportd repro change your read on root cause - i.e. is this a securityd/CSSM regression in 26.6.x rather than something specific to third-party keychain use?

Thanks for all that additional info. Most interesting.

securityd is a bit like the kernel. You shouldn’t be able to crash it just by calling its API. Rather, if you make a mistake like this, securityd should start returning errors or, in extreme circumstances, kill you.

Given that, this failure is automatically bugworthy, and I’d appreciate you filing a bug report about it, including a sysdiagnose log taken shortly after reproducing the problem. Please post your bug number, just for the record.

Looking at the crash report I have some theories as to why it actually crashed, but I don’t want to go too far down that rabbit hole. Rather, I’d like to stay focused on what you’re doing.

1- Is our root cause plausible from your side?

It’s certainly plausible. Regardless, the current behaviour of your keychain code is clearly wrong, and thus you should fix that.

2- Is fully moving to SecItem the right long-term direction … ?

Yes, but…

or is there extra guidance for apps that still need to scope lookups to a specific keychain?

There are likely to be exceptions in your case.

I suspect you’ve already read TN3137 On Mac keychain APIs and implementations but, if not, I encourage you to take a look at it now. The key takeaways are:

  • Keychain has two implementations (file-based and data protection).
  • The file-based keychain implementation is deprecated.

Moving to the SecItem API is a necessary to get off the file-based keychain, but it’s not sufficient. To start, you have to explicitly opt in, but there are further complications. If parts of your product run outside of a user context then the data protection keychain isn’t an option. You have to stick with the file-based keychain, and specifically the System keychain.

So:

  • It definitely makes sense to move to the SecItem API.
  • And avoid the deprecated file-based keychain APIs as much as possible (more on this below).
  • Moving to the data protection may not be possible.
  • Even if it is, it’s a non-trivial task and not something I’d recommend for a bug fix release.

When working with the file-based keychain my general advice is:

  • Stick with the SecItem API as much as possible.
  • If you need control over which file-based keychain you act on, use kSecMatchItemList (for queries) and kSecUseKeychain (for adds).
  • Try to avoid using custom keychains.
  • Rather, target the standard login keychain (assuming you’re in a user context) and system keychain (in any context).
  • Which you can get to via SecKeychainCopyDefault. Or, in the rare cases where it doesn’t do the right thing, SecKeychainCopyDomainDefault.
Where we still need user-vs-system scoping, we build the search list via SecKeychainCopyDomainSearchList

Yeah, that’ll work too (-:


It turns out Apple's own airportd triggers the exact same [problem]

Well, that’s not good. Make sure to mention that in your bug report.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks Quinn, this is really helpful.

I've filed the bug: FB24637565. It includes the securityd crash report and a sysdiagnose taken after reproducing, and - as you suggested - it calls out that Apple's own airportd triggers the same CSSMERR_DL_INVALID_DB_HANDLE and takes securityd down, with no third-party software involved in the crash window.

We've also read TN3137 - thanks for pointing to it. Your guidance lines up with what we've done: we've moved to the SecItem API and off the deprecated SecKeychain* calls, and since parts of our product run outside a user context we're staying on the file-based (System) keychain rather than attempting a data-protection migration in a bug-fix release.

In parallel, we're also engaging Apple through AppleCare Enterprise for additional help on this (case 20000149598654), so the two efforts can reference each other.

Thanks again for the quick, detailed responses.

I've filed the bug: FB24637565.

Thanks.

Quoting my keychain engineering contact “a crash there is indeed bad” O-:

rather than attempting a data-protection migration in a bug-fix release.

Agreed!

parts of our product run outside a user context

Yeah, I thought that might be the case, and it’s a real kicker. I’d love to get everyone off the file-based keychain, but products like yours are stuck there until we make the data protection keychain available to third-party daemons )-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Repeated login Keychain prompts and securityd crash after app upgrade on macOS 26.6.x
 
 
Q