Use Strongbox As Your SSH Agent

Strongbox can act as an SSH Agent on macOS. This means you can store your SSH Keys securely within Strongbox and have them available on all of your devices. There is no need to distribute these sensitive items across various machines in various locations. You can also generate new fresh SSH Keys within Strongbox.

NB: SSH Agent is a Pro feature available for KeePass 2.x databases on macOS only.

SSH Agent

What is an SSH Agent?

An SSH Agent is a process that holds and manages sensitive private keys and signs requests on behalf of other processes which need to connect to servers, for example Github, an SFTP server or any other server you may need to use.

SSH Agent Operation

When an SSH client like git or ssh runs on your machine it needs to authenticate to the remote server. This is usually done via SSH public key authentication. The private key is stored securely inside an SSH agent and the SSH client process asks the SSH agent to sign an authentication request proving to the remote server that you have access to the private key without exposing the private key itself.

Note that the private key never leaves the SSH Agent and neither the remote server nor the requesting process (e.g. ssh or git) has access to the private key.

The Default SSH Agent

Most modern operating systems like Linux or macOS come with a default or built-in SSH Agent. This agent uses files stored on your device to get the private key. This means you copy the private keys around different devices which can become unwieldy and hard to manage.

Strongbox as a replacement SSH agent

Strongbox can replace this default SSH Agent implementation using keys stored inside your Strongbox database. It can sign authentication requests on behalf of SSH client processes like git or ssh.

Strongbox is a more secure SSH agent

The default macOS SSH Agent allows any process access to any key that has been added to the agent. Strongbox instead asks you to approve access upfront which puts you in the drivers seat.
Approve Key Usage
When you approve a request to use a key, Strongbox will sign an authorisation request using the correct key allowing the requesting SSH Client to connect to the remote server. The private key never leaves Strongbox.

Strongbox SSH Agent Advantages
  • Strongbox notifies you when a process is trying to use an SSH Key
  • You can see what process and key is being requested and approve or deny the request
  • There is no need to store SSH keys on the file system of any device
  • Your keys are available on any device with Strongbox installed
  • Your private key never leaves Strongbox
  • It's easy to find and organise keys within the Sidebar (SSH Keys)
  • It's easy to generate, view, export and add existing SSH Keys

How to Use Strongbox as your SSH Agent

Using Strongbox as an SSH Agent is straightforward though there is a little initial setup.

1. Enable SSH Agent

First, enable the SSH Agent under: App Preferences > SSH Agent:

SSH Agent Preferences

2. Setup a Symlink (Optional)

Strongbox listens on a local domain socket so that SSH clients can request signing to authenticate to servers. This socket is located in a rather terse or verbose location on your system. To improve upon this and make things a little more convenient, we recommend creating a nice symlink to ease the next configuration step.

You can create the symlink using the commands below in your terminal App:

mkdir ~/.strongbox

ln -s ~/Library/Group\ Containers/group.strongbox.mac.mcguill/agent.sock ~/.strongbox/agent.sock
3. Configure SSH Clients to use Strongbox

SSH clients use a config file to determine where and how they should get request signing for authentication. To tell them to use Strongbox, add the lines below or similar to the top of your SSH Config file (~/.ssh/config):

Host *
   IdentityAgent ~/.strongbox/agent.sock

Note that you can be more granular with this IdentityAgent setting and have Strongbox act as an agent only for a specific host or host rather than all of them.

NB: If you didn't create the symlink in step 2 above, please use the longer direct path to the socket:

~/Library/Group\ Containers/group.strongbox.mac.mcguill/agent.sock
4. Generate or Add an SSH Key

Now that all the configuration is done you can start generating new SSH keys or adding existing ones to Strongbox. You may already have these in place if you have used KeeAgent on other platforms or KeePass applications. Strongbox tries to maintain compatibility with the KeeAgent conventions where possible.

To generate an SSH key in Strongbox, simply create a new entry as you normally would (click the + button in the toolbar) and then click the "Generate SSH Key" button (see the screenshot below) under the SSH Key section.

SSH Key Generation

We recommend the new ED25519 SSH keys which are shorter and more modern.

Click 'Save' to finish adding your SSH key.

5. Use your new SSH Key

You can now use this key with any supported service. You can add the public key to Github for example. You'll find the public key available for copy/view on the Details pane of your new SSH Key Entry. You can also export the key in standard OpenSSH format with a passphrase if needs be.

SSH Key Details

Technical Details

There is much to configure with SSH and to go beyond the basics is beyond the scope of this article but we try to offer some helpful tips and pointers in the topics below. More detail can be found in the relevant man pages (e.g. man ssh_config, man ssh-add, man ssh-keygen etc).

Eligible keys

For the Strongbox SSH agent to work with your SSH keys, your SSH key must meet the following requirements:

  • Use standard RSA or ED25519 algorithms
  • Be stored in the standard OpenSSH format
  • Have the 'Enabled for SSH Agent' setting turned ON
  • Must have the password field correctly set if they use a passphrase (applies to existing imported SSH keys only)
  • Be located in a Searchable group (e.g. not in the Recycle Bin)

Note, that you will still be asked to approve signing requests by any SSH client.

KeeAgent Compatibility

Strongbox strives to maintain compatibility with the KeeAgent KeePass plugin and other clients that follow its conventions, e.g. KeePassXC. We use the same KeeAgent.settings XML configuration file stored as an attachment with the entry.

