errSecInvalidOwnerEdit returned from SecItemDelete

Have an app I'm working on that stores an item in the keychain. Everything was was working fine. I have a button in the UI that allows the user to clear out the keychain item:


NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrService: service,
                            (__bridge id)kSecAttrAccount: accountKey};

OSStatus status = SecItemDelete((__bridge CFDictionaryRef)(query));


Status is -25244 which is errSecInvalidOwnerEdit. This app created the keychain item to begin with. What would be the appropriate way to handle this type of error?

Replies

hmm...so when I get this error, I try to update the item using SecItemUpdate. SecItemUpdate for the item does not return an error (I get errSecSuccess).


So I can update the the keychain item, but I cannot delete it?

I just opened keychain access and deleted the item there. Then I ran my app, created a new item and deleting it from the keychain now works again.


Would be interested in hearing suggestions of how to handle this error if this were to happen in a production release. An alert "go to keychain access and delete this manually" doesn't seem great.

I presume, based on your mention of Keychain Access, that we’re talking about macOS here. If so, this is likely a code signing issue.

When you create a keychain item (in the old school Mac keychain, not iCloud Keychain, which works like iOS), it gets a default ACL that allows your app to access, modify and delete that item. How does it identify “your app”? Based on its code signature (technically its designated requirement). If you add a keychain item and then change your code signing, and hence your DR, you can get into situations like this.

Unless you see this happening in end user scenarios, I wouldn’t add code to handle it.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yep, it's a macOS app. Thank you for your helpful response.

Quinn, I have the same issue with a keychain in my app. It seems to happen when I move my application bundle in a different place on disk. For example: the app is launched from the ~/Downloads folder and a new keychain item is created. As far as the app stays in place I can update or delete my keychain item as I like. But after the app is moved to another path, like /Applications (or whatever) I only can read, but cannon remove the item from the keychain. I get errSecInvalidOwnerEdit error. I am definitely sure there are no issues with codesign. Would you please help? It seems to me that this observed differentiation of apps based on their launch path is extremely limited and inconvenient. IMO Keychain ACL should differentiate apps based on their identity, not their location. On Mac it's perfectly legal to duplicate apps, move them around and so on...


Update: It seems like you have to rename the app bundle to reproduce this issue.

It seems like you have to rename the app bundle to reproduce this issue.

I don’t much in the way of meaningful input here. Honestly, this sounds like a bug, and I think it’d be reasonable for you to file it as such (please post your bug number, just for the record). If you’d like to dig into it deeper, you should open a DTS tech support incident so that you can discuss this with one of my colleagues.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
I have the same bug after 4 years

I have the same bug after 4 years

Unfortunately no one posted a bug number so I’ve no way to track down what happened here. However, my earlier offer still stands: If you’d like someone to help you investigate this, you should open a DTS tech support incident.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
We've also seen the same bug in our application on macOS. We can reliably reproduce it by renaming the .app file after the initial keychain item creation.

I've submitted feedback for this: FB9055785.

We can reliably reproduce it by renaming the .app file after the
initial keychain item creation.

Well, that’s weird. Some clarifications:
  • This is a rename in the Finder, right?

  • And the app is not running at the time you do the rename?

  • And the app is signed, right?

  • Is this Developer ID signing? Or is this a Mac App Store app?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I can reliably reproduce the same issue: SecItemDelete returns errSecInvalidOwnerEdit after renaming the app bundle.

This is a rename in the Finder, right?
And the app is not running at the time you do the rename?

Yes, a simple rename in Finder is enough to break this.

Another use case is for app to copy itself under a different name using FileManager.default.copyItem(at:to:). In this case, the app is running at the moment of copying. The copy won't be able to modify any pre-existing keychain items due to the same error.

And the app is signed, right? Is this Developer ID signing?
Or is this a Mac App Store app?

The app is signed using Developer ID and notarized.

I can reliably reproduce the same issue

Interesting. And thanks for answering my questions.

I don’t have a good answer here. My general expectation is that the keychain implements access control via the app’s code signature, something that’s not affected by renaming the app. Looking at joekw’s bug (FB9055785) it’s clear that the keychain team has the same basic expectation, although there’s not yet been a thorough investigation as to why this is failing.

I have two suggestions:
  • You could switch to using the iOS-style keychain. Its access control is definitely based only on your code signature.

  • If that’s not feasible, you should open a DTS tech support incident so that I can dig into the file-based keychain side of this in more detail (although, just to set expectations here, this could turn out to be Just A Bug™ with no good workaround).

Share and Enjoy

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

Looks like SecItemUpdate is not affected by this issue, so we ended up with the following solution:
  • for modifications use SecItemUpdate instead of SecItemDelete + SecItemAdd

  • for cleanup use SecItemUpdate with an empty data as a fallback when SecItemDelete fails

for modifications use SecItemUpdate instead of SecItemDelete +
SecItemAdd

Well, that’s best practice anyway.

Share and Enjoy

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

Someone opened a DTS tech support incident about this problem (although in a very different context) and I found the root cause.

To start, some context. TN3137 On Mac keychain APIs and implementations discusses the shim from the SecItem API to the file-based keychain. As explained there, and as I further explain in SecItem: Pitfalls and Best Practices, that shim is the ‘gift that keeps on giving’ when it comes to mysterious keychain behaviours. And this is another one of its gifts (-:

This error is being flagged by this line of code in the shim. Looking up that function, the real cause is this comparison. If you rename your app, currentAppName is the new name and itemAppName is the old name and you end up getting this error.

For most folks the best solution is to do what TN3137 recommends: Adopt the data protection keychain!

If you have to use the file-based keychain for some reason — say you’re working on a daemon — post a follow-up here and we can discuss your particulars.

Share and Enjoy

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