fix: resolve gateway secret from OpenClaw credentials store#25
Conversation
If no secret is found in plugin config or env vars, fall back to reading <state_dir>/credentials/gateway_token via api.runtime.state.resolveStateDir(). This covers local installs where the HMAC secret lives in the credentials store rather than the process environment (e.g. launchd agents without shell profile sourcing). Existing priority order is preserved — env vars still take precedence over the credential file. No config schema changes.
contextablemark
left a comment
There was a problem hiding this comment.
Thank you for the submission! Overall, it's a clean, well-scoped fix and it's great that it's backward-compatible.
In addition to my inline suggestion, I would also expect some additional tests for the credentials-store fallback, since it isn't covered by any existing tests. It would be good to add cases for insuring that it :
-
Reads token from credentials store when config and env are absent (happy path)
-
Returns null when credentials file does not exist (or is empty or contains only whitespace) and fallback is attempted
-
Prefers existing plugin config over credentials store (i.e., preserves backwards compatibility)
Other extension test files (e.g. extensions/phone-control/index.test.ts, extensions/nostr/src/nostr-state-store.test.ts) provide examples of how to mock runtime.state.resolveStateDir)
Thanks again!
| return token; | ||
| } | ||
| } catch { | ||
| // File not found or unreadable — fall through |
There was a problem hiding this comment.
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 :
| // File not found or unreadable — fall through | |
| api.logger?.warn?.("credentials store fallback failed", { path: credPath, err }); |
Problem
On local installs where OpenClaw manages credentials via its credentials store (e.g.
~/.openclaw/credentials/gateway_token),resolveGatewaySecret()returnsnullbecause it only checks plugin config and env vars. This causes/v1/clawg-uito return:{"error":{"message":"Gateway not configured","type":"server_error"}}This is common when the gateway runs as a launchd agent — the HMAC secret exists in the credentials store but is not duplicated into the process environment.
Fix
Add a 4th fallback that reads
<state_dir>/credentials/gateway_tokenusingapi.runtime.state.resolveStateDir(). If the file is missing or unreadable, it silently falls through — no new failure modes.Priority order (unchanged for existing sources):
gateway.auth.token)OPENCLAW_GATEWAY_TOKENenv varCLAWDBOT_GATEWAY_TOKENenv var<state_dir>/credentials/gateway_token)null→ 500 Gateway not configuredNo config schema changes. Narrow, backward-compatible fix.