Macos – Application always asks for permission to access keychain

macosxcode4

I have an application that stores username and password in the keychain. Everything was working fine when working on Xcode 3, I recently moved to Xcode 4 and now when I run the application, I get a prompt:

Application wants to use your confidential information stored in keychain" in your keychain.

After hitting always allow I see the application added to access control list of the keychain item, but I get every time I run the app.

Also after hitting Always allow again, I see that the access control has two instances of the same app. Seems like OS thinks this is a new application.

Any ideas appreciated.

Best Answer

I believe the problem is that your signature's designated requirement causes it to not accept itself as "the same app" as itself (for Keychain purposes).

One common cause for this—and I think it's yours—is using a Developer ID Application cert, with no designated requirement, and without the intermediate cert installed.

A standard Developer ID requirement looks like this:

designated => anchor apple generic and 
identifier \"com.example.appName\" and 
((cert leaf[field.1.2.840.113635.100.6.1.9] exists) or 
 (certificate 1[field.1.2.840.113635.100.6.2.6] exists and 
 certificate leaf[field.1.2.840.113635.100.6.1.13] exists  and 
 certificate leaf[subject.OU] = \"1AZBYCXDW9V\" ))

If you want to construct this yourself, you have to replace the identifier with your bundle identifier and the subject.OU with the value from your cert. (If you double-click it in Keychain Access, it should be listed as the Organizational Unit.) Then you can add to "Other Code Signing Flags":

--requirements "=designated ..." (the whole mess from above)

However, a much better way to do this is to use Xcode 4.3.2 or later. If it recognizes that you're using a Developer ID Application cert, and can see the intermediate cert in the keychain, it will generate this by default.

Also, if you use the Archive Organizer in Xcode to "Export Developer ID-signed Application", instead of just using the build from your target directory, it will make sure to sign your app and any other enclosed signables, and it will test that everything is setup properly. (The failures are pretty cryptic—e.g., your "Choose a Developer ID to sign with" step may just have no choices, with a message in the syslog that has no useful information—but at least the fact that it failed or succeeded narrows down where your problem is.)

Either way, you need to download and install (on your build machine) the intermediate cert, called "Developer ID Certification Authority", from the "Developer ID Intermediate Certificate" link at the Developer Certificate Utility site.

One last thing: Even if this solves your problem running on your build machine, you really want to test on the oldest OS version you support. For example, the requirements compiled by Lion's codesign sometimes can't be parsed on Leopard, or sometimes even on Snow Leopard. If that happens… see Gatekeeper vs. Leopard: an ongoing tale.

Related Topic