However there are some incompatibilities which may affect you if you are an existing KeeAgent user. We do not support:

  • External Files - All Keys must be stored within the database
  • Timed Constraints - Timed constraints are not supported, the use of automatic database locking can be used as an alternative.
  • Add / Remove Constraints - SSH Keys are available when you approve them, or if you disable approval, they are available while the database is unlocked. To block access to a key, simply lock the database or disable the SSH Agent setting.
Converting existing incompatible SSH Keys to OpenSSH Format

You may have keys that begin with something like:

BEGIN RSA KEY

To convert these keys to the standard OpenSSH format you can use the following command in your terminal:

ssh-keygen -p -N "" -f my-key.pem

NB: that this overwrites the file directly in place.

SSH Key Limits, Multiple Github Accounts and Key Specification

Sometimes you want to tell an SSH client to use a particular SSH key for a particular host instead of trying all available keys, which is the default SSH behaviour. In fact most SSH servers will only let you try 6 different keys before terminating the connection for security reasons. This is a problem if you've got a lot of keys and the first 6 are rejected by the SSH Server.

Another problem can arise when a service, e.g. Github, uses the SSH Key rather than a username to identify an account. Many developers have more than one Github account, one for work and one for personal projects or just multiple work accounts.

Both of these problems can be solved using the same technique. You can specify in the SSH config file which key to use for which host, i.e. you specify the public key (not the private key) using the configuration option IdentityFile. Note, you can always export the public key from Strongbox at any time if you don't already have it. It is available on the detail pane of the SSH key. This is the file you will point at in the IdentityFile attribute.

Take a look at the sample config (~/.ssh/config) below which configures two Github accounts:

Host * 
   IdentityAgent ~/.strongbox/agent.sock

# My Personal Github Account
Host personal-git
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal.pub
    IdentitiesOnly yes

# My Work Github Account
Host work-git
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work.pub
    IdentitiesOnly yes

Now when you want to use your work Github account you simply specify the work host (work-git) in the remote URL:

git remote set-url origin work-git:my-organisation/super-cool-project.git

Alternatively using your personal Github account:

git remote set-url origin personal-git:my-username/hello-world.git

Git Commit Signing

You can also use Strongbox for signing commits. Note, this is different from connecting/authenticating with a git remote. Yes, that's right there are 2 different uses of SSH keys with Git. One for connecting to a remote git server and authenticating that connection, and another for signing your commits. You can use the same or different SSH keys for these two different operations.

Configuring Git to Sign Commits

To configure your git repository to sign commits using an SSH key do the following:

git config gpg.format ssh
git config user.signingkey ~/.ssh/github-strongbox-mark.pub
git config gpg.ssh.allowedSignersFile ~/.ssh/git_allowed_signers

NB: All of the above can be applied globally to all repositories with the --global switch.

Allowed Signers File

You must create an allowedSignersFile and add your public commit key to it. In the above example the file is located here: ~/.ssh/git_allowed_signers and the contents could look something like this:

mark@github.com ssh-ed25519 ABCAC3NzaC1AAAAAAAA5AAAAIMymMXSbc4KPv91QlR89t6u1n8ytulFnmjX4kH1FEDS mark@github.com

Signing a Commit

Once configured signing a commit is as simple as including the -S switch:

git commit -S -m 'My First Signed Commit'

Setting SSH_AUTH_SOCK correctly

Unfortunately Git doesn't use/respect the IdentityFile or IdentityAgent ssh config setting, it uses the older method of requesting signing via the SSH_AUTH_SOCK environment variable. This means you need to set this variable to point at the Strongbox SSH agent before you can use Strongbox for signing your commits. This can be done manually on the command line like so:

SSH_AUTH_SOCK=~/.strongbox/agent.sock; export SSH_AUTH_SOCK; # git commit signing via Strongbox

or if this becomes tedious, you can simply add this command to your ~/.zshrc file (or your shell equivalent) so that it runs on shell startup.

Setting SSH_AUTH_SOCK for GUI Apps

While the above will work for you from the terminal/command line, GUI Apps may not receive the proper SSH_AUTH_SOCK value. You can workaround this by doing the following in your terminal:

SSH_AUTH_SOCK=~/.strongbox/agent.sock; export SSH_AUTH_SOCK;
open -a /Applications/<your SSH or Git client>.app

This may be a little cumbersome. See below for a more permanent solution.

Setting SSH_AUTH_SOCK for all Apps (Globally)

To make sure that all apps receive the correct SSH_AUTH_SOCK value on launch, you use the commands below in your terminal to create a launch agent. You only need to do this one time.

cat << EOF > ~/Library/LaunchAgents/com.strongbox.SSH_AUTH_SOCK.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "[http://www.apple.com/DTDs/PropertyList-1.0.dtd](http://www.apple.com/DTDs/PropertyList-1.0.dtd)">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.strongbox.SSH_AUTH_SOCK</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/sh</string>
    <string>-c</string>
    <string>/bin/ln -sf $HOME/.strongbox/agent.sock \$SSH_AUTH_SOCK</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>
EOF
launchctl load -w ~/Library/LaunchAgents/com.strongbox.SSH_AUTH_SOCK.plist

NB: that the above commands are using the Strongbox symlink created above. If you didn't create a symlink, you'll need to adjust the path accordingly.

Sep 11, 2024