Using a SSH deploy key in GitHub Actions to access private repositories

Matthias Pigulla  ·  06. September 2019

Update 2019-09-15: We've published the webfactory/ssh-agent GitHub Action which takes care of starting the SSH agent, adding the key and setting up host keys. With that action, most of the configuration described here is no longer necessary.
Update 2021-03-05: The Action now also supports running Mac OS, Windows- and Docker Container-based workflows. Also, GitHub Deploy (SSH) keys are supported and will be mapped to their respective repositories.

When staging a project to run tests or build a Docker image, you might need to fetch additional dependencies (libraries or "vendors") from private repositories. However, GitHub Actions are limited to accessing the repository they run for.

To solve this, you can create an additional SSH key with sufficient access privileges. Store that key in the secrets storage which is in the "Settings" area of your repository. The secret content is the private SSH key, as you will find it in the id_rsa file.

For the following example, the name of the secret should be SSH_PRIVATE_KEY.  Then, have a look at the following workflow definition:

# .github/workflows/my-workflow.yml
# ... other config here
        runs-on: ubuntu-18.04
            -   uses: actions/checkout@v1

            -   name: Setup SSH Keys and known_hosts
                    SSH_AUTH_SOCK: /tmp/ssh_agent.sock
                run: |
                    ssh-agent -a $SSH_AUTH_SOCK > /dev/null
                    ssh-add - <<< "${{ secrets.SSH_PRIVATE_KEY }}"

            -   name: Some task that fetches dependencies
                    SSH_AUTH_SOCK: /tmp/ssh_agent.sock
                run: ./

We start the ssh-agent , binding it to a predictable socket location, and import the SSH private key into the agent. The nice thing about the way this happens is that the private key is never written to disk.

After the setup step has run, the SSH agent will still be running and can be used by other processes. To make this happen, set the SSH_AUTH_SOCK environment variable. Commands like git run ssh under the hood and will make use of the key stored in the agent when they authenticate to other hosts.

Right now, you will have to set the environment variable for every step that needs it, but it looks as if an improvement for this is already underway

Where to register the public SSH key part?

To actually grant the SSH key access, you can – on GitHub – use at least two ways:

  • Deploy keys can be added to individual GitHub repositories. They can give read and/or write access to the particular repository. When pulling a lot of dependencies, however, you'll end up adding the key in many places. Rotating the key probably becomes difficult.
  • A machine user can be used for more fine-grained permissions management and have access to multiple repositories with just one instance of the key being registered. It will, however, count against your number of users on paid GitHub plans.
Avatar von Matthias Pigulla

Matthias Pigulla

Diplom-Wirtschaftsinformatiker, Geschäftsführer

Der strategische Kopf hinter unseren Softwaresystemen behält bei der Entwicklung und Betreuung komplexer Architekturen den Überblick, kümmert sich um die technische Infrastruktur oder berichtet über seine Erfahrungen und Erkenntnisse auf der Symfony User Group. Und wenn er abends damit fertig ist, entspannt der zweifache Vater entweder auf seiner Yogamatte oder lässt beim Fotografieren die Seele baumeln.