You can keep separate GitHub identities per workspace folder by pointing the
gh CLI at a per-workspace config directory via the GH_CONFIG_DIR
environment variable. Each workspace gets its own active account; your
default account stays intact for everything outside the workspace.
This guide walks through the full setup on Windows + PowerShell, using
a Dawere workspace at I:\code\dawere\ as a working example. Adapt the
paths to your case.
| Context | Active account |
|---|---|
| Default shell / any other folder | personal account |
| Inside the Dawere workspace | work account |
Both accounts coexist in the OS credential store (keyring). The active one
is decided by the hosts.yml file that gh reads — and that file lives
in whichever directory GH_CONFIG_DIR points to.
mkdir I:\code\dawere\.gh-configAdd a .gitignore so the auth state never gets committed if the workspace
itself is a git repo:
# I:\code\dawere\.gh-config\.gitignore
*
!.gitignore
This makes every new terminal (cmd, PowerShell, Git Bash) inside the workspace pick the variable up automatically.
setx GH_CONFIG_DIR "I:\code\dawere\.gh-config"
setxwrites the variable to the Windows registry. Existing shells won't see it until they're closed and reopened.
Verify in a brand-new PowerShell:
[Environment]::GetEnvironmentVariable("GH_CONFIG_DIR", "User")
$env:GH_CONFIG_DIRBoth should print I:\code\dawere\.gh-config.
If you only want the variable in the current shell, skip setx and run:
$env:GH_CONFIG_DIR = "I:\code\dawere\.gh-config"Open a fresh PowerShell inside the workspace so $env:GH_CONFIG_DIR
is already set, then:
gh auth loginWizard answers:
- Where do you use GitHub? →
GitHub.com - Preferred protocol for Git operations? →
HTTPS(or SSH, your call) - Authenticate Git with your GitHub credentials? →
Yes - How would you like to authenticate? →
Login with a web browser - Copy the one-time code, press Enter, paste it in the browser, and log in with the work account.
After it finishes, verify the work account landed in the workspace config:
gh auth statusYou should see the work account as Active account: true and a
hosts.yml file inside I:\code\dawere\.gh-config\.
Outside the workspace, gh reads %APPDATA%\GitHub CLI\hosts.yml. If
your personal account is already the default there, you're done. If not:
# Run in a shell where GH_CONFIG_DIR is NOT set
gh auth switch -u <personal-username>If your personal account isn't logged in globally yet, log it in once:
gh auth login…in a shell where $env:GH_CONFIG_DIR is empty (e.g. cmd /c or a
PowerShell where you ran Remove-Item Env:GH_CONFIG_DIR first).
Run both checks in two different shells.
Outside the workspace (or anywhere GH_CONFIG_DIR is unset):
gh auth status
# Expected: personal account is ActiveInside the workspace (where GH_CONFIG_DIR points to the per-folder
config dir):
gh auth status
# Expected: work account is ActiveFinal sanity check by hitting a private org repo:
gh repo view <org>/<repo> --json name,viewerPermissionghkeeps two pieces of state per host: a smallhosts.ymlconfig file and the actual auth token.hosts.ymldecides which username is the active one. It lives inGH_CONFIG_DIR(or the default%APPDATA%\GitHub CLI\when the var is unset).- The token itself is stored in the OS credential store (Windows
Credential Manager on Windows, Keychain on macOS, Secret Service on
Linux), keyed by host + username. All
ghconfig dirs on the same machine share the same keyring, so you only ever log in once per account — switching the active account just means switching which usernamehosts.ymlpoints at. - That's why you can have N config dirs, each picking a different active account from the shared credential store.
# List every account that gh knows about on this host
gh auth status
# Switch the active account inside the current config dir
gh auth switch -u <username>
# Drop the workspace var in the current shell (revert to global)
Remove-Item Env:GH_CONFIG_DIR
gh auth status # back to the global default
# Completely remove the persisted var
setx GH_CONFIG_DIR ""setxdoesn't update the current shell. Always reopen the terminal after running it.- The token lives in the OS keyring, not in the per-folder config
dir. Don't expect to copy
.gh-config\to another machine and have it work — the keyring entries won't follow. - Token scopes are per-account, not per-config-dir. If the work account
needs
workflowscope and the personal one doesn't, generate the tokens accordingly when logging each one in. - Git push/pull doesn't use the
ghCLI auth automatically — it uses the Git credential manager. If you also want git pushes to a private org repo to authenticate as the work account, configure that separately (e.g. SSH keys or a per-repo credential helper).