Claude Code stores OAuth tokens differently per platform. Here's how to access them manually.
| Platform | Storage | Location |
|---|---|---|
| macOS | Encrypted Keychain | Service: Claude Code-credentials |
| Linux | JSON file | ~/.claude/.credentials.json |
| Windows (WSL) | JSON file | ~/.claude/.credentials.json (inside WSL) |
| Windows (native) | JSON file | %USERPROFILE%\.claude\.credentials.json |
Note: On macOS, Claude Code actively deletes
~/.claude/.credentials.jsonand migrates credentials into the Keychain. Don't expect the file to persist on Mac.
All platforms store the same JSON structure:
{
"claudeAiOauth": {
"accessToken": "sk-ant-oat01-...",
"refreshToken": "sk-ant-ort01-...",
"expiresAt": 1748276587173,
"scopes": ["user:inference", "user:profile"]
}
}Read:
security find-generic-password -s "Claude Code-credentials" -wWrite:
security add-generic-password -U -s "Claude Code-credentials" -a "$USER" -w '{
"claudeAiOauth": {
"accessToken": "sk-ant-oat01-YOUR_TOKEN",
"refreshToken": "sk-ant-ort01-YOUR_REFRESH_TOKEN",
"expiresAt": 1748276587173,
"scopes": ["user:inference", "user:profile"]
}
}'Delete:
security delete-generic-password -s "Claude Code-credentials"If you're SSH'd into a Mac, you may need to unlock the Keychain first:
security unlock-keychain ~/Library/Keychains/login.keychain-db
Read:
cat ~/.claude/.credentials.jsonWrite:
mkdir -p ~/.claude
cat > ~/.claude/.credentials.json << 'EOF'
{
"claudeAiOauth": {
"accessToken": "sk-ant-oat01-YOUR_TOKEN",
"refreshToken": "sk-ant-ort01-YOUR_REFRESH_TOKEN",
"expiresAt": 1748276587173,
"scopes": ["user:inference", "user:profile"]
}
}
EOF
chmod 600 ~/.claude/.credentials.json
chmod 700 ~/.claudeDelete:
rm ~/.claude/.credentials.jsonRead:
Get-Content "$env:USERPROFILE\.claude\.credentials.json"Write:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.claude" | Out-Null
@'
{
"claudeAiOauth": {
"accessToken": "sk-ant-oat01-YOUR_TOKEN",
"refreshToken": "sk-ant-ort01-YOUR_REFRESH_TOKEN",
"expiresAt": 1748276587173,
"scopes": ["user:inference", "user:profile"]
}
}
'@ | Set-Content "$env:USERPROFILE\.claude\.credentials.json"Delete:
Remove-Item "$env:USERPROFILE\.claude\.credentials.json"For Windows via WSL, follow the Linux instructions inside your WSL distro.
Skip credential files entirely by exporting the token:
export CLAUDE_CODE_OAUTH_TOKEN="sk-ant-oat01-YOUR_TOKEN"
⚠️ This silently overrides any stored credentials. If you set this once and forget, you'll get confusing auth errors months later when the token expires.
For CI/CD and headless environments:
claude setup-tokenThis opens a browser for OAuth, then outputs a long-lived token you can export as CLAUDE_CODE_OAUTH_TOKEN. Useful for GitHub Actions, Docker containers, and remote servers.
- Docker / Devcontainers — Containers can't access the macOS Keychain. Export the token from your host and inject it into the container via
credentials.jsonorCLAUDE_CODE_OAUTH_TOKEN. - SSH into macOS — SSH sessions can't reach the Keychain by default. Either unlock the keychain (
security unlock-keychain) or write acredentials.jsonmanually. - CI/CD Pipelines — GitHub Actions, GitLab CI, etc. need a token injected as a secret. Use
claude setup-tokento generate a long-lived one. - Multi-machine sync — Copy credentials across dev machines without re-authenticating on each.
- Debugging auth issues — When Claude Code says "Missing API key" but you just logged in, inspecting the raw token helps pinpoint the problem (wrong service name, expired token, env var override, etc.).
- Backup before reinstall — Save your token before nuking
~/.claudeso you can restore without re-auth.
A common pattern for running Claude Code in containers from a Mac host:
# 1. Extract token from macOS Keychain
CREDS=$(security find-generic-password -s "Claude Code-credentials" -w)
# 2. Inject into container
docker run -it \
-e CLAUDE_CODE_OAUTH_TOKEN="$(echo $CREDS | jq -r '.claudeAiOauth.accessToken')" \
your-claude-container
# OR mount as a file
echo "$CREDS" > /tmp/claude-creds.json
docker run -it \
-v /tmp/claude-creds.json:/root/.claude/.credentials.json:ro \
your-claude-containerLast verified: Feb 2026 · Claude Code v2.1.x