"Error connecting to agent: permission denied" when forwarding 1Password SSH agent to Docker

ideabucket
ideabucket
Community Member
edited August 2022 in SSH

I am trying to mount the 1Password SSH agent's socket inside a Docker container using the process described in Docker's ssh agent forwarding documentation.

In my docker-compose.yml I have:

services:
    servicename:
        environment:
            - SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock
        volumes:
            - type: bind
              source: /run/host-services/ssh-auth.sock
              target: /run/host-services/ssh-auth.sock

On the (Mac) host:

  • $SSH_AUTH_SOCK is set to ~/.1password/agent.sock, which is a symlink to ~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock as recommended in the 1P docs
  • running ssh-add -L produces the expected list of keys stored in 1Password

However, when I try to access the agent from inside the container, I get:

(base) jovyan@5bfec89674ae:~$ echo $SSH_AUTH_SOCK
/run/host-services/ssh-auth.sock
(base) jovyan@5bfec89674ae:~$ ssh-add -L
Error connecting to agent: Permission denied
(base) jovyan@5bfec89674ae:~$ 

Things I have tried which don't make any difference:

  • Setting the host's $SSH_AUTH_SOCK explicitly to the ~/Library/Group Containers/… location rather than to the symlink
  • Setting ForwardAgent yes in ~/.ssh/config

The Docker daemon is running as me so should have the necessary permissions on the .sock file.

Any idea what I'm doing wrong?


1Password Version: 8.8.0
Extension Version: Not Provided
OS Version: macOS 12.5.1
Browser:_ Not Provided

