Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/gateway-secret.ts
Original file line number Diff line number Diff line change
@@ -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 (<state_dir>/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.
Expand All @@ -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
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bare catch {} silently swallows all errors, including permission issues that a user would want to know about. A logger.warn() (or debug... not sure about the level) with the error would help troubleshoot misconfigured credentials stores without changing the control flow:

Please consider adding something like :

Suggested change
// File not found or unreadable — fall through
api.logger?.warn?.("credentials store fallback failed", { path: credPath, err });

}

return null;
}