picoclaw

Sensitive Data Filtering

PicoClaw can filter sensitive values (API keys, tokens, secrets, passwords) from tool call results before they are sent to the LLM. This prevents the LLM from seeing its own credentials, which could otherwise leak through tool output or cause confusing behavior.


Overview

When the LLM uses a tool that returns its own credentials (e.g., a tool that echoes the API key being used), those values are automatically replaced with [FILTERED] in the message sent to the LLM.

Sensitive values are collected from .security.yml — the centralized storage for all sensitive configuration (API keys, tokens, secrets stored alongside config.json). This includes:


Configuration

Sensitive data filtering is configured in the tools section of config.json:

Config Type Default Description
filter_sensitive_data bool true Enable/disable filtering. When false, no filtering is performed.
filter_min_length int 8 Minimum content length to trigger filtering. Short content is skipped for performance.
{
  "tools": {
    "filter_sensitive_data": true,
    "filter_min_length": 8
  }
}

Environment Variable

Variable Description
PICOCLAW_TOOLS_FILTER_SENSITIVE_DATA Set to true or false to override the config value

How It Works

  1. On startup: All sensitive values are collected from .security.yml using reflection and compiled into a strings.Replacer (O(n+m) performance, computed once).

  2. Per tool result: Before sending any tool result content to the LLM:
    • If filter_sensitive_data is false, content is passed through unchanged
    • If content length < filter_min_length, content is passed through unchanged (fast path)
    • Otherwise, all sensitive values are replaced with [FILTERED]
  3. Replacement: Uses strings.Replacer for efficient O(n+m) string substitution, where n = content length and m = total sensitive value length.

Logging

Tool call logs (registry, tool loop and agent execution pipeline) record only the argument names and their count, never the argument values. Secrets passed to a tool are therefore not written to log files. This is independent of filter_sensitive_data, which only applies to the content sent to the LLM.


Example

Given the following .security.yml:

model_list:
  my-model:
    api_keys:
      - sk-secret-key-12345

channels:
  telegram:
    token: "123456:ABC-DEF"

And a tool result containing:

The model is using API key sk-secret-key-12345 and Telegram bot 123456:ABC-DEF

The LLM will receive:

The model is using API key [FILTERED] and Telegram bot [FILTERED]

Performance


Security Considerations