Skip to content

fix(gateway): show OAuth auth URLs in wizard prompts#92234

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

fix(gateway): show OAuth auth URLs in wizard prompts#92234
bkudiess wants to merge 1 commit into
openclaw:mainfrom
bkudiess:bkudiess/feat-wizard-auth-url-protocol

Conversation

@bkudiess

@bkudiess bkudiess commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

When OAuth setup runs through an RPC wizard client, the gateway can ask for a redirect URL while only printing the authorization URL to gateway stdout. That leaves clients like the Windows companion without the link the user needs to open.

This PR makes redirect-paste OAuth prompts self-contained by including the generated authorization URL directly in the wizard text prompt. Terminal logging is preserved.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #
  • This PR fixes a bug or regression

Real behavior proof (required for external PRs)

Behavior addressed: RPC wizard OAuth setup now shows the generated authorization URL in the same text prompt that asks for the redirect URL.
Real environment tested: Windows companion app driving an OpenClaw gateway wizard OAuth setup flow, plus the local Windows OpenClaw worktree.
Exact steps or command run after this patch: Opened the Windows companion, started the gateway/provider OAuth wizard flow, verified the wizard prompt displayed the authorization URL before the redirect URL input, opened the URL in a browser, and completed the redirect paste step. Also ran node scripts/run-vitest.mjs run src\plugins\provider-oauth-flow.test.ts extensions\openai\openai-chatgpt-oauth.runtime.test.ts extensions\google\oauth.test.ts extensions\openrouter\oauth.test.ts src\commands\auth-choice.apply.plugin-provider.test.ts src\wizard\session.test.ts; pnpm tsgo:core && pnpm tsgo:core:test && pnpm tsgo:extensions && pnpm tsgo:extensions:test; pnpm exec oxlint <touched files>; git diff --check.
Evidence after fix: Human verification confirmed the Windows companion wizard showed the OAuth authorization URL inline with the redirect paste prompt. Focused tests also assert authorization URLs are included in prompt messages for the shared OAuth helper, Gemini, OpenAI ChatGPT/Codex, and OpenRouter paths.
Observed result after fix: The Windows companion flow exposed the authorization URL in the wizard prompt and the redirect paste step could be completed. Focused Vitest passed 5 shards / 64 tests; TypeScript core/test and extensions/test checks passed; direct oxlint on touched files passed; git diff --check passed.
What was not tested: Full repository pnpm check, full repository pnpm test, and every provider's live OAuth service.
Before evidence (optional but encouraged): Before this patch, the gateway printed the authorization URL to runtime.log / stdout while the wizard step only asked for a redirect URL.

Root Cause (if applicable)

  • Root cause: OAuth redirect flows treated runtime logs as the user-facing place to show authorization URLs, but RPC wizard clients receive wizard steps rather than gateway stdout.
  • Missing detection / guardrail: Existing tests covered local CLI/provider OAuth behavior but not whether RPC-visible prompt messages contained the URL needed to complete manual redirect flows.
  • Contributing context (if known): RPC wizard clients need the auth challenge rendered in-band even when the gateway process itself can write the URL to logs.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/plugins/provider-oauth-flow.test.ts, extensions/openai/openai-chatgpt-oauth.runtime.test.ts, extensions/google/oauth.test.ts, extensions/openrouter/oauth.test.ts, src/commands/auth-choice.apply.plugin-provider.test.ts, src/wizard/session.test.ts.
  • Scenario the test should lock in: Manual OAuth redirect prompts include the generated authorization URL in the prompt message; auth-presenting RPC prompters use the manual path; CLI/non-auth-presenting paths keep their existing note/log behavior.
  • Why this is the smallest reliable guardrail: It covers the shared helper, representative provider integrations, and wizard/auth-choice seam without requiring live OAuth credentials.
  • Existing test that already covers this (if any): N/A; focused coverage was added/updated.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

RPC wizard clients now receive OAuth authorization URLs directly in the text prompt message for redirect-paste flows. Terminal CLI users still see URL logging and the same prompt flow.

Diagram (if applicable)

Before:
OAuth provider -> gateway runtime.log(url) -> RPC client only sees "paste redirect URL"

