Allow multiple account credentials
ncmans opened this issue · 75 comments
Describe the feature or problem you’d like to solve
I have two accounts on github each with access to a different set of private repositories. Currently I use a combination of git's [IncludeIf ...]
config and a custom config which overrides the SSH private key I use for certain repositories. E.g.:
In ~/.gitconfig
:
[includeIf "gitdir:~/work/"]
path = ~/work/.gitconfig
and in ~/work/.gitconfig
:
[core]
sshCommand = "ssh -i ~/.ssh/work"
It will be great if the credentials for gh
can also be configured per repository as well.
Proposed solution
There are a bunch of options I can think of:
- Allow overriding
gh
config by a file in a local clone's.git
directory - Allow defining rules in the
gh
config which defines which repos/orgs should use which credential. E.g.
github.com/google:
- user: gemployee
oauth_token: ...
github.com/microsoft:
- user: msemployee
oauth_token: ...
github.com:
- user: personal
oauth_token: ...
How will it benefit CLI and its users?
It will allow Github users with multiple accounts of varying access to seamlessly work on different repositories.
Is there currently a way to work around this by removing the current authentication? I can't seem to find it.
Reinstalling seems to work, but it's very cumbersome.
@eXamadeus GitHub CLI currently has no mechanism for switching between multiple GitHub accounts and I don't really have a workaround to suggest for you at this moment, sorry.
The only approach I could imagine, but would not recommend to anyone, would be to authenticate with 1st account, save a copy of ~/.config/gh/hosts.yml
somewhere & delete the original file, authenticate again with the 2nd account, and now you can swap the ~/.config/gh/hosts.yml
file with the backup file when you need to switch accounts.
Since this solution involves using SSH for git protocol, make sure both configuration files include the git_protocol: ssh
line.
If we can add two entries or as many entries on every gh auth login
. It might become easier with something like this:
github.com:
user: aitchkhan
oauth_token: xxx
user: haroonKhan-10p
oauth_token: xxx
git_protocol: ssh
If the cli
can somehow sense which username the current repository is associated to. It would be easy to find the user in the hosts.yml and rest would be magic.
PS: I have not gone through the codebase. These are my assumptions.
Searched and landed here. This feature would help people with two or more accounts (personal/business/others) and use both of them every day (swapping the config file would be too much for them).
It's a bit hacky, but I solved this so that I could evaluate if I want to actually use this cli by using the token auth capabilities, putting this into my dotfiles.
alias gh_cli=$(which gh)
function gh() {
if [[ $(pwd) =~ {PATH_TO_PERSONAL_CODE} ]]; then
GITHUB_TOKEN=$PERSONAL_GH_CLI_TOKEN
else
GITHUB_TOKEN=$WORK_GH_CLI_TOKEN
fi
GITHUB_TOKEN=$GITHUB_TOKEN gh_cli $@
unset GITHUB_TOKEN
}
@fdm1 Which config file did you fill that in?
Now that #2179 has been merged, perhaps it will be less effort to implement this feature?
Would be nice to have something like how git
handles it:
~/.gitconfig
[includeIf "gitdir:~/dev/"]
path = ~/.gitconfig.personal
[includeIf "gitdir:~/workspace/"]
path = ~/.gitconfig.work
~/.gitconfig.work
[user]
name = example-work-user
email = example@example.com
edit
Now that I think about it some more, can gh
infer which authed account to use from the current git config user.name
or email?
Since #2444 has been merged, as an alternative solution, set the environment variable GH_CONFIG_DIR
to different directories could allow multiple accounts.
I just implemented simple multi-account support based on the remote.origin.url
config property (of course GH_HOST is on board as well): #3278
So having hosts.yml as
github.com:
user: personal-account
oauth_token: personal-token
github.com/acme:
user: work-account
oauth_token: work-token
we use work credentials for all acme repositories and personal credentials for everything else.
Unfortunately, gh cli uses global settings for "default" host, so I postponed the implementation of Implemented.gh auth status
which uses several credentials at the same time.
Maybe this is a workaround if u wanna use multi credentials for a specific command. such as pr view
/usr/local/pr2
#!/usr/bin/python3
import subprocess
import json
import os
import re
with open(os.path.expanduser('~/.pr-config.json')) as f:
configs = json.load(f)
command = 'gh pr view --web'
remote_url = subprocess.check_output(['git', 'config', '--get', 'remote.origin.url']).strip().decode()
for pattern, config in configs.items():
is_match = re.match(pattern, remote_url)
if is_match:
os.system(
f'GH_HOST={config["host"]} GH_ENTERPRISE_TOKEN={config["token"]} {command}'
)
break
~/.pr-config.json
{
"git@enterprise.com": {
"host": "enterprise.com",
"token": ""
},
"git@enterprise1.com": {
"host": "enterprise1.com",
"token": ""
}
}
I am able to have multiple accounts signed in and that is nice, but one thing that I am trying to do is when I am creating a repository I would like to select my account. Doing something like gh repo create my_name/repo_name
doesn't seem to work because one of my accounts is enterprise and one is public. Passing in my enterprise name like this causes HTTP 404: Not Found (https://api.github.com/users/my_enterprise_username)
when I am logged into both my personal and enterprise GitHub but trying to create a repo for my private Github. This is not like a first-logged into account gets priority, no matter the order in which I log into my GitHub accounts I will receive this error when trying to create a repo for my enterprise account. Is there a way to force gh repo create
to use the enterprise API instead of the public one? Right now I must log out of my personal account to create an enterprise repo unless I am doing something wrong.
I've created a bash wrapper script for gh
which makes it easier to do multiple accounts. Uses personal access tokens.
¡Hello!
After having read everything, I believe it'd be more robust not to second-guess anything, and mark the user to use via Git's own configuration mechanism.
From the original submission, the work config would be expanded to specify the username to use for the server in question:
# ~/work/gitconfig
[core]
sshCommand = "ssh -i ~/.ssh/work"
[gh "github.com"]
user = workuser
That way, we'd leverage the includeIf
mechanism that everybody is already using to customize Git to their needs; hosts.yml could just have an array of stanzas for the same (or different) servers.
$ git config --get gh.github.com.user
workuser
(The hosts.yml format would have to be adjusted to be able to take multiple user stanzas, of course. A bit, but not quite, like #326 (comment).)
Edited to add: sadly, it would not work for things like gh repo clone
, because all includeIf directives only when already in a repo.
Replying now to #326 (comment):
Now that I think about it some more, can
gh
infer which authed account to use from the currentgit config user.name
or email?
I'm not sure that's a viable approach, since some users may not alter user.*
variables (see the original submission where only sshCommand
is changed).
I strongly recommend using direnv in conjunction with GH_CONFIG_DIR
to use multiple accounts.
This is by far the easiest solution. If you don't like/cannot use direnv, you can still manually prefix GH_CONFIG_DIR
. Shell wrappers above are clever, but this gets the job done just fine. @lucatpa Thanks for sharing!
I strongly recommend using direnv in conjunction with GH_CONFIG_DIR to use multiple accounts.
Similar to @lucatpa I use a tool to manage my GH_CONFIG_DIR
but I use OnDir instead. The advantage of this is that I don't have to setup multiple .envrc
files in each repo
So I have this setup in my .config/gh
folder
├── config.yml
├── org1
│ └── hosts.yml
└── org2
└── hosts.yml
and I have this setup in my ~/.ondirrc
config file
enter ~/source/org1/([^/]+)
export GH_CONFIG_DIR="/Users/username/.config/gh/org1"
leave ~/source/org1/([^/]+)
unset GH_CONFIG_DIR
enter ~/source/org2/([^/]+)
export GH_CONFIG_DIR="/Users/username/.config/gh/org2"
leave ~/source/org2/([^/]+)
unset GH_CONFIG_DIR
HTH
(Just to make it super clear, all my code is in /Users/username/source/)
Shingle.org.com
What about using git credential fill
to get the creds and delegate it all to git-credential-helpers? If gh
did this, it would work perfectly for my use case (two GitHub accounts with git already set up to use the right creds for various repos depending on repo org/user). It also means that gh
does not need to store tokens in plaintext on the filesystem.
I want to share my little approach that I build after reading this issue here some time ago, it does just link the hosts.yml
config to user-specific hosts-username.yml
files (which you need to create first), depending on a git repo setting (that you have to config).
However, it makes it possible to use use specific gh for specific Github users that you setup per local repo.
https://gist.github.com/ezzra/ec5a575a6cab368179bbd6a95e6f7fe6
(using git credential fill
might be worth to use here, I didn't know about this when I created my workaround)
Just linking to git credential
for easy ref.
[1] https://git-scm.com/docs/git-credential/2.35.0
[2] https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage
seriously? 2 years and github still won't listen to such an obvious feature?
@tr4g please be kind. i know it's frustrating, but there's so much work that can be done, not everything will get done. I personally want to take a crack at this, using git credential
, but time keeps ticking.
For what it's worth, I have a switchhub
script that symlinks a -<username>
file to the main config file for hub
and gh
. It's a little manual, but eases the pain a bit for now. Attached.
switchhub.txt (renamed to .txt to be able to attach)
@eabase the last line of the script is the same as
# Only run main if executed as a script and not "sourced".
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then main "$@"; fi
I've been doing this a long time before ${BASH_SOURCE}
worked for this and caller
was the only way I found to do it. It is just inspecting the function call stack. I should update my script template.
This is a terrible Dev experience. Someone please fix this.
Too bad this did not work something like Kubectx. Just run a Kubectx command (which is pointed at all the Kube certs you have), and select which Kube cluster you want to work with. Made my life soo much easier!
https://github.com/ahmetb/kubectx
Not hating on the devs, just though I would chime in, Keep up the good work devs!
I strongly recommend using direnv in conjunction with
GH_CONFIG_DIR
to use multiple accounts.
I have never head of direnv...you have started a new rabbithole and have saved me so much work...Thank you!
I have never head of direnv...you have started a new rabbithole and have saved me so much work...Thank you!
@j33pguy if you are down a rabbithole, you might as well try ondir 😁
Similar to @lucatpa I use a tool to manage my
GH_CONFIG_DIR
but I use OnDir instead. The advantage of this is that I don't have to setup multiple.envrc
files in each repo
Until multiple accounts are not implemented in gh
, I've ended up with such aliases to switch between regular GitHub and Company's GitHub (thank God gh
supports aliases 😝): https://gist.github.com/yermulnik/017837c01879ed3c7489cc7cf749ae47
Describe the feature or problem you’d like to solve
I have two accounts on github each with access to a different set of private repositories. Currently I use a combination of git's
[IncludeIf ...]
config and a custom config which overrides the SSH private key I use for certain repositories. E.g.:In
~/.gitconfig
:[includeIf "gitdir:~/work/"] path = ~/work/.gitconfig
and in
~/work/.gitconfig
:[core] sshCommand = "ssh -i ~/.ssh/work"
It will be great if the credentials for
gh
can also be configured per repository as well.Proposed solution
There are a bunch of options I can think of:
- Allow overriding
gh
config by a file in a local clone's.git
directory- Allow defining rules in the
gh
config which defines which repos/orgs should use which credential. E.g.github.com/google: - user: gemployee oauth_token: ... github.com/microsoft: - user: msemployee oauth_token: ... github.com: - user: personal oauth_token: ...
How will it benefit CLI and its users?
It will allow Github users with multiple accounts of varying access to seamlessly work on different repositories.
[includeIf` "gitdir:~/work/"]
path = ~/work/.gitconfig
@thinkstack
I haven't used any of those, but seems like direnv
supports exactly the same thing (print from their docs below), by searching parent folders for a .envrc
(or .env
) file.
So I guess you don't really need to put one file per directory if you organize your directories appropriately.
Thanks! That's a very lightweight alternative if we don't want to install anything else.
How do you folks manage your credentials with those solutions?
1618365730
How do you folks manage your credentials with those solutions?
Not sure this is what you're asking but I use 1password and chezmoi.
direnv
setsGH_CONFIG_DIR
, for example to~/.config/gh/work
- credentials are stored in 1password
- chezmoi does dotfiles management and supports returning data from 1password using the cli. The template file for
~/.config/gh/work/hosts.yml
looks like this:
github.com:
user: leon-work
oauth_token: {{ (onepasswordItemFields "2qaegfeuivaudgbx5zmdjtcjeu").credential.v }}
git_protocol: ssh
Somewhat related: today I attempted to use gh pr create
and was rebuffed because the GITHUB_TOKEN
in my env was a token with very limited permissions. I'm using said token to authenticate with a GH package registry, so it has read-only permissions. It's loaded into my env by direnv. gh
preferred the GITHUB_TOKEN
env var over its other auth method. It would be useful to have a mechanism to ignore the environment variables. Or specify preferred ordering of auth method, i.e. first: try token negotiated with gh auth
; then: try GITHUB_TOKEN
etc.
Until this is officially supported, I have created a simple gh extension to manage multiple profiles. Check it out at gabe565/gh-profile.
Describe the feature or problem you’d like to solve
I have two accounts on github each with access to a different set of private repositories. Currently I use a combination of git's
[IncludeIf ...]
config and a custom config which overrides the SSH private key I use for certain repositories. E.g.:In
~/.gitconfig
:[includeIf "gitdir:~/work/"] path = ~/work/.gitconfig
and in
~/work/.gitconfig
:[core] sshCommand = "ssh -i ~/.ssh/work"
It will be great if the credentials for
gh
can also be configured per repository as well.Proposed solution
There are a bunch of options I can think of:
- Allow overriding
gh
config by a file in a local clone's.git
directory- Allow defining rules in the
gh
config which defines which repos/orgs should use which credential. E.g.github.com/google: - user: gemployee oauth_token: ... github.com/microsoft: - user: msemployee oauth_token: ... github.com: - user: personal oauth_token: ...
How will it benefit CLI and its users?
It will allow Github users with multiple accounts of varying access to seamlessly work on different repositories.
Duplicate of #
@eXamadeus GitHub CLI currently has no mechanism for switching between multiple GitHub accounts and I don't really have a workaround to suggest for you at this moment, sorry.
The only approach I could imagine, but would not recommend to anyone, would be to authenticate with 1st account, save a copy of
~/.config/gh/hosts.yml
somewhere & delete the original file, authenticate again with the 2nd account, and now you can swap the~/.config/gh/hosts.yml
file with the backup file when you need to switch accounts.Since this solution involves using SSH for git protocol, make sure both configuration files include the
git_protocol: ssh
line.
Since we can use GH_CONFIG_DIR
to specify different gh
config dir, I use direnv
to set that env var for different projects.
After logging in with gh auth login
, I copy .config/gh
to my project dir, then use direnv
to set GH_CONFIG_DIR
to that location.
Since we can use
GH_CONFIG_DIR
to specify differentgh
config dir, I usedirenv
to set that env var for different projects.After logging in with
gh auth login
, I copy.config/gh
to my project dir, then usedirenv
to setGH_CONFIG_DIR
to that location.
I did this too for a while! My gh extension actually takes advantage of direnv, but it sets up the .envrc
file for you 😊
Here to add that this is a much desired feature please. constant nightmare switching accounts
Would also love to see a purpose-built solution added to the CLI please 🙏
@leonhfr was playing around with this today along with the 1Password CLI op
. This seems to have worked for me:
- Run
gh auth setup-git
to get the helpers structure written to~/.gitconfig
- Edit
~/.gitconfig
so the helpers point instead atop
as follows:helper = !op plugin run -- gh auth git-credential
- After that when you want to run the git CLI, it passes you directly through to 1Password - no templating in the gh hosts.yaml needed and multiple accounts stored in 1Password.
The current gh CLI command in item 1 above writes absolute paths to the gh
binary without considering aliases that op
adds.
Not sure what all the fuss is about. I got this to work fairly easily after purchasing a new computer for each Github account I have. Never had a problem since...
The issue is opened for a long time and still there is no native resolution. Maybe gh cli extension could be handy, here is one that I found https://github.com/gabe565/gh-profile.
Probably a gh cli extension that updates symlinks for the configuration files is easy to achieve. E.g.
There are many ways to solve it, but I would love to see a native support without any wrappers.
Since no one has brought it up, I would like to bring up the approach Gitlab's cli, glab
, took to allow multiple accounts. I don't know if their approach was designed for this, but I found that it works very nicely with way I have already configured ssh.
glab
allows you to define an api_host
for each host you use. The api_host
is simply the hostname of the Gitlab instance glab
communicates with. The hostname is only used to for git communication. So if you set the git_protocol as ssh, ssh is what resolves the specified hostname to the correct hostname. The following configuration might clarify what I mean.
glab-cli/config.yml
:
hosts:
work.gitlab.com:
api_host: gitlab.com
user: <work user>
token: <work_token>
git_protocol: ssh
personal.gitlab.com:
api_host: gitlab.com
user: <personal user>
token: <personal_token>
git_protocol: ssh
.ssh/config
:
Host personal.gitlab*
IdentityFile ~/.ssh/ed25519_personal
Host work.gitlab*
IdentityFile ~/.ssh/ed25519_work
Host *gitlab*
Hostname gitlab.com
User git
IdentitiesOnly yes
In your work projects you would set the remote url as:
git@work.gitlab.com:Work/work_project.git
And in your personal projects you would set the remote url as:
git@personal.gitlab.com:Persnoal/personal_project.git
If you want to define a default user for gitlab, you would then simply have to add gitlab.com
as a host into both
.ssh/config
and hosts.yml
.
As you can see, when glab
and ssh
see the domain name personal.gitlab.com
, they communicate with gitlab.com
, but they have correctly setup the authentication for the personal
user. I think gh
would benefit from implementing such a separation between the api hostname and the specified hostname.
As a bonus, if you don't want to type git@personal.gitlab.com
everytime you set a remote url and instead prefer persnoal@github.com
, add the following lines to your git/config
[url "git@personal.gitlab.com"]
insteadOf = personal@gitlab.com
This way git
auto expands the url personal@gitlab.com
to git@personal.github.com
.
I have written a simple wrapper script to handle my github cli commands.
It uses fzf
to dispatch on the username.
Usage
I use a keyring (gnome-keyring
) with libsecret
and set the git credential helper to that:
$ git config credential.helper=libsecret
I never have to enter passphrases with it (neither for ssh commit signing).
You add the token to the keyring:
$ username='exprpapi'
$ token="TOKEN_GH_${username}"
$ secret-tool store --label="${token}" "${token}" token
You can retrieve it like this:
$ username='exprpapi'
$ token="TOKEN_GH_${username}"
$ secret-tool lookup "${token}" token
I added the following to my shell config:
get_gh_name() {
local names=('exprpapi' 'other_username1' 'other_username2')
local name="$(printf '%s\n' "${names[@]}" | fzf)"
echo "${name}"
}
get_gh_token() {
local name="${1:-$(get_gh_name)}"
local token="TOKEN_GH_${name}"
local attribute="${token}"
local value='token'
local gh_token="$(secret-tool lookup "${attribute}" "${value})"
echo "${gh_token}"
}
gh() {
GH_TOKEN="$(get_gh_token)" /usr/bin/gh "$@"
}
I can now run cli commands and it will prompt me with fzf
asking which identity to run it with:
To add some internal context here: we want this feature and have wanted it for a long time but have run into issues regarding respecting GitHub's terms of service around multiple account support. I think it's more likely than ever that we'll be able to do this but don't have it prioritized, yet.
GitHub's terms of service around multiple account support
@vilmibm What is the issue here? What if one is an external individual contributor for many GitHub enterprises that utilize managed users?
For what it's worth, I use git-credential
(with git config --global credential.useHttpPath true
) to manage different credentials for different repositories, and a wrapper function in my ~/.bashrc
sets environment variables for each execution of gh
.
gh() (
: ${GH_HOST:=github.com}
if [[ -z ${GH_REPO:-} ]]; then
local URL=$(git config remote.origin.url)
case $URL in
https://${GH_HOST}/*) GH_REPO=${URL#https://${GH_HOST}/};;
*@${GH_HOST}:*) GH_REPO=${URL#*@${GH_HOST}:};;
esac
GH_REPO=${GH_REPO%.git}
fi
if [[ -n ${GH_REPO:-} && -z ${GH_TOKEN:-} && -z ${GITHUB_TOKEN:-} ]]; then
exec {fd}< <(git credential fill <<<url="https://${GH_HOST}/${GH_REPO}.git")
while read -r -u $fd; do
case $REPLY in
password=*) GITHUB_TOKEN=${REPLY#*=};;
esac
done
exec {fd}<&-
fi
export GH_HOST GH_REPO GH_TOKEN GITHUB_TOKEN
command gh "$@"
)
We are under migration from GHES to GHEC (Enterprise Managed Users) and facing the same problem. Our employees are often required to use both GHEC EMU and the public GitHub.com to work with external collaborators or contribute to open-source projects, and needing the option to switch between EMU and public GitHub accounts.
To add some internal context here: we want this feature and have wanted it for a long time but have run into issues regarding respecting GitHub's terms of service around multiple account support.
I think there is documentation specific to this topic: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-personal-account/managing-multiple-accounts
However, the method the doc suggests (use SSH for one account and HTTPS for the other) is too tricky, so we're expecting the GitHub CLI to solve this problem.
Describe the feature or problem you’d like to solve
I have two accounts on github each with access to a different set of private repositories. Currently I use a combination of git's
[IncludeIf ...]
config and a custom config which overrides the SSH private key I use for certain repositories. E.g.:In
~/.gitconfig
:[includeIf "gitdir:~/work/"] path = ~/work/.gitconfig
and in
~/work/.gitconfig
:[core] sshCommand = "ssh -i ~/.ssh/work"
It will be great if the credentials for
gh
can also be configured per repository as well.Proposed solution
There are a bunch of options I can think of:
- Allow overriding
gh
config by a file in a local clone's.git
directory- Allow defining rules in the
gh
config which defines which repos/orgs should use which credential. E.g.github.com/google: - user: gemployee oauth_token: ... github.com/microsoft: - user: msemployee oauth_token: ... github.com: - user: personal oauth_token: ...
How will it benefit CLI and its users?
It will allow Github users with multiple accounts of varying access to seamlessly work on different repositories.
gh-profile
is cool but it softly broken due to 2.26.0 release.
Work around is go back to insecure storage (gh auth login --insecure-storage
). gh-profile
readme has the details.
It is worth mentioning that:
- GitHub Mobile app now supports multi-account: https://github.blog/changelog/2023-08-15-log-in-with-multiple-github-accounts-on-github-mobile/
- Multi-account support is planned to be implemented on the GitHub.com website in 2023: github/roadmap#795
I think the last part missing is the multi-account support in the gh
command.
following Multi-account support on GitHub.com accouterments. is gh going to add support for multi-account?
following Multi-account support on GitHub.com accouterments. is gh going to add support for multi-account?
@electriquo : To give an explicit answer: yes
As you might see on this issue in the timeline, @williammartin and @samcoe have been working through the implications of multiple account and how this affects the authentication schema and the product experience.
To give a more nuanced answer: mostly, but it depends exactly what you mean
As @andyfeller mentioned above we are very actively exploring native support for being able to log into multiple accounts on a single host, and switch between them manually. In #8281 we are laying the ground work for the configuration schema and keyring migrations that need to occur to support this whilst providing backwards and a reasonable amount of forwards compatibility. After we feel comfortable with this, we will look to ship a UX focused around something like gh auth switch
, providing the ability to change the currently active user on a host.
Explicitly out of scope for this tranche of work is automatic account switching based on some criteria (be that cwd
, remote.origin.url
, git config gh.github.com.user
or anything else). We aren't ruling this out for the future but the myriad creative approaches outlined in this issue demonstrate that there are quite a few competing ideas and hopes and it needs some attention separate from the obvious use case outlined above.
Cheers ✌
To give a more nuanced answer: mostly, but it depends exactly what you mean
As @andyfeller mentioned above we are very actively exploring native support for being able to log into multiple accounts on a single host, and switch between them manually. In #8281 we are laying the ground work for the configuration schema and keyring migrations that need to occur to support this whilst providing backwards and a reasonable amount of forwards compatibility. After we feel comfortable with this, we will look to ship a UX focused around something like
gh auth switch
, providing the ability to change the currently active user on a host.Explicitly out of scope for this tranche of work is automatic account switching based on some criteria (be that
cwd
,remote.origin.url
,git config gh.github.com.user
or anything else). We aren't ruling this out for the future but the myriad creative approaches outlined in this issue demonstrate that there are quite a few competing ideas and hopes and it needs some attention separate from the obvious use case outlined above.Cheers ✌
For Christmas, I'm asking Santa for gh auth switch
🤞
Having read through many issues on the topic now, I'm wondering if a proposal like this: #7081 (separating out the protocol + not hardcoding it into the host URL) couldn't be extended to also include ssh
and solve the problem much more easily for people who already have different ssh configs set up for switching between accounts, e.g. when using git
, than reworking the auth system.
Having to repeatedly (re)set and look up environment variables like GH_CONFIG_DIR
also seems redundant/convoluted when existing tools are already configured to differentiate between users/scenarios, like, as said, via ssh config files or Git config settings which were pointed out up-thread.
I haven't really dug into the code (not a Go person) but considering --hostname
is an option available for so many commands, I'm wondering if it couldn't be adapted for more flexibility.
Hi @keikoro, I'm not really following your comment sorry. Can you outline a bit more how you would expect this to work? In particular, how you would expect this to impact a scenario like: "I want to trigger workflow runs in private repositories that I only have access to in different accounts".
Cheers!
Hey folks, especially @ConnorIngold 🎅 ,
As we're heading towards releasing the first piece of multi-account functionality, I just wanted to share the multi-account-beta-20231202 branch which contains most of the changes we'd like to ship. Specifically, the UX changes are in:
gh auth login
which now will add a new account under a host rather than replacing the old onegh auth switch
which is a new command that allows for switching between the active user for a host (if there are 2 it will automatically switch, 3 or more, will prompt for selection)gh auth logout
now prompts for logout if there is more than 1 account on the host, and switches to another on logout if there is onegh auth status
now shows all known accounts for hosts, and highlights the active one
The consequence of this is that you should be able to get tokens for multiple accounts and switch between those tokens easily with auth switch
. Specifically, this will switch the token used for GitHub API requests and the token returned by gh
when it is set up to manage git credentials.
We know there are many more features requested throughout this issue (e.g. automatic switching, automatic user and email git configuration), and there are plenty of other quality of life (get token with gh auth token --user
, user specific configuration) and docs improvements we already know would be useful on top of this work. However, we're interested in releasing what we have before the Christmas break, assuming it already provides value, and then iterating on that with any feedback we receive.
If you're interested in playing around with this branch, read on...
Testing out multi account
The multi-account-beta-20231202 branch can be built from source and can be used at outlined above.
Note that there is not yet an account switching interstitial page in the authentication flow with GitHub, so at the point you open your browser, you'll want to have used the browser based account switcher to be logged in as the user you intend to authenticate with in the CLI.
The main challenge in this work was that the gh
hosts.yml
file (where hosts, their config, their user, and in --insecure-storage
cases, their token live) schema only supported a single user per host, and having persistent data on disk presented a compatibility challenge. Be aware that this branch performs a migration on the data in this file (updating to a one-to-many mapping), and also adds a version to the config.yml
file. We've attempted to retain forward compatibility so you should be able to use the current and older releases of gh
with the new schema but given these are plain text files that could have been modified in any way, that's not something we can guarantee. If you are concerned about the data in these files, we advise you to take a backup but in the worst case, if something goes awry, you should be able to delete them, and use the release version again without any further burden other than logging in.
If you do run into issues with any of this, particularly around the schema migration, we'd love to know. Please leave feedback relating to this test branch in #8403, to avoid adding more noise to this issue.
Cheers!
@gabe565 : wanted to make an intentional effort to invite you to test this beta feature and share your insights given https://github.com/gabe565/gh-profile 🙇 thank you again for supporting our community's needs for so long ❤
We've shipped the initial work described above in v2.40.0. Please read the release notes and the linked technical document for more details about what is in and out of scope and what the sharp edges might be.
Please leave any feedback on the release discussion.
As described in the technical document, we know there are plenty of things discussed in this issue that were not in scope for this release, so I will be leaving this issue open.
@williammartin , I was reviewing my GitHub CLI configuration and you've just delighted me with the support for multiple logins. I'm pleased to see that you are working on the extra features to make this complete. I'm now subscribed to the issue to stay up to date.
Describe the feature or problem you’d like to solve
I have two accounts on github each with access to a different set of private repositories. Currently I use a combination of git's
[IncludeIf ...]
config and a custom config which overrides the SSH private key I use for certain repositories. E.g.:In
~/.gitconfig
:[includeIf "gitdir:~/work/"] path = ~/work/.gitconfig
and in
~/work/.gitconfig
:[core] sshCommand = "ssh -i ~/.ssh/work"
It will be great if the credentials for
gh
can also be configured per repository as well.Proposed solution
There are a bunch of options I can think of:
- Allow overriding
gh
config by a file in a local clone's.git
directory- Allow defining rules in the
gh
config which defines which repos/orgs should use which credential. E.g.github.com/google: - user: gemployee oauth_token: ... github.com/microsoft: - user: msemployee oauth_token: ... github.com: - user: personal oauth_token: ...
How will it benefit CLI and its users?
It will allow Github users with multiple accounts of varying access to seamlessly work on different repositories.
It's great to read that there is progress being made on this request.
Addressing one consistent comment:
Explicitly out of scope for this tranche of work is automatic account switching based on some criteria
I agree that there shouldn't be complex logic that determines which account to use, but if there is support for gh auth switch
, could we add an --account
flag for cloning?
Similarly, is the current scope to only support controlling the globally authenticated user (or "context", if using k8s parlance)? It would be really nice to not do that, and instead run with a UX that matches the other Github apps, where most users are assumed to have a "default" username that they use for most things, and N other usernames used for work/private uses.
@cornfeedhobo thanks for the feedback. It would be great if you could create an enhancement
request for both of these so that we can discuss them specifically. We could then get a better understanding of your use cases and blend it into any larger designs (e.g. offering the ability to act as a particular authenticated user for any command). It also gives the community an opportunity to chime in without trudging through this horrendously long thread.
Cheers!