How to get SSH to work with 1password + Docker Desktop + macOS (within a container)
Background
@nckrtl and I have been working together on trying to resolve his issue. We learned a lot and I am putting together this guide as initial notes.
Important concepts to understand
- 1password stores your SSH keys in it’s vault (you don’t keep your keys in
~/.ssh
- You must follow their guide on how to create/import SSH keys
- Once a key is saved, you use the 1password SSH Agent to securely load and authorize use of your keys
- š REMEMBER: Docker Desktop does not run docker natively on your Mac, so they created this
/run/host-services/ssh-auth.sock
that will return a mounted
Set up
Use these steps to complete set up.
Generate your SSH key
Follow the 1password docs to generate your SSH key. The SSH key should be stored in their vault, not in your ~/.ssh
.
Enable the 1password SSH Agent
Follow the docs to enable the 1password SSH Agent.
Where things start to get confusing
When you first enable your agent, you’ll be prompted to add this to your ~/.ssh/config
file.
NOTE: If you mount your SSH directory into your container (which you probably want to), your container will want to reference
~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock
which probably WILL NOT exist without some configuration.
Understanding IdentityAgent
vs SSH_AUTH_SOCK
In my testing, the IdentityAgent
wasn’t always required but the 1password documentation talks about this more in their Working with SSH clients section on how you can pick and choose.
In this example, we’re assuming you’re following what 1password wants you to do with the SSH config, which adds a little extra work for your container.
We’re assuming you have a ~/.ssh/config
that looks like this on your host:
Host *
# You might not need this line. Read this for more:
# https://developer.1password.com/docs/ssh/agent/compatibility/#working-with-ssh-clients
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
Another layer of confusion: Docker Desktop on macOS
When you’re running Docker Desktop, Docker runs very differently as it would on a Linux machine running the Docker engine. Docker Desktop runs a tiny virtual machine to run the Docker daemon that sits in between your macOS host and the Docker engine. This adds another level of complexity.
Docker Desktop Doesn’t inherit shell environments by default
One really confusing thing was I was setting all of these configurations and I couldn’t get it to work. It wasn’t until I saw this post by a 1password employee that explains Docker Desktop is managed by launchd
on macOS and it will not inherit the shell environment by default.
I had to close Docker Desktop and launch it with:
open -a /Applications/Docker.app/
To get this to work permanently, you need to configure a .plist
file following the “Configure SSH_AUTH_SOCK globally for every client” in the 1password documentation.
Exposing the SSH Auth socket with Docker + macOS
Docker Desktop provides a “magic” path to share your SSH Auth Socket at /run/host-services/ssh-auth.sock
. This means we need to mount this path and set the $SSH_AUTH_SOCK
variable in the container.
docker run -it --rm \
\
# Mount the `.ssh` directory as READONLY
-v "$HOME/.ssh:/.ssh:ro" \
# Mount the known_hosts as READ-WRITE
-v "$HOME/.ssh/known_hosts:/.ssh/known_hosts:rw" \
# Set the magic auth socket for Docker Desktop
-v "/run/host-services/ssh-auth.sock:/run/host-services/ssh-auth.sock" \
# Set the SSH_AUTH_SOCK variable in the container to point to our magic
-e "SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock" \
# Set your image (this is our image with SSH installed)
docker.io/serversideup/ansible-core:alpine sh
Where the SSH Config confusion comes in
Now that we have the following:
- ā A mounted SSH directory (as read only)
- ā A mounted authorized keys file (as read/write)
- ā
The
/run/host-services/ssh-auth.sock
mounted to/run/host-services/ssh-auth.sock
in the container - ā
The
SSH_AUTH_SOCK
variable set to/run/host-services/ssh-auth.sock
in the container - ā The ability for Alpine Linux to understand your
~/.ssh/config
file
The problem lies with this part of the config:
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
That does not exist in the Alpine container. As a workaround, we create this :
mkdir -p "$HOME/Library/Group Containers/2BUA8C4S2C.com.1password/t"
ln -sf "$SSH_AUTH_SOCK" "$HOME/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
This essentially creates the file and we symbolically link it to the Docker Socket, which then links it to your host š¤Æ
Testing
You’ll know if everything is working correctly if you run ssh-add -l
in the container and it comes back with something like:
256 SHA256:4G9mDIDnn1VsLZFSWYMzvsyzF9I4n4HghjKDIeMIKcE SSH Key (ED25519)
Advanced Usage: Dropping Privileges
If you intend to run an unprivileged user, be sure your user has permissions to access the sockets.