Blog
How the macOS Keychain and Secure Enclave work
macOS keeps your passwords and keys in a database with per-item access rules, not one vault with a single lock. What 'encrypted' and 'never leaves the chip' actually mean changes what you should trust it to protect.
The macOS Keychain is an encrypted database storing passwords, keys and certificates as individually access-controlled items, not one locked vault. Each item carries an access control list naming which apps may read it and whether that requires Touch ID. On a Mac with Apple silicon or a T2 chip, a private key can also be generated inside the Secure Enclave, a separate chip: the key's bytes never exist outside it, only the ability to ask it to sign or decrypt for you. The limit: a key that never leaves is still usable by anything that clears the access check, since the Secure Enclave verifies who is asking, not why.
What a keychain item actually is
A keychain item is a row in a database, not a file you can copy off the disk and read. Apple's Platform Security Guide describes the mechanism directly: keychain items are encrypted with two different AES-256-GCM keys, a table key for the item's metadata and a separate per-row key for the secret value itself. The metadata key is cached so searching the keychain stays fast; the secret key is not, and reading the actual password or key material always requires what Apple calls a round trip through the Secure Enclave.
That split is why you can list what's in a keychain, service names, account names, labels, without decrypting a single secret. Seeing that an item exists and reading its value are different operations with different checks attached.
The login keychain and the data protection keychain
Every Mac user gets a default keychain created automatically, the file you'd find as login.keychain-db and manage in Keychain Access.app. It's a SQLite database unlocked with your account password; that's the keychain that has existed since the beginning of Mac OS X, and it still holds plenty of items today.
Apple's Keychain Services API now also treats items as belonging to what it calls the data protection keychain, when an app opts in with the kSecUseDataProtectionKeychain attribute, so they behave the way an iOS keychain item does rather than the legacy macOS one. Apple's developer documentation puts it plainly: set that attribute to true for all keychain operations, and only skip it if you specifically need access to items stored under the old legacy keychain. In practice, newer software writes into the layer whose secret keys get the Secure Enclave round trip described above, while older items may still sit behind your login password alone.
Access control lists: who is allowed to ask
Every item carries its own access control list rather than a single switch. Apple's security guide states it directly: keychains use ACLs to set accessibility and authentication requirements per item, and items can require that they not be accessed unless the user authenticates with Face ID, Touch ID, Optic ID, or a passcode. An ACL can go further and require that the enrolled biometry hasn't changed since the item was added, specifically to stop an attacker who gets hold of an unlocked device from adding their own fingerprint and walking straight in.
Those checks aren't performed by the app asking for the secret. The guide is explicit that ACLs are evaluated inside the Secure Enclave and released to the kernel only once their conditions are met, so the gate sits in hardware the requesting process doesn't control.
The same idea shows up in the command-line tool. When add-generic-password creates an item, the app that created it is trusted by default; you can name other apps allowed in with -T, or you can explicitly withdraw default trust with -T "" so every access prompts. There's also a documented escape hatch, -A, which Apple's own man page labels "allow any application to access this item without warning (insecure, not recommended!)", a reminder that the wide-open option exists and is spelled out as a bad idea by the tool itself.
The security command line, briefly
/usr/bin/security is Apple's own description of itself: a command line interface to keychains and the Security framework, and everything Keychain Access.app does in a window, this does from a shell. A few commands cover most of what you'll ever need.
security find-generic-password -s github.com -wprints only the secret for a matching item, if the calling process is allowed to read it.security add-generic-password -a me -s my-service -wadds a new password item, prompting for the value if you leave it off the end of the line.security dump-keychain -a login.keychain-dblists every item's access control list without touching a single secret value, useful for seeing who's trusted to read what.security delete-generic-password -s my-serviceremoves a matching item outright.
What "never leaves the Secure Enclave" actually means
The Secure Enclave is, in Apple's own words, a dedicated secure subsystem integrated into the Mac's chip, isolated from the main processor, with its own boot process and its own protected memory. It ships on every Apple silicon Mac and on Intel Macs built around the T1 or T2 chip.
Apple's developer documentation is specific about what the guarantee covers: when you protect a private key with the Secure Enclave, you never handle the plain-text key at all. You instruct the chip to create the key and later to decode and perform operations with it, and you receive only the output, encrypted data or a signature, never the key bytes themselves. Signing and decryption genuinely happen inside the chip; your code calls an API and gets a result back.
Two real restrictions come with that guarantee. First, the Secure Enclave works only with NIST P-256 elliptic curve keys, usable for signing, verification, and Diffie-Hellman key exchange, nothing else; there's no RSA inside it. Second, it can't encode a key you already have: you must generate the key inside the Secure Enclave from the start, since there's deliberately no way to move plain-text key material in or out. A key imported from elsewhere, or one needing an algorithm the Enclave doesn't support, doesn't get this protection no matter what you call it.
Touch ID gating a specific item
Requiring Touch ID for one keychain item is the access control flag from the ACL section above, applied at creation time. Apple's documentation describes supplying an access control instance built from an accessibility setting plus a flag requiring user presence, typically letting the system pick between biometrics or a passcode fallback depending on what's available at the moment.
What actually happens when you see that Touch ID prompt: the app asked the Secure Enclave to produce a result, the chip checked the item's ACL, found a presence requirement attached, and held the answer until your fingerprint (or a fallback passcode) satisfied it. The app itself can't skip that step or answer on your behalf, because the check and the secret both live on the other side of the same boundary.
The limit: anyone who can ask, can use it
This is the part worth stating plainly rather than leaving implied. An access control list decides which processes, or which authentication state, are allowed to ask the Secure Enclave for a signature or a decrypted value. Once that check passes, the chip answers faithfully, every time, regardless of what the request is for. There's no judgment layer asking whether this particular request looks reasonable; there's only "did the caller match the ACL, and was the required proof supplied."
That means a key that can never be exported is not the same as a key that can't be misused. Export-resistance stops someone stealing the key material itself, say by copying a keychain file off a stolen disk, which really does become unreadable. It doesn't stop a process already trusted by the item's ACL, or a Touch ID prompt you approve because it looked like your own app asking, from getting a valid signature or decrypted value out of it. The hardware boundary protects the bytes; it was never designed to judge intent.
How this works in Forkbench
Forkbench's Vault stores your API keys, tokens and passwords in the macOS Keychain rather than in Forkbench's own database. Per Forkbench's security page, values are stored sealed to the Mac holding them: encrypted under a key that lives in that Mac's Secure Enclave and cannot be exported from it, so a copied keychain file or a stolen disk yields nothing. Notes work the same way: each Mac you enroll opens your notes key with its own Secure Enclave key rather than a password to remember.
The same limit from above applies here: the Secure Enclave key decides what a stolen disk can read, not what a process already granted access is allowed to do. If every Mac holding that key is lost, there's a separate, documented path back in, covered in what happens to your keys if you lose your Mac.
Related: What happens to my keys if I lose my Mac?, How Forkbench's Vault uses the Keychain and the Secure Enclave, Why an AI agent's credentials need a lifecycle too
Frequently asked
What is the difference between the macOS Keychain and the Secure Enclave?
The Keychain is the encrypted database that stores every item: web passwords, Wi-Fi credentials, certificates, app secrets. The Secure Enclave is a separate processor that some of those items can be bound to. Every keychain secret gets a round trip through the Secure Enclave to be decrypted, but a private key specifically generated inside the Secure Enclave is different: its bytes exist only inside that chip, and the keychain holds just a reference plus the public half.
Can a key stored in the Secure Enclave be exported or backed up?
No. Apple's documentation states there's deliberately no mechanism to move plain-text key data into or out of the Secure Enclave, which is fundamental to its security model. It also can't protect a key you already have: you must generate the key inside the Secure Enclave from the start, and only as a NIST P-256 elliptic curve key, since that's the only type it supports.
Does Touch ID protect every password in my keychain?
Only items created with that requirement attached. Touch ID gating is an access control list flag an app sets when it creates the item, not a blanket setting applied to the whole keychain. Most saved web passwords don't carry it unless the browser or app specifically asked for it.
How do I see what's protecting a keychain item from the command line?
security dump-keychain -a <keychain>lists every item's access control list without revealing any secret value, showing which apps are trusted to read what.security find-generic-password -s <service> -wprints just the secret for one matching entry, if the calling process is allowed to. Both come from Apple's own/usr/bin/securitytool, the command-line equivalent of Keychain Access.app.If a key never leaves the Secure Enclave, is it safe from misuse?
It's safe from theft; nobody can extract the key bytes from the chip or from a stolen disk. It isn't safe from a process that's already allowed to ask for a signature or a decryption and does so for the wrong reason, because the access control list governs who may ask, not what they're asking for. Non-exportability and misuse-resistance are two different guarantees.
Keep reading
Sources
- Apple Platform Security Guide: The Secure Enclave
- Apple Platform Security Guide: Keychain data protection
- Apple Developer Documentation: Protecting keys with the Secure Enclave
- Apple Developer Documentation: Restricting keychain item accessibility
- Apple Developer Documentation: kSecUseDataProtectionKeychain