feat: Claude /login subscription billing for claude_code (openlock-ndb)#67
Conversation
…com/cai authorize, platform.claude.com redirect/token, CLAUDE_AI scopes)
|
…etached session meta (review)
…import), not setup-token
…rofile export', import only when absent (fixes reattach/re-seed crash)
…attach) hung any piped/CI stdout capture (sleep-infinity child held the pipe open)
…uard against outlives-CLI stdout-inherit hangs (openlock-sqw)
Status: steps 1–2 DONE, CI green ✅ — remaining gates require the maintainer
Done autonomously:
main, taggedv0.6.5,openlock-release.ymlpublished all binaries.OPENSHELL_FORK_TAGbumpedv0.6.4→v0.6.5(4ba4e4c). CI now downloads the value_prefix-capable binary.test,Analyze,CodeQL, and bothlive-integration(docker + podman) pass against the v0.6.5 binary (live gateway+sandbox cred_inject exercised end-to-end).Remaining (maintainer-only):
mainbranch protection requires maintainer review/approval.Summary
Replaces openlock's
claude setup-token(API-billing) path with a host-side OAuth/loginflow so a sandboxed Claude Code bills the user's Claude subscription, with the real token never entering the sandbox.End-to-end flow:
openlock login --provider anthropicruns a host-side OAuth PKCE paste-back flow (hosted callbackplatform.claude.com/oauth/code/callback, no localhost) → real access+refresh token pair.ANTHROPIC_BEARER_TOKEN+ arefreshblock.ensure-providerimports a runtimeclaude-oauthprofile and seeds the gateway once (never-clobber), wiring the gateway's native OAuth refresher..credentials.json+CLAUDE_CONFIG_DIR→ flips Claude Code into OAuth mode.Authorizationand re-injectsAuthorization: Bearer <raw token>viavalue_prefix: "Bearer "(fork v0.6.5).Breaking / behavior changes (for release notes)
credentials.jsonlossy-migrated: a legacy setup-token is dropped on migration → user re-runsopenlock login.claude_code-only.Remaining e2e checklist (maintainer, real account)
openlock login --provider anthropic→ record hasrefresh; access token not loggedopenshell provider refresh statusshowsoauth2_refresh_token, configured, token_url setclaude --debug→ OAuth mode (not "Skipped: no usable OAuth"); completion succeedsanthropic-beta: ...oauth-2025-04-20...; bills sub base bucket (overage-status: rejected,unified-5h-status: allowed); exactly oneAuthorizationheader.credentials.jsonnever leaves sandbox; real token never enters itCloses openlock-ndb (after merge). Fork: vessux/OpenShell#8 (merged, v0.6.5).