Comments

  • That's odd. Your configuration looks good. For debugging isolation purposes, could you run the following command and share the output?

    SSH_AUTH_SOCK=~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock ssh-add -l && docker run -v /run/host-services/ssh-auth.sock:/run/host-services/ssh-auth.sock -e SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock alpine sh -c 'apk add openssh && ssh-add -l'
    

    What I'm getting:

    256 SHA256:<my fingerpint> <my key name> (ED25519)
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/main/x86_64/APKINDEX.tar.gz
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/community/x86_64/APKINDEX.tar.gz
    (1/10) Installing openssh-keygen (8.8_p1-r1)
    (2/10) Installing ncurses-terminfo-base (6.3_p20211120-r1)
    (3/10) Installing ncurses-libs (6.3_p20211120-r1)
    (4/10) Installing libedit (20210910.3.1-r0)
    (5/10) Installing openssh-client-common (8.8_p1-r1)
    (6/10) Installing openssh-client-default (8.8_p1-r1)
    (7/10) Installing openssh-sftp-server (8.8_p1-r1)
    (8/10) Installing openssh-server-common (8.8_p1-r1)
    (9/10) Installing openssh-server (8.8_p1-r1)
    (10/10) Installing openssh (8.8_p1-r1)
    Executing busybox-1.34.1-r3.trigger
    OK: 12 MiB in 24 packages
    256 SHA256:<my fingerpint> <my key name> (ED25519)
    

    (ssh-add -l working both locally and in the container)

  • ideabucket
    ideabucket
    Community Member
    edited September 2022

    Thanks for that—here's my output:

    3072 SHA256: <fingerprint> <keyname> (RSA)
    256 SHA256: <fingerprint> <keyname> (ED25519)
    256 SHA256: <fingerprint> <keyname> (ED25519)
    Unable to find image 'alpine:latest' locally
    latest: Pulling from library/alpine
    9b18e9b68314: Pull complete
    Digest: sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad
    Status: Downloaded newer image for alpine:latest
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/main/aarch64/APKINDEX.tar.gz
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/community/aarch64/APKINDEX.tar.gz
    (1/10) Installing openssh-keygen (9.0_p1-r2)
    (2/10) Installing ncurses-terminfo-base (6.3_p20220521-r0)
    (3/10) Installing ncurses-libs (6.3_p20220521-r0)
    (4/10) Installing libedit (20210910.3.1-r0)
    (5/10) Installing openssh-client-common (9.0_p1-r2)
    (6/10) Installing openssh-client-default (9.0_p1-r2)
    (7/10) Installing openssh-sftp-server (9.0_p1-r2)
    (8/10) Installing openssh-server-common (9.0_p1-r2)
    (9/10) Installing openssh-server (9.0_p1-r2)
    (10/10) Installing openssh (9.0_p1-r2)
    Executing busybox-1.35.0-r17.trigger
    OK: 12 MiB in 24 packages
    The agent has no identities.
    
  • Ah, so it is successfully connecting to a socket, just the wrong one for some reason. Could you try restarting Docker Desktop and running that command again?

  • ideabucket
    ideabucket
    Community Member

    No difference, as far as I can tell:

    3072 SHA256:<fingerprint> <keyname> (RSA)
    256 SHA256:<fingerprint> <keyname> (ED25519)
    256 SHA256:<fingerprint> <keyname> (ED25519)
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/main/aarch64/APKINDEX.tar.gz
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/community/aarch64/APKINDEX.tar.gz
    (1/10) Installing openssh-keygen (9.0_p1-r2)
    (2/10) Installing ncurses-terminfo-base (6.3_p20220521-r0)
    (3/10) Installing ncurses-libs (6.3_p20220521-r0)
    (4/10) Installing libedit (20210910.3.1-r0)
    (5/10) Installing openssh-client-common (9.0_p1-r2)
    (6/10) Installing openssh-client-default (9.0_p1-r2)
    (7/10) Installing openssh-sftp-server (9.0_p1-r2)
    (8/10) Installing openssh-server-common (9.0_p1-r2)
    (9/10) Installing openssh-server (9.0_p1-r2)
    (10/10) Installing openssh (9.0_p1-r2)
    Executing busybox-1.35.0-r17.trigger
    OK: 12 MiB in 24 packages
    The agent has no identities.
    

    In addition to restarting docker desktop I tried a complete reboot. Same result.

  • Could you try the following:

    1. Quit Docker

    2. Launch Docker from your terminal with SSH_AUTH_SOCK set:

    SSH_AUTH_SOCK=~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock open /Applications/Docker.app
    
    1. Run the container again:
    docker run -v /run/host-services/ssh-auth.sock:/run/host-services/ssh-auth.sock -e SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock alpine sh -c 'apk add openssh && ssh-add -l'
    
  • ideabucket
    ideabucket
    Community Member

    That worked!

    3072 SHA256:<fingerprint> <keyname> (RSA)
    256 SHA256:<fingerprint> <keyname> (ED25519)
    256 SHA256:<fingerprint> <keyname> (ED25519)
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/main/aarch64/APKINDEX.tar.gz
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/community/aarch64/APKINDEX.tar.gz
    (1/10) Installing openssh-keygen (9.0_p1-r2)
    (2/10) Installing ncurses-terminfo-base (6.3_p20220521-r0)
    (3/10) Installing ncurses-libs (6.3_p20220521-r0)
    (4/10) Installing libedit (20210910.3.1-r0)
    (5/10) Installing openssh-client-common (9.0_p1-r2)
    (6/10) Installing openssh-client-default (9.0_p1-r2)
    (7/10) Installing openssh-sftp-server (9.0_p1-r2)
    (8/10) Installing openssh-server-common (9.0_p1-r2)
    (9/10) Installing openssh-server (9.0_p1-r2)
    (10/10) Installing openssh (9.0_p1-r2)
    Executing busybox-1.35.0-r17.trigger
    OK: 12 MiB in 24 packages
    3072 SHA256:<fingerprint> <keyname> (RSA)
    256 SHA256:<fingerprint> <keyname> (ED25519)
    256 SHA256:<fingerprint> <keyname> (ED25519)
    

    So it's something to do with the environment Docker's starting up in? And indeed:

    $ launchctl getenv SSH_AUTH_SOCK
    /private/tmp/com.apple.launchd.lKheVhxcy5/Listeners
    
  • ideabucket
    ideabucket
    Community Member

    Results of some further investigation:

    This github comment appears to describe what's going on—Docker Desktop's $SSH_AUTH_SOCK comes from launchd unless explicitly started from a shell.

    If I inspect the Docker process's environment it is clearly not picking up the correct $SSH_AUTH_SOCK (CRs added for readability)

    $ ps Eww 8510
      PID   TT  STAT      TIME COMMAND
     8510   ??  S      0:00.16 /Applications/Docker.app/Contents/MacOS/Docker 
    USER=<me> 
    SECURITYSESSIONID=186fe 
    __CFBundleIdentifier=com.docker.docker 
    COMMAND_MODE=unix2003 
    DISPLAY=/private/tmp/com.apple.launchd.himcQtrOZF/org.xquartz:0 
    LOGNAME=<me> 
    PATH=/usr/bin:/bin:/usr/sbin:/sbin 
    SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.1YAMzFNnmk/Listeners
    SHELL=/bin/bash 
    HOME=/Users/<me> 
    __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0 
    LaunchInstanceID=7A5BB568-BB71-4335-A5D0-87D22CE7BC2E 
    TMPDIR=/var/folders/np/kfknfjg550g6lr8k1wsdmr_h0000gn/T/ XPC_SERVICE_NAME=application.com.docker.docker.6088138.6088438 
    XPC_FLAGS=1
    

    I tried creating a launch agent according to these instructions but, after a restart, unfortunately:

    $ launchctl getenv SSH_AUTH_SOCK
    /Users/<me>/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock
    $ ps Eww 887
      PID   TT  STAT      TIME COMMAND
      887   ??  S      0:00.17 /Applications/Docker.app/Contents/MacOS/Docker 
    USER=<me> 
    SECURITYSESSIONID=186b1 
    __CFBundleIdentifier=com.docker.docker 
    COMMAND_MODE=unix2003 
    DISPLAY=/private/tmp/com.apple.launchd.HL2M5C2c66/org.xquartz:0 
    LOGNAME=<me> 
    PATH=/usr/bin:/bin:/usr/sbin:/sbin 
    SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.NtvX8s84bQ/Listeners 
    SHELL=/bin/bash 
    HOME=/Users/<me> 
    __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0 
    LaunchInstanceID=C16BCFC2-1665-45C5-808D-5670FB7DA0AA 
    TMPDIR=/var/folders/np/kfknfjg550g6lr8k1wsdmr_h0000gn/T/ 
    XPC_SERVICE_NAME=application.com.docker.docker.6088138.6088438 
    XPC_FLAGS=1
    

    …Docker's environment still has the Apple $SSH_AUTH_SOCK.

  • floris_1P
    edited September 2022

    Great you got it working! For persisting SSH_AUTH_SOCK with launchd, see this section in our docs.

    TL;DR: you'll need to tell launchd to create a symlink where macOS points SSH_AUTH_SOCK to.

  • ideabucket
    ideabucket
    Community Member

    Success!

    To close the loop in case anybody comes across this thread later: although fixing the host-side SSH_AUTH_SOCK issue was an essential part of solving this problem, the specific "Error connecting to agent: permission denied" error turned out to be due to running the container as a non-root user that did not have write permissions to /run/host-services/ssh-auth.sock inside the container.

This discussion has been closed.