SSH sessions require re-login despite valid ~/.claude/.credentials.json (macOS Keychain unavailable)

Resolved 💬 5 comments Opened Mar 1, 2026 by sannc Closed Apr 10, 2026

Problem

When connecting to a macOS machine via SSH and starting Claude Code, the CLI prompts to /login even though valid credentials exist in ~/.claude/.credentials.json. This happens because macOS's Keychain is locked in SSH sessions (not bound to the GUI login session), so the CLI cannot retrieve the stored OAuth token.

Steps to Reproduce

  1. Log in to Claude Code on a macOS machine (subscription-based, not API key)
  2. SSH into the same machine from another device
  3. Run claude in any directory
  4. CLI prompts: "Please use /login"

Expected Behavior

The CLI should fall back to reading credentials from ~/.claude/.credentials.json when the macOS Keychain is unavailable (e.g., in SSH sessions). The file already exists, has correct permissions (-rw-------), and contains valid credentials — they are just not used.

Actual Behavior

The CLI ignores .credentials.json and requests re-authentication via /login.

Workaround

Manually unlock the Keychain before using Claude Code:

security unlock-keychain ~/Library/Keychains/login.keychain-db

Or add to ~/.zshrc:

if [ -n "$SSH_CONNECTION" ]; then
    security unlock-keychain ~/Library/Keychains/login.keychain-db 2>/dev/null || true
fi

Environment

  • macOS Darwin 25.2.0
  • Claude Code CLI (subscription auth / OAuth, not API key)
  • SSH session into local Mac

Impact

Users who work via SSH on their own Mac (common for developers using terminal multiplexers, remote access, etc.) are forced to re-authenticate on every new SSH session, which is especially painful with subscription-based auth (no ANTHROPIC_API_KEY fallback available).

Suggested Fix

When the macOS Keychain is unavailable or locked, fall back to reading credentials from ~/.claude/.credentials.json before prompting for re-login.

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