feat(oauth): add automatic OAuth token refresh for Claude API credentials#1725
Open
Saxin wants to merge 1 commit intoqwibitai:mainfrom
Open
feat(oauth): add automatic OAuth token refresh for Claude API credentials#1725Saxin wants to merge 1 commit intoqwibitai:mainfrom
Saxin wants to merge 1 commit intoqwibitai:mainfrom
Conversation
…ials NanoClaw uses Claude's OAuth tokens (sk-ant-oat01-...) from ~/.claude/.credentials.json to authenticate containers. Without refresh, tokens expire and containers receive 401 errors. This adds src/oauth-token.ts with ensureFreshOAuthToken(): - Reads the OAuth token from ~/.claude/.credentials.json - Calls platform.claude.com/v1/oauth/token with grant_type=refresh_token, client_id, and scope fields (all required by the endpoint) - Writes the new access_token and rotating refresh_token back to credentials.json - Syncs the fresh token into an OneCLI secret (ONECLI_OAUTH_SECRET_ID) so containers always receive a valid credential Wired up in two places: - container-runner.ts: refresh on every container launch (on-demand) - index.ts: background setInterval every 30 min (prevents expiry during inactivity when no containers are launched for a long time) Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
pakkeiC
pushed a commit
to pakkeiC/nanoclaw
that referenced
this pull request
Apr 13, 2026
…ials Port of upstream PR qwibitai#1725. NanoClaw uses Claude OAuth tokens from ~/.claude/.credentials.json. Without refresh, tokens expire and containers receive 401 authentication errors. Changes: - src/oauth-token.ts: new ensureFreshOAuthToken() — reads credentials.json, calls platform.claude.com/v1/oauth/token with refresh_token grant, writes new access_token back to credentials.json, optionally syncs to OneCLI secret (ONECLI_OAUTH_SECRET_ID) for future OneCLI migration - src/credential-proxy.ts: read OAuth token dynamically from credentials.json on each proxied request instead of once at startup — prevents stale .env tokens from causing 401s - src/container-runner.ts: call ensureFreshOAuthToken() before each container launch (on-demand refresh) - src/index.ts: background setInterval every 30 min (prevents expiry during inactivity when no containers are launched) - src/config.ts: add ONECLI_BIN and ONECLI_OAUTH_SECRET_ID constants
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/oauth-token.tswithensureFreshOAuthToken()— refreshes Claude OAuth tokens from~/.claude/.credentials.jsonbefore they expire401 Invalid authentication credentialsDetails
The
platform.claude.com/v1/oauth/tokenendpoint requiresclient_idandscopefields in addition togrant_type+refresh_token— omitting them returns400 Invalid request format. The rotatingrefresh_tokenfrom the response is also written back tocredentials.json.Configuration via
.env:ONECLI_OAUTH_SECRET_ID— OneCLI secret ID to sync the fresh token into (optional; skip if not using OneCLI)Files changed
src/oauth-token.ts(new) — token refresh logicsrc/config.ts—ONECLI_OAUTH_SECRET_IDandONECLI_BINexportssrc/container-runner.ts— callensureFreshOAuthTokenbefore each container launchsrc/index.ts— background 30-min refresh intervalTest plan
ensureFreshOAuthToken(mockinghttps.requestandfs)🤖 Generated with Claude Code