Question
We noticed that when deploying an AgentHarness with the openclaw backend, the real API key and Slack tokens are visible in the openclaw process environment (PID's /proc/\<pid\>/environ), even though openclaw.json uses openshell:resolve:env:* placeholders.
What we observed
openclaw.json correctly uses placeholders:
"apiKey": "openshell:resolve:env:OPENAI_API_KEY"
"botToken": "xoxb-OPENSHELL-RESOLVE-ENV-SLACK_BOT_TOKEN_PLATFORM"
But the sandbox process env has the real values:
OPENAI_API_KEY=sk-... (real key)
SLACK_BOT_TOKEN_PLATFORM=xoxb-... (real token)
SLACK_APP_TOKEN_PLATFORM=xapp-... (real token)
Where this comes from
Tracing the code, BuildBootstrapJSON (in openclaw/bootstrap.go) resolves the real credentials from k8s secrets and returns them in an env map. OnAgentHarnessReady (in openclaw.go) then passes that env map directly to ExecSandbox when running both the config install and openclaw gateway run:
// openclaw.go L105, L120
code, stderr, err = b.ExecSandbox(..., installCmd, jsonBytes, env, 120)
code, stderr, err = b.ExecSandbox(..., gatewayCmd, nil, env, 90)
This means the process that openclaw runs in has the real credentials in its environment, accessible to any tool the LLM spawns (e.g. process.env in Node.js, shell commands, etc.).
The design question
Our understanding of the openshell:resolve:env:* security model is:
openclaw.json stores placeholders — real credentials never written to disk
- The OpenShell proxy intercepts outbound requests from the sandbox
- Proxy looks up the real credential from the attached sandbox provider in OpenShell's store
- Proxy replaces the placeholder header with the real key before forwarding
If that model is correct, the sandbox process should never need the real credentials in its env — the proxy handles resolution exclusively from the provider store.
Is it intentional that ExecSandbox injects the real credentials into process env as well? Is there a threat model where this is considered safe, or is this a gap where the real credentials should be kept out of process env entirely and resolved only via the proxy?
Context
Question
We noticed that when deploying an
AgentHarnesswith theopenclawbackend, the real API key and Slack tokens are visible in the openclaw process environment (PID's/proc/\<pid\>/environ), even thoughopenclaw.jsonusesopenshell:resolve:env:*placeholders.What we observed
openclaw.jsoncorrectly uses placeholders:But the sandbox process env has the real values:
Where this comes from
Tracing the code,
BuildBootstrapJSON(inopenclaw/bootstrap.go) resolves the real credentials from k8s secrets and returns them in anenvmap.OnAgentHarnessReady(inopenclaw.go) then passes thatenvmap directly toExecSandboxwhen running both the config install andopenclaw gateway run:This means the process that openclaw runs in has the real credentials in its environment, accessible to any tool the LLM spawns (e.g.
process.envin Node.js, shell commands, etc.).The design question
Our understanding of the
openshell:resolve:env:*security model is:openclaw.jsonstores placeholders — real credentials never written to diskIf that model is correct, the sandbox process should never need the real credentials in its env — the proxy handles resolution exclusively from the provider store.
Is it intentional that
ExecSandboxinjects the real credentials into process env as well? Is there a threat model where this is considered safe, or is this a gap where the real credentials should be kept out of process env entirely and resolved only via the proxy?Context
940c478v2026.5.4with an OpenAI-compatible LiteLLM gateway