Fix onboard ignoring OPENCLAW_GATEWAY_TOKEN env var (#22658)

* Fix onboard ignoring OPENCLAW_GATEWAY_TOKEN env var

When running onboard via docker-setup.sh, the QuickStart wizard
generates its own 48-char token instead of using the 64-char token
already set in OPENCLAW_GATEWAY_TOKEN. This causes a token mismatch
that breaks all CLI commands after setup.

Check process.env.OPENCLAW_GATEWAY_TOKEN before falling back to
randomToken() in both the interactive QuickStart path and the
non-interactive path.

Closes #22638

Co-authored-by: Clawborn <tianrun.yang103@gmail.com>

* Tests: cover quickstart env token fallback

* Changelog: note docker onboarding token parity fix

* Tests: restore env var after non-interactive token fallback test

* Update CHANGELOG.md

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
Clawborn
2026-03-02 11:40:40 +08:00
committed by GitHub
parent 8e69fd80e0
commit 77ccd35e5e
5 changed files with 88 additions and 4 deletions

View File

@@ -149,6 +149,46 @@ describe("onboard (non-interactive): gateway and remote auth", () => {
});
}, 60_000);
it("uses OPENCLAW_GATEWAY_TOKEN when --gateway-token is omitted", async () => {
await withStateDir("state-env-token-", async (stateDir) => {
const envToken = "tok_env_fallback_123";
const workspace = path.join(stateDir, "openclaw");
const prevToken = process.env.OPENCLAW_GATEWAY_TOKEN;
process.env.OPENCLAW_GATEWAY_TOKEN = envToken;
try {
await runNonInteractiveOnboarding(
{
nonInteractive: true,
mode: "local",
workspace,
authChoice: "skip",
skipSkills: true,
skipHealth: true,
installDaemon: false,
gatewayBind: "loopback",
gatewayAuth: "token",
},
runtime,
);
const configPath = resolveStateConfigPath(process.env, stateDir);
const cfg = await readJsonFile<{
gateway?: { auth?: { mode?: string; token?: string } };
}>(configPath);
expect(cfg?.gateway?.auth?.mode).toBe("token");
expect(cfg?.gateway?.auth?.token).toBe(envToken);
} finally {
if (prevToken === undefined) {
delete process.env.OPENCLAW_GATEWAY_TOKEN;
} else {
process.env.OPENCLAW_GATEWAY_TOKEN = prevToken;
}
}
});
}, 60_000);
it("writes gateway.remote url/token and callGateway uses them", async () => {
await withStateDir("state-remote-", async () => {
const port = getPseudoPort(30_000);