Skip to content

fix(anthropic): keep OAuth callback on loopback#96917

Merged
steipete merged 7 commits into
openclaw:mainfrom
xialonglee:fix/issue-96485-oauth-callback-host
Jul 6, 2026
Merged

fix(anthropic): keep OAuth callback on loopback#96917
steipete merged 7 commits into
openclaw:mainfrom
xialonglee:fix/issue-96485-oauth-callback-host

Conversation

@xialonglee

@xialonglee xialonglee commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Anthropic OAuth allowed the local callback listener host to be configured without validating that it was loopback-only. The earlier PR revision also derived the OAuth redirect_uri from that bind host, but Anthropic's current client contract requires http://localhost:53692/callback even when the listener binds an equivalent loopback address.

Fixes #96485.

Why This Change Was Made

The callback bind address and provider redirect identity are separate contracts:

  • OPENCLAW_OAUTH_CALLBACK_HOST is validated only when login starts and accepts localhost, 127.0.0.1, or ::1;
  • the listener defaults to 127.0.0.1 and may bind any accepted loopback address;
  • authorization URLs, manual-code prompts, and token exchange always use Anthropic's required http://localhost:53692/callback.

This is smaller and safer than deriving the redirect URI from local bind configuration. Direct inspection of the installed Claude Code 2.1.201 client confirmed the same contract: localhost redirect URI, loopback listener. Anthropic's public Claude Code issue #11469 documents the localhost callback behavior as well.

User Impact

Invalid/non-loopback callback hosts fail only when Anthropic login starts, so unrelated CLI imports and commands remain unaffected. Operators can still choose IPv4 or IPv6 loopback binding without changing the provider-visible redirect URI.

Evidence

  • Blacksmith Testbox tbx_01kwt6qx4r4ptdbg4ps3yhnj55: src/llm/utils/oauth/anthropic.test.ts, 11/11 passed.
  • The focused suite opens a real TCP callback listener on 127.0.0.1:53692, sends an HTTP callback, and verifies both authorization and token-exchange requests use the fixed localhost redirect URI.
  • Remote oxfmt --check passed for source and tests.
  • Fresh full-diff autoreview: no actionable findings, confidence 0.96.
  • git diff --check passed.

Live Anthropic token exchange was not run because it requires an interactive user credential. No docs change is needed; the Unreleased changelog entry is included.

@clawsweeper

clawsweeper Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 5, 2026, 8:20 PM ET / 00:20 UTC.

Summary
The PR restricts Anthropic OAuth callback binding to explicit loopback hosts, keeps the provider-facing redirect URI fixed at localhost, adds callback-host tests, and adds a changelog entry.

PR surface: Source +12, Tests +82, Docs +1. Total +95 across 3 files.

Reproducibility: yes. Source inspection on current main and v2026.6.11 shows the listener host can diverge from the fixed localhost redirect URI; I did not run a live Anthropic login.

Review metrics: 1 noteworthy metric.

  • Auth Env Surface: 1 tightened, 0 added, 0 removed. The PR narrows accepted values for an existing OAuth environment variable, so maintainers need to review upgrade and operator compatibility before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #96485
Summary: This PR is the candidate fix for the open Anthropic OAuth callback-host and redirect-URI mismatch security report.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted current-head terminal logs or live output for invalid-host rejection and an allowed loopback callback path.
  • Include enough diagnostic output to show the callback and redirect_uri behavior without exposing private tokens, IPs, or account details.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body reports focused Testbox coverage with a real local TCP callback request, but the token exchange is mocked and there is no redacted current-head CLI/login proof for the changed auth flow. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Existing users or operators with a non-loopback OPENCLAW_OAUTH_CALLBACK_HOST will now fail closed when Anthropic OAuth login starts instead of attempting that bind.
  • [P1] The patch depends on Anthropic/Claude Code accepting the fixed localhost redirect URI while OpenClaw may bind an equivalent loopback address; the source and package probes support this, but current-head real CLI/login proof is still missing.
  • [P1] The PR body proof is a Testbox suite with mocked token exchange, not redacted live CLI output or a real Anthropic login path.