After:
OAuth provider -> wizard text message includes url -> RPC client shows url + paste box -> user completes login

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation: N/A. The authorization URL was already intentionally logged for user action; this change carries the same non-secret authorization URL in the wizard prompt message. Redirect URLs containing authorization codes remain user input.

Repro + Verification

Environment

  • OS: Windows
  • Runtime/container: Node/pnpm OpenClaw worktree
  • Model/provider: Windows companion OAuth wizard flow, plus OpenAI ChatGPT/Codex OAuth, Chutes/shared OAuth helper, Google Gemini CLI OAuth, and OpenRouter OAuth seams via focused tests
  • Integration/channel (if any): Gateway wizard / provider auth prompts
  • Relevant config (redacted): OAuth credentials and generated authorization URLs redacted

Steps

  1. Open the Windows companion against the patched gateway.
  2. Start a provider OAuth wizard flow that uses redirect-URL paste.
  3. Confirm the wizard text prompt includes the generated authorization URL and the redirect paste instruction.
  4. Open the authorization URL in the browser and complete the redirect paste step.

Expected

  • The protocol-visible text step message contains the authorization URL needed to complete OAuth.

Actual

  • The Windows companion showed the authorization URL in the wizard prompt and the redirect paste step completed.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: Windows companion OAuth wizard prompt showed the generated authorization URL inline with the redirect paste prompt; shared OAuth helper remote and local fallback prompts include the authorization URL; Gemini manual OAuth prompt includes the URL; OpenAI auth-presenting flow collapses copy into the redirect paste prompt; OpenRouter remote OAuth prompt includes the URL.
  • Edge cases checked: Existing terminal logging remains; local fallback prompt stays unchanged before an auth URL exists.
  • What you did not verify: Full repository test suite and every provider's live OAuth service.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: Authorization URLs become visible in a wizard prompt message instead of only gateway logs.
    • Mitigation: These URLs were already intentionally shown/logged for users and do not contain the returned authorization code; the secret-bearing redirect remains user input.
  • Risk: Prompt messages become longer for OAuth redirect flows.
    • Mitigation: The longer prompt is self-contained and preserves compatibility for clients that render only message text.

AI-assisted: Yes. Implemented with Copilot-assisted sessions and reviewed by separate adversarial compatibility passes before simplifying to the message-only approach.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime commands Command implementations extensions: chutes extensions: google size: M triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels Jun 11, 2026
@clawsweeper

clawsweeper Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 17, 2026, 2:46 PM ET / 18:46 UTC.

Summary
The PR adds OAuth authorization URLs to provider wizard prompt messages, adds an optional auth-presenting marker to wizard prompters, and updates provider OAuth tests across OpenAI, Google, Chutes, OpenRouter, MSTeams, and the shared helper.

PR surface: Source +66, Tests +316. Total +382 across 17 files.

Reproducibility: yes. there is a high-confidence source-level path: current main exposes wizard steps over RPC while remote OAuth helpers can log the auth URL separately from the text prompt. I did not run a live provider OAuth service in this read-only review.

Review metrics: 2 noteworthy metrics.

  • Provider Auth Locality Rule: 1 changed. Provider auth methods now receive remote mode from RPC presentation capability as well as host environment, which affects upgrade behavior.
  • Wizard Prompter API Surface: 1 optional field added. Adding a prompter capability is an internal API surface that plugin/provider auth callers may start depending on.

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

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦪 silver shellfish
Patch quality: 🧂 unranked krab
Result: blocked until stronger 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] Fix the WizardTextParams import/export shape so the patched source typechecks.
  • Keep RPC auth presentation separate from ProviderAuthContext.isRemote.
  • [P1] Add redacted real behavior proof such as a screenshot, recording, terminal output, or logs showing the after-fix wizard OAuth flow.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body describes human Windows companion verification, but no redacted screenshot, recording, terminal output, copied live output, log excerpt, or linked artifact is available to inspect. 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.

Mantis proof suggestion
A visible RPC wizard OAuth run would materially help verify the prompt URL and redirect completion behavior that unit tests cannot show. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify an RPC wizard OAuth setup shows the authorization URL in the text prompt and completes the redirect flow without changing local browser callback behavior.

