Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the same deploy key for multiple github projects

Tags:

git

github

ssh

People also ask

Can I use SSH key for multiple GitHub accounts?

GitHub does not allow us to use the same SSH key in multiple accounts, so we'll have to create separate keys for each account. We can create SSH keys and add them to our SSH agent by following this guide from the GitHub Documentation.

Can I use the same SSH key for multiple repositories GitLab?

GitLab does not allow you to use the same SSH key in multiple accounts, so you'll have to create separate keys for each account. You can create SSH keys and add them to your SSH agent by following this guide from the GitHub Documentation.

How do GitHub deploy keys work?

You can launch projects from a repository on GitHub.com to your server by using a deploy key, which is an SSH key that grants access to a single repository. GitHub attaches the public part of the key directly to your repository instead of a personal account, and the private part of the key remains on your server.

Can there be multiple repositories for each project?

It is a combination of two Git tools that you can use to manage multiple repositories within one project. The two tools are HelixTeamHub and Helix4Git Do. Here, HelixTeamHub lets you work with multiple repositories, whereas the developers can use Helix4Git to contribute to the sub-projects or repositories.


The only reason, illustrated by the workaround you reference (creating a single "build" user, or sharing the same id_rsa.REPONAME.pub 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".


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.


Unfortunately, this is a scenario where github just misinterprets the distinction between a key pair and an account or project.

Since a key pair is used for authentication and authorization, it is effectively an identity. Github accounts are another identity. Connecting github accounts to key pairs effecticely establishes a 1:N mapping between github account based identities and key pair identities.

Conversely, github enforces a 1:N mapping of projects to key pair based identities. The real world analogue is that there is a door granting access to the project that can be unlocked by many different people. But once any of them gets a key to the door, they cannot get any other keys for any other doors, ever again.

It makes sense not to re-use keys often from the perspective of containing breaches if a key gets compromised. But that's just a good administration policy. It doesn't make much sense to prevent a key from being used more than once on principle. That there are some keys for some doors that are never re-used, well, again that's down to policy.


A slightly more complex view is to illustrate key pairs as roles. You can possess many key pairs, and therefore inhabit many roles. The private key authenticates you for the role.

Github's deploy key mapping to projects states that a role can never encompass more than one task. That's rarely realistic.

None of which changes what github allows, of course.


It took me a lot of thinking to rationalize the implications and came up with this scenario.

Imagine that you create a single deploy key for a user which you've assigned to multiple repositories. Now you want to revoke that key but it's used in multiple places. So instead of being able to revoke all access you may inadvertently only revoke partial access.

This may sound like a benefit but this many-to-one relationship is actually inherently insecure once you consider the human factor. This is because you can't know for sure if you've really revoked all access without inspecting every repository and compare each public key individually in the case that you've forgotten to where you've actually assigned it.

It's definitely frustrating to assign and manage so many unique keys but the security implications are clear with how GitHub has instituted their policy: when you revoke a key you're guaranteed to be revoking all access granted by that key because it's only used in one place.