Relevance of kSecAttrIsInvisible in iOS

The Keychain item attribute key

kSecAttrIsInvisible
is described as:

A key whose value is a Boolean indicating the item's visibility.

This has been available in the iOS SDK since iOS 2.0+.


I assume that this may hide the Keychain item from appearing on a macOS system where the user can view the Keychain items via the Keychain Access app.


My question is, what does enabling this attribute key do on an iOS device, if anything?

Accepted Reply

I assume that this may hide the Keychain item from appearing on a macOS system where the user can view the Keychain items via the Keychain Access app.

Correct.

My question is, what does enabling this attribute key do on an iOS device, if anything?

Not much. Given that iOS does not have a general-purpose way to view keychain items, the only specific effect I can think of relates to iCloud Keychain. If the item gets sync’d over to a Mac via iCloud Keychain, you might want to make it invisible there.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

I assume that this may hide the Keychain item from appearing on a macOS system where the user can view the Keychain items via the Keychain Access app.

Correct.

My question is, what does enabling this attribute key do on an iOS device, if anything?

Not much. Given that iOS does not have a general-purpose way to view keychain items, the only specific effect I can think of relates to iCloud Keychain. If the item gets sync’d over to a Mac via iCloud Keychain, you might want to make it invisible there.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

BEWARE anyway :


I recently added this attribute to hide some items from my iOS application when the iCloud keychain is active and can be seen on a Mac, also because the MacOS version of our app is now almost ready.


And we faced critical situation where iOS users where unable to store their purchases in the Keychain because of this obscure and undocumented behaviour :

  • If you setup a dictionary to delete and rewrite an item in the KC, adding the kSecAttrIsInvisible attribute, then the delete will FAIL if the previous write was done without the invisible attribute. The error is errSecItemNotFound. Because the item is not deleted, it can't be stored again.
  • On the contrary, an item stored with the invisible attribute can be deleted with a query dictionary including or not including the attribute.


So to correctly migrate to using this attribute one should :

  1. Delete an item with a query without the kSecAttrIsInvisible attribute.
  2. If the delete fails, redo the delete with the attribute. We did not see that situation but it should be planned in the code.
  3. Then write the item with the attribute.


Future delete can succeed with the attribute, but the previous steps work with only one attempt to delete in any case we tested.

Could you confirm if kSecAttrIsInvisible also prevents keychain items autofilling in Safari on macOS? I'd like to store an entry of type kSecClassInternetPassword but don't want it viewable by the user.

If you setup a dictionary to delete and rewrite an item in the KC, adding the

kSecAttrIsInvisible
attribute, then the delete will FAIL if the previous write was done without the invisible attribute.

Right. This is expected behaviour. Remember that the dictionary you pass to

SecItemDelete
is a query dictionary: It’s used to match the items to delete. If you supply a specific attribute value, the query will on match items with that value, meaning it’ll fail to match:
  • Items with a different value

  • Items with no value

My preferred approach for dealing with the keychain is to carefully limit the contents of my query dictionary to those attributes that participate in uniqueness. There’s a list of such attributes in the docs for

errSecDuplicateItem
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"