fix(gateway): require auth for control ui bootstrap config#70247
fix(gateway): require auth for control ui bootstrap config#70247drobison00 merged 6 commits intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR fixes a missing auth gate on Confidence Score: 5/5Safe to merge — the fix is well-scoped, all call sites are updated, and new tests cover the added auth gate. All remaining findings are at most P2. The core auth gate is correctly implemented following the same pattern as sibling Control UI read routes. Every call site that uses the now-async handler is properly awaited. New tests cover the unauthorized (401) and authorized (200) bootstrap scenarios. No regressions introduced. No files require special attention. Reviews (1): Last reviewed commit: "fix(gateway): require auth for control u..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b28756c9f2
ℹ️ 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".
de300ca to
3a96e29
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3a96e29903
ℹ️ 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".
401355e to
827160a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 827160a697
ℹ️ 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".
827160a to
68bd62f
Compare
68bd62f to
d555597
Compare
🔒 Aisle Security AnalysisWe found 1 potential security issue(s) in this PR:
1. 🔵 Auth retry loop can amplify failed-auth attempts and trigger rate-limit lockouts
Description
If the gateway’s
Vulnerable code: const attempts: string[] = authCandidates.length > 0 ? authCandidates : [""];
for (const candidate of attempts) {
...
res = await fetch(url, { method: "GET", headers, credentials: "same-origin" });
if (res.ok) break;
if (res.status !== 401 && res.status !== 403) return;
}RecommendationReduce the number of automatic shared-secret retries and/or avoid counting multiple failures toward lockout for a single UI action. Options:
Example (client: cap retries to 1): const authCandidates = sameOrigin ? resolveControlUiAuthCandidates(state) : [];
const attempts = authCandidates.slice(0, 2); // at most one retryAnalyzed PR: #70247 at commit Last updated on: 2026-04-22T22:51:04Z |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d5555976a1
ℹ️ 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".
| void loadControlUiBootstrapConfig( | ||
| host as unknown as Parameters<typeof loadControlUiBootstrapConfig>[0], | ||
| ); |
There was a problem hiding this comment.
Avoid clobbering session identity on hello bootstrap refresh
Triggering loadControlUiBootstrapConfig inside onHello races with loadAssistantIdentity, and both write assistantName/assistantAvatar/assistantAgentId on the same host object. The bootstrap response is derived from config-level identity (via src/gateway/server-http.ts passing resolveAssistantIdentity({ cfg }).agentId into the bootstrap handler), not the active session’s agent, so in non-default sessions this extra fetch can overwrite the correct per-session identity if it finishes last.
Useful? React with 👍 / 👎.
…70247) * fix(gateway): require auth for control ui bootstrap config * fix(ui): send auth on bootstrap fetch * fix(ui): keep bootstrap auth same-origin * fix(ui): refresh bootstrap after auth hello * docs(changelog): note control ui bootstrap auth * fix(ui): retry bootstrap auth with alternate shared secret on 401
…70247) * fix(gateway): require auth for control ui bootstrap config * fix(ui): send auth on bootstrap fetch * fix(ui): keep bootstrap auth same-origin * fix(ui): refresh bootstrap after auth hello * docs(changelog): note control ui bootstrap auth * fix(ui): retry bootstrap auth with alternate shared secret on 401
…70247) * fix(gateway): require auth for control ui bootstrap config * fix(ui): send auth on bootstrap fetch * fix(ui): keep bootstrap auth same-origin * fix(ui): refresh bootstrap after auth hello * docs(changelog): note control ui bootstrap auth * fix(ui): retry bootstrap auth with alternate shared secret on 401
…70247) * fix(gateway): require auth for control ui bootstrap config * fix(ui): send auth on bootstrap fetch * fix(ui): keep bootstrap auth same-origin * fix(ui): refresh bootstrap after auth hello * docs(changelog): note control ui bootstrap auth * fix(ui): retry bootstrap auth with alternate shared secret on 401
fix(gateway): require auth for control ui bootstrap config
Summary
Describe the problem and fix in 2–5 bullets:
If this PR fixes a plugin beta-release blocker, title it
fix(<plugin-id>): beta blocker - <summary>and link the matchingBeta blocker: <plugin-name> - <summary>issue labeledbeta-blocker. Contributors cannot label PRs, so the title is the PR-side signal for maintainers and automation./__openclaw/control-ui-config.jsonreturned bootstrap metadata even whengateway.authwas configured.server-httpnow passes the resolved auth context into that handler, and gateway tests cover both unauthorized and authorized bootstrap requests.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
For bug fixes or regressions, explain why this happened, not just what changed. Otherwise write
N/A. If the cause is unclear, writeUnknown.handleControlUiHttpRequest()served the bootstrap config branch without callingauthorizeControlUiReadRequest(), and its request options did not accept the auth-related fields used by sibling Control UI read routes.Regression Test Plan (if applicable)
For bug fixes or regressions, name the smallest reliable test coverage that should catch this. Otherwise write
N/A.src/gateway/control-ui.http.test.ts401without a valid credential whengateway.authis enabled and still return200with the valid token.src/gateway/control-ui.http.test.ts.User-visible / Behavior Changes
gateway.authenabled now require valid Control UI read auth before returning/__openclaw/control-ui-config.json.Diagram (if applicable)
N/A
Security Impact (required)
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) YesYes, explain risk + mitigation: bootstrap config data is no longer exposed to unauthenticated callers when gateway auth is configured; the route now uses the same read-auth path as the sibling Control UI read endpoints.Repro + Verification
Environment
Linux 6.8.0-110-generic<operator to fill>gateway.controlUienabled;gateway.auth.mode=tokenSteps
GET /__openclaw/control-ui-config.jsonwithout an auth credential.Expected
Actual
Evidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
node ./node_modules/vitest/vitest.mjs run --reporter=verbose --config test/vitest/vitest.gateway.config.ts src/gateway/control-ui.http.test.ts src/gateway/control-ui.auto-root.http.test.ts src/gateway/gateway-misc.test.tsand confirmed3files /67tests passed, including the new bootstrap auth cases.200; existing direct callers and tests were updated toawaitthe now-async Control UI HTTP handler.curlreproduction outside the test harness.Review Conversations
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
Yes/No) YesYes/No) NoYes/No) NoRisks and Mitigations
List only real risks for this PR. Add/remove entries as needed. If none, write
None.handleControlUiHttpRequest()contract.awaitthe handler.gateway.authis enabled.