Unable to read/write Keychain Access Group in FileProvider Extension

Hi -- I'm working on a macOS FileProvider extension which needs access to the same keychain as my main app (to retrieve the app's Dropbox access token).

I've set both programs up in Xcode to use a Keychain Access Group ($(AppIdentifierPrefix)com.orexresearch.EMPSecure.Shared), and to make sure it uses the group, I'm writing the token to the shared group using the kSecAttrAccessGroup attribute:

queryDict[kSecAttrAccessGroup as String] = "CD......7C.com.orexresearch.EMPSecure.Shared" as AnyObject?

The main program reads and writes the token successfully. But the extension cannot read the entry either with or without that attribute -- it produces an error -25300 (errKCItemNotFound), and if I try to write to the keychain it produces CSSM Exception: -2147415840 CSSMERR_CSP_NO_USER_INTERACTION. (Presumably this is saying it doesn't have default access to the keychain, and the system is blocking its attempt to pop a dialog to let the user select Allow.)

Any ideas what I'm missing?

Answered by jblum2000 in 701201022

Final answer was the comment posted to Matt's response: the app group container was correct, but the bundle identifier was different between the main app and extension, and Dropbox's retrieval code was using the bundle identifier as part of its search string!

I also had to patch the Dropbox Swift toolkit so that it stored the token with the kSecAttrAccessGroup attribute set to the Keychain Access Group value, and the kSecUseDataProtectionKeychain attribute set to TRUE -- the documentation at https://developer.apple.com/documentation/security/keychain_services/keychain_items/sharing_access_to_keychain_items_among_a_collection_of_apps glosses over the fact that you need to set either kSecUseDataProtectionKeychain or kSecAttrSynchronizable for kSecAttrAccessGroup to work.

Further info: this may relate to this issue: https://developer.apple.com/forums/thread/118773

The main app was built a few years ago in an earlier version of Xcode, and it may have a unique app identifier rather than using my Team ID. In the above example, the Team ID is CD......7C, but I have an app group which has been working all this time to allow communication with another extension, and its prefix is 3R......RQ. Do I need to swap everything to use the Team ID, and if so how would I do that?

Update on my update: it doesn't look likely that there's a mismatch. Both the main app and the extension have identical embedded.provisionprofile files, with the same CD......7C value for ApplicationIdentifierPrefix, com.apple.developer.team-identifier, com.apple.application-identifier (with a .), and keychain-access-groups (also with a .). There's no mention of the 3R......RQ app group anywhere in either. (Should there be? It's still being used to share the Group Containers subfolder with the other app extension...)

Further update: this is odd. I noticed the Dropbox tokens were originally being written with a minimal set of attributes and no access control:

acct = 1.....9 labl = com.orexresearch.EMPSecure.dropbox.authv2 class = genp svce = com.orexresearch.EMPSecure.dropbox.authv2 mdat = 2022-01-10 11:10:03 +0000 cdat = 2022-01-10 10:46:08 +0000

So I'm calling SecItemUpdate with the following entries in the query:             (kSecAttrAccount as String): key as AnyObject         (kSecClass as String): kSecClassGenericPassword         (kSecAttrService as String) : "(bundleId).dropbox.authv2" as AnyObject?         (kSecAttrAccessible as String) : kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly ...and the following attributes to be updated:         attributesToUpdate[kSecAttrAccessGroup as String] = "CD......7C.com.orexresearch.EMPSecure.Shared" as AnyObject?         attributesToUpdate[kSecUseDataProtectionKeychain as String] = true as AnyObject?

This returns a value of 0, so it appears to succeed... but when I query the entry again, the extra attributes haven't been added. Do I need to delete and re-add the whole entry for this to work?

This problem usually stems from 1 of 2 things; first check that the File Provider Extension and the container app are accessing the same app group container. Maybe try writing a value between the two outside the Keychain to see what this produces. Second, the extension is operating with elevated privileges so accessing the app group of the container app causes issues. However, I'm leaning towards the first option as the second is usually only present with System Extensions.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Accepted Answer

Final answer was the comment posted to Matt's response: the app group container was correct, but the bundle identifier was different between the main app and extension, and Dropbox's retrieval code was using the bundle identifier as part of its search string!

I also had to patch the Dropbox Swift toolkit so that it stored the token with the kSecAttrAccessGroup attribute set to the Keychain Access Group value, and the kSecUseDataProtectionKeychain attribute set to TRUE -- the documentation at https://developer.apple.com/documentation/security/keychain_services/keychain_items/sharing_access_to_keychain_items_among_a_collection_of_apps glosses over the fact that you need to set either kSecUseDataProtectionKeychain or kSecAttrSynchronizable for kSecAttrAccessGroup to work.

Unable to read/write Keychain Access Group in FileProvider Extension
 
 
Q