Files
moltbot/src/cli/root-guard.ts
忻役 ca8121d22b fix: add root guard to prevent CLI execution as root (#67478)
Block openclaw CLI from running as root (uid 0) to prevent:
- Separate state directory at /root/.openclaw/
- Conflicting systemd user services racing on port 18789
- Root-owned files in the service user state dir (EACCES)

The guard runs early in src/entry.ts before any state/config operations.
Root-level --help and --version bypass the guard so users can discover
the OPENCLAW_ALLOW_ROOT=1 override. Subcommand help paths still enforce
the guard since they enter runCli() and resolve state directories.

Closes #67478
2026-05-07 23:31:03 -04:00

35 lines
1.1 KiB
TypeScript

import process from "node:process";
/**
* Block CLI execution when running as root (uid 0) unless explicitly opted in.
*
* Running as root causes:
* - Separate state dir (/root/.openclaw/ vs /home/<user>/.openclaw/)
* - Conflicting systemd user services (port 18789 race)
* - Root-owned files in the service user's state dir (EACCES)
*/
export function assertNotRoot(env: NodeJS.ProcessEnv = process.env): void {
if (typeof process.getuid !== "function") {
return;
}
if (process.getuid() !== 0) {
return;
}
if (env.OPENCLAW_ALLOW_ROOT === "1") {
return;
}
process.stderr.write(
"[openclaw] Refusing to run as root.\n" +
"\n" +
"Running the CLI as root causes:\n" +
" - A separate state directory under /root/.openclaw/ instead of the service user's\n" +
" - Conflicting systemd user services that race on port 18789\n" +
" - Root-owned files in the service user's state dir (EACCES errors)\n" +
"\n" +
"Run as a non-root user (e.g. su - <service-user>),\n" +
"or override this check:\n" +
" OPENCLAW_ALLOW_ROOT=1 openclaw ...\n",
);
process.exit(1);
}