gh auth login: Usage, Options & Common CI Errors
Authenticate the GitHub CLI - interactively, or with a token in CI.
gh auth login authenticates gh to GitHub.com or an Enterprise host. Interactively it runs a web/device flow; in CI you pass a token via stdin or the GH_TOKEN environment variable.
What it does
gh auth login establishes credentials for the GitHub CLI and (optionally) configures git to use gh as a credential helper. It supports a browser/device flow for humans and token-based auth for automation. Credentials are stored per host.
Common usage
# Interactive login (browser or device code)
gh auth login
# Non-interactive token login (pipe a PAT via stdin)
echo "$MY_PAT" | gh auth login --with-token
# Log in to a GitHub Enterprise Server host
gh auth login --hostname github.example.com
# In CI, the simplest path is just setting the env var:
# GH_TOKEN=$GITHUB_TOKEN gh pr listCommon error in CI: prompts for interactive input
In CI, gh auth login can fail with "could not prompt: terminal is not interactive" or hang waiting for a code. Fix: either pipe a token with gh auth login --with-token from a masked secret, or skip login entirely and set GH_TOKEN (github.com) / GH_ENTERPRISE_TOKEN (GHES) in the environment - gh reads those automatically. In GitHub Actions, setting GH_TOKEN to secrets.GITHUB_TOKEN is the standard pattern; ensure the workflow grants the needed permissions.
Key options
| Option | Purpose |
|---|---|
| --with-token | Read a token from stdin |
| --hostname HOST | Authenticate to an Enterprise host |
| --web | Use the browser-based flow |
| --scopes LIST | Request additional OAuth scopes |
Using this in CI
Cloud CLIs behave differently on a runner than on your laptop. They assume no interactive terminal, no cached credentials, and no browser for device-code flows, so the same command that works locally can hang or fail on a runner.
- Authenticate with a short-lived OIDC token rather than a long-lived static key. GitHub Actions can exchange
id-token: writefor cloud credentials with no stored secret. - Always pass the non-interactive flag. Most cloud CLIs will otherwise prompt and hang until the job times out.
- Pin the CLI version. Cloud CLIs change output formats between minor releases, and any script parsing that output will break silently.
- Set the output format explicitly (
--output json) rather than relying on the default, which can differ by version and configuration profile.