Skip to content

Gateway: allow extension origins in browser allowlist#44

Open
BingqingLyu wants to merge 1 commit into
mainfrom
fork-pr-38290-feature-allow-chrome-extension-origins
Open

Gateway: allow extension origins in browser allowlist#44
BingqingLyu wants to merge 1 commit into
mainfrom
fork-pr-38290-feature-allow-chrome-extension-origins

Conversation

@BingqingLyu

@BingqingLyu BingqingLyu commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: gateway.controlUi.allowedOrigins could not explicitly allowlist chrome-extension://<id> because the origin checker normalized extension origins through URL.origin, which becomes "null" for that scheme.
  • Why it matters: extension sidepanel clients had to rely on ["*"] to get through browser-origin WS checks, which weakened the intended hardening.
  • What changed: the origin matcher now keeps exact URL parsing/validation but falls back to exact scheme://host matching for non-standard origins, so chrome-extension://<id> can be allowlisted exactly; focused unit and handshake tests were added.
  • What did NOT change (scope boundary): no wildcard/prefix expansion, no acceptance of literal Origin: null, no changes to token/device auth, host-header fallback, or non-browser client auth behavior.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

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

Linked Issue/PR

User-visible / Behavior Changes

  • gateway.controlUi.allowedOrigins can now contain exact extension origins such as chrome-extension://abcdefghijklmnop, and those browser-origin Gateway WS connects will succeed when otherwise authenticated.
  • Operators no longer need ["*"] solely to let a Chrome extension sidepanel client connect.
  • Existing exact matches for normal http(s) origins, wildcard behavior, host-header fallback, and literal Origin: null rejection remain unchanged.

Security Impact (required)

  • New permissions/capabilities? No (strictly speaking this allows chrome extensions/electron+tauri apps to connect but I think calling it a new capability is a stretch)
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local Bun + Vitest
  • Model/provider: N/A
  • Integration/channel (if any): Gateway WS browser-origin client; Chrome extension origin emulated in handshake tests via ws
  • Relevant config (redacted): gateway.auth.mode="token", gateway.controlUi.allowedOrigins=["chrome-extension://abcdefghijklmnop"]

Steps

  1. Configure the Gateway with token auth and gateway.controlUi.allowedOrigins=["chrome-extension://abcdefghijklmnop"].
  2. Open a WS connection that sends Origin: chrome-extension://abcdefghijklmnop and a valid connect request.
  3. Observe the handshake result.

Expected

  • An exactly allowlisted extension origin should be accepted, just like an exactly allowlisted https://... origin.

Actual

  • Before this fix, the request was rejected with origin not allowed because the checker collapsed the extension origin to "null" internally.
  • After this fix, the handshake succeeds and returns hello-ok.

Evidence

Attach at least one:

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

CleanShot 2026-03-06 at 16 30 46@2xCleanShot 2026-03-06 at 16 32 05@2x

Human Verification (required)

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

  • Verified scenarios: whitelisted the chrome extension I'm developing and successfully connected to the Gateway via WS
  • Edge cases checked: N/A
  • What you did not verify: did not try with other protocols (app://, tauri://)

Compatibility / Migration

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

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this commit; if extension access is urgently blocked, temporarily fall back to gateway.controlUi.allowedOrigins=["*"] until the regression is understood.
  • Files/config to restore: src/gateway/origin-check.ts; optionally restore prior gateway.controlUi.allowedOrigins values in config.
  • Known bad symptoms reviewers should watch for: an exactly allowlisted chrome-extension://<id> still being rejected; malformed/non-matching non-standard origins unexpectedly being accepted; regressions in existing http(s) origin allowlisting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ClawControl app: 'origin not allowed' for app://localhost even when in allowedOrigins

2 participants