Skip to content

fix(gateway): deliver OAuth authorization URLs to non-terminal clients#94300

Closed
bkudiess wants to merge 1 commit into
openclaw:mainfrom
bkudiess:fix/wizard-oauth-auth-url
Closed

fix(gateway): deliver OAuth authorization URLs to non-terminal clients#94300
bkudiess wants to merge 1 commit into
openclaw:mainfrom
bkudiess:fix/wizard-oauth-auth-url

Conversation

@bkudiess

Copy link
Copy Markdown
Contributor

Summary

OAuth redirect-paste setup over the RPC wizard only printed the authorization URL to gateway stdout, so non-terminal clients (e.g. the Windows companion app) never received the link the user needs to sign in. This carries the generated authorization URL in-band in the wizard text prompt via a presentsAuthChallenge prompter capability. Terminal CLI logging is preserved.

Covers the shared OAuth helper plus Google, OpenAI ChatGPT/Codex, OpenRouter, Chutes, and MS Teams provider paths, with focused tests.

Clean re-open of #92234 on top of latest main. The previous branch was based on an older main and conflicted with refactor(wizard): hide prompt session types (f3ae525), which made WizardTextParams non-exported. This version reconciles WizardSessionPrompter.text() with the current inline param type. Supersedes #92234.

Change type

  • Bug fix

Scope

  • Gateway / orchestration
  • Auth / tokens
  • Integrations
  • UI / DX

Real behavior proof

Behavior addressed: RPC wizard OAuth setup now shows the generated authorization URL in the same text prompt that asks for the redirect URL, so non-terminal clients can complete sign-in.
Real environment tested: Windows companion app driving an OpenClaw gateway wizard OAuth flow, plus the local Windows OpenClaw worktree on latest main.
Exact steps or command run after this patch: Opened the Windows companion against the patched gateway, started a provider OAuth wizard flow that uses redirect-URL paste, confirmed the wizard prompt displayed the authorization URL before the redirect input, opened it in a browser, and completed the redirect paste step. Also ran, cold-cache, on latest main: pnpm tsgo:core; pnpm tsgo:core:test; node scripts/check-extension-package-tsc-boundary.mjs; node scripts/run-vitest.mjs run src/wizard/session.test.ts src/plugins/provider-oauth-flow.test.ts extensions/google/oauth.test.ts extensions/openai/openai-chatgpt-oauth.runtime.test.ts extensions/openrouter/oauth.test.ts src/commands/auth-choice.apply.plugin-provider.test.ts.
Evidence after fix: Human verification confirmed the Windows companion wizard showed the OAuth authorization URL inline with the redirect paste prompt. Local checks on latest main: tsgo:core and tsgo:core:test exit 0; extension package boundary check passed (114 plugins) exit 0; focused Vitest passed 5 shards, including forwards manual OAuth URLs into wizard text messages.
Observed result after fix: The Windows companion flow exposed the authorization URL in the wizard prompt and the redirect paste step could be completed.
What was not tested: Full-repository pnpm check and pnpm test, and every provider's live OAuth service.

Compatibility

  • Backward compatible? Yes — terminal logging is unchanged and the presentsAuthChallenge capability is additive.
  • Config/env changes? No.
  • Migration needed? No.

Security impact

The authorization URL was already intentionally shown/logged for user action; this carries the same non-secret authorization URL in the wizard prompt message. The secret-bearing redirect URL remains user input. No new permissions, secrets handling, network calls, or execution surface.

AI-assisted: Yes.

@openclaw-barnacle openclaw-barnacle Bot added the triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. label Jun 17, 2026
@bkudiess
bkudiess force-pushed the fix/wizard-oauth-auth-url branch from 227c734 to bab4196 Compare June 18, 2026 19:43
@bkudiess bkudiess changed the title fix(gateway): include OAuth authorization URL in wizard prompts fix(gateway): deliver OAuth authorization URLs to non-terminal clients Jun 18, 2026
@bkudiess

Copy link
Copy Markdown
Contributor Author

Broadened this PR to fully close the OAuth-for-non-terminal-clients story (rebased on latest main):

  1. Documented the presentsAuthChallenge capability. It was introduced here ad hoc; it now has a doc comment on WizardPrompter explaining the contract (clients that render auth challenges in-band set it; providers surface the URL in the prompt instead of relying on a gateway-host browser or terminal-only logging).

  2. Local-gateway companion fix. The shared OAuth helper previously only surfaced the URL in-band when isRemote. A companion driving a local gateway over RPC can't use a browser opened on the gateway host either, so the helper now surfaces the URL in-band whenever the client presents auth challenges — handled centrally in createVpsAwareOAuthHandlers so every caller (including openclaw models auth) is covered, not just the auth-choice path.

  3. Contract guardrail test. Added a test that locks in "an auth-presenting client always receives the authorization URL in a protocol-visible prompt" for both remote and local hosts, so new providers can't regress to stdout-only delivery.

