I am working on a couple of maven-projects where common java-classes is placed in a submodule. The submodule is then added to each maven-project and the project is cloned from a private github-repo to a docker container.
I have created a ssh-key for each project and the submodule, added the public key to 'Deploy keys' in 'Settings' in the github-repo. All keys are created without a password.
Downloading the main-repo went fine but adding the submodule failed with git@github.com: Permission denied (publickey).
. And hence the compile failed. Both keys were loaded before cloning the repo and updating the submodule.
It turns out I can have only one key loaded at a time. So I modified the script that clone so it unload all keys before loading the key for the submodule.
eval $(ssh-agent -s)
ssh-add /home/docker/.ssh/id_ed25519_maven_repo
ssh-keyscan -H github.com >> /home/docker/.ssh/known_hosts
cd /home/docker/code
git clone git@github.com:foo/main.git
cd main
ssh-add -D <--- Unload all keys ---
ssh-add /home/docker/.ssh/id_ed25519_submodule
git submodule init
git submodule update
mvn compile
Why must I unload and load before updating the submodule instead of having both keys loaded at the same time?
(spent hours troubleshooting)
It sounds like you have two SSH keys that are either associated with different GitHub accounts or that are deploy keys with different repositories. If so, the reason this happens is due to the SSH protocol.
When any user wants to connect to a remote machine via SSH using an SSH key, the authentication happens before any command is sent or anything is known about the desired behavior. In this case, all users connect to the git
user on github.com
, so the only way to distinguish users and the access which they have is by the SSH key. If you authenticate with a particular key and that key is valid for some access, GitHub will accept it, and then if it is not valid for what you want to access, then it will reject your request.
Since the SSH protocol does not allow specifying the resource to access until authentication has completed, GitHub has no way to know that you really wanted to use a different key to access that resource, one which does indeed have the ability to access it.
If you need to use multiple SSH keys for different resources, that case is covered in the Git FAQ:
For example, you could write something like the following in
~/.ssh/config
, substituting the proper private key file:
# This is the account for author on git.example.org.
Host example_author
HostName git.example.org
User git
# This is the key pair registered for author with git.example.org.
IdentityFile ~/.ssh/id_author
IdentitiesOnly yes
# This is the account for committer on git.example.org.
Host example_committer
HostName git.example.org
User git
# This is the key pair registered for committer with git.example.org.
IdentityFile ~/.ssh/id_committer
IdentitiesOnly yes
Then, you can adjust your push URL to use
git@example_author
orgit@example_committer
instead ofgit@example.org
(e.g.,git remote set-url git@example_author:org1/project1.git
).