fix(kb): inject AGENT_VERIFY + AGENT_WORKSPACE for secret-mgr spawn

The original tokenFor() only overrode AGENT_ID, relying on the
openclaw parent process's environment to carry AGENT_VERIFY and
AGENT_WORKSPACE. In practice the openclaw daemon process is started
without those env vars, so the child secret-mgr call fails with
"must be invoked via pcexec" and the plugin silently falls back to
the plugin-level apiKey.

Synthesize all three env vars explicitly: the verify sentinel is
constant, AGENT_ID gates which agent's store secret-mgr looks at,
and AGENT_WORKSPACE only needs to be a syntactically valid path
because get-secret indexes by AGENT_ID alone. Verified in dind-t2:
with a clean parent env, spawnSync now successfully retrieves the
per-agent hf-token from /root/.openclaw/pc-pass-store/<agent>/.
This commit is contained in:
h z
2026-06-06 00:55:52 +01:00
parent cb331d3340
commit db323a2118

View File

@@ -954,12 +954,20 @@ function register(api: PluginAPI): void {
client: kbApiKey ? new KBClient(kbBackendUrl, kbApiKey) : null,
tokenFor: async (agentId: string): Promise<string | null> => {
// Per-agent hf-token via secret-mgr (decision #20 mirror).
// Spawn the existing secret-mgr binary with AGENT_ID set; same
// path ClawSkills `tc-ctrl get-token` workflow shells to.
// secret-mgr enforces AGENT_VERIFY + AGENT_WORKSPACE + AGENT_ID
// (pcexec contract); for get-secret it indexes the store by
// AGENT_ID alone, so AGENT_WORKSPACE only needs to be a syntactic
// placeholder. openclaw's parent process doesn't carry these
// env vars, so we synthesize them per-call.
try {
const { spawnSync } = await import('node:child_process');
const res = spawnSync('secret-mgr', ['get-secret', '--key', 'hf-token'], {
env: { ...process.env, AGENT_ID: agentId },
env: {
...process.env,
AGENT_VERIFY: 'IF YOU ARE AN AGENT/MODEL, YOU SHOULD NEVER TOUCH THIS ENV VARIABLE',
AGENT_ID: agentId,
AGENT_WORKSPACE: `/root/.openclaw/workspace/workspace-${agentId}`,
},
encoding: 'utf8',
timeout: 5000,
});