This release fixes issues for SREs watching stability and regressions.
✓ No known CVEs patched in this version
Topics
+13 more
Affected surfaces
Summary
AI summaryFixes false "not logged in" block for Claude Code native/macOS Keychain login.
Full changelog
Fix: native/Keychain Claude login no longer misread as "not logged in"
-
loki startno longer falsely blocks a genuinely logged-in user. The auth
preflight assumed the Claude Code OAuth login always lives in
~/.claude/.credentials.json. That is false for the native Claude Code install
(2.x on macOS), which stores the login in the macOS Keychain (service
"Claude Code-credentials") and writes NO.credentials.json. A subscription
user who was fully logged in was told "Claude Code is installed but not logged
in -- the build would stall" and blocked from every build: the exact opposite
of the zero-friction intent. -
The preflight now asks the CLI's own local auth-status first. A new
_loki_claude_login_state()helper (autonomy/run.sh) prefersclaude auth status(zero-network, ~0.2s, JSON"loggedIn"), which is authoritative for
BOTH the file-based and the native/Keychain login, then falls back to the
credentials file, then to a macOS Keychain existence check (existence only,
never reading the secret, so it can never trigger a GUI keychain prompt that
would hang a headless build). Critically it applies "inconclusive never
false-fails" to auth: it hard-blocks ONLY on positive evidence of no login
("loggedout") or an expired token ("expired"); when the state cannot be proven
("unknown", e.g. an older CLI on a non-macOS box with no file) it fails OPEN
and proceeds, so a real login is never blocked on uncertainty.claude login
guidance and theLOKI_SKIP_AUTH_PREFLIGHT=1/ANTHROPIC_API_KEYopt-outs
are unchanged. -
A stale expired credentials file never overrides a live Keychain login.
The native install can leave a now-expired~/.claude/.credentials.jsonnext
to a valid Keychain login (it rotates the Keychain, not the file). The helper
therefore checks the Keychain (a positive signal) BEFORE concluding "expired"
from the file: a valid file -> logged in; else a Keychain entry -> logged in;
only with neither is an expired file treated as genuinely expired. Genuine
expiry (expired file, no Keychain) still returns "expired", so the 401-avoiding
fast-fail is preserved. -
loki doctornow affirmatively confirms the login, on BOTH the bash and Bun
routes. Both readclaude auth status, so each shows "Claude CLI is logged in
(subscription/OAuth login)" for a Keychain-backed login (previously the bash
route fell through to a neutral "ANTHROPIC_API_KEY not set" line and the Bun
route wrongly reported "login EXPIRED" for a Keychain login), warns on a genuine
logged-out or expired state, and keeps the file-based expiry fallback for older
CLIs. The bash<->Bun doctor output stays byte-identical (enforced by the
bun-parity matrix). -
Regression coverage:
tests/test-claude-login-state.shextracts the real
_loki_claude_login_state()helper from run.sh and drives every login state
with fakeclaudeANDsecuritybinaries on PATH (fully deterministic,
independent of the machine's real login). The cases: auth-status logged in
(no file); auth-status logged out; valid JSON with no explicitloggedIn
boolean plus a valid file (must fall through to logged in, never a false hard
block); valid file; expired file with no keychain (-> expired); expired file
WITH a live keychain (-> logged in: the regression guard that a stale file
never overrides a real Keychain login); keychain-only with no file; and the
confident-logout path. Proves the exact user-reported scenario (logged in, no
.credentials.json) no longer blocks.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About Loki Mode
Multi-agent autonomous SDLC framework. Spec to deployed app. PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief. 5 AI providers, 11 quality gates.
Related context
Related tools
Beta — feedback welcome: [email protected]