Hi, I would like to share a keychain item common for mac os app (sandboxed) and swift cli app (non sandboxed). Is there a recommended way for doing this?
Thanks
I’m presuming that these programs are both from the same team. If they’re from different teams then there isn’t any good solution to this problem.
For programs from the same team, there are two paths to take, depending on the type of keychain you’re targeting. See TN3137 On Mac keychain APIs and implementations for more background on that.
For the data protection keychain, this is possible but slightly clunky.
Access to the data protection keychain is mediated by entitlements [1]. Those entitlements are restricted, meaning that their use must be authorised by a provisioning profile [2]. This isn’t a problem for the app, but it’s any annoying issue for your command-line tool. There’s no way to embed a profile in a command-line tool (r. 125850707), so you have to embed your tool in an app-like wrapper. For advice on how to do that, see Signing a daemon with a restricted entitlement.
In short, this is the same complication that you faced with app groups in your other thread.
[1] See Sharing access to keychain items among a collection of apps.
[2] See TN3125 Inside Code Signing: Provisioning Profiles.
For the file-based keychain, you should be able to make this work by correctly setting up the kSecAttrAccess attribute on the keychain item. This is a SecAccess value. If you don’t supply a value the system defaults to using a value that trusts just the calling process. In your case you’ll want to create the value using the SecAccessCreate(_:_:_:) function, which lets you supply a list of trusted programs.
IMPORTANT You must do this at creation time. If you attempt to change the access attribute after the fact, the system will ask the user to authorise that action )-:
I recommend that you use the first approach. The second approach relies on the file-based keychain which, as TN3137 mentions, is effectively deprecated. That’s why, for example, SecAccessCreate is deprecated.
The main drawback with the first approach is the app-like wrapper, but you can avoid most of that inconvenience by making the user-visible command-line tool a symlink to the actual executable inside your wrapper.
And when you do this, you can switch your app group code over to using an iOS-style app group, which is another forward-looking improvement.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"