openclaw - ✅(Solved) Fix [Security] Sensitive credentials exposed in plain text in Control UI tool call display [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#72283Fetched 2026-04-27 05:32:03
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Author
Participants
Timeline (top)
labeled ×2cross-referenced ×1

Sensitive credentials (API keys, tokens, secrets) are exposed in plain text in the Control UI tool call display. When the assistant reads or modifies configuration files via tool calls, all sensitive values like apiKey, apiSecret, and accessToken are displayed without masking or redaction.

Root Cause

Sensitive credentials (API keys, tokens, secrets) are exposed in plain text in the Control UI tool call display. When the assistant reads or modifies configuration files via tool calls, all sensitive values like apiKey, apiSecret, and accessToken are displayed without masking or redaction.

Fix Action

Fixed

PR fix notes

PR #72319: fix(agents): redact secrets in tool call output to Control UI

Description (problem / solution / changelog)

Fixes #72283

Problem

Tool call results streamed to the Control UI render configuration JSON in plaintext, including provider API keys (OpenRouter, Ollama, Tavily…), channel credentials, and auth tokens. The same data is already redacted in /config show (config.get) and skills.update responses — tool call output was bypassing the redaction layer.

The leak is reproducible by asking the assistant to inspect plugin/model configuration: any tool whose text output happens to contain credentials (read of a config file, bash/exec running cat, plugin/MCP tools dumping their state) emits the plaintext over the agent-event websocket.

Fix

sanitizeToolResult() in src/agents/pi-embedded-subscribe.tools.ts is the chokepoint every tool result passes through on its way to the Control UI — both handleToolExecutionUpdate (partial) and handleToolExecutionEnd (final) call it before emitAgentEvent.

This PR runs each text content block through the existing redactSensitiveText(..., { mode: "tools" }) helper from src/logging/redact.ts before truncation. That utility already covers the patterns called out in the issue — JSON apiKey, ENV-style *_KEY=/*_TOKEN=/*_SECRET= assignments, Authorization: Bearer …, PEM blocks, and common token prefixes (sk-, ghp_, xox[baprs]-, AIza…, pplx-, gsk_, npm_, Telegram bot tokens) — and is the same utility used elsewhere for log redaction.

Production change: 1 import + 1 line. No new abstractions, no per-tool patches.

Tests

Added 5 new cases to pi-embedded-subscribe.tools.test.ts covering:

  • JSON-style "apiKey": "…" field
  • ENV-style OPENROUTER_API_KEY=… assignment
  • Bare common-prefix tokens (sk-…, ghp_…)
  • Authorization: Bearer … header
  • Passthrough of non-sensitive text (no false positives)
  • Existing image-content stripping behavior preserved (regression check)

Verification

  • pnpm exec vitest run src/agents/pi-embedded-subscribe.tools.test.ts — 8/8 passed
  • pnpm tsgo:core:test — exit 0, no diagnostics
  • Manual repro of issue's steps (open Control UI, ask for plugin/model config, confirm credentials are masked in tool call output)

Changed files

  • src/agents/pi-embedded-subscribe.handlers.tools.test.ts (modified, +87/-1)
  • src/agents/pi-embedded-subscribe.handlers.tools.ts (modified, +5/-3)
  • src/agents/pi-embedded-subscribe.tools.test.ts (modified, +126/-1)
  • src/agents/pi-embedded-subscribe.tools.ts (modified, +47/-21)
  • src/logging/redact.ts (modified, +16/-0)

Code Example

"apiKey": "sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

---
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Sensitive credentials (API keys, tokens, secrets) are exposed in plain text in the Control UI tool call display. When the assistant reads or modifies configuration files via tool calls, all sensitive values like apiKey, apiSecret, and accessToken are displayed without masking or redaction.

Steps to reproduce

  1. Open Control UI webchat
  2. Ask the assistant to check plugin or model configuration
  3. Tool call output displays openclaw.json with all API keys in plain text

Expected behavior

Sensitive fields should be automatically masked/redacted before being rendered in the Control UI, consistent with the existing redaction already implemented in:

  • /config show replies (redact secrets ✅)
  • skills.update response (redact secrets ✅)

Actual behavior

API keys and tokens are visible in plain text in tool call outputs, including:

  • Provider API keys (openrouter, ollama, tavily, scnet, modelscope, etc.)
  • Channel credentials
  • Authentication tokens (gateway auth token)
  • Any other apiKey / secret fields in openclaw.json

Example:

  "apiKey": "sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

OpenClaw version

2026.04.24

Operating system

docker

Install method

No response

Model

minimax m2.5

Provider / routing chain

openclaw

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

Anyone with access to the Control UI can view all API keys and credentials in plain text, enabling potential unauthorized access to external services (LLM providers, messaging channels, etc.). This is especially critical in shared or multi-user environments.

Additional information

No response

extent analysis

TL;DR

Masking or redacting sensitive fields like API keys and tokens in the Control UI tool call display is necessary to prevent exposure.

Guidance

  • Review the existing redaction implementation in /config show replies and skills.update response to understand how sensitive fields are currently being masked.
  • Modify the tool call output rendering in the Control UI to apply similar redaction to sensitive fields like apiKey, apiSecret, and accessToken.
  • Verify that the redaction is applied consistently across all tool call outputs, including those related to plugin or model configuration.
  • Consider implementing a global configuration option to control the redaction of sensitive fields in the Control UI.

Example

No specific code snippet can be provided without more context, but the redaction logic from /config show replies or skills.update response can be used as a reference.

Notes

The exact implementation details may vary depending on the underlying technology stack and framework used in the Control UI. It is essential to ensure that the redaction is applied correctly to prevent any potential security vulnerabilities.

Recommendation

Apply a workaround by modifying the tool call output rendering in the Control UI to mask sensitive fields, as the existing redaction implementation in other parts of the system can be used as a reference.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Sensitive fields should be automatically masked/redacted before being rendered in the Control UI, consistent with the existing redaction already implemented in:

  • /config show replies (redact secrets ✅)
  • skills.update response (redact secrets ✅)

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING