Claude CLI přes SSH na macOS: keychain unlock a správné řešení
Původní zadání: Claude CLI / Claude Code přes SSH na macOS opakovaně žádá přihlášení nebo hlásí chybějící API klíč, i když uživatel už
/loginprovedl. Cílem je praktický interní postup, který jasně odliší doporučené řešení od nouzového workaroundusecurity unlock-keychain ~/Library/Keychains/login.keychain-db.
1. Krátké shrnutí problému
Na macOS ukládá Claude Code přihlašovací údaje z běžného subscription/OAuth loginu do šifrovaného macOS Keychainu. To je oficiálně popsané chování Claude Code: na macOS jsou credentials v encrypted macOS Keychainu; na Linuxu a Windows se používá soubor .credentials.json s lokálními oprávněními. [1]
V SSH/headless scénáři se může stát, že proces spuštěný přes terminál nemá přístup k odemčenému login keychainu. Praktický projev: Claude Code přes SSH znovu žádá /login, hlásí „Missing API key“ nebo ignoruje dříve funkční OAuth přihlášení. Tento scénář je popsaný v několika veřejných issue v repozitáři anthropics/claude-code, včetně hlášení explicitně pojmenovaného jako „macOS Keychain unavailable“ při SSH sessions. [3][4][5][6]
Krátká odpověď:
- Doporučené řešení: pro SSH/headless automatizaci nepoužívat interaktivní keychain login jako primární mechanismus; použít
claude setup-tokena proměnnouCLAUDE_CODE_OAUTH_TOKEN. [1][2] - Nouzový workaround: v konkrétní SSH session ručně odemknout login keychain příkazem
security unlock-keychain ~/Library/Keychains/login.keychain-db. Tento příkaz je ověřený jako workaround v issue reportech a odpovídá existenci příkazuunlock-keychainv macOSsecurityCLI. [3][4][7]
2. Co je ověřená příčina
Ověřený základ problému je kombinace těchto faktů:
- Claude Code na macOS ukládá OAuth/subscription credentials do šifrovaného macOS Keychainu. [1]
CLAUDE_CODE_OAUTH_TOKENje oficiální alternativa pro SDK/automatizovaná prostředí a má přednost před credentials uloženými v keychainu. [2]- Ve veřejných issue se opakovaně objevuje stejný vzorec: přes SSH nebo v nové shell session Claude Code neumí použít credentials uložené v macOS Keychainu, dokud se keychain neodemkne. [3][4][5][6]
- macOS
securityCLI má příkazunlock-keychain, který odemyká zadaný keychain. [7]
Praktická interpretace:
- Nejde primárně o to, že by
/loginnikdy neproběhl. - Nejde primárně o chybějící
.credentials.jsonjako na Linuxu. - Jde o to, že SSH/headless proces nemusí mít přístup k odemčenému macOS login keychainu, kde Claude Code na macOS hledá OAuth credentials. [1][3][4]
Co není ověřené:
- Není bezpečné tvrdit, že jeden konkrétní bug ID pokrývá všechny verze Claude Code a všechny macOS konfigurace.
- Není bezpečné tvrdit, že odemčení keychainu je dlouhodobě nejlepší řešení pro automatizaci; oficiální dokumentace naopak uvádí token přes environment variable jako variantu pro CI/scripts bez browser loginu. [1][2]
3. Relevantní varianty řešení
Varianta A — doporučené řešení: claude setup-token + CLAUDE_CODE_OAUTH_TOKEN
Oficiální dokumentace Claude Code uvádí CLAUDE_CODE_OAUTH_TOKEN jako OAuth access token pro Claude.ai autentizaci, alternativu k /login pro SDK a automated environments; token má přednost před keychain-stored credentials a generuje se přes claude setup-token. [1][2]
Použít, když:
- Claude Code běží přes SSH.
- Claude Code běží ve skriptu, CI, launchd jobu nebo jiné headless session.
- Potřebujeme stabilní chování bez ručního odemykání macOS keychainu.
Výhoda: obchází závislost na odemčeném GUI/login keychainu. [1][2]
Limit: token je citlivý secret; nesmí se commitovat do repozitáře, logovat ani sdílet v plain textu. Dokumentace ho popisuje jako long-lived OAuth token pro prostředí, kde není browser login. [1]
Varianta B — nouzový workaround: ruční odemčení login keychainu
Doslovný workaround:
security unlock-keychain ~/Library/Keychains/login.keychain-db
Tento workaround je uvedený ve veřejných issue reportech Claude Code pro macOS/SSH keychain problém a security unlock-keychain je legitimní macOS příkaz pro odemčení keychainu. [3][4][7]
Použít, když:
- Potřebujeme rychle opravit aktuální interaktivní SSH session.
- Chceme ověřit, že problém je opravdu v přístupu ke keychainu.
- Nechceme nebo zatím nemůžeme zavádět token workflow.
Nepoužívat jako hlavní dlouhodobý postup pro automatizaci. Je to per-session ruční zásah a pořád závisí na macOS keychainu. [3][4][7]
Varianta C — opakovat /login
/login je standardní subscription OAuth login cesta pro Claude Pro/Max/Team/Enterprise uživatele. [1]
Použít, když:
- Uživatel opravdu ještě přihlášený není.
- Přihlašovací údaje byly smazané, expirované nebo poškozené.
Nepoužívat jako hlavní workaround pro SSH keychain problém, pokud se chyba opakuje v každé nové SSH session. Veřejná issue ukazují právě scénář, kdy opakovaný login neřeší kořen problému s dostupností keychainu. [3][4][5]
Varianta D — API key místo Claude.ai OAuth
Claude Code podporuje více zdrojů autentizace, včetně API key / helper mechanismů a OAuth tokenu. [1]
Použít jen pokud organizace skutečně chce API-key režim a má k tomu správný billing/security model. Pro uživatele subscription OAuth není automaticky lepší než CLAUDE_CODE_OAUTH_TOKEN. [1][2]
4. Doporučený postup krok za krokem
Krok 1 — potvrdit symptom
V SSH session na macOS spusť:
claude
Pokud Claude Code znovu žádá /login, hlásí chybějící API key nebo se chová, jako by OAuth credentials nebyly dostupné, pokračuj dál. Veřejná hlášení popisují právě tento typ symptomu u SSH/macOS keychain scénáře. [3][5][6]
Krok 2 — krátká diagnostika workaroundem
V té samé SSH session spusť:
security unlock-keychain ~/Library/Keychains/login.keychain-db
Potom zkus znovu:
claude
Pokud se Claude Code po odemčení keychainu rozběhne bez opakovaného /login, je velmi pravděpodobné, že problém je dostupnost macOS login keychainu v SSH/headless session. Tento postup odpovídá veřejně reportovanému workaroundu. [3][4][7]
Krok 3 — zavést doporučený token režim
Na macOS stroji, kde uživatel může provést interaktivní přihlášení, vygeneruj long-lived token:
claude setup-token
Výsledný token nastav pro SSH/headless prostředí jako proměnnou:
export CLAUDE_CODE_OAUTH_TOKEN="...token..."
Claude Code dokumentace uvádí, že CLAUDE_CODE_OAUTH_TOKEN je OAuth token pro Claude.ai autentizaci, alternativa k /login pro SDK a automatizovaná prostředí, má přednost před keychain credentials a generuje se přes claude setup-token. [1][2]
Praktické uložení závisí na prostředí:
- pro ruční SSH: shell profile uživatele, např.
~/.zshrc, ale jen pokud je soubor bezpečně chráněný, - pro launchd/CI: secret store nebo protected environment configuration,
- nikdy ne commit do gitu ani sdílený dotfile.
Krok 4 — ověřit, že Claude Code bere token
V nové SSH session ověř:
env | grep '^CLAUDE_CODE_OAUTH_TOKEN=' >/dev/null && echo "token set"
claude
Očekávání: Claude Code už nemá být závislý na odemčeném keychainu, protože CLAUDE_CODE_OAUTH_TOKEN má podle dokumentace přednost před keychain-stored credentials. [2]
Krok 5 — odstranit workaround z běžného provozu
Pokud token režim funguje, nechej security unlock-keychain ... jen jako diagnostický/nouzový krok. Dlouhodobě je čistší, aby SSH/headless běh používal mechanismus určený pro automated environments. [1][2]
5. Kdy a proč použít jen workaround
Použij jen workaround:
security unlock-keychain ~/Library/Keychains/login.keychain-db
jen v těchto situacích:
- potřebuješ rychle pokračovat v aktuální SSH session,
- ověřuješ hypotézu „Claude Code nevidí macOS keychain“,
- token workflow zatím nejde zavést kvůli interním pravidlům nebo chybějícímu schválení.
Proč je to jen nouzovka:
- funguje per session a nemusí přežít novou SSH session nebo zamčení keychainu,
- opírá se o interaktivní stav macOS login keychainu,
- není to oficiálně doporučená cesta pro CI/scripts; pro automated environments dokumentace uvádí
CLAUDE_CODE_OAUTH_TOKEN. [1][2][3][4]
6. Rizika / limity / otevřené otázky
- Token je secret.
CLAUDE_CODE_OAUTH_TOKENje autentizační token; musí se chránit jako heslo/API klíč. Dokumentace ho popisuje jako long-lived OAuth token. [1][2] - Workaround může chtít heslo ke keychainu.
security unlock-keychainodemyká keychain; podle nastavení macOS může být potřeba zadat heslo. Samotná existence příkazu a účel jsou popsané vsecurity(1). [7] - Různé verze Claude Code se mohou lišit. GitHub issue jsou důkaz reálného chování u konkrétních verzí/konfigurací, ne garance stejného chování u všech budoucích verzí. [3][4][5][6]
- Apple Keychain heslo a login heslo mohou být oddělené. Apple dokumentace popisuje situace, kdy je potřeba aktualizovat keychain password, pokud se liší od uživatelského hesla. To může komplikovat ruční unlock. [8]
- Bare/headless nuance. Dokumentace autentizace zmiňuje i headless/bare mode nuance; pokud skript používá speciální režimy, ověř konkrétní auth flow proti aktuální dokumentaci. [1]
7. Zdroje
[1] Anthropic / Claude Code documentation — Authentication: https://code.claude.com/docs/en/authentication
[2] Anthropic / Claude Code documentation — Environment variables, CLAUDE_CODE_OAUTH_TOKEN: https://code.claude.com/docs/en/env-vars
[3] GitHub issue anthropics/claude-code #29816 — SSH sessions require re-login despite valid credentials, macOS Keychain unavailable; uvádí workaround security unlock-keychain ~/Library/Keychains/login.keychain-db: https://github.com/anthropics/claude-code/issues/29816
[4] GitHub issue anthropics/claude-code #9403 — macOS Keychain issue, OAuth authentication nepersistuje bez security unlock-keychain v session: https://github.com/anthropics/claude-code/issues/9403
[5] GitHub issue anthropics/claude-code #5957 — macOS Keychain: SSH Authentication Failure for Pro Plan Users: https://github.com/anthropics/claude-code/issues/5957
[6] GitHub issue anthropics/claude-code #5515 — Missing API key when SSH’ing into macOS; uvádí security unlock-keychain ~/Library/Keychains/login.keychain-db: https://github.com/anthropics/claude-code/issues/5515
[7] macOS security(1) man page — command line interface to keychains, unlock-keychain: https://keith.github.io/xcode-man-pages/security.1.html
[8] Apple Support — If you need to update your keychain password on Mac: https://support.apple.com/guide/keychain-access/change-keychain-password-kyca2429/mac