Skip to main content

Keychain

The iOS Keychain is a secure storage system that allows apps to store sensitive information such as passwords, keys, and login tokens. It uses end-to-end encryption, providing the highest level of data security. The Keychain is implemented as an SQLite database, stored on the file system. Keychain items are encrypted using two different AES-256-GCM keys: a table key (metadata) and a per-row key (secret key). The metadata key is protected by the Secure Enclave but is cached in the Application Processor to allow fast queries of the keychain. The secret key always requires a round trip through the Secure Enclave. 

Keychain data is stored locally on the device and can also be synced across all your devices using iCloud. When iCloud Keychain is turned on, your passwords and passkeys will sync to your device again. If you choose to keep the information when you sign out of iCloud on your device while iCloud Keychain is turned on, your passwords and passkeys are stored locally on your device, but aren't deleted or updated when you make changes on other devices. An encrypted copy of your Keychain data is kept on iCloud servers. 

Access to the Keychain is controlled by the securityd daemon, which determines which keychain items each process or app can access. Keychain Access APIs result in calls to the daemon, which queries the app's "Keychain-access-groups," "application-identifier," and "application-group" entitlements. Rather than limiting access to a single process, access groups allow keychain items to be shared between apps. Keychain items can be shared only between apps from the same developer. To share keychain items, third-party apps use access groups with a prefix allocated to them through the Apple Developer Program in their application groups. The prefix requirement and application group uniqueness are enforced through code signing, provisioning profiles, and the Apple Developer Program. 

Items stored in the Keychain can also have accessibility protections set for each entry. This determines how the data in the keychain entry can be accessed, whether it can be copied into a backup, or even transferred to a new device. Data protection for the Keychain items is set by using the kSecAttrAccessible key to SecItemAdd or SecItemUpdate.

There are several values that the kSecAttrAccessible key may have:

  • kSecAttrAccessibleAlways

  • kSecAttrAccessibleAlwaysThisDeviceOnly

  • kSecAttrAccessibleAfterFirstUnlock

  • kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly

  • kSecAttrAccessibleWhenUnlocked

  • kSecAttrAccessibleWhenUnlockedThisDeviceOnly

  • kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly

In addition to accessibility protections, Keychain items may also have access control protections.

These are set through the kSecAccessControl keys.

  • kSecAccessControlDevicePasscode

  • kSecAccessControlBiometryAny

  • kSecAccessControlBiometryCurrentSet

  • kSecAccessControlUserPresence

Any keys that are secured by biometrics (Touch ID or Face ID), are protected by the Secure Enclave Processor (SEP). In these cases, the Keychain does not hold the actual value of the key. Rather it holds a token that can be used to query SEP to obtain the actual key. This query will require you to provide a valid biometric authentication to obtain the key.