Securely store SSH keys with Secretive

Secretive is an app by Max Goedjen for storing and managing SSH keys in the Secure Enclave on macOS.

Most of us keep our private SSH keys on disk at ~/.ssh/id_* with restrictive file permissions to keep them a secret. However, it is not difficult for malware to copy these private keys from disk.

Secretive stores SSH private keys in the Secure Enclave1 where they cannot be exported by design. This makes it much more difficult for a malicious program to use them.

You can also require stronger access controls like authentication before every use, which can be set when creating a new secret key.

Accessing such a key requires authentication with your Apple Watch, Touch ID, or password.

In any case, whenever your keys are accessed, you get a notification. This keeps you aware of anything which uses your key — including by SSH agent forwarding. This works great for cloning from private Git repositories when deploying WordPress on a remote server.

Since the private keys cannot be exported, you cannot back them up or use the same private keys on multiple computers. You can create different keys on every computer you use which keeps the private keys safe. I have another computer with Secretive which I use as a backup, but you may consider a cold storage strategy for backup keys which are not stored on your main computer’s disk.

Secretive is available on GitHub. The binaries are created in an auditable build process which allows you to verify the source code for a given build corresponds to the release binary.

You can install Secretive with Homebrew:

brew install --cask secretive

Once you have Secretive and its SecretAgent running, a simple configuration change to your ~/.ssh/config gets you going:

Host *
  IdentityAgent "~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh"

Secretive exclusively uses ecdsa-sha2-nistp256 public keys2 which some services do not support, e.g. Azure DevOps which only supports ssh-rsa. For these keys, I use 1Password for SSH and include its IdentityAgent and Host settings for ssh.dev.azure.com earlier in my config file like this:

Host ssh.dev.azure.com
  IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
Host *
  IdentityAgent "~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh"

Since I am using identity agents like this, I no longer have any problems which require me to mess with running ssh-agent and ssh-add — access to servers and GitHub works well and seamlessly.

Many large companies have been using similar tools like Yubikeys to store keys and secure important systems. I am glad to bring this kind of technology home for my own servers.

One more thing: If you have an older Mac without a Secure Enclave, you can use Secretive with smart cards like a Yubikey.

  1. The Secure Enclave is a part of modern Mac systems on chip (SoCs) which is “designed to keep sensitive user data secure even when the Application Processor kernel becomes compromised.” If you have a recent Mac with a T series chip or M series chip, you have a Secure Enclave.
  2. Why this type? The NIST P-256 elliptic curve digital signature algorithm is used for signing because it’s what the Secure Enclave hardware supports. As a bit of an aside, some folks are cautious about this algorithm because they believe it is rigged due to an unexplained seed. This is difficult to prove or disprove. I am more likely to experience the threat of malware than a possible curve weakness.