What is the owner of a keychain item?

I have items written to the keychain by an XPC service. On disk, it's just a plain binary.

There are times when this service shows a system authentication dialog via LAContext. By default, the application icon is a tiny version of a terminal. We found that if we wrap the binary in a bundle, we can include an icon and it will show up in the authentication dialog.

The problem is that this new bundle seems to be different, as updates to an existing keychain item (created by the old, standalone binary) fail with errSecInvalidOwnerEdit. The bundle ID of the embedded binary has not changed.

How does the system decide who is the owner of a keychain item and is there any way to do a migration like this without affecting item ownership?

The concept of item keychain item ownership is a complex one, and it varies based on the keychain implementation you’re using. See TN3137 On Mac keychain APIs and implementations for more background on this.

You mentioned Local Authentication, which suggests you’re using the data protection keychain. Please confirm.

I have items written to the keychain by an XPC service.

Please clarify what you mean by “XPC service”. This this a small bundled code item, with the extension .xpc, that lives within your app? Or are you referring to a named XPC endpoint vended by some other process, like a daemon or an agent?

Share and Enjoy

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

The items are written to the older macOS filesystem keychain, not the data protection keychain. LAContext is being used as a user presence check, unrelated to protection of the keychain items.

The XPC service is vended by a launch agent. While we're trying to wrap it inside a bundle, it won't be contained within an application. The bundle is intended to get an app icon to show on the LAContext-driven system dialog, nothing more.

Local Authentication is intended to be used by app-like code. I’m not surprised it’s behaving weirdly when you use it from a standalone launchd agent. I’m also not surprised that putting your agent in an app-like wrapper makes it work again.

Does your agent have AssociatedBundleIdentifiers set? Some, but not all, components of the system will use that to associate your agent with its ‘parent’ app.

The problem is that this new bundle seems to be different, as updates to an existing keychain item … fail with errSecInvalidOwnerEdit.

The file-based keychain uses the caller’s designated requirement to track ownership. See TN3127 Inside Code Signing: Requirements for more background on this. I recommend that you check the DR of the old standalone executable and the DR of the new wrapped executable to see what changed.

Share and Enjoy

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

What is the owner of a keychain item?
 
 
Q