Using the same deploy key for multiple github projects


Github does not allow the same ssh deploy key to be used for more than one project, which would be very useful in some cases (e.g. CI server dealing with project with private sub-modules). I’ve seen various threads that seem to say that this limitation is there for ‘security reasons’, but I’m yet to see a convincing explanation about exactly what risk that would raise.

Note that the fact that Github doesn’t allow Account Level keys to be reused makes sense (two users shouldn’t share keys). It is only the restriction on Deploy Keys that I’m questioning.

And to be clear, I’m not looking for workarounds (create a dummy user, use multiple keys, …), but only for a plausible explanation for this limitation on Deploy Keys.

Related threads:


The only reason, illustrated by the workaround you reference (creating a single “build” user, or sharing the same per repo) is:

avoid sharing public/private key for different user

Even though that wouldn’t be the case in your situation (build multiple project), allowing to reuse the same ssh key would open the possibility for two different users to share the same ssh key, which would defeat the authentication purpose.

Authentication means:
“using a certain ssh key should imply that you are supposed to know who is using it”.
However, as noted in jtlindsey‘s answer, this is less related to authentication/identity/good policy, and more related to a “role” you attach to those keys. (role to deploy a certain repository).

As noted in “Why can’t I use one ssh key on more than one github repo?” by tkeeler:

This workflow becomes a problem when using automated systems and git submodules.
You can’t use the same deploy key in more than one repo, so the workaround becomes adding that key to their user account (or a dedicated machine account).

Taking the least path of resistance, most users will add it to their own account resulting in a greater security risk.

GitHub should rather let the user choose and assume the risk on a per repository basi

The GitHub page “Managing deploy keys” details the various accounts using ssh:

  • SSH agent forwarding: Agent forwarding uses the SSH keys already set up on your local development machine when you SSH in to your server and run git commands.
    You can selectively let remote servers access your local ssh-agent as if it was running on the server.
    So no need to replicate your private key on the server.
  • Machine users: (this is the “dummy account” strategy) Attach the key to a user account. Since this account won’t be used by a human, it’s called a machine user.
    You would treat this user the same way you would a human though, attach the key to the machine user account as if it were a normal account.
    Grant the account collaborator or team access to the repos it needs access to.
    So one private key associated to one “machine user”, one per server.

(DHa points out in the comments to a deploy key limit number, and the fact you can have only one machine user account)

  • Deploy key (one per GitHub repo) SSH key that is stored on the server and grants access to a single repo on GitHub.
    This key is attached directly to the repo instead of to a user account.
    Instead of going to your account settings, go to the target repo’s admin page.
    Go to “Deploy Keys” and click “Add deploy key“. Paste the public key in and submit.

This time, the ssh key isn’t attached to a user (for which you could grant access to several repo), but to one repo.
Granting the ssh access for several repo would be the equivalent of a “machine user”.

In term of authentication:

  • using the same key for several repos is okay when it is done by a user (which has said key associated to his/her account)
  • using the same key for several repo is NOT okay when the key is attached by a repo, because you don’t know at all who accessed what.
    That differs from the “machine user” where a “user” is declared as a collaborator for many repo.
    Here (Deploy key), there is no “collaborator”, just a direct ssh access granted to the repo.

Yusuf Bhabhrawala further illustrates this model limitation in the comments:

Consider these very plausible use cases – a python project using a private pip module or a node project using a private npm package – both from another repo in same organization.

Currently there is no way to deploy this very simple use case either using a deploy key or an account key (which exposes too many other repos).

And Chris Stenkamp points out to “How to discover where ‘pip install git+ssh://...‘ is searching for ssh keys?“, which involves setting the GIT_SSH_COMMAND environment variable.

Leave a Reply