Skip to content

[Security] Agent tools expose secrets to session transcripts via config.get and env commands #5995

@K4LUTN

Description

@K4LUTN

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

  1. Configure OpenClaw with secrets using env var substitution:

    {
      channels: {
        telegram: { botToken: "${TELEGRAM_BOT_TOKEN}" }
      },
      skills: {
        entries: {
          goplaces: { apiKey: "${GOOGLE_PLACES_API_KEY}" }
        }
      }
    }
  2. In a chat session, ask the agent to check the current config (or the agent decides to do so autonomously)

  3. Agent calls gateway config.get tool

  4. The tool returns the resolved config with actual secret values:

    {
      "channels": {
        "telegram": { "botToken": "8236723808:AAG33tn..." }
      }
    }
  5. This response is written to ~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl

  6. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsecuritySecurity documentationstaleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions