Claude Code Authentication: Every Login Method Explained

It follows a fixed precedence order: cloud provider credentials first, then a bearer auth token, then an API key, then an apiKeyHelper script, then a long-lived OAuth token, then Anthropic profile and federation credentials, and finally the subscription login. A signed-in gateway session sits outside the list and outranks everything.
Run the setup-token command, which opens the same browser authorisation flow as signing in and prints a one-year OAuth token. Set it as the OAuth token environment variable in your pipeline. It authenticates with your subscription, can only make model requests, and is not read in bare mode.
On macOS in the encrypted system Keychain. On Linux in a credentials file under your Claude directory with mode 0600. On Windows in the same file under your user profile directory, inheriting its access controls. Setting a custom config directory moves the file on Linux and Windows.
Set the login method and organisation UUID keys in managed settings. Note the gaps: token minting and the GitHub app path enforce only the method key, Console logins are only pre-selected rather than verified, and gateway sign-in is selected by the method key rather than restricted by it.
You get a startup warning three days out, which never blocks a request. Once the login actually expires, every request fails until you sign in again. This matters most for unattended work: a background or Remote Control session that outlives its login stops making progress and cannot recover on its own.

Key Takeaway
Claude Code can authenticate with a claude.ai subscription, a Console API key, a bearer token, an apiKeyHelper script, a long-lived OAuth token, an Anthropic profile, or a cloud provider — and when several are present it picks one by a fixed precedence order. Knowing that order is what turns most authentication confusion into a one-line fix.
A colleague once spent two days convinced their Max subscription had stopped working. Their requests were being billed to a Console organisation that had been disabled months earlier, because an API key was still exported in a shell profile from a project they had finished. Claude Code was behaving exactly as documented. The documentation for that behaviour is one table, and neither of us had read it.
So here is that table and everything around it: the precedence order, where credentials are stored on each operating system, how to authenticate a CI pipeline without a browser, running a script for rotating credentials, restricting login to your organisation and the paths where that restriction is weaker than it looks, and what happens when a login expires under an unattended session.
When more than one credential is present, Claude Code chooses in a fixed order, and the top of that list beats everything below it. A signed-in gateway session sits outside the list entirely: it is a provider selection and it outranks all of them, so when one exists none of the credential sources below are used at all.
The precedence order, highest first:
| Credential | What it is for |
|---|---|
| Cloud provider credentials | Selected by the provider environment variable for Bedrock, Google Cloud or Foundry. Nothing below is consulted |
| A bearer auth token | Sent as an Authorization header. For routing through a gateway or proxy that authenticates with bearer tokens rather than API keys |
| An API key | Sent as an API key header. In interactive mode you approve it once and the choice is remembered; in non-interactive mode it is always used when present |
| An apiKeyHelper script | For dynamic or rotating credentials, such as short-lived tokens from a vault |
| A long-lived OAuth token | Generated for CI and scripts. Read again in every new session until you remove it from your shell profile or settings |
| Profiles, then the subscription login | Anthropic profile and federation credentials rank above a login in most configurations. The subscription login from the sign-in flow is the default and the last resort |
The consequence worth internalising: an API key in your environment beats your subscription once approved. If it belongs to a disabled or expired organisation, your requests fail in a way that looks like your account is broken. Removing the variable and checking which credential is active takes ten seconds and is the correct first move every time.
Storage differs by platform, and all three are managed through the sign-in and sign-out commands rather than by editing files. If you are trying to point requests at a different endpoint, the base URL environment variable is the mechanism — editing the credential file is not.
# Where the credential actually lives
macOS the encrypted system Keychain
Linux ~/.claude/.credentials.json mode 0600
Windows %USERPROFILE%\.claude\.credentials.json
(inherits your profile directory's access controls)
# CLAUDE_CONFIG_DIR moves the file on Linux and Windows.
# Claude Code manages it through /login and /logout — to send
# requests somewhere else, set ANTHROPIC_BASE_URL instead of
# editing this file.
/status # which credential is active, and for which org
/login # sign in, or renew a login about to expire
/logout # sign out; also resets first-launch setup stateCI has no browser, so there are two supported routes and they suit different situations. A long-lived token is the simple one: it authenticates with your subscription, lasts a year, and is generated by a command that opens the same browser flow you use interactively. A credential helper is the right answer when tokens rotate.
# For CI, a browser login is not available. Mint a token:
claude setup-token
export CLAUDE_CODE_OAUTH_TOKEN=your-token
# - one year, tied to a Pro, Max, Team or Enterprise plan
# - the command does NOT save it anywhere; copy it yourself
# - MODEL REQUESTS ONLY: it cannot establish Remote Control
# sessions or fetch claude.ai connectors. Locally configured
# MCP servers still work
# - bare mode does NOT read it — use an API key or a helper
# For rotating credentials from a vault, run a script instead:
{ "apiKeyHelper": "/usr/local/bin/fetch-claude-key.sh" }
CLAUDE_CODE_API_KEY_HELPER_TTL_MS=… # default: 5 min, or on 401
# Over 10 seconds to return and you get a warning in the prompt
# bar. Three failed attempts and requests fail outright.The long-lived token has deliberate limits worth planning around. It can only make model requests, so it cannot establish Remote Control sessions or fetch claude.ai connectors — locally configured MCP servers still work. And bare mode does not read it at all, so a script that passes that flag needs an API key or a helper instead. Neither limitation is a bug; both surprise people once.
Two managed settings keys direct which login method developers use and require claude.ai logins to belong to a specific organisation. They are the right tool, and they have gaps that are worth knowing before you rely on them as a control:
The same settings also decide whether a session using no login credential can start at all. An environment API key, a bearer token or a credential helper is blocked at startup, because organisation membership cannot be verified for an environment credential. That is a genuinely useful property: it stops a developer bypassing your organisation restriction by exporting a personal key.
Two things are not blocked. Cloud provider sessions start normally, because they authenticate against your cloud rather than against Anthropic — restrict those through your cloud identity and access policies. And Anthropic profile and federation credentials are not blocked either, and the keys do not check which organisation the profile belongs to.
A login within three days of expiring produces a startup warning telling you to renew. The warning never blocks a request — authentication keeps working until the login actually expires, after which every request fails until you sign in again. You can see the state before that happens: the status command shows an expired-login row along with the organisation and email it has saved.
Renewing early matters most for anything unattended. A background session or a Remote Control session that outlives its login stops making progress the moment the credential expires and cannot recover until a person signs in. If you run long autonomous work, treat the three-day warning as a task rather than a notice.
If your organisation uses Workload Identity Federation or the Anthropic CLI, a named profile or a pair of federation variables can supply the credential, and both rank above your login. One rule is worth knowing: an active profile written by an interactive Anthropic CLI login ranks below a working sign-in credential, specifically so a leftover profile does not silently move your requests off the account you signed in to. While any of these is selected, features that need your claude.ai login are unavailable.
Learn the precedence order and check which credential is active before you change anything — between them those two habits resolve most authentication problems in under a minute. For CI, mint a token rather than shipping an API key, and know its two limits. And if you are an administrator, read what the organisation restriction keys actually enforce on each login path, because the gaps are specific and they are not the paths you would guess.
Sources & further reading