Validated locally on latest main: src/plugins/provider-oauth-flow.test.ts (5, +2 new), focused OAuth set (google/openrouter/openai-chatgpt/auth-choice/session) green, tsgo:core + tsgo:core:test exit 0, oxlint + oxfmt clean.

@clawsweeper

clawsweeper Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 26, 2026, 4:07 PM ET / 20:07 UTC.

Summary
The PR adds a presentsAuthChallenge WizardPrompter capability and carries OAuth authorization URLs into wizard text prompts across shared and bundled provider OAuth flows for RPC/non-terminal clients.

PR surface: Source +77, Tests +355. Total +432 across 17 files.

Reproducibility: yes. at source level. Current main sends only wizard prompt text to RPC clients while the shared OAuth helper can leave the authorization URL in runtime logs or a gateway-opened browser path.

Review metrics: 2 noteworthy metrics.

  • Wizard prompter capability: 1 optional field added. WizardPrompter is passed into provider auth contexts and exported through plugin-facing surfaces, so maintainers should consciously accept the new contract.
  • Provider auth routing decision: 1 condition broadened. Auth-presenting RPC clients are treated as remote for provider auth, changing OAuth browser/manual behavior without a config or migration surface.

Stored data model
Persistent data-model change detected: serialized state: src/wizard/session.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #94661
Summary: This PR is the candidate fix for the OAuth authorization URL sub-gap under the broader wizard RPC parity issue; other related PRs cover separate progress and pairing QR gaps.

Members:

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

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof 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 inspectable proof showing the Windows companion OAuth prompt with the authorization URL and completed redirect-paste flow.
  • Rebase or otherwise resolve the current conflicting merge state.
  • [P1] Get maintainer acceptance of the presentsAuthChallenge provider-auth routing semantics before merge.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR text describes Windows companion verification, but there is no inspectable after-fix media, terminal output, copied live output, linked artifact, or redacted log; the contributor should add proof and update the PR body.

Proof path suggestion
A visible companion/wizard proof would materially help confirm the user-facing OAuth URL delivery path that unit tests cannot show. Mantis is currently scoped to Telegram, Discord, and web UI chat proof, so it is not the right proof path for this surface.
Use maintainer screenshot/manual proof, browser or Playwright proof, Crabbox where appropriate, or normal local artifact proof instead.

Risk before merge

  • [P1] The contributor describes Windows companion verification, but there is no inspectable after-fix media, terminal output, copied live output, linked artifact, or redacted log showing the real client flow.
  • [P1] GitHub currently reports the PR as conflicting, so this exact branch cannot land until it is rebased or otherwise made mergeable.
  • [P1] The PR adds a plugin-facing optional prompter capability and changes provider-auth routing for auth-presenting RPC clients, which needs explicit maintainer acceptance before merge.

Maintainer options:

  1. Require Proof, Clean Merge, And Contract Acceptance (recommended)
    Ask for inspectable redacted companion proof, a rebase or conflict fix, and maintainer acceptance of presentsAuthChallenge before merge.
  2. Accept The New Auth Capability Contract
    Maintainers can intentionally accept the compatibility-sensitive provider-auth routing once proof and mergeability are resolved.
  3. Pause Behind The RPC Parity Umbrella
    If maintainers want one settled wizard RPC contract for auth challenges, progress, and pairing QR, keep this paused behind the broader parity issue.

Next step before merge

  • [P1] The remaining work is contributor proof, conflict resolution, and maintainer acceptance of a compatibility-sensitive auth-provider contract rather than a narrow automated repair.

Security
Cleared: No concrete security or supply-chain concern was found; the diff carries an already user-actionable authorization URL through existing wizard prompts while the secret-bearing redirect remains user input.

Review details

Best possible solution:

Land the shared auth-challenge capability after the branch is clean, maintainers accept the provider-auth routing contract, and the contributor adds redacted inspectable Windows companion proof showing the URL and completed redirect-paste flow.

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

Yes, at source level. Current main sends only wizard prompt text to RPC clients while the shared OAuth helper can leave the authorization URL in runtime logs or a gateway-opened browser path.

Is this the best way to solve the issue?

Yes with merge-safety caveats. The shared prompter/OAuth-helper seam is the maintainable fix shape, but the new plugin-facing capability and routing semantics need maintainer acceptance plus real-client proof.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 1089253ca97c.

Label changes

