kSecAttrAccessGroup in SecItemCopyMatching query

I want to store some cryptographic keys in the keychain. I've been able to commit a few in my application, but when I go to search for them, I get a lot of extraneous results. This happens even if I try to use kSecAttrAccessGroup in my query like so:


let keychainQuery: [String: Any] = [kSecClass as String: kSecClassKey,
kSecAttrAccessGroup as String: "7X6QFLT4GF.com.example.myApp",
kSecReturnAttributes as String: true,
kSecMatchLimit as String: kSecMatchLimitAll]
var keychainItems: CFTypeRef?
let keychainSearchStatus = SecItemCopyMatching(keychainQuery as CFDictionary, &keychainItems)


keychainItems winds up containing things like my iMessage keys. The baffling part is these items don't even have an agrp key in their dictionary, so how are they matching my query for a specific group?


Every reasonable filter I have tried returns either no results OR the nine extraneous keys OR my keys plus the nine extraneous keys. I tried filtering by key length (all the keys I have stored happen to be 521-bit ECDSA), and I got only my keys, so I know filtering works at all.


What is the right way to find only items which my application has added?




Separately, when I'm using Keychain Access, should I see things my application adds? I currently do not, and I'm not sure if that is relevant.

Accepted Reply

Figured it out, and yes, I was missing something obvious. You apparently have to also have the keys kSecUseDataProtectionKeychain or kSecAttrSynchronizable set to true in your query dictionary for kSecAttrAccessGroup filters to work. It's right there in the documentation, and I evidently missed it.


Still not sure what's going on with kSecAttrIsInvisible, but I don't actually need that working.

Replies

Sorry, forgot to include my version. I'm on macOS 10.15.4, targeting macOS 10.15.


My application has the Keychain Group "com.example.myApp" specified in its Signing & Capabilities section, and "$(AppIdentifierPrefix)com.example.myApp" in its entitlements file.


Weirdly enough, I do see the nine additional items which keep showing up in my query in Keychain Access under login > Keys. When I search for kSecAttrIsInvisible: true, I get only the nine keys I see in Keychain Access. When I search for kSecAttrIsInvisible: false, I get ... the nine keys I see in Keychain Access.


I just feel like there must be something critical I'm misunderstanding about how these queries are meant to work.

Figured it out, and yes, I was missing something obvious. You apparently have to also have the keys kSecUseDataProtectionKeychain or kSecAttrSynchronizable set to true in your query dictionary for kSecAttrAccessGroup filters to work. It's right there in the documentation, and I evidently missed it.


Still not sure what's going on with kSecAttrIsInvisible, but I don't actually need that working.