fix(gateway): default-deny missing connect scopes

This commit is contained in:
Peter Steinberger
2026-02-09 21:32:51 -06:00
parent 27453f5a31
commit cfd112952e
5 changed files with 184 additions and 24 deletions

View File

@@ -290,7 +290,11 @@ export async function startGatewayServer(port: number, opts?: GatewayServerOptio
return await mod.startGatewayServer(port, resolvedOpts);
}
export async function startServerWithClient(token?: string, opts?: GatewayServerOptions) {
export async function startServerWithClient(
token?: string,
opts?: GatewayServerOptions & { wsHeaders?: Record<string, string> },
) {
const { wsHeaders, ...gatewayOpts } = opts ?? {};
let port = await getFreePort();
const prev = process.env.OPENCLAW_GATEWAY_TOKEN;
if (typeof token === "string") {
@@ -310,7 +314,7 @@ export async function startServerWithClient(token?: string, opts?: GatewayServer
let server: Awaited<ReturnType<typeof startGatewayServer>> | null = null;
for (let attempt = 0; attempt < 10; attempt++) {
try {
server = await startGatewayServer(port, opts);
server = await startGatewayServer(port, gatewayOpts);
break;
} catch (err) {
const code = (err as { cause?: { code?: string } }).cause?.code;
@@ -324,7 +328,10 @@ export async function startServerWithClient(token?: string, opts?: GatewayServer
throw new Error("failed to start gateway server after retries");
}
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
const ws = new WebSocket(
`ws://127.0.0.1:${port}`,
wsHeaders ? { headers: wsHeaders } : undefined,
);
await new Promise<void>((resolve, reject) => {
const timer = setTimeout(() => reject(new Error("timeout waiting for ws open")), 10_000);
const cleanup = () => {
@@ -415,7 +422,11 @@ export async function connectReq(
: process.env.OPENCLAW_GATEWAY_PASSWORD;
const token = opts?.token ?? defaultToken;
const password = opts?.password ?? defaultPassword;
const requestedScopes = Array.isArray(opts?.scopes) ? opts?.scopes : [];
const requestedScopes = Array.isArray(opts?.scopes)
? opts.scopes
: role === "operator"
? ["operator.admin"]
: [];
const device = (() => {
if (opts?.device === null) {
return undefined;
@@ -455,7 +466,7 @@ export async function connectReq(
commands: opts?.commands ?? [],
permissions: opts?.permissions ?? undefined,
role,
scopes: opts?.scopes,
scopes: requestedScopes,
auth:
token || password
? {