Open-Source Wikis

/

GitHub CLI

/

Systems

/

Config and auth (system view)

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 detection

Key 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):

  1. GH_TOKEN / GITHUB_TOKEN environment variable.
  2. Token in the OS keyring for the active host + user.
  3. Token in hosts.yml (legacy or fallback).
  4. No token (commands fail with cmdutil.SilentError plus 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's Config lazy func.
  • Consumed by every API call (Config.Authentication().DefaultHost() and Token()), by the prompter (default git protocol), and by the browser (Config.Browser).
  • The auth check guard (cmdutil.CheckAuth in pkg/cmdutil/auth_check.go) inspects Config.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.go and surface getters/setters on gh.Config. Add coverage in config_test.go.
  • New auth source (e.g. cloud secret manager): extend Authentication.Token precedence and document behaviour in docs/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.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Config and auth (system view) – GitHub CLI wiki | Factory