Risk before merge

  • [P1] The PR currently imports a non-exported WizardTextParams type, so the patched source will not typecheck until that import/export shape is repaired.
  • [P1] Changing ProviderAuthContext.isRemote for every RPC wizard prompter can make existing local gateway OAuth setup behave like remote/manual auth, affecting browser opening and callback capture.
  • [P1] The contributor describes a real Windows companion run, but the review still lacks inspectable redacted media, logs, terminal output, or artifacts showing the after-fix flow.

Maintainer options:

  1. Separate Presentation From Locality (recommended)
    Keep ProviderAuthContext.isRemote tied to the gateway host environment and pass any RPC auth-presentation capability separately into prompt builders or OAuth helpers.
  2. Accept RPC Manual Mode Explicitly
    Maintainers may intentionally make RPC wizard provider auth manual-first, but that needs documented compatibility intent and real client proof before landing.
  3. Pause For Inspectable Proof
    Keep the PR open until the contributor adds redacted screenshot, recording, terminal output, or logs that show the wizard prompt URL and completed redirect flow.

Next step before merge

  • [P1] This PR needs contributor/maintainer follow-up for inspectable real proof and an auth-locality compatibility decision; automation cannot provide the contributor's Windows companion proof.

Security
Cleared: The diff adds no dependencies, permissions, token storage, downloads, or new execution surface; it exposes authorization URLs that were already intended for user action.

Review findings

  • [P1] Export the prompt params type before importing it — src/wizard/session.ts:7
  • [P1] Keep auth presentation separate from host locality — src/plugins/provider-auth-choice.ts:288
Review details

Best possible solution:

Keep the authorization URL in protocol-visible prompt text, fix the type export/import issue, preserve host locality as a separate provider-auth fact, and add redacted real behavior proof before merge.

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

Yes, there is a high-confidence source-level path: current main exposes wizard steps over RPC while remote OAuth helpers can log the auth URL separately from the text prompt. I did not run a live provider OAuth service in this read-only review.

Is this the best way to solve the issue?

No, not as currently patched. The URL-in-prompt approach is a good narrow fix, but the non-exported type import and the broad isRemote semantic change need to be fixed first.

Full review comments:

  • [P1] Export the prompt params type before importing it — src/wizard/session.ts:7
    WizardTextParams is still a file-local type in src/wizard/prompts.ts, so importing it here makes the patched source fail type checking. Either keep the local structural parameter type in session.ts or export the type from prompts.ts intentionally.
    Confidence: 0.98
  • [P1] Keep auth presentation separate from host locality — src/plugins/provider-auth-choice.ts:288
    This makes every RPC wizard provider auth method receive isRemote: true. Providers use that flag to choose browser opening, callback capture, manual input, and prompt copy, so a local gateway reached through an RPC wizard client can lose the existing local browser/callback path. Pass a separate presentation capability without redefining host locality.
    Confidence: 0.94

Overall correctness: patch is incorrect
Overall confidence: 0.93

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 7019da8c7bb1.

Label changes

Label justifications:

  • P2: The PR targets a bounded OAuth wizard usability bug with limited blast radius, but current correctness and compatibility blockers prevent merge.
  • merge-risk: 🚨 compatibility: Changing remote-mode semantics for RPC wizard clients can break existing local OAuth setup behavior during upgrade.
  • merge-risk: 🚨 auth-provider: The diff changes provider OAuth browser opening, callback capture, and redirect prompt behavior.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body describes human Windows companion verification, but no redacted screenshot, recording, terminal output, copied live output, log excerpt, or linked artifact is available to inspect. 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 +66, Tests +316. Total +382 across 17 files.

View PR surface stats
Area Files Added Removed Net
Source 11 131 65 +66
Tests 6 328 12 +316
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 17 459 77 +382

