Skip to content

feat(runtime): warn admins before a Claude Code login expires (v0.450.0) - #846

Merged
vikasprogrammer merged 1 commit into
mainfrom
feat/login-expiry-warning
Oct 3, 2026
Merged

vikasprogrammer merged 1 commit into
mainfrom
feat/login-expiry-warning

Conversation

@vikasprogrammer

Copy link
Copy Markdown
Owner

Problem

Every claude login has a refresh token with a fixed lifetime (claudeAiOauth.refreshTokenExpiresAt), and using the account doesn't extend it. On instapods, tools refreshed its access token all day on 10-02 and its expiry didn't move. When that date passes, Claude Code wipes the record and every run is refused.

  • expresstech: the box default died at 2026-10-02 23:14 UTC while running 6–30 sessions a day.
  • instapods: the tools2-new pool account died the same way on 09-26.

Both were found only by the refusal card, after runs had already stopped, even though the date had been sitting in the credential file all along.

Change

  • src/edge/login-expiry.ts: an hourly sweep that spawns nothing, run off the scheduler tick. It reads the expiry for the box default and every enabled credential-dir pool account.
    • It posts one admin card per login on entering each band: 7 → 3 → 1 day → expired. Each card replaces the previous one.
    • The runtime.login.expiring audit trail guards against repeats, so a restart doesn't re-alarm.
    • Signing in again closes the card and records runtime.login.renewed.
    • A login Claude Code has already wiped is left to the existing launch-path cards, so the same news isn't posted twice.
    • Each card carries the exact CLAUDE_CONFIG_DIR=… claude /login command, with a Keychain/ssh hint on macOS only.
  • Settings → Runtime: shows "login expires in N days" for each account and for the box default (amber within a week, red once dead). GET /api/runtime-accounts now returns loginExpiresAt/loginDead per account plus boxDefault.
  • The v0.449.1 "signed out" card's Keychain hint now appears only on macOS.

Test

New test scripts/login-expiry-test.cjs (25 checks, file-based credentials, CI-portable), added to test:governance. The full suite and the web build pass.

🤖 Generated with Claude Code

Claude Code logins carry a fixed refreshTokenExpiresAt that use does not
extend; the expresstech box default died at its date mid-use and was found
only by the refusal card. An hourly spawn-free sweep now reads that date
for the box default and each enabled pool account and raises one admin
card per login at 7/3/1 days and on expiry (superseding, audit-guarded),
closing it when the login is renewed. Settings -> Runtime shows the expiry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vikasprogrammer
vikasprogrammer merged commit 7ad7d4e into main Oct 3, 2026
1 check passed
@vikasprogrammer
vikasprogrammer deleted the feat/login-expiry-warning branch October 3, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant