cli/cli
Config and auth (system view)
Active contributors: William Martin, Mislav, vilmibm
Purpose
The config and auth system reads, writes, and migrates user configuration; performs OAuth device flow; and stores tokens in the OS keyring. From the command layer's perspective, the abstraction is a single gh.Config interface that always returns the right host, user, token, and scopes.
Directory layout
internal/config/
config.go # ~25 KB: the on-disk config representation
stub.go # InMemoryConfig used by tests
auth_config_test.go # exhaustive auth precedence tests
migration/migrate.go # v1 -> v2 migration
internal/gh/
gh.go # The gh.Config interface (with Authentication, Aliases, etc.)
projects.go # Project-related config fields
ghtelemetry/ # Telemetry-aware config types
internal/authflow/ # OAuth device flow client
internal/keyring/ # zalando/go-keyring wrapper
internal/ghinstance/ # Default host detectionKey abstractions
| Symbol | File | Role |
|---|---|---|
gh.Config |
internal/gh/gh.go |
The interface every command uses. |
Config.Authentication() |
gh.go |
Returns AuthConfig, which exposes DefaultHost, Token, User, Scopes, GitProtocol per host. |
Config.Aliases() |
gh.go |
User-defined aliases. |
Config.Telemetry() |
gh.go |
Telemetry preference. |
internal/config.NewConfig |
config.go |
Loads from $GH_CONFIG_DIR/config.yml and hosts.yml, with migration. |
Migration |
migration/migrate.go |
Upgrades v1 single-account configs to v2 multi-account form. |
authflow.Flow |
internal/authflow/ |
OAuth device flow client. |
keyring |
internal/keyring/ |
OS keyring access (Keychain, Secret Service, wincred). |
How it works
Token resolution precedence (highest priority first):
GH_TOKEN/GITHUB_TOKENenvironment variable.- Token in the OS keyring for the active host + user.
- Token in
hosts.yml(legacy or fallback). - No token (commands fail with
cmdutil.SilentErrorplus an auth-help message).
graph TD
A[Config.Authentication.Token] --> B{GH_TOKEN set?}
B -->|yes| C[return env value]
B -->|no| D{Keyring entry?}
D -->|yes| E[return keyring value]
D -->|no| F{hosts.yml has token?}
F -->|yes| G[return file value]
F -->|no| H[return empty + AuthError]Migration is lazy: when the loader notices a v1 layout it returns an upgraded copy and persists it before any command sees the data.
Integration points
- Constructed in
internal/ghcmd/cmd.go(config.NewConfig) and exposed via the factory'sConfiglazy func. - Consumed by every API call (
Config.Authentication().DefaultHost()andToken()), by the prompter (default git protocol), and by the browser (Config.Browser). - The auth check guard (
cmdutil.CheckAuthinpkg/cmdutil/auth_check.go) inspectsConfig.Authentication().HasActiveToken()and short-circuits with an exit-4 error when no token is available.
Entry points for modification
- New config key: extend
internal/config/config.goand surface getters/setters ongh.Config. Add coverage inconfig_test.go. - New auth source (e.g. cloud secret manager): extend
Authentication.Tokenprecedence and document behaviour indocs/multiple-accounts.md. - New OAuth scope: update the scope tables under
pkg/cmd/auth/shared/.
Key source files
| File | Purpose |
|---|---|
internal/config/config.go |
On-disk layout + accessors. |
internal/config/migration/migrate.go |
v1 -> v2 migration. |
internal/gh/gh.go |
The Config interface. |
internal/authflow/flow.go |
Device flow. |
internal/keyring/keyring.go |
OS keyring access. |
internal/ghinstance/host.go |
Default host helpers. |
Related pages
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.