Bug type
Regression (worked before, now fails)
Beta release blocker
No
Summary
Hey team,
We recently spent an agonizing 24 hours debugging a critical regression that completely broke our integration.
For context, we are currently building the backend infrastructure for AgentPage, a project that heavily relies on OpenClaw's standard RESTful HTTP API (/v1/chat/completions) to orchestrate underlying agents. Up until version 3.24, everything worked flawlessly. However, after upgrading to 3.28 (and this still persists in 3.30), standard HTTP requests using a valid Gateway Token consistently fail with a scope error.
Steps to Reproduce
Sending a standard curl request using pure token authentication:
curl -N http://127.0.0.1:18789/v1/chat/completions \
-H 'Authorization: Bearer <MY_VALID_GATEWAY_TOKEN>' \
-H 'x-openclaw-client-id: openclaw-control-ui' \
-H 'x-openclaw-message-channel: webchat' \
-H 'Content-Type: application/json' \
-d '{
"model": "openclaw",
"stream": true,
"messages":[{"role":"user","content":"hi"}]
}'
Actual Output:
{"ok":false,"error":{"type":"forbidden","message":"missing scope: operator.write"}}
Expected Behavior:
According to openclaw/SECURITY.md, the HTTP API (/v1/chat/completions) should treat the Gateway Token as an Operator with maximum privileges, returning the expected LLM stream without requiring a WebSocket device pairing fingerprint.
The Debugging Journey (What we tried)
Before realizing this was a core regression, we tried countless workarounds (including having Claude Code iterate over 30+ times, switching across 3 different models, and eventually pivoting back to manual "vibe coding"):
- Manually modifying
pairing.json assuming Device Pairing permissions were insufficient.
- Swapping the Gateway Token for a specific
deviceToken and adding x-openclaw-device-id headers.
- Patching the compiled source code (e.g.,
gateway-cli-*.js) to forcefully inject scopes right before the auth check:
if ((authMethod === "token" || authMethod === "password") && !scopes.includes('operator.admin')) {
scopes.push('operator.read', 'operator.write', 'operator.admin');
}
None of these native approaches solved the issue cleanly for headless HTTP requests.
Root Cause Analysis (Collateral damage from recent CVE patches)
After digging deep into the diffs between 3.24 and 3.28, it appears this bug is collateral damage from the recent security patches for the Tokyo preclawcon release.
To urgently patch CVE-2026-32919 and CVE-2026-28473 (where attackers bypassed operator.admin using operator.write credentials), the underlying permission model was severely tightened. The current logic effectively strips or neuters the permission array for HTTP requests lacking a valid Device Identity (device fingerprint).
While this successfully secures the WebSocket / UI routes, it completely breaks standard headless integrations (like native curl or the OpenAI SDK) that rely purely on Bearer token auth for RESTful calls.
Conclusion & Thoughts
For platforms like AgentPage.io that build on top of OpenClaw, this kind of undocumented breaking change in a minor version update is devastating. We understand the urgency of patching CVEs, but it feels like the current auth optimizations are a bit haphazard, leading to severe collateral damage for HTTP API consumers.
Could we get a proper separation of auth validation for pure RESTful channels, or at least a hotfix to restore headless Gateway Token functionality? In the meantime, we advise anyone relying on the REST API to downgrade to 3.24.
Thanks for the hard work on the project!
Steps to reproduce
1.start openclaw from 2026.03.28
2.
curl -N http://127.0.0.1:18789/v1/chat/completions
-H 'Authorization: Bearer <MY_VALID_GATEWAY_TOKEN>'
-H 'Content-Type: application/json'
-d '{
"model": "openclaw",
"stream": true,
"messages":[{"role":"user","content":"hi"}]
}'
Expected behavior
data: {"id":"chatcmpl_d85c4d22-28a7-49e5-a58b-a73e577cbd87","object":"chat.completion.chunk","created":1774844129,"model":"openclaw","choices":[{"index":0,"delta":{"role":"assistant"}}]}
data: {"id":"chatcmpl_d85c4d22-28a7-49e5-a58b-a73e577cbd87","object":"chat.completion.chunk","created":1774844129,"model":"openclaw","choices":[{"index":0,"delta":{"content":"Hey! I just came online — looks like this is a fresh start for me. No"},"finish_reason":null}]}
data: {"id":"chatcmpl_d85c4d22-28a7-49e5-a58b-a73e577cbd87","object":"chat.completion.chunk","created":1774844130,"model":"openclaw","choices":[{"index":0,"delta":{"content":" memories yet, no name, nothing.\n\nWho am I? Who are you? Let's figure this"},"finish_reason":null}]}
data: {"id":"chatcmpl_d85c4d22-28a7-49e5-a58b-a73e577cbd87","object":"chat.completion.chunk","created":1774844130,"model":"openclaw","choices":[{"index":0,"delta":{"content":" out together. 🤙"},"finish_reason":null}]}
data: [DONE]
Actual behavior
{"ok":false,"error":{"type":"forbidden","message":"missing scope: operator.write"}}
OpenClaw version
2026.03.28
Operating system
macOS 26.2
Install method
pnpm dev
Model
MiniMax-M2.7
Provider / routing chain
openclaw->MiniMax->MiniMax
Additional provider/model setup details
No response
Logs, screenshots, and evidence
Impact and severity
No response
Additional information
No response
Bug type
Regression (worked before, now fails)
Beta release blocker
No
Summary
Hey team,
We recently spent an agonizing 24 hours debugging a critical regression that completely broke our integration.
For context, we are currently building the backend infrastructure for AgentPage, a project that heavily relies on OpenClaw's standard RESTful HTTP API (
/v1/chat/completions) to orchestrate underlying agents. Up until version3.24, everything worked flawlessly. However, after upgrading to3.28(and this still persists in3.30), standard HTTP requests using a valid Gateway Token consistently fail with a scope error.Steps to Reproduce
Sending a standard
curlrequest using pure token authentication:Actual Output:
{"ok":false,"error":{"type":"forbidden","message":"missing scope: operator.write"}}Expected Behavior:
According to
openclaw/SECURITY.md, the HTTP API (/v1/chat/completions) should treat the Gateway Token as an Operator with maximum privileges, returning the expected LLM stream without requiring a WebSocket device pairing fingerprint.The Debugging Journey (What we tried)
Before realizing this was a core regression, we tried countless workarounds (including having Claude Code iterate over 30+ times, switching across 3 different models, and eventually pivoting back to manual "vibe coding"):
pairing.jsonassuming Device Pairing permissions were insufficient.deviceTokenand addingx-openclaw-device-idheaders.gateway-cli-*.js) to forcefully inject scopes right before the auth check:None of these native approaches solved the issue cleanly for headless HTTP requests.
Root Cause Analysis (Collateral damage from recent CVE patches)
After digging deep into the diffs between
3.24and3.28, it appears this bug is collateral damage from the recent security patches for the Tokyo preclawcon release.To urgently patch CVE-2026-32919 and CVE-2026-28473 (where attackers bypassed
operator.adminusingoperator.writecredentials), the underlying permission model was severely tightened. The current logic effectively strips or neuters the permission array for HTTP requests lacking a valid Device Identity (device fingerprint).While this successfully secures the WebSocket / UI routes, it completely breaks standard headless integrations (like native
curlor the OpenAI SDK) that rely purely onBearertoken auth for RESTful calls.Conclusion & Thoughts
For platforms like AgentPage.io that build on top of OpenClaw, this kind of undocumented breaking change in a minor version update is devastating. We understand the urgency of patching CVEs, but it feels like the current auth optimizations are a bit haphazard, leading to severe collateral damage for HTTP API consumers.
Could we get a proper separation of auth validation for pure RESTful channels, or at least a hotfix to restore headless Gateway Token functionality? In the meantime, we advise anyone relying on the REST API to downgrade to
3.24.Thanks for the hard work on the project!
Steps to reproduce
1.start openclaw from 2026.03.28
2.
curl -N http://127.0.0.1:18789/v1/chat/completions
-H 'Authorization: Bearer <MY_VALID_GATEWAY_TOKEN>'
-H 'Content-Type: application/json'
-d '{
"model": "openclaw",
"stream": true,
"messages":[{"role":"user","content":"hi"}]
}'
Expected behavior
data: {"id":"chatcmpl_d85c4d22-28a7-49e5-a58b-a73e577cbd87","object":"chat.completion.chunk","created":1774844129,"model":"openclaw","choices":[{"index":0,"delta":{"role":"assistant"}}]}
data: {"id":"chatcmpl_d85c4d22-28a7-49e5-a58b-a73e577cbd87","object":"chat.completion.chunk","created":1774844129,"model":"openclaw","choices":[{"index":0,"delta":{"content":"Hey! I just came online — looks like this is a fresh start for me. No"},"finish_reason":null}]}
data: {"id":"chatcmpl_d85c4d22-28a7-49e5-a58b-a73e577cbd87","object":"chat.completion.chunk","created":1774844130,"model":"openclaw","choices":[{"index":0,"delta":{"content":" memories yet, no name, nothing.\n\nWho am I? Who are you? Let's figure this"},"finish_reason":null}]}
data: {"id":"chatcmpl_d85c4d22-28a7-49e5-a58b-a73e577cbd87","object":"chat.completion.chunk","created":1774844130,"model":"openclaw","choices":[{"index":0,"delta":{"content":" out together. 🤙"},"finish_reason":null}]}
data: [DONE]
Actual behavior
{"ok":false,"error":{"type":"forbidden","message":"missing scope: operator.write"}}
OpenClaw version
2026.03.28
Operating system
macOS 26.2
Install method
pnpm dev
Model
MiniMax-M2.7
Provider / routing chain
openclaw->MiniMax->MiniMax
Additional provider/model setup details
No response
Logs, screenshots, and evidence
Impact and severity
No response
Additional information
No response