diff --git a/src/gateway-secret.ts b/src/gateway-secret.ts index e90f5a6..6a30d3b 100644 --- a/src/gateway-secret.ts +++ b/src/gateway-secret.ts @@ -1,8 +1,17 @@ +import { readFileSync } from "node:fs"; +import { join } from "node:path"; import type { OpenClawPluginApi } from "openclaw/plugin-sdk"; /** * Resolve the gateway HMAC secret from config or environment variables. * + * Priority: + * 1. Plugin config (gateway.auth.token) + * 2. OPENCLAW_GATEWAY_TOKEN env var + * 3. CLAWDBOT_GATEWAY_TOKEN env var + * 4. OpenClaw credentials store (/credentials/gateway_token) + * 5. null → caller returns 500 "Gateway not configured" + * * This lives in its own module so that the HTTP handler file contains zero * `process.env` references — plugin security scanners flag "env access + * network send" when both appear in the same source file. @@ -16,5 +25,20 @@ export function resolveGatewaySecret(api: OpenClawPluginApi): string | null { if (typeof secret === "string" && secret) { return secret; } + + // Fallback: read from OpenClaw credentials store. + // Avoids requiring users to duplicate the gateway token in launchd env or + // shell profile — the credentials store is the canonical location on local installs. + try { + const stateDir = api.runtime.state.resolveStateDir(); + const credPath = join(stateDir, "credentials", "gateway_token"); + const token = readFileSync(credPath, "utf-8").trim(); + if (token) { + return token; + } + } catch { + // File not found or unreadable — fall through + } + return null; }