Maintainer options:

  1. Add Current-Head Auth Proof Before Merge (recommended)
    Refresh the PR body with redacted terminal logs or live output showing invalid-host rejection and a permitted loopback callback path on the current head.
  2. Accept The Fail-Closed Env Change
    Maintainers can explicitly accept that non-loopback callback-host overrides which current main attempted will now stop at Anthropic login startup.
  3. Pause For Callback Surface Redesign
    Pause or close this PR if the team wants to remove or redesign the callback-host override rather than preserve a loopback-only compatibility surface.

Next step before merge

  • [P1] Manual review is needed because the remaining blockers are auth compatibility/security acceptance and contributor real-behavior proof, not a narrow code defect for automated repair.

Maintainer decision needed

  • Question: Should Anthropic OAuth reject all non-loopback OPENCLAW_OAUTH_CALLBACK_HOST values while keeping the provider-visible redirect URI fixed at http://localhost:53692/callback?
  • Rationale: This changes an auth-provider environment surface from permissive to fail-closed and relies on a provider redirect contract that mocked tests and source inspection cannot fully validate for existing users.
  • Likely owner: steipete — steipete is assigned and authored the latest behavior-shaping commits on this PR, making him the best current owner for the auth compatibility decision.
  • Options:
    • Accept After Proof (recommended): Require redacted current-head CLI/login proof for invalid-host rejection and an allowed loopback callback path, then accept the fixed-localhost redirect contract.
    • Require Stronger Provider Evidence: Ask for live Anthropic or installed-client evidence that localhost is the required redirect URI for the supported loopback binds before merge.
    • Pause For Auth Redesign: Pause this PR if the desired direction is to remove or redesign the Anthropic callback-host override instead of hardening it narrowly.

Security
Cleared: No concrete security or supply-chain regression was found in the diff; the auth-provider compatibility and proof questions are tracked as merge risk.

Review details

Best possible solution:

Land the narrow loopback-only callback fix after maintainers accept the fail-closed auth-env compatibility tradeoff and current-head real CLI/login proof demonstrates invalid-host rejection plus at least one permitted loopback callback path.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection on current main and v2026.6.11 shows the listener host can diverge from the fixed localhost redirect URI; I did not run a live Anthropic login.

Is this the best way to solve the issue?

Unclear until maintainer acceptance and real proof. The patch is a narrow and plausible hardening fix, but the fail-closed environment change and fixed-localhost provider contract need explicit acceptance before merge.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 04a6a318591c.

Label changes

Label justifications:

  • P2: This is scoped Anthropic auth-provider hardening with limited blast radius, not a broad runtime outage or confirmed emergency bypass.
  • merge-risk: 🚨 compatibility: The PR rejects callback-host environment values that current main and the latest release would attempt to use.
  • merge-risk: 🚨 auth-provider: The changed path controls Anthropic OAuth login, callback receipt, and token-exchange redirect_uri behavior.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body reports focused Testbox coverage with a real local TCP callback request, but the token exchange is mocked and there is no redacted current-head CLI/login proof for the changed auth flow. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +12, Tests +82, Docs +1. Total +95 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 1 20 8 +12
Tests 1 83 1 +82
Docs 1 1 0 +1
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 104 9 +95

What I checked:

