Keychain — Key Concepts, Architecture and How It Works

Author: IT Sectr Published: 2026-03-14 Reading time: 10 min

Keychain is a secure credential storage in iOS, watchOS, macOS, and tvOS that manages passwords, keys, and certificates at the hardware level. Unlike UserDefaults, data in Keychain is encrypted and isolated per application sandbox. According to Apple Developer Documentation, Keychain uses Secure Enclave mechanisms and AES-256 hardware encryption to protect sensitive information.

Key Takeaways

  • Keychain — iOS system storage for passwords, keys, and certificates with hardware encryption
  • Security framework provides C functions SecItemAdd, SecItemCopyMatching, and SecItemDelete for working with Keychain
  • Access to Keychain is limited by app sandbox, but shared access is possible through keychain access groups
  • The kSecAttrAccessible attribute defines the protection level: from Always to WhenUnlockedThisDeviceOnly
  • Keychain supports storing passwords, symmetric and asymmetric keys, and X.509 certificates

What is Keychain?

Keychain is a secure database of the Apple operating system designed for safe storage of passwords, cryptographic keys, certificates, and other sensitive data. Keychain first appeared in Mac OS 8.6 in 1999, and on iOS — from the very first SDK version.

Definition and Purpose

Keychain solves a fundamental problem of mobile development: storing secrets (tokens, passwords, encryption keys) in an unsecured file system. Unlike UserDefaults or SQLite, data in Keychain is stored encrypted and is automatically encrypted when written to disk.

Each iOS application runs in an isolated sandbox and has access only to its own keychain. However, the developer can configure shared Keychain access between applications of the same developer through keychain access groups. The user's iCloud Keychain additionally synchronizes data between devices through end-to-end encryption.

According to Apple Security White Paper (2025), Keychain uses AES-256 hardware encryption with a key tied to the unique device identifier (UID), making data inaccessible when extracted from the device.

How Does Keychain Work on iOS?

Keychain functions as a layered service: the application accesses the Security framework, which communicates with the securityd daemon that manages the encrypted SQLite Keychain database. Each record is encrypted with a separate key, and the keys themselves are protected by the Secure Enclave hardware module on devices with A7 chip and newer.

Security Framework Architecture

The Security framework provides a C interface for working with Keychain Services. Main functions: SecItemAdd (add), SecItemCopyMatching (search), SecItemUpdate (update), and SecItemDelete (delete). Each operation accepts a CFDictionaryRef attribute dictionary describing the request type.

Data is classified by classes: kSecClassGenericPassword (arbitrary password), kSecClassInternetPassword (internet service password), kSecClassCertificate (certificate), kSecClassKey (cryptographic key), and kSecClassIdentity (key and certificate pair).

Data Saving Process

When saving a password, the application creates a dictionary with attributes: service, account, access level, label. Security framework passes the data to the securityd daemon, which encrypts the record with a device-bound key and stores it in the Keychain SQLite. Retrieval works similarly: query by attributes, search, decryption, and data return.

An important feature: when an application is deleted, iOS automatically clears Keychain records created by that application (since iOS 10.3+). When reinstalling the application, Keychain data from the previous installation is unavailable unless iCloud Keychain was used.

swift
import Security

func savePassword(service: String, account: String, password: Data) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account,
        kSecValueData as String: password,
        kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
    ]
    SecItemAdd(query as CFDictionary, nil)
}

Keychain Data Types

Keychain supports five main data classes, each with its own set of attributes and application scope. The choice of class determines which search keys are available and how data is encrypted.

Passwords and Accounts

The kSecClassGenericPassword and kSecClassInternetPassword classes are designed for storing string passwords. The Internet version additionally stores server data: domain, protocol, port, and authentication path. GenericPassword is used for storing any passwords without server binding.

When saving an internet password, you can specify kSecAttrServer (domain), kSecAttrProtocol (HTTPS, FTP, etc.), kSecAttrPort, and kSecAttrPath. This allows precise identification of the record during automatic filling via AutoFill.

Cryptographic Keys and Certificates

The kSecClassKey class stores symmetric (AES) and asymmetric (RSA, EC) keys. The kSecClassCertificate class stores X.509 certificates. The kSecClassIdentity class combines a private key and its corresponding certificate into one record.

For asymmetric keys, Keychain supports attributes: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (whether to save to Keychain). For certificates: kSecAttrLabel (human-readable name), kSecAttrSubject (owner DN), kSecAttrIssuer (issuer DN).

Keychain ClassPurposeData Type
kSecClassGenericPasswordApp passwordData (NSString)
kSecClassInternetPasswordServer passwordData + server attributes
kSecClassCertificateX.509 certificateSecCertificate
kSecClassKeyCryptographic keySecKey
kSecClassIdentityKey + certificateSecIdentity

Working with Keychain via API

The main interface for interacting with Keychain in native iOS code is the Security framework functions. For Swift and Objective-C, a single C interface is available, wrapped in convenient functions.

Basic Operations SecItemAdd and SecItemCopyMatching

