{"slug": "native-secure-enclaved-backed-ssh-keys-on-macos", "title": "Native Secure Enclaved backed ssh keys on MacOS", "summary": "MacOS Sequoia (Tahoe) now natively supports generating and using SSH keys backed by the device's Secure Enclave, replacing third-party tools like Secretive. This is achieved through the `/usr/lib/ssh-keychain.dylib` library, which implements the `SecurityKeyProvider` interface to allow SSH to directly load keys from the Secure Enclave instead of relying on external FIDO2 hardware like Yubikeys. Users can create biometric-protected keys via the `sc_auth` command and use them with standard SSH tools by setting the `SSH_SK_PROVIDER` environment variable.", "body_md": "# Native Secure Enclave backed ssh keys on MacOS \n\nIt turns out that MacOS Tahoe can generate and use secure-enclave backed SSH keys! This replaces projects like https://github.com/maxgoedjen/secretive\n\nThere is a shared library `/usr/lib/ssh-keychain.dylib` that traditionally has been used to add smartcard support\nto ssh by implementing `PKCS11Provider` interface. However since recently it also implements `SecurityKeyProivder`\nwhich supports loading keys directly from the secure enclave! `SecurityKeyProvider` is what is normally used to talk to FIDO2 devices (e.g. `libfido2` can be used to talk to your Yubikey). However you can now use it to talk to your Secure Enclave instead!\n\n\n\nhttps://gist.github.com/user-attachments/assets/ff033694-13e1-454e-b42b-b5c19e0fb2a0\n\n\nSeems this method was first discovered in https://lists.mindrot.org/pipermail/openssh-unix-dev/2024-July/041451.html\n\n## Key setup\n\nSee `man sc_auth` and `man ssh-keychain` for all the options\n\nTo create a Secure Enclave backed key that requires biometrics, run the\nfollowing command and press TouchID:\n```\n% sc_auth create-ctk-identity -l ssh -k p-256-ne -t bio\n```\n\nYou can confirm that the key was create with the `list-ctk-identities` command:\n```\narian@Mac ssh-keychain % sc_auth  list-ctk-identities       \nKey Type Public Key Hash                          Prot Label Common Name Email Address Valid To        Valid \np-256-ne A71277F0BC5825A7B3576D014F31282A866EF3BC bio  ssh   ssh                       23.11.26, 17:09 YES\n```\n\n\nIt also supports listing the ssh key fingerprints instead:\n```\n% sc_auth  list-ctk-identities -t ssh\nKey Type Public Key Hash                                    Prot Label Common Name Email Address Valid To        Valid \np-256-ne SHA256:vs4ByYo+T9M3V8iiDYONMSvx2k5Fj2ujVBWt1j6yzis bio  ssh   ssh                       23.11.26, 17:09 YES \n```\n\nKeys can be deleted with\n```\n% sc_auth delete-ctk-identity -h <Public Key Hash>\n```\n\n\n## Usage with `ssh`\n\nYou can \"download\" the public / private keypair from the secure enclave using the following command:\n```\n% ssh-keygen -w /usr/lib/ssh-keychain.dylib -K -N \"\"\nEnter PIN for authenticator: \nYou may need to touch your authenticator to authorize key download.\nSaved ECDSA-SK key to id_ecdsa_sk_rk\n% cat id_ecdsa_sk_rk.pub \nsk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBKiHAiAZhcsZ95n85dkNGs9GnbDt0aNOia2gnuknYV2wKL3y0u+d3QrE9cFkmWXIymHZMglL+uJA+6mShY8SeykAAAAEc3NoOg== ssh:\n```\n\nYou can just use the empty string for PIN. For some reason `openssh` always asks for\nit even if the authenticator in question does not use a PIN but a biometric.\nNote that the \"private\" key here is just a reference to the FIDO credential. It does\nnot contain any secret key material. Hence I'm specifiyng `-N \"\"` to skip an encryption\npassphrase.\n\nNow if you copy this public key to your authorized keys file, it should work!\n\n```\n% ssh-copy-id -i id_ecdsa_sk_rk localhost\n% ssh -o SecurityKeyProvider=/usr/lib/ssh-keychain.dylib localhost\n```\n\n\n## Usage with `ssh-agent`\n\nInstead of downloading the public/private keypair to a file you can also directly\nmake the keys available to `ssh-agent`. For this you can use the following command:\n```\n% ssh-add -K -S /usr/lib/ssh-keychain.dylib\nEnter PIN for authenticator: \nResident identity added: ECDSA-SK SHA256:vs4ByYo+T9M3V8iiDYONMSvx2k5Fj2ujVBWt1j6yzis\n% ssh-add -L\nsk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBKiHAiAZhcsZ95n85dkNGs9GnbDt0aNOia2gnuknYV2wKL3y0u+d3QrE9cFkmWXIymHZMglL+uJA+6mShY8SeykAAAAEc3NoOg== \n% ssh-copy-id localhost\n% ssh -o SecurityKeyProvider=/usr/lib/ssh-keychain.dylib localhost\n```\n\n\n## Using the SecurityKeyProvider by default\n\n`SecurityKeyProvider` can be configured in `.ssh/config` but I recommend setting\n`export SSH_SK_PROVIDER=/usr/lib/ssh-keychain.dylib` in your `.zprofile` instead as\nthat environment variable gets picked up by `ssh`, `ssh-add` and `ssh-keygen`.\n\nThis means you can just do:\n\n```\nssh-add -K\nssh my-server\n```\n\nor\n\n```\nssh-keygen -K\nssh -i id_ecdsa_rk_sk my-server\n```\n\nto ssh into your server\n\n\n## Exportable keys\n\nThere's also an exportable variant where the private key is encrypted using the secure enclave as opposed to generated on the secure enclave. This is might be considered less secure but is convenient for key backup.\n\n````\n% sc_auth create-ctk-identity -l ssh-exportable -k p-256 -t bio\n% sc_auth list-ctk-identities\np-256    A581E5404ED157C4C73FFDBDFC1339E0D873FCAE bio  ssh-exportable ssh-exportable               23.11.26, 19:50 YES  \n% sc_auth export-ctk-identity -h A581E5404ED157C4C73FFDBDFC1339E0D873FCAE -f ssh-exportable.pem\nEnter a password which will be used to protect the exported items:\nVerify password:\n````\n\nYou can then re-import it on another device\n\n```\n% sc_auth import-ctk-identities -f ssh-exportable.pem.p12 -t bio\nEnter PKCS12 file password:\n```\n\n", "url": "https://wpnews.pro/news/native-secure-enclaved-backed-ssh-keys-on-macos", "canonical_source": "https://gist.github.com/arianvp/5f59f1783e3eaf1a2d4cd8e952bb4acf", "published_at": "2025-11-23 17:53:28+00:00", "updated_at": "2026-05-22 09:52:56.246537+00:00", "lang": "en", "topics": ["cybersecurity", "developer-tools", "products", "open-source", "research"], "entities": ["macOS", "Secure Enclave", "TouchID", "ssh-keychain.dylib", "FIDO2", "Yubikey", "Secretive", "maxgoedjen"], "alternates": {"html": "https://wpnews.pro/news/native-secure-enclaved-backed-ssh-keys-on-macos", "markdown": "https://wpnews.pro/news/native-secure-enclaved-backed-ssh-keys-on-macos.md", "text": "https://wpnews.pro/news/native-secure-enclaved-backed-ssh-keys-on-macos.txt", "jsonld": "https://wpnews.pro/news/native-secure-enclaved-backed-ssh-keys-on-macos.jsonld"}}