Repository navigation
Conversation
When multiple accounts are logged in for a host, gh resolves one global active account, switched with gh auth switch. That state is shared by every terminal and directory on the machine, so working across repositories belonging to different accounts means switching back and forth, and concurrent sessions race each other: a switch in one terminal silently changes the identity every other terminal acts as. This adds an opt-in per-repository pin: setting the github.account git configuration key to the username of a logged-in account makes token resolution for commands run in that repository use that account's stored credentials. Environment tokens (GH_TOKEN and friends) still take precedence, and an unauthenticated pin falls back to the stored active account unchanged. SwitchUser's rollback now captures the stored active token through a pin-immune helper so a failed switch inside a pinned repository cannot write the pinned account's token into the active slot. Requested in cli#12459. Co-Authored-By: Claude Fable 5 <[email protected]>
Contributor
|
Thanks for your pull request! Unfortunately, it doesn't meet the requirements for review:
Please update your PR to address the above. This PR will be automatically closed in 4 days if these requirements are not met. Full contribution requirements
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Relates to #12459.
Description
When multiple accounts are logged in for a host,
ghresolves a single global active account, changed withgh auth switch. That state is shared by every terminal and directory on the machine. Working across repositories belonging to different accounts means switching back and forth, and concurrent shells race each other: a switch in one terminal silently changes the identity every other terminal acts as, so agh pr createaimed at a work account can land under a personal one (or vice versa) depending on timing.This PR adds the opt-in, per-repository pin proposed in #12459: setting the
github.accountgit configuration key to the username of a logged-in account makes token resolution for commands run inside that repository use that account's stored credentials. Because the pin lives in git config it follows the repository rather than the process, and git's conditional includes extend it to whole directory trees (e.g. everything under~/work/).Resolution order in
ActiveToken:GH_TOKEN/GITHUB_TOKEN(and the enterprise variants) still win — an environment token is an explicit per-process choice.github.accountpin, when set and that account has stored credentials (keyring or insecure config) for the hostname.An unauthenticated pin (for example after
gh auth logout) falls back silently to the active account rather than erroring, so a stale pin never breaks a repository.One correctness detail:
SwitchUsercaptured its rollback token viaActiveToken, which would have let a pin substitute another account's token into the rollback path. The stored-active resolution is extracted into a pin-immunestoredActiveTokenhelper andSwitchUseruses it, soauth switch/auth logout/auth statussemantics are unchanged by a pin.How did you test this change?
Built
ghfrom this branch on macOS with two accounts logged in (bwt615active, a work account secondary, both keyring-stored), in a freshgit initdirectory, without ever runningauth switch:Given no
github.accountkey is setWhen I run
gh api userThen I see
bwt615(the active account — behavior unchanged)Given
git config github.account <work-account>When I run
gh api userThen I see the work account (the pin overrides the active account)
Given
git config github.account no-such-account-zzzWhen I run
gh api userThen I see
bwt615(an unauthenticated pin falls back to the active account)Given
git config github.account <work-account>andGH_TOKENset to thebwt615tokenWhen I run
gh api userThen I see
bwt615(the environment token wins over the pin)Also verified that
gh auth tokeninside the pinned repository returns the pinned account's token, and thatgh auth statusstill reports the stored active account throughout.Key points
git config --get github.account(viasafeexec), cached once per process;ghnever changes its working directory, so the value cannot change between calls. When git is unavailable or the key is unset this costs one failed lookup and behaves exactly as today.ActiveUser,auth switch,auth logout, andauth statusintentionally keep operating on the stored active account in this PR — surfacing the pin inauth statusoutput is a natural follow-up, left out to keep this reviewable.GH_ACCOUNTenvironment variable as a process-scoped equivalent.help wantedissue, and Feature: Auto-switch accounts based on git config #12459 does not carry that label yet (feat: auto-switch accounts based on git config github.account #12628 was closed on that basis). I've asked on the issue for triage, and I'm opening this anyway in case a concrete, tested implementation is useful for evaluating the proposal — happy to adjust or split it however the team prefers, and no hard feelings if it's closed pending triage.Notes for reviewers
Start with
ActiveTokenininternal/config/config.go(the resolution-order change), thenpinnedActiveToken, then theSwitchUserrollback change together withTestStoredActiveTokenIgnoresPinnedAccount, which documents whystoredActiveTokenexists.github.accountkey name.help wantedissue.Authorship and follow-up
Who wrote this:
Who answers review comments: