Viki Liu
Viki Liu

Reputation: 112

Connecting to GitHub with SSH to a project located not in my account

I was trying to set ssh key in order NOT to type my username/Token every time I push updates. I used this manual to set ssh key and added ssh key to my GitHub account:

https://docs.github.com/en/authentication/connecting-to-github-with-ssh

But it still asks me about my username/Token. I figured out that my URL address is HTTPS rather than [email protected], so I was trying to follow the solution from here:

SSH Key - Still asking for password and passphrase

to replace URL using command:

git remote set-url origin [email protected]:USERNAME/REPOSITORY.git

However, because the project repository is locating not in my account (it is located in my company account where I authorized to commit changes), this does not work (cannot see repository). I am not sure how should I rewrite this command to make it work.

Upvotes: 1

Views: 870

Answers (1)

torek
torek

Reputation: 489223

I'm a bit confused by your confusion. Let's see if I can straighten myself out. 😀 When you identify yourself to GitHub, you claim to be someone. That someone that you claim to be either does have access to some repository, or does not have access to that repository.

(With me so far?)

When you "log in" to GitHub with HTTPS, you provide:

  • a user name: this is just a user name, i.e., it's not secret, and it identifies who you are; and
  • a password (in Ye Olden Dayse anyway): this is just your secret password, and all it does is prove that you are who you say you are.

They've now fancied things up so that instead of a "password" you provide a "PAT", which is still a secret but now has some internal structure that allows you to do fancy things like say that some PATs have lesser authentication value than others. This also means that if your "password", i.e., PAT, is ever compromised, you still have the truly secret one—the actual password—which you can use to revoke the old PATs and generate new ones.

If you like this system, you can continue to use it, but if you like the ssh system—it's my own preference—then we have a something a bit trickier. When you "log in" to GitHub with ssh, you provide:

  • the fixed user name git: it's not secret, but it also does not identify you; and
  • an ssh key as generated with ssh-keygen or some similar program.

The ssh key is not, and never has been, just a password. It's full of structure: it says what kind of encryption was used to make it, for instance, so that we know if it's a old very-short RSA key (no longer secure), a fancier longer RSA key (still secure), an ECDSA key, an ed25519 key, etc. They also come in pairs: there is a public key and a private key in each pair. The public key is designed so that you can hand it over to someone else—including GitHub—maybe even in cleartext. That someone-else that you give this key to can send you a "challenge", that they have encrypted; your computer uses your corresponding private key to decrypt the "challenge" and respond, proving that you are in fact who you claim to be.

But hang on a moment. Who did you claim to be? We just said that we're going to claim to be the fixed name git. Well, now we have a slightly dirty trick: these public-and-private key pairs are unique. When you generate your pair, the public key you hand over to GitHub is unique. All they—GitHub—have to do is record who you are at the time you give them the public key, which you do by logging in to GitHub with your actual password.

So, here you are, being yourself, on your computer, with your ssh. You may have generated, say, three identity keys. If only one of these three works for accessing the repository you want, you simply present to GitHub the one identity key that does work, and not the other two that don't work.

The way you do that is ... not with Git at all. Git doesn't do ssh. Git runs ssh, which does all the ssh work. So you must check your ssh documentation.1 Fortunately, almost all ssh implementations share a lot of commonality, including the idea of $HOME/.ssh/config files. These configuration files let you tell ssh that, if you ask to connect to a host named hub-id1, you'd like to use one key-pair to connect to the host actually named github.com. If you ask to connect to a host named hub-id2, you'd like to use a different single key-pair to connect to the host actually named github.com. You can repeat for as many key-pairs as you have, for as many identities as you want to use.

To do this, in your .ssh/config file, you'll want these magic lines:

Host hub-id1
    Hostname github.com
    IdentityFile ~/.ssh/id_github_1
    User git
    IdentitiesOnly yes

Host hub-id2
    Hostname github.com
    IdentityFile ~/.ssh/id_github_2
    User git
    IdentitiesOnly yes

and so on.

The host-name you put on the Host line is up to you, but it should match the name you set in your ssh URL:

git remote set-url origin ssh://hub-id2/path/to/repo.git

or:

git remote set-url origin hub-id2:path/to/repo.git

The User line is optional, but if you include it here, you can leave out the git@ in front of the place where you'd put [email protected], but are now putting git@hub-id1 and so on.

The HostName line is required: it's what ssh will look up to get an IP address to connect to GitHub.

The IdentityFile line is required: it provides the path name to the file(s) in which you've stored the public and/or private key(s). There is a bit of trickiness here: if you use the ssh agent, you can provide just the pathname of the .pub file, and you need only the .pub file on this host if you're logging in to some corporate machine from your laptop and keep your private keys only on your laptop, for instance. In some cases, however, you must point ssh to the private key file, and have the public key have the same name but with .pub added.

The IdentitiesOnly line is optional, but advisable: it says use only the key I listed here. If you omit this line, ssh will try other keys as well, if the IdentityFile keys don't seem to be working. (You can observe this in action with ssh -Tv output: each key that ssh tries, results in a debug line.)

If you only have one identity on GitHub, you don't need this complication. Your one identity on GitHub—you as yourself—will give you access to the repository, or won't, based on what whoever owns the repository set up. But if you have more than one identity on GitHub, and are using ssh, this is how you tell your ssh commands which identity to send to GitHub.

(Note that if you have encrypted access to your private ssh keys with a passphrase, you may have to type your passphrase into ssh, or into your ssh agent. This is quite independent of all of the above.)


1On Windows systems, Git comes with a replacement ssh,2 in case your Windows ssh is too ancient to be usable. Modern Windows comes with a modern ssh, which is usable. These two different ssh-es may use different file storage. Be careful about which ssh you're using. Make sure your Git uses the ssh you want it to use, whichever one that is. Most other systems are easier to deal with, as they have just one ssh.

2This is similar to the way Git-for-Windows usually comes with a usable version of bash, because the old CLIs in old Windows systems are unusable (at least by Git). Neither the included bash, called for short, nor the included ssh are actually part of Git. They're just packaged together with Git for Windows, to make it usable.

Upvotes: 2

Related Questions