Label justifications:

  • P2: This is a normal-priority auth/onboarding bug fix for non-terminal clients with limited but real provider setup impact.
  • merge-risk: 🚨 compatibility: The PR adds a plugin-facing prompter capability and changes provider-auth behavior for RPC clients, which can affect companion and onboarding flows.
  • merge-risk: 🚨 auth-provider: The changed surface controls OAuth URL delivery, browser launching, manual redirect input, and provider auth completion paths.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab 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 text describes Windows companion verification, but there is no inspectable after-fix media, terminal output, copied live output, linked artifact, or redacted log; the contributor should add proof and update the PR body.
Evidence reviewed

PR surface:

Source +77, Tests +355. Total +432 across 17 files.

View PR surface stats
Area Files Added Removed Net
Source 11 136 59 +77
Tests 6 367 12 +355
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 17 503 71 +432

What I checked:

  • Root policy and scoped guides applied: Root AGENTS.md and the extension/plugin scoped guides were read; provider routing, plugin-facing API, and auth/session behavior are compatibility-sensitive review surfaces. (AGENTS.md:21, 1089253ca97c)
  • Current main RPC wizard text surface: On current main, WizardSessionPrompter.text() sends only params.message as the protocol-visible text step, so gateway stdout/runtime logs are not part of the RPC wizard prompt. (src/wizard/session.ts:118, 1089253ca97c)
  • Current main shared OAuth helper behavior: On current main, the remote OAuth helper logs the authorization URL but prompts with only manualPromptMessage, which is the source-level path that can leave an RPC client without the URL. (src/plugins/provider-oauth-flow.ts:29, 1089253ca97c)
  • PR head carries the URL in-band: The PR head adds withOAuthUrl(), treats remote or auth-presenting clients as in-band auth clients, and includes the authorization URL in prompter.text. (src/plugins/provider-oauth-flow.ts:33, 34ad72e0d096)
  • PR head changes provider auth routing: The PR broadens provider auth dispatch so auth-presenting prompters are treated as remote for provider auth selection. (src/plugins/provider-auth-choice.ts:289, 34ad72e0d096)
  • Real behavior proof is not inspectable: The PR body describes Windows companion verification, but no screenshot, recording, copied live output, linked artifact, or redacted log is attached; GitHub also reports failed Real behavior proof checks. (34ad72e0d096)

Likely related people:

  • Peter Steinberger: History shows prior work isolating provider SDK auth/model helpers, simplifying provider OAuth prompts, and unifying onboarding/config surfaces touched by this PR. (role: provider auth and wizard architecture contributor; confidence: high; commits: dde89d2a834a, 71efba043ca1, 53baba71faa3; files: src/plugins/provider-oauth-flow.ts, src/plugins/provider-auth-choice.ts, src/wizard/session.ts)
  • Vincent Koc: Recent history on provider auth choice and Chutes/provider SDK seams includes compatibility-sensitive auth/plugin paths adjacent to the changed routing. (role: recent provider auth/plugin seam contributor; confidence: medium; commits: d8a1ad0f0d5c, 7198a9f0eeed; files: src/plugins/provider-auth-choice.ts, extensions/chutes/index.ts)
  • sudie-codes: MS Teams delegated OAuth history appears in the provider path updated by this PR. (role: adjacent MS Teams OAuth contributor; confidence: medium; commits: 355794c24a39; files: extensions/msteams/src/oauth.ts)
  • Agustin Rivera: Google OAuth history includes prior OAuth state/PKCE work in the Gemini OAuth path updated by this PR. (role: adjacent Google OAuth contributor; confidence: medium; commits: a26f4d0f3ef0; files: extensions/google/oauth.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.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. 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. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 18, 2026
OAuth redirect-paste setup over the RPC wizard only printed the authorization URL to gateway stdout (or opened a browser on the gateway host), so non-terminal clients (e.g. the Windows companion) never received the link needed to sign in. Carry the authorization URL in-band in the wizard text prompt via a documented presentsAuthChallenge prompter capability; terminal CLI logging is preserved.

Covers the shared OAuth helper plus Google, OpenAI ChatGPT/Codex, OpenRouter, Chutes, and MS Teams provider paths. The shared helper now also surfaces the URL in-band on a LOCAL gateway when the client presents auth challenges (a companion cannot use a browser opened on the gateway host), and a contract test locks in that auth-presenting clients always receive the URL in a protocol-visible prompt.

Refs openclaw#94661.

Co-authored-by: Copilot <[email protected]>
@bkudiess
bkudiess force-pushed the fix/wizard-oauth-auth-url branch from bab4196 to 34ad72e Compare June 18, 2026 20:45
@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. and removed 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. labels Jun 18, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 19, 2026
@steipete steipete closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: msteams Channel integration: msteams commands Command implementations extensions: chutes extensions: google extensions: openai extensions: openrouter 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: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: L status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants