How do people handle multiple git identities with github+ssh? Since you always log in as the `git` user, you can't reuse keys. I end up with an ~/.ssh/config like:
Host github-client1
Hostname github.com
User git
IdentityFile ~/.ssh/id_rsa-client1
Host github-client2
Hostname github.com
User git
IdentityFile ~/.ssh/id_rsa-client2
Then clone using `git clone git@github-client1:username/repo.git` Is there a better way?
Different gitconfigs per path on disk, git automatically uses the right identity depending on where you are on disk. Allows you to separate all projects into different users and every repository within those directories will use the specified user.
Main/default config (~/.gitconfig):
[user]
email = git@victor.earth
name = Victor Bjelkholm
[includeIf "gitdir:/home/user/projects/user-a/"]
path = /home/user/.gitconfig-user-a
[includeIf "gitdir:/home/user/projects/user-b/"]
path = /home/user/.gitconfig-user-b
You can also filter based on the remote URL! I find this much more useful than the location of the directory on disk.
; include only if a remote with the given URL exists (note
; that such a URL may be provided later in a file or in a
; file read after this file is read, as seen in this example)
[includeIf "hasconfig:remote.*.url:https://example.com/\*"]
path = foo.inc
[remote "origin"]
url = https://example.com/git*
Note that this doesn't work if you have a default IdentityKey specified in your ssh config, because `-i` is always unioned with the default IdentityKey in that case (which is a feature, not a bug, of how IdentityKey / `-i` work) and it's possible that that key will be sent to the server before the one you specified in `-i`
Say my IdentityKey that I use for regular ssh is also associated with GH user foo, and then I have the above gitconfig to use a different key associated with GH user bar under certain directories. It's still possible that ssh will try the IdentityKey before the `-i` key when I do git operations under those directories, which means GH will identify me as user foo anyway.
I'm not sure what order ssh uses to sort the union, if any, but at least in my case it seems to always use the IdentityKey before the `-i` key even though it prints them in the opposite order initially (according to `-vvvv`).
And no, `-o IdentitiesOnly=yes` doesn't affect this behavior.
You can also set that in your `.git/config` file on a per repo basis. Additionally you can set `GIT_SSH_COMMAND="ssh -i /tmp/custom_key_ed25519 -o IdentitiesOnly=yes" git pull` to override whatever is in your global or repo config for 1 off pulls / clones as a different user.
I set the common github configs in the top Host block, then each Match block looks at the arguments passed to ssh, parses them, and checks for the github username and if it matches, sets the correct key.
The ~/Developer/C/getargv/bin/getargv program is just an implementation of `cat /proc/$PPID/cmdline` for macOS, on linux you don't need a separate tool.
I was doing this, and sent a question to Github support for a particular thing I was trying to do with my multiple accounts. I got a fairly strong warning about how I was in violation of their service agreement and I could get my subscription terminated if I was found to be using multiple accounts.
It was very odd. Either (a) the person responding to me was uninformed, or (b) that's actually Github's policy and it's not nearly as prominently displayed as it should be.
> One person or legal entity may maintain no more than one free Account (if you choose to control a machine account as well, that's fine, but it can only be used for running a machine).
This is the primary reason why I have only ever used my own personal account for work stored at GitHub. If a company is expecting its employees to use a separate work GH account, one assumes that company is planning to pay for all those accounts for its employees.
Having said that, given that many people do use separate GitHub accounts for their separate private and work personas, and many organisations seemingly expect their employees to do so, perhaps GitHub could consider revising this Terms of Service restriction to better reflect reality.
There have also been times when I would like to have access to a second GitHub account for testing purposes. (In particular, for testing GH behaviour when the accounts corresponding to PR commits, PR creator, and PR merger all differ -- see for example <https://github.com/isaacs/github/issues/1368>.)
> One person or legal entity may maintain no more than one free Account (if you choose to control a machine account as well, that's fine, but it can only be used for running a machine).
In context of parent post, I wonder if people realize github is not where git things come from...
"if you choose to control a machine account as well, that's fine, but it can only be used for running a machine"
I'm not aware that "running a machine" has a legal definition. I think it's fine, if you have a corporate account and a private email you are probably fine. I think they mainly have that as some sort of rate limiting legalese, to prevent abuse from "account hopping" i.e. abusing the github api or spamming, etc..
If your work account is a "legal entity", i.e. it is a person under corporate personhood laws, this definition also doesn't really hold water (both you and the corporation account count as legal persons, so this doesn't do much, other than the cost of an incorporation being non-zero). Just don't do weird things with your separate accounts, and actually keep them separate, and you're probably fine.
I'm curious, what are people's opinions about the pro/cons of maintaining multiple GitHub identities like this?
Personally, I have never found it necessary to do this, but about 1/3 to ½ of the people I work with usually have "-companyname" in their usernames, so it appears semi-popular.
What I do is just add my work email as a secondary to my GitHub account and configure the work laptop to use that email, and I generate a new RSA key and add it to my one account. Then I also set up the notifications to use that work email as the notification email for things in that organization
My "Pros" list for doing it this way:
* Simple to configure my git/ssh settings - just add the SSH key on my work laptop to my normal GitHub account
* Easy for someone to identify and even reach me if they were to see a commit in GitHub. For instance, if they know I wrote something they might want to hire me again later to update it.
* I "Sign in with GitHub" to things like developer tools (like Codesandbox, for instance), I get to easily keep control of that account even when I change jobs.
"Cons" I can think of:
* Technically a malicious actor in (or who has compromised) corporate IT could impersonate me by stealing my key from my work-owned computer, cloning my private Github repos, and could introduce changes into other repos I have access to. So I assume if I had high-level access to important OSS projects, this would be a danger for targeted hacking. (Obviously since I can remove the keys at the end of an engagement, I can at least limit my exposure to just current clients/employers.)
Is there anything else that makes you prefer to use a company-specific identity?
Keeping work/private life separate is reason enough to me (also, we don't use Github - we use bitbucket - the decision was made for me!)
Ultimately, I think having work-specific accounts is preferable, and I wouldn't be surprised if a lot of IT departments also prefer this (however, this is also coming from the medical space, where controls are rather tight and security is extremely important and heavily audited)
I've worked for a handful of medical companies, including ones that handle de-anonymized PHI/patient data and/or develop medical devices, both very heavily audited and regulated even in comparison to other medical companies. Using a personal GitHub account attached to an organization on either GitHub proper or GitHub Enterprise was never an issue. Sure we had some folks create a separate account because they wanted to, but there no directive from the IT/security folks even suggesting that, and I'd consider them showing any preference toward not just attaching your personal account a big organization red flag - it means they're just defaulting to "don't do that" rather than actually taking five minutes to understand the constraints and ramifications.
That con was reason enough for me to never do this. Another reason is, when using my personal GitHub account, I'm doing personal things and don't want to see work-related stuff (even if it is just private contributions or the "use SSO to see $employer repositories" message).
The company can mandate SSO, security settings, profile settings like avatar or description, etc that you don't want to apply to your personal account.
Also, once you leave that company, you don't have to worry about unsubscribing from that company's repos, issue threads, etc, or worry about people still @-mentioning you because you participated in those repos before.
about the "cons", another con is that granting access to your unified account from your work or business perspective is "tricky". Github Business accounts can grant specific access only for people identifying with your company's identity provider, like okta or similar. So that can potentially reduce that risk as well, so that your employer can revoke access to okta, and thus revoke access to work repositories, for example. Without that you need to be very strict and do some manual work to grant and revoke accesses.
Curious, why would you need separate ssh keys for the same site? In the above example, you're authenticating the GitHub, not really to client1 or client2.
The only thing that would need to change, AFAIK, is the name and email you use for commits, not necessarily our ssh key.
Last I checked, one can't use the same SSH key for multiple github accounts, so if that is part of your workflow then you have to have different keys configured.
True, but I guess I am still wondering why would you need multiple GitHub accounts. I could see 1 for personal and 1 for work but still kind of wonder why. Even in that scenario, you would only need to account for 2 different ssh keys.
Typically, for Client1 and Client2, both clients could invite the same account to the organization.
It depends on the client but several of mine have wanted me to use a separate account with an email for their domain. I suppose this is so they can take over the account rather than just removing my main account.
> How do people handle multiple git identities with github+ssh?
Perhaps not the answer you're expecting (mentioning this anyways, because perhaps it'll be useful/interesting to some folks), but I just ended up paying for GitKraken and suddenly managing multiple accounts (not just GitHub, but also my self-hosted Gitea instance and other servers) became as easy as choosing a different value in a dropdown: https://www.gitkraken.com/blog/managing-mulitple-github-acco...
Paying for something like a Git client felt silly, but at the same time it's good, does what I need and runs on every playform that I use, while also not annoying me too much, same as with JetBrains IDEs and something like MobaXTerm. Before that I used SourceTree and Git Cola because some operations are more convenient with a GUI instead of a CLI, though they didn't have that functionality.
I’ve done exactly this to manage a test user identity separately from my main GitHub identity, for debugging GitHub apps.
I didn’t clone separately, though. I added separate remotes to the repo so I could push a branch to either `github` or `github-test`, and those were associated with the separate hosts/identities from my ssh config.
This was a significant problem for me across a few consulting clients. What ended up making things significantly better for me was doing my SSH over GPG: https://opensource.com/article/19/4/gpg-subkeys-ssh This way, I can create and delete GPG subkeys all I want, export the SSH files for upload to a client's system. When it comes time to authenticate, I only ever have to unlock a single secret, which in my case is my GPG keys on my Yubikey devices: https://github.com/drduh/YubiKey-Guide
Why do you need multiple keys for "a few consulting clients" to begin with?
Yubikey's have a limited number of slots for GPG keys by the way... I'm curious to know how you stuffed as many subkeys as you want into the single AUT subkey slot (or even stuffed subkeys usable for authentication into all 4 of the slots it gives you)...
If you wanted to have it all in your git config, you could set core.sshCommand to "ssh -i ~/.ssh/id_rsa-client", maybe combined with includeIf as in the article (since it's a glob match, you could match on the github org name).
I developed a program to help with this — it's called "gitprof", since it helps with Git profiles. It's not completely flawless but it works fine, and I find it very helpful.
It's what I've been doing up to now, but dealing with git submodules is very painful this way :-(
The includeIf approaches on gitdir or remote URL are better in that respect.
I have the email address problem, but that's the only paramter that needs to vary. I use the simplest way of handling this, which is this in my .config/git/config:
[user]
name = "My Name"
useConfigOnly = true
Then, the first time you commit in each repo, you'll get an "Author Identity Unknown" message. Then just run `git config --local user.email hello@example.com` to set the config for that repo.
That is a nice trick. I've had my main email address in .config/git/config, added an override in ./.git/config for projects that need it, and checked who I am from time to time with
Handy, but is it really easier to type? Or as pleasantly reminiscent of one of the first Unix commands you ever learnt, back in the days when they actually really were multiuser machines? :-)
This is what I’ve been doing for years, with some aliases to set work or personal. But honestly, I’ve started to find it annoying enough (for those first commits) to start wanting something else; yet still not annoying enough for me to research a different solution. Seeing this post, I’ll probably switch to the ”includeIf” way!
Beware that the trailing slash in the string after `gitdir` is significant! This string is a globbing pattern (it is not obvious at first sight, and seldom mentioned), and the trailing slash implies `**` [1].
So if you type "gitdir:~/work" instead of "gitdir:~/work/", you will lose some time wondering why your configuration is ignored.
I find one disadvantage of SSH key auth, in case of GitHub in particular, that SSH key grants access to all the repos independently on the organization, etc, which becomes a bigger problem when sharing the machine with other people.
One can set a password on the ssh key, but I still felt a bit paranoid about it. I found a way out with fine-grained personal access tokens which allow you to choose the repositories this token will have access to [1].
My setup consists of two ingredients:
1. GPG encrypted fine-grained PAT: `gpg -c --no-symkey-cache --pinentry-mode loopback my_name` ends up into `my_name.gpg` secret.
2. A git credential configuration which is generic across git repositories:
[credential "https://oauth2@github.com"]
helper = "!f() { test \"$1\" = get && echo \"password=$(gpg -d --pinentry-mode loopback --no-symkey-cache $_GITHUB_TOKEN)\"; }; f"
Now switching identities results into setting the env var `$_GITHUB_TOKEN` to the path to my gpg encrypted token, which will be decrypted by git on the fly. You can figure out a suitable way to alias this for yourself :)
And it only activates for git urls of the from "oauth2@github.com" which allows you to clone public repos without questions.
Another advantage is that you can share the same repo with other people, no need to maintain a copy.
Disadvantage is that you have to enter password each time you push/pull.
> Disadvantage is that you have to enter password each time you push/pull.
Run ssh-add in your terminal session before doing your push/pull dance — this way you only have to enter the password once. This gives you the security of the password protected key without bothering you too much in practise.
If you need to pull on a remote that doesn't have your private keys (as is good and proper) you can run ssh -A foo@bar.com to take that identity with you onto that remote (e.g. so you are able to pus/pull from there).
thanks for the suggestion. I haven't used agent forwarding myself. I read a bit in the manual, and this seems to have a problem if the users I'm sharing the machine with have `sudo`:
> Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the agent's UNIX-domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent. A safer alternative may be to use a jump host (see -J).
> Run ssh-add in your terminal session before doing your push/pull dance
originally my comment was about gpg encrypted files. also I suspect any kind of agent would expose privileges of my key to others if they have sudo.
> I find one disadvantage of SSH key auth, in case of GitHub in particular, that SSH key grants access to all the repos independently on the organization, etc.
I'm speaking about a situation when the space is shared. Basically every co-worker can ssh into machine and then do `sudo su` into a shared user, under which some R&D script is running and being fixed/adapted once for a while.
For scientific projects it may also be convenient, having a jupyter notebook running under tmux of the same account. Then collaborative (but not concurrent) work is possible on the project.
I use conditional includes for this, but I also add a single letter describing which Git identity I'm currently using to my PS1 so that it appears before $ in my shell prompt. This prevents me from committing code with the wrong identity, in case I'm using a git checkout that's anywhere not covered by the conditional include rules.
I use Starship (https://starship.rs) to manage my prompt, and wrote a short script that only runs if I'm somewhere in a git repo, and if so finds my Git user's email and looks up the corresponding letter in an associative array declared in my ~/.config/starship-zsh/.zshenv:
[custom.git_user]
command = "ZDOTDIR=~/.config/starship-zsh /path/to/the-script-above.sh" # set ZDOTDIR, makes zsh load the .zshenv file
when = "git rev-parse --git-dir >/dev/null 2>/dev/null" # only run if we're in a git repo
format = ' $output'
The .zshenv file contains the STARSHIP_GIT_USERS variable and its values, with a `declare -A` since it's an associative array.
nixos solves private keys and tools switch easy.
for folders, i ended up with overlays.
just follow origin upstream remote locally so that http and file united.
i mean if remote is https github com slash dzmitry lahoda slash web3.nix
than local is /home/dz/github com slash dzmitry lahoda slash web3.nix
navigation is easy. forks easy. no project1 or client 1. just navigation overlay. same works for consumption of knowledge and learning.
one may do codespace with nix easy too or many local homes.
nix and path overlays is superior and easy to maintain.
nix makes remote, local, ci, codespace, user switch, depending on dlmany versions of same repo super easy.
even by unix idiots like me.
that not full schema so. there are tags and data properties (security, size, files count, uniquiness of copy).
so decide if store local or remo only, git and syncthing same time, torrent and syncthing, gdrive and git, keepass and syncthing, what devices, ipfs. any combo.
tags when overlays (forced hierarchy fail). when git forks, than many remotes with overlay following most active fork.
that approach partially fixes some of my mental issue i guess. oh, i want to install zfs to fix duplication.
hardware keys for security i use also. thesd days can mix same key, but held ssh, crypto, aws creds on same device.
Check the following comment in previous discussion about git capabilities to manage multiple identities to commit, authenticate and sign based on directories or remote repository URL. https://news.ycombinator.com/item?id=36800853
I think the noreply email behavior on Github is a bit strange. I commit with my newer email. Then it gets merged to the upstream I was making a pull request in. Then it seems that the committer's (me) email is that noreply email. And then my author email gets rewritten to my old email (the one registered on GitHub first—but both are registered on GitHub). (Why does it much with my emails... I'm just wondering out loud.)
Probably the older email address is still the primary one for the GitHub account.
GitHub took it upon themselves to change email addresses and author names when merging via the UI buttons like "Squash and Merge" in 2018 and then again in 2019. See <https://github.com/isaacs/github/issues/1368> for the tedious details.
Essentially the post-2019 behaviour seems to be that where possible with "Squash and Merge" they will set noreply@github as the committer so that they can sign the merged commit themselves, and set author name & email to what they have recorded for the GH account involved (and the signature is then a record that GH have verified that account's involvement).
Personally I think it is shocking that they ignore the name and email address that the actual author of the commit has selected. This is both a violation of the author's intentions -- for example, you may set work and personal email addresses in different repositories as discussed here, but GitHub will rewrite them all to the same thing when other people press "Squash and Merge" on your pull requests -- and potentially a doxxing security risk.
I have considered re-reporting this to GitHub via the newer community discussions or via support again, but given the extent to which they've ignored all such reports over the last five years it is hard to find the motivation to do so.
Thank you for the explanation and link. I'll have to look into that some more.
It's definitely very dissapointing that GitHub will just change the commit metadata like that. I'm not strongly tied to GitHub right now so I might end up looking somewhere else for similar services.
I have a github.com folder with all the repos I cloned from GH but I always have to type git config user.name/email before committing. It's so annoying at this point.
You could try overriding 'git' in your PATH with a shell script wrapper that prepends something like -c user.name=yourname before the rest of the command, or that runs git config if it hasn't been run yet, etc. (whatever makes sense for your case)
Recently I tried to work on two projects that required different git credentials for push/pull. I ended up using basic auth with HTTPS with one repo, and the other on SSH.
I don't see what's wrong with .git/config. If anything, it's better because it keeps data close to where it is used. The only benefit to centralized config is that every git identity is in one place. But that may not be desirable, e.g. in the case you have MANY repos and identities.
I find the usage of the .envrc files better because it allows for more than just git config. I use it for loading all manner of org-specific information. I'm sure there's a way to configure the ssh keys using this approach as well, but I've yet to take the time to figure it out.