Summary
When an agent calls gateway config.get (or shell commands like env, printenv), resolved secrets are returned and persisted to session transcripts (.jsonl files). This creates a systemic security issue where API keys, bot tokens, and other credentials end up stored in plaintext on disk, even when users follow best practices like storing secrets in environment variables.
Reproduction
-
Configure OpenClaw with secrets using env var substitution:
{
channels: {
telegram: { botToken: "${TELEGRAM_BOT_TOKEN}" }
},
skills: {
entries: {
goplaces: { apiKey: "${GOOGLE_PLACES_API_KEY}" }
}
}
}
-
In a chat session, ask the agent to check the current config (or the agent decides to do so autonomously)
-
Agent calls gateway config.get tool
-
The tool returns the resolved config with actual secret values:
{
"channels": {
"telegram": { "botToken": "8236723808:AAG33tn..." }
}
}
-
This response is written to ~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl
-
Secrets are now persisted in plaintext on disk
Scope of the Problem
This affects all OpenClaw users who:
- Use the
gateway tool (specifically config.get)
- Have agents that run
env, printenv, set, or similar shell commands
- Use any tool that might echo environment variables
Even users who correctly use 1Password, env vars, or other secret management are vulnerable because the resolution happens at tool execution time and the resolved values flow into transcripts.
Current Mitigations (Insufficient)
| Mitigation |
Limitation |
logging.redactSensitive: "tools" |
Only affects console output, not transcripts |
logging.redactPatterns |
Same - console only |
File permissions (chmod 600) |
Limits disk access but secrets still written |
| Behavioral rules (RULES.md) |
Relies on model compliance - can be bypassed |
| Manual transcript scrubbing |
Reactive, not preventive |
Suggested Fixes
1. config.get should return placeholders by default
The config.get RPC should return ${VAR_NAME} placeholders instead of resolved values. Add an explicit flag for when resolution is actually needed:
// Default behavior - safe for transcripts
config.get() → { botToken: "${TELEGRAM_BOT_TOKEN}" }
// Explicit opt-in for debugging (should require elevated permissions)
config.get({ resolve: true }) → { botToken: "actual-value" }
2. Extend redaction to transcripts
Apply redactPatterns (and built-in patterns for common API key formats) to tool outputs before writing to session transcripts:
// Before writing to .jsonl
const sanitized = applyRedactionPatterns(toolOutput, config.logging.redactPatterns);
transcript.write(sanitized);
3. Tool-level output filtering
Add a tools.redactOutput config that scrubs sensitive patterns from tool results before they enter the session:
{
tools: {
redactOutput: {
enabled: true,
patterns: [
"sk-[a-zA-Z0-9]{20,}", // OpenAI keys
"[0-9]+:AA[a-zA-Z0-9_-]+", // Telegram tokens
"AIza[a-zA-Z0-9_-]{35}", // Google API keys
"ghp_[a-zA-Z0-9]{36}" // GitHub PATs
]
}
}
}
4. Prohibit dangerous commands in default tool policy
Consider adding env, printenv, set, and gateway config.get to a default denylist (or requiring explicit opt-in) when secrets are configured.
5. Automatic transcript scrubbing (optional)
A background job or on-write hook that scrubs known secret patterns from transcripts, similar to what detect-secrets does for git repos.
Related Issues
Environment
- OpenClaw version: 2026.1.30
- Platform: macOS (Apple Silicon)
- Channel: Telegram
Workaround (Current)
We created a manual scrub script and added rules to our agent's RULES.md prohibiting these commands:
### Secret-Leaking Commands (NEVER EXECUTE)
- `env` or `printenv`
- `gateway config.get`
- `echo $SECRET_VAR`
- `set`
This is fragile because it relies on the model obeying instructions.
This is a systemic issue affecting all OpenClaw deployments. Even security-conscious users who follow best practices (env vars, 1Password, etc.) are vulnerable because secrets are resolved and persisted at runtime.
Summary
When an agent calls
gateway config.get(or shell commands likeenv,printenv), resolved secrets are returned and persisted to session transcripts (.jsonlfiles). This creates a systemic security issue where API keys, bot tokens, and other credentials end up stored in plaintext on disk, even when users follow best practices like storing secrets in environment variables.Reproduction
Configure OpenClaw with secrets using env var substitution:
In a chat session, ask the agent to check the current config (or the agent decides to do so autonomously)
Agent calls
gateway config.gettoolThe tool returns the resolved config with actual secret values:
{ "channels": { "telegram": { "botToken": "8236723808:AAG33tn..." } } }This response is written to
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonlSecrets are now persisted in plaintext on disk
Scope of the Problem
This affects all OpenClaw users who:
gatewaytool (specificallyconfig.get)env,printenv,set, or similar shell commandsEven users who correctly use 1Password, env vars, or other secret management are vulnerable because the resolution happens at tool execution time and the resolved values flow into transcripts.
Current Mitigations (Insufficient)
logging.redactSensitive: "tools"logging.redactPatternschmod 600)Suggested Fixes
1.
config.getshould return placeholders by defaultThe
config.getRPC should return${VAR_NAME}placeholders instead of resolved values. Add an explicit flag for when resolution is actually needed:2. Extend redaction to transcripts
Apply
redactPatterns(and built-in patterns for common API key formats) to tool outputs before writing to session transcripts:3. Tool-level output filtering
Add a
tools.redactOutputconfig that scrubs sensitive patterns from tool results before they enter the session:4. Prohibit dangerous commands in default tool policy
Consider adding
env,printenv,set, andgateway config.getto a default denylist (or requiring explicit opt-in) when secrets are configured.5. Automatic transcript scrubbing (optional)
A background job or on-write hook that scrubs known secret patterns from transcripts, similar to what
detect-secretsdoes for git repos.Related Issues
Environment
Workaround (Current)
We created a manual scrub script and added rules to our agent's RULES.md prohibiting these commands:
This is fragile because it relies on the model obeying instructions.
This is a systemic issue affecting all OpenClaw deployments. Even security-conscious users who follow best practices (env vars, 1Password, etc.) are vulnerable because secrets are resolved and persisted at runtime.