Something new in keychain-access-groups

All identifiers updated in summer 2020 has new value for keychain-access-groups - com.apple.token. What is its purpose? What can happen if this value will not be added to entitlements?
com.apple.token is the value of kSecAttrAccessGroupToken.

Share and Enjoy

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

As per this documentation - https://developer.apple.com/documentation/security/ksecattraccessgrouptoken?language=objc

kSecAttrAccessGroupToken - Access to this group is granted by default and does not require an explicit entry in your app's Keychain Access Groups Entitlement.

If I try to fetch an item from the keychain by specifying this group, OSStatus is coming as -34018 - errSecMissingEntitlements. However, everything works fine if we have this com.apple.token entry in the entitlements file.

Can someone please provide a snippet to fetch tokens from keychain by just specifying the kSecAttrAccessGroupToken in the search query. Please refer the attached screenshot -

I have tried to debug the issue using **codesign -d --entitlements :- ** command but 'com.apple.token' is not listed in the keychain access groups keys -

This is one of the few places where the data protection keychain [1] varies between macOS and iOS:

  • On macOS, all apps with access to the data protection keychain get implicit access to the com.apple.token keychain access group (com.apple.token is the value of kSecAttrAccessGroupToken). The app does not need to list it in its keychain-access-groups. Indeed, the app can’t list it there, because there’s no way to create a macOS provisioning profile that authorises it.

  • On iOS, and its child platforms, the com.apple.token keychain access group acts like a normal keychain access group. To use it you must claim access by adding it to the keychain-access-groups array and that claim must be authorised by your provision profile (which it is, as noticed by Mihik when they started this thread).

The documentation fails to capture this subtlety, and I’d appreciate you filing a bug against it. Please post post your bug number, just for the record.

Can someone please provide a snippet to fetch tokens from keychain by just specifying the kSecAttrAccessGroupToken in the search query.

One does not “fetch tokens from the keychain”, but rather credentials (keys, certificates, or digital identies) that are hosted within tokens. Here’s an example of how I get a list of token-hosted digital identities:

let identityRefs = try secCall { SecItemCopyMatching([
    kSecClass: kSecClassIdentity,
    kSecAttrAccessGroup: kSecAttrAccessGroupToken,
    kSecMatchLimit: kSecMatchLimitAll,
    kSecReturnRef: true,
    kSecReturnPersistentRef: true,
] as NSDictionary, $0) } as! [[String: Any]]

The same code works on macOS and iOS, once you get the entitlements sorted out per my notes above.

ps This is using the helpers from here.

Share and Enjoy

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

[1] In contrast, there are a bunch of places where the file-based keychain varies from the data protection keychain. See TN3137 On Mac keychain APIs and implementations for the full backstory here.

Effectively I confirm that com.apple.token is required in keychain-access-groups entitlement on macOS as well when using kSecAttrAccessGroupToken. Missing to do so, will return error -34018 (tested on macOS 14).

Something new in keychain-access-groups
 
 
Q