What I checked:

  • Repository policy applied: Read the full root policy plus scoped extensions and src/plugins policies; provider auth routing and plugin auth context behavior are compatibility-sensitive under those rules. (AGENTS.md:21, 7019da8c7bb1)
  • Current main keeps locality host-based: Current main passes only isRemoteEnvironment() into ProviderAuthContext, so isRemote is the gateway host/browser environment, not an RPC presentation capability. (src/plugins/provider-auth-choice.ts:288, 7019da8c7bb1)
  • PR changes provider auth locality: The PR changes provider auth invocation to isRemoteEnvironment() || params.prompter.presentsAuthChallenge === true, making every RPC wizard provider auth method see remote mode. (src/plugins/provider-auth-choice.ts:288, a5d29548c3f8)
  • isRemote controls browser and callback behavior: The shared OAuth helper skips openUrl and starts manual prompting when isRemote is true, while local mode opens the URL and waits for callback/fallback behavior. (src/plugins/provider-oauth-flow.ts:29, 7019da8c7bb1)
  • Type export blocker: Current main intentionally keeps WizardTextParams file-local, but the PR imports it from session.ts without exporting it from prompts.ts. (src/wizard/prompts.ts:22, 7019da8c7bb1)
  • Codex OAuth contract checked: Sibling Codex source shows app-server ChatGPT login returns auth_url to the client while running a local callback server with open_browser=false, matching the need to display auth URLs without redefining locality. (../codex/codex-rs/app-server/src/request_processors/account_processor.rs:342, d9e0551564f7)

Likely related people:

  • vincentkoc: Recent commit f3ae525 made WizardTextParams file-local in src/wizard/prompts.ts, which is directly relevant to the PR's non-exported type import. (role: recent wizard type contributor; confidence: high; commits: f3ae5252115e; files: src/wizard/prompts.ts, src/wizard/session.ts)
  • steipete: Recent history on the provider auth choice and shared OAuth helper paths includes provider auth/runtime contract documentation and helper refactors. (role: provider auth architecture contributor; confidence: medium; commits: 040ebadfc52f, ca7c2714f695, 71efba043ca1; files: src/plugins/provider-auth-choice.ts, src/plugins/provider-oauth-flow.ts)
  • anurag-bg-neu: Prior merged work added sensitive text prompt support across wizard prompt/session types, adjacent to the prompt contract changed by this PR. (role: wizard prompt contributor; confidence: medium; commits: 727398f41a85; files: src/wizard/prompts.ts, src/wizard/session.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: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed 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. labels Jun 11, 2026
@bkudiess
bkudiess marked this pull request as draft June 11, 2026 21:04
@bkudiess
bkudiess force-pushed the bkudiess/feat-wizard-auth-url-protocol branch from 9ee6911 to 2814ab0 Compare June 12, 2026 15:58
@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. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 12, 2026
@bkudiess
bkudiess force-pushed the bkudiess/feat-wizard-auth-url-protocol branch from 2814ab0 to 7c922be Compare June 12, 2026 20:12
@clawsweeper clawsweeper Bot added 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 15, 2026
Add structured auth metadata to wizard text steps so RPC wizard clients can show OAuth authorization URLs alongside the redirect paste prompt. Preserve existing CLI logging and local browser behavior while covering shared OAuth providers and Gemini.

Co-authored-by: Copilot <[email protected]>
@bkudiess
bkudiess force-pushed the bkudiess/feat-wizard-auth-url-protocol branch from 7c922be to a5d2954 Compare June 15, 2026 20:37
@openclaw-barnacle openclaw-barnacle Bot removed the app: web-ui App: web-ui label Jun 15, 2026
@openclaw-barnacle openclaw-barnacle Bot added channel: msteams Channel integration: msteams extensions: openrouter and removed gateway Gateway runtime labels Jun 15, 2026
@bkudiess
bkudiess marked this pull request as ready for review June 17, 2026 17:47
@bkudiess bkudiess changed the title fix(gateway): surface OAuth auth URLs in wizard protocol fix(gateway): show OAuth auth URLs in wizard prompts Jun 17, 2026
@bkudiess

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

The PR has been simplified to a message-only prompt fix: the title/body were updated and the API/contracts scope was removed. Please refresh the review comment and labels against the current diff.

@clawsweeper

clawsweeper Bot commented Jun 17, 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.

Re-review progress:

@bkudiess

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

The PR description has been updated with human Windows companion OAuth wizard verification and the current message-only prompt approach. Please refresh the proof/readiness comment and labels.

@bkudiess

Copy link
Copy Markdown
Contributor Author

Superseded by #94300 - a clean single-commit re-open on top of latest main. This branch was based on an older main and conflicted with the wizard prompt-type refactor (f3ae525), which made WizardTextParams non-exported. #94300 reconciles that (reverts the incidental WizardSessionPrompter.text() change to the inline param type) and is green locally: tsgo core + core-test, extension package boundary (114 plugins), and the focused Vitest suite all pass. Closing in favor of the clean PR.

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.

1 participant