Repository navigation
Account incorrectly reported active in gh auth status #10136
Description
Activity
Hello @williammartin, for your question about using
GH_CONFIG_DIRwith direnv, I prefer separating accounts config and I like gitincludeIfpattern.# ~/.gitconfig [includeIf "gitdir:~/dev/org1/"] path = ~/dev/org1/.gitconfig [includeIf "gitdir:~/dev/org2/"] path = ~/dev/org2/.gitconfig
For
ghI had to use direnv to achieve this, and also I prefergh auth statusto only report one account, which is the one I'm expecting in my filesystem context.Interesting issue... I have been able to repro this, and it looks like it actually might be an issue with how
GH_CONFIG_DIRis working alongsidegh api... It seems thatgh apiis not respecting the custom config pointed to by theGH_CONFIG_DIRenv var. I suspect that it's defaulting to the global config before falling back to the specified config.Repro steps
- Log out of all accounts
- Create a new repo
- Create a new config in that repo
mkdir .config - Log into account 1 and save creds to the custom config
GH_CONFIG_DIR=./.config gh auth login - Confirm this has saved to the new config
GH_CONFIG_DIR=./.config gh auth status. Alternatively, you can runcat ./.config/hosts.yml - Hit the api:
GH_CONFIG_DIR=./.config gh api /user | jq .login. This should show the same account you are logged in with - Now log in globally with a different account
gh auth login - Hit the api again:
GH_CONFIG_DIR=./.config api /user | jq .login. This will show the account you've logged into globally and not the one logged into with the specified config.
I'm not entirely sure what's going on, yet, but I am concerned that this might not be scoped only to
gh api. Thanks for pointing this out! We'll discuss and get back to you.- addeddiscussFeature changes that require discussion primarily among the GitHub CLI teamFeature changes that require discussion primarily among the GitHub CLI team
on Dec 26, 2024 @jtmcg this is a bit of a funny scenario that has fallen between the Triage rotation cracks. I probably could have been clearer in #9111 (comment) but I'm pretty confident the issue at hand is a disconnect between the way the Active User is determined, and the Active Token is fetched.
I'll explain those now.
Active User
This is the user referenced by the
userkey under a particular host in thehosts.ymlActive Token
This is, in order:
- The value of the token env vars
- The value of the
oauth_tokenkey under a particular host in thehosts.yml(legacy, insecure) - The value in the keyring keyed by a particular host
So in this case, we're dealing with a changing hosts.yml containing the same host (github.com), but a keyring value that is keyed by a particular host.
So when the active token is fetched, it returns whatever token happened to be put in there last.
The reason
auth switchresolves this is because auth switching was implemented by also keying tokens in the keyring byhostandusername, then swapping the token into thehostkeyed entry to make it active. This was for backwards compatibility reasons.I have some thoughts on how we might resolve this but I'm on vacation and just wanted to drop this message so that you don't wild goose chase.
@jtmcg this is a bit of a funny scenario that has fallen between the Triage rotation cracks. I probably could have been clearer in #9111 (comment) but I'm pretty confident the issue at hand is a disconnect between the way the Active User is determined, and the Active Token is fetched.
I'll explain those now.
Active User
This is the user referenced by the
userkey under a particular host in thehosts.ymlActive Token
This is, in order:
- The value of the token env vars
- The value of the
oauth_tokenkey under a particular host in thehosts.yml(legacy, insecure) - The value in the keyring keyed by a particular host
So in this case, we're dealing with a changing hosts.yml containing the same host (github.com), but a keyring value that is keyed by a particular host. When the active token is fetched, it returns whatever token happened to be put in there last.
The reason
auth switchresolves this is because auth switching was implemented by also keying tokens in the keyring byhostandusername, then swapping the token into thehostkeyed entry to make it active. This was for backwards compatibility reasons.I have some thoughts on how we might resolve this but I'm on vacation and just wanted to drop this message so that you don't wild goose chase.
Ah, this is my bad. I totally missed the linked issue #9111 😅 This did, at least, give me a chance to explore this a bit and I can confirm the behavior! lol
- removeddiscussFeature changes that require discussion primarily among the GitHub CLI teamFeature changes that require discussion primarily among the GitHub CLI team
on Feb 27, 2025 I am hoping this issue will be resolved.
I want to switch the active account ofghfor each directory.
For only my use case, I don't necessarily want to support theGH_CONFIG_DIRswitch by direnv, since I only need to be able to specify the active account ofghper directory.- addedpriority-3Affects a small number of users or is largely cosmeticAffects a small number of users or is largely cosmetic
on Apr 23, 2025 - addedneeds-designAn engineering task needs design to proceedAn engineering task needs design to proceedand removedneeds-triageneeds to be reviewedneeds to be reviewed
on Apr 23, 2025 - marked Keyring state may not match the current user specified in
hosts.yml#11009 as a duplicate of this issueon May 27, 2025 Acceptance Criteria
Given I have two accounts on a single github host
And Given I have each of these accounts as the active user in separatehosts.ymlfiles
When I setGH_CONFIG_DIRto either of the files
And When I rungh api /user .login
Then I see the active user is correct as per the hosts.yml file
Describe the bug
Running
gh auth statusreports account as active, but API calls use another account.> gh --version gh version 2.63.0 (1980-01-01) https://github.com/cli/cli/releases/tag/v2.63.0Steps to reproduce the behavior
github.com, last active account isuser1.GH_CONFIG_DIR(via direnv), with a custom config which has one useruser2gh auth statusgh api /user | jq .name=> printsuser1, contradictingauth statusoutputThe expected behavior is to use the token for the given
host+userof current repository without needing togh auth switch, and report active account correctly.Context
Active token is fetched from keyring using only hostname
cli/internal/config/config.go
Lines 202 to 218 in 5402e20
Related to #9111 (comment))