As knittl noted in a comment, user.name
and user.email
aren't credentials and are not used during credential setup and checking. That leaves a big question, though: Where do any credentials come from? Unfortunately, the answer is: it depends, which means we have another question: depends on what? The first part of that is the URL you're using:
- An
http
or https
URL causes Git to go through libcurl, which means you get libcurl authentication and credentials. This is then complicated by your OS: libcurl is built with OS-specific code.
- An
ssh
URL causes Git to go through ssh, which means you get ssh authentication and credentials. This is then complicated by your OS: ssh is not only built with OS-specific code, but on Windows, the Git distributions tend to include an ssh implementation in case Windows doesn't have one, and yet some versions of Windows have one.
This gets you to the next steps to take. That's as far as we can actually go, given the information you provided—but I have a guess based on the fact that you've included the github tag and that GitHub have been pushing people to use ssh (by, among other things, temporarily disabling https access entirely now and then). I don't know what your OS is, so I can't include Windows- or macOS-specific items (and wouldn't anyway as I don't use Windows and try not to depend on macOS-specific tricks since I use Unix/Linux-y systems a lot too). But we can get pretty far just assuming ssh-and-GitHub, because of the way GitHub has you "log in" to their computers.
SSH authentication
When using ssh in general, the way authentication works is a multi-step process:
First, your computer looks up any host name you provide (via ssh user@host command
or scp file user@host:path
or whatever; with Git URLs it is ssh://user@host/path
or user@host:path
if you use the shorthand syntax). This gets translated to an IP address—IPv4 or IPv6—to use to contact the host. Or, if you provide an IP address directly, ssh uses that.
Next, your ssh contacts the ssh server at that host and obtains the server's "fingerprint". Your computer can compare this fingerprint to one stored in a known_hosts
file or similar. Your ssh may, depending on options, now ask you to confirm that this is the machine you intended to contact, or if it's already listed in the known_hosts
file and the fingerprint matches, just assume that it's the right machine.
Your ssh client and the ssh server (sshd
) now go through a fairly fancy dance where they exchange protocol information and key-exchange information. This is so that they can encrypt stuff even before they get to the point of doing authentication. We get to ignore all of this here, although there's a lot to it. (Use the -v
option to ssh
, multiple times for more debug information, and you'll see some of this happening.)
Eventually, your Git-invoked ssh provides, to the server, the user name you provided—which, for GitHub, must be git
—along with a public key. Since the user name that Git must provide here must be git
, we get to ignore this one too! (Except that we have to spell it out somewhere, e.g., in the URL as ssh://git@github.com/path/to/repo.git
.) The server—in this case, GitHub—uses this information to figure out who you are claiming to be. We'll come back to this in just a moment.
Now that the server sshd knows you you claim to be, sshd sends you more stuff which your ssh must decrypt using your private key. If your ssh is able to do this, the server sshd now believes that you are indeed the person you claimed to be. Data may now flow across the ssh/sshd connection; on GitHub, sshd now invokes the GitHub Git (through some extra code that the GitHub folks wrote, which has access to the person-you-claimed-to-be information as verified by GitHub's sshd: this extra code does whatever checking is appropriate).
The boldface sentence above therefore contains the key (if you'll pardon the expression) to making the GitHub sshd authenticate you "correctly", for your personal definition of "correct". Since you must claim to be git
, the actual user name is not provided here at all. Instead, it's secretly smuggled in via the public key.
When you use the GitHub web interface to set up your public-key access to your repositories, you authenticate to GitHub over https (not ssh). This gives you a place to type in a user name, along with a place to copy-paste an ssh-keygen
-generated public key. When you do all of this, GitHub saves the public key along with your user name. Later, when you give GitHub a public key, they look up that public key in their database of "all public keys that have some user using them". This database provides them the user name.
What this means, bottom line, is: When using ssh on GitHub, the user name you're using to authenticate doesn't come over the Internet at all. It's just assumed via the public key you send. You must therefore be very precise about which public key(s) you send. The first public key that you send and that they accept determines who they believe you are.
Your ssh will, in general, try keys from your "key ring" one at a time until one works, or it runs out of keys. This creates problems.
You have one user name per public key for GitHub
If you have only one public key that you use with GitHub, everything is easy(ish). There's only one key that can work in the lock. That one key is associated with your one user name on GitHub. You use that key and they know who you are.
If you have two public keys, though, and two user names, now it gets complicated. Each of your two public keys has one user name attached. Let's call these keys A and B, and the associated user names ua
and ub
.
If you present key A first, it works and GitHub believe you are ua
.
If you present key B first, it works and GitHub believe you are ub
.
If ua
and ub
have access to different repositories, you're going to have to be careful which key you present.
(There's a related problem: if you have thousands or millions of keys, and you let your ssh try them all one at a time, including all the wrong ones, their sshd may grow suspicious. Imagine how you'd feel if you were at home and some stranger came up to your locked front door and just started trying a million keys in your lock. We'll ignore this here, though.)
Controlling the key your ssh presents
Each OS can have its own add-ons for ssh, and they may throw extra wrinkles into this process, but at the base ssh-for-all-OSes level, ssh itself will read a configuration file. In this configuration file, you get to set various options:
IdentityFile
names a file on your system that contains the public and/or private keys (they're normally paired, so that ~/.ssh/id1
and ~/.ssh/id1.pub
are the private and public keys for id1
, for instance).
- The
IdentitiesOnly
flag tells your ssh not to offer additional keys not listed via IdentityFile
lines.
User
is convenient: you can use this to avoid having to type git@
.
HostName
is convenient as well: see below.
You will therefore want to use at least these options: IdentitiesOnly
to tell your ssh don't try other keys and IdentityFile
to tell your ssh do try this key.
To get your ssh program to match the right entry, you will probably want to use Host
lines. Here's an example ~/.ssh/config
file. Be careful about cut and pasting from this; see bold text below.
Host gh-work
HostName github.com
User git
IdentityFile ~/.ssh/id_work.github.pub
IdentitiesOnly yes
Host gh-home
HostName github.com
User git
IdentityFile ~/.ssh/id_home.github.pub
IdentitiesOnly yes
You can now use ssh://gh-work/corp/work-repo.git
and ssh://gh-home/me/personal-project.git
as the Git URLs for some corporate work repository and some personal project. The gh-work
"host name" will match the appropriate entry in ~/.ssh/config
. The User git
and HostName github.com
parts will replace gh-work
with git@github.com
, and the identity lines will make sure you present just the one correct key, so that GitHub identify you as your "work persona". The gh-home
entry works nearly identically, but presents a different key, so that GitHub identify you as your "home persona".
These two entries list .pub
files. This is the key you want your Git to send. This generally works well when you use an ssh-agent. It may or may not work if you don't use the agent. You may have to list the file names without the .pub
part, so that your IdentityFile
line points to the private key. Don't worry if you have to do this: your ssh will send over the public key, not the private one (use ssh -Tvv gh-work
or ssh -Tvv gh-home
to verify this). But do consider using the agent, so that you don't have to do this, nor even store the private key on that particular host at all in some cases. The agent adds an extra layer of security.
(There is much more you can do with ssh, but this is enough for now.)