fix(gateway): return default scopes when trusted HTTP request has no scope header#58603
Conversation
…scope header resolveTrustedHttpOperatorScopes() returns [] when the x-openclaw-scopes header is absent, even for trusted requests (--auth none). This causes 403 "missing scope: operator.write" on /v1/chat/completions. Root cause: src/gateway/http-utils.ts:138-140. PR openclaw#57783 (f0af186) replaced the old resolveGatewayRequestedOperatorScopes which had an explicit fallback to CLI_DEFAULT_OPERATOR_SCOPES when no header was present. The new function treats absent header the same as empty header — both return []. Fix: distinguish absent header (undefined → return defaults) from empty header ("" → return []). Trusted clients without an explicit scope header get the default operator scopes, matching pre-openclaw#57783 behavior. Closes openclaw#58357 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: HCL <chenglunhu@gmail.com>
This comment was marked as low quality.
This comment was marked as low quality.
Greptile SummaryThis PR fixes a regression introduced in #57783 where The fix is minimal and targeted: by splitting
The change is consistent with how Confidence Score: 5/5Safe to merge — single-file, minimal change that correctly restores the intended fallback for absent scope headers. No P0 or P1 issues found. The fix correctly separates the absent-header case from the empty-header case, uses the already-imported constant, and is consistent with the existing pattern in resolveOpenAiCompatibleHttpOperatorScopes. No files require special attention.
|
| Filename | Overview |
|---|---|
| src/gateway/http-utils.ts | Correct fix that distinguishes absent header (→ default scopes) from empty header (→ no scopes) in resolveTrustedHttpOperatorScopes, restoring pre-#57783 behavior for --auth none setups. |
Reviews (1): Last reviewed commit: "fix(gateway): return default scopes when..." | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 110413e4af
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (headerValue === undefined) { | ||
| // No scope header present — trusted clients without an explicit header | ||
| // get the default operator scopes (matching pre-#57783 behavior). | ||
| return [...CLI_DEFAULT_OPERATOR_SCOPES]; |
There was a problem hiding this comment.
Restrict default scope fallback to shared-secret compat auth
This fallback now applies to every trusted HTTP request, not just shared-secret compat calls. In trusted-proxy or none modes, omitting x-openclaw-scopes now grants CLI_DEFAULT_OPERATOR_SCOPES (which includes operator.admin in src/gateway/method-scopes.ts), so compat requests are treated as owner via resolveOpenAiCompatibleHttpSenderIsOwner and can access owner-only tools without explicitly declared scopes. That regresses the explicit-scope boundary for identity-bearing proxy flows and can privilege-escalate authenticated users when the proxy does not inject a scopes header.
Useful? React with 👍 / 👎.
fabianwilliams
left a comment
There was a problem hiding this comment.
LGTM — reviewed code, tests, and approach. Clean implementation.
…scope header (openclaw#58603) resolveTrustedHttpOperatorScopes() returns [] when the x-openclaw-scopes header is absent, even for trusted requests (--auth none). This causes 403 "missing scope: operator.write" on /v1/chat/completions. Root cause: src/gateway/http-utils.ts:138-140. PR openclaw#57783 (f0af186) replaced the old resolveGatewayRequestedOperatorScopes which had an explicit fallback to CLI_DEFAULT_OPERATOR_SCOPES when no header was present. The new function treats absent header the same as empty header — both return []. Fix: distinguish absent header (undefined → return defaults) from empty header ("" → return []). Trusted clients without an explicit scope header get the default operator scopes, matching pre-openclaw#57783 behavior. Closes openclaw#58357 Signed-off-by: HCL <chenglunhu@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…scope header (openclaw#58603) resolveTrustedHttpOperatorScopes() returns [] when the x-openclaw-scopes header is absent, even for trusted requests (--auth none). This causes 403 "missing scope: operator.write" on /v1/chat/completions. Root cause: src/gateway/http-utils.ts:138-140. PR openclaw#57783 (b77a5fb) replaced the old resolveGatewayRequestedOperatorScopes which had an explicit fallback to CLI_DEFAULT_OPERATOR_SCOPES when no header was present. The new function treats absent header the same as empty header — both return []. Fix: distinguish absent header (undefined → return defaults) from empty header ("" → return []). Trusted clients without an explicit scope header get the default operator scopes, matching pre-openclaw#57783 behavior. Closes openclaw#58357 Signed-off-by: HCL <chenglunhu@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…scope header (openclaw#58603) resolveTrustedHttpOperatorScopes() returns [] when the x-openclaw-scopes header is absent, even for trusted requests (--auth none). This causes 403 "missing scope: operator.write" on /v1/chat/completions. Root cause: src/gateway/http-utils.ts:138-140. PR openclaw#57783 (cc4ce76) replaced the old resolveGatewayRequestedOperatorScopes which had an explicit fallback to CLI_DEFAULT_OPERATOR_SCOPES when no header was present. The new function treats absent header the same as empty header — both return []. Fix: distinguish absent header (undefined → return defaults) from empty header ("" → return []). Trusted clients without an explicit scope header get the default operator scopes, matching pre-openclaw#57783 behavior. Closes openclaw#58357 Signed-off-by: HCL <chenglunhu@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…scope header (openclaw#58603) resolveTrustedHttpOperatorScopes() returns [] when the x-openclaw-scopes header is absent, even for trusted requests (--auth none). This causes 403 "missing scope: operator.write" on /v1/chat/completions. Root cause: src/gateway/http-utils.ts:138-140. PR openclaw#57783 (d089836) replaced the old resolveGatewayRequestedOperatorScopes which had an explicit fallback to CLI_DEFAULT_OPERATOR_SCOPES when no header was present. The new function treats absent header the same as empty header — both return []. Fix: distinguish absent header (undefined → return defaults) from empty header ("" → return []). Trusted clients without an explicit scope header get the default operator scopes, matching pre-openclaw#57783 behavior. Closes openclaw#58357 Signed-off-by: HCL <chenglunhu@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…scope header (openclaw#58603) resolveTrustedHttpOperatorScopes() returns [] when the x-openclaw-scopes header is absent, even for trusted requests (--auth none). This causes 403 "missing scope: operator.write" on /v1/chat/completions. Root cause: src/gateway/http-utils.ts:138-140. PR openclaw#57783 (f727495) replaced the old resolveGatewayRequestedOperatorScopes which had an explicit fallback to CLI_DEFAULT_OPERATOR_SCOPES when no header was present. The new function treats absent header the same as empty header — both return []. Fix: distinguish absent header (undefined → return defaults) from empty header ("" → return []). Trusted clients without an explicit scope header get the default operator scopes, matching pre-openclaw#57783 behavior. Closes openclaw#58357 Signed-off-by: HCL <chenglunhu@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
lobster-biscuit
Closes #58357
Problem
HTTP
/v1/chat/completionsreturns 403 "missing scope: operator.write" when the gateway is configured with--auth none. The OpenAI-compatible API is completely broken for unauthenticated setups.Root cause
src/gateway/http-utils.ts:138-140—resolveTrustedHttpOperatorScopes()returns[]when thex-openclaw-scopesheader is absent, even for trusted requests. PR #57783 (f0af18672) replaced the old scope resolution which had an explicit fallback toCLI_DEFAULT_OPERATOR_SCOPESwhen no header was present.The new function treats absent header (
undefined) the same as empty header ("") — both return[]→ zero scopes → 403.User impact
All
--auth noneHTTP API users get 403 on every request. OpenAI-compatible API completely broken for unauthenticated gateway setups.Fix
Distinguish absent header (
undefined→ returnCLI_DEFAULT_OPERATOR_SCOPES) from empty header ("" → return []). Uses existingCLI_DEFAULT_OPERATOR_SCOPESfrommethod-scopes.ts(already imported at line 20).1 file, +7/-1.
How to verify
--auth nonecurl http://localhost:18789/v1/chat/completions -d ...Tests
The scope resolution is tested via the HTTP auth integration tests. The fix restores pre-#57783 behavior for the absent-header case — the same test expectations apply.
🤖 Generated with Claude Code