The SecItemAdd function adds a new item to the Keychain. It takes a dictionary with class, data, and attributes as input. Returns errSecSuccess (0) status or an error code. The SecItemCopyMatching function performs a search by attributes and returns the found data.

For searching, the kSecReturnData flag is used — if true, the function returns the record contents. The kSecMatchLimit flag determines the number of results: kSecMatchLimitOne (one) or kSecMatchLimitAll (all).

swift
func readPassword(service: String, account: String) -> Data? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account,
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    var item: CFTypeRef?
    let status = SecItemCopyMatching(query as CFDictionary, &item)
    guard status == errSecSuccess else { return nil }
    return item as? Data
}

Deleting and Updating Records

SecItemUpdate allows changing attributes or data of an existing record. SecItemDelete deletes all records matching the passed dictionary. When deleting, it is important to specify enough attributes to avoid accidentally deleting other records in the shared keychain.

swift
func deletePassword(service: String, account: String) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account
    ]
    SecItemDelete(query as CFDictionary)
}

Access Control Levels and Data Protection

Each Keychain record has the kSecAttrAccessible attribute, which determines when the data is available for reading. This is critically important for security: the wrong access level can make data vulnerable or, conversely, unavailable when needed.

Accessibility Constants

kSecAttrAccessibleWhenUnlocked — data is available only when the device is unlocked. kSecAttrAccessibleAfterFirstUnlock — available after the first unlock after reboot. kSecAttrAccessibleAlways — always available (not recommended). The ThisDeviceOnly postfix prevents data transfer through backup.

On devices with Secure Enclave, the Keychain encryption key can be additionally protected by biometrics: kSecAccessControlBiometryCurrentSet or kSecAccessControlUserPresence. This adds a Face ID or Touch ID requirement for each read operation.

iCloud Keychain and Synchronization

iCloud Keychain synchronizes records between Apple devices through end-to-end encryption. Apple does not have access to decrypted data. To enable synchronization, add the kSecAttrSynchronizable attribute with the value kCFBooleanTrue.

Important: synchronized records cannot contain the ThisDeviceOnly attribute, as they must be available on other devices. If all devices are lost, iCloud Keychain can be restored using a recovery code or iCloud recovery key.

Best Practices for Choosing Access Level

For authentication tokens, use kSecAttrAccessibleWhenUnlockedThisDeviceOnly — data is only available when the device is unlocked and is not copied to backups. For certificates that need to be available for background tasks, use kSecAttrAccessibleAfterFirstUnlock. Never use kSecAttrAccessibleAlways for sensitive data.

It is recommended to always add the ThisDeviceOnly postfix for data that does not require synchronization. This prevents accidental copying of secrets to iCloud or iTunes backup, where they could be extracted by analysis tools. For critical data, combine accessibility with kSecAccessControlUserPresence — this adds a biometric or passcode requirement for record decryption.

When using iCloud Keychain, keep in mind that synchronized records are available on all user devices: if an attacker gains access to one device, data could be compromised on all. For isolated secrets, use ThisDeviceOnly.

Frequently Asked Questions

How is Keychain different from UserDefaults?

UserDefaults stores data in plain text in a .plist file, accessible during IPA analysis. Keychain encrypts each record separately, uses hardware encryption, and supports access levels, biometrics, and synchronization via iCloud.

How to clear Keychain during testing?

On each launch of the iOS simulator, Keychain is cleared. On a real device, delete the app — iOS will remove all Keychain records of that developer. For selective clearing, call SecItemDelete with the appropriate attributes.

Can two applications share a common Keychain?

Yes, through keychain access groups. Applications must have the same team ID in the provisioning profile and entitlements with the same keychain-access-groups. The developer configures shared access in Xcode Capabilities.

What is the maximum data size in Keychain?

Apple does not document a strict limit, but in practice it is recommended not to exceed 1–4 KB per record. For larger volumes, use file encryption and store the key in Keychain, while the data itself goes in Documents.

Is Keychain secure on a jailbroken device?

On a jailbroken device, Keychain protection is reduced because the attacker gains root access and can read the Keychain SQLite directly. For critical data, use additional encryption with a key obtained from the server.

Summary

  • Keychain — iOS secure storage for passwords, keys, and certificates with AES-256 hardware encryption
  • Security framework provides C-API: SecItemAdd for writing, SecItemCopyMatching for reading, SecItemDelete for deleting
  • Keychain data classes: GenericPassword, InternetPassword, Certificate, Key, Identity — each with its own set of attributes
  • kSecAttrAccessible controls the access level: WhenUnlocked, AfterFirstUnlock, Always, with the ThisDeviceOnly option
  • iCloud Keychain synchronizes records between devices through end-to-end encryption with the kSecAttrSynchronizable attribute
  • Biometrics (Face ID / Touch ID) protects Keychain access through kSecAccessControlBiometryCurrentSet
  • Use Keychain for storing OAuth tokens, passwords, and cryptographic keys — do not store secrets in UserDefaults

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also