Likely related people:

  • steipete: Live PR data shows steipete is assigned, authored the latest branch commits that shape the callback-host behavior, and has multiple recent merged commits in Anthropic auth/setup history. (role: assigned reviewer and recent Anthropic auth contributor; confidence: high; commits: 838ca379dbbb, b8d372b62d4f, 19933024da0a; files: src/llm/utils/oauth/anthropic.ts, src/llm/utils/oauth/anthropic.test.ts, extensions/anthropic/register.runtime.ts)
  • Vincent Koc: The current Anthropic OAuth helper and tests enter this checkout through the v2026.6.11 release commit authored by Vincent Koc, and adjacent Anthropic provider history includes multiple Vincent-authored refactors and fixes. (role: current-main OAuth area contributor; confidence: medium; commits: e085fa1a3ffd, 7e7460c2f9e1, 9efc03343477; files: src/llm/utils/oauth/anthropic.ts, src/llm/utils/oauth/anthropic.test.ts, extensions/anthropic/register.runtime.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (5 earlier review cycles)
  • reviewed 2026-06-26T07:23:07.106Z sha d938725 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-05T23:06:57.290Z sha ffbe0ba :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-05T23:14:48.951Z sha ffbe0ba :: needs real behavior proof before merge. :: [P2] Rename the test hook so lint can pass | [P2] Narrow the mocked request body before parsing
  • reviewed 2026-07-05T23:32:47.824Z sha 8cf8fe4 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-05T23:53:21.687Z sha 2b9ebd5 :: needs real behavior proof before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jun 26, 2026
@xialonglee

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jun 26, 2026
@steipete steipete self-assigned this Jul 5, 2026
@steipete
steipete force-pushed the fix/issue-96485-oauth-callback-host branch from d938725 to 34d4036 Compare July 5, 2026 22:54
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 5, 2026
@steipete
steipete force-pushed the fix/issue-96485-oauth-callback-host branch from ffbe0ba to 8cf8fe4 Compare July 5, 2026 23:19
@steipete steipete changed the title fix(anthropic): restrict OAuth callback host to loopback addresses and derive redirect URI fix(anthropic): keep OAuth callback on loopback Jul 5, 2026
@steipete
steipete force-pushed the fix/issue-96485-oauth-callback-host branch 5 times, most recently from 1993302 to 0aa16e3 Compare July 6, 2026 01:38
@steipete
steipete force-pushed the fix/issue-96485-oauth-callback-host branch from 0aa16e3 to 36d34e7 Compare July 6, 2026 01:39
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Land-ready at exact head 36d34e717d3ec73a8e83bf8b7ba2e49794f40e4a.

The callback listener and provider redirect are separate contracts: the listener binds only to localhost, 127.0.0.1, or ::1, while authorization, manual guidance, and token exchange consistently use Anthropic's fixed http://localhost:53692/callback redirect. Validation occurs inside login so importing the provider cannot fail because of an unrelated environment override.

Proof:

  • direct inspection of installed Claude Code 2.1.201 confirmed a fixed localhost redirect and loopback listener contract;
  • Blacksmith Testbox: 12 focused cases passed, including a real TCP callback through the listener and token exchange;
  • Blacksmith Testbox: targeted oxlint and oxfmt passed after the final test-surface cleanup;
  • fresh rebased-tree autoreview: clean, confidence 0.96;
  • native review artifacts: validated, zero findings;
  • exact-head hosted CI: green.

No live Anthropic token exchange was run because that requires an interactive user credential; the network callback and redirect propagation are exercised end to end with the mocked token endpoint.
The release-note entry and @xialonglee credit are deferred to the grouped maintainer changelog after code landing to avoid repeated merge starvation from unrelated concurrent changelog updates.

@steipete
steipete merged commit 2b773a6 into openclaw:main Jul 6, 2026
96 checks passed
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

@xialonglee
xialonglee deleted the fix/issue-96485-oauth-callback-host branch July 6, 2026 01:59
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 6, 2026
* fix(anthropic): restrict OAuth callback host to loopback addresses and derive redirect URI

* fix(anthropic): restore localhost as default OAuth callback host to match shipped behavior

* fix(anthropic): defer OAuth callback host validation to login path

* refactor(anthropic): bind callback host independently

Co-authored-by: xialonglee <[email protected]>

* docs(changelog): note Anthropic callback fix

Co-authored-by: xialonglee <[email protected]>

* fix(oauth): satisfy Anthropic callback lint

Co-authored-by: xialonglee <[email protected]>

* chore: defer Anthropic OAuth changelog

---------

Co-authored-by: Peter Steinberger <[email protected]>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
* fix(anthropic): restrict OAuth callback host to loopback addresses and derive redirect URI

* fix(anthropic): restore localhost as default OAuth callback host to match shipped behavior

* fix(anthropic): defer OAuth callback host validation to login path

* refactor(anthropic): bind callback host independently

Co-authored-by: xialonglee <[email protected]>

* docs(changelog): note Anthropic callback fix

Co-authored-by: xialonglee <[email protected]>

* fix(oauth): satisfy Anthropic callback lint

Co-authored-by: xialonglee <[email protected]>

* chore: defer Anthropic OAuth changelog

---------

Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] OAuth callback host/URI inconsistency allows authorization code interception (V-01)

2 participants