openclaw - ✅(Solved) Fix [Security]: Log redaction parity across sinks — file logs, console, and diagnostic traces [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#67953Fetched 2026-04-18 05:54:33
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×1mentioned ×1subscribed ×1unsubscribed ×1

Error Message

| P1 | Cache trace | Yes | Medium | prompt/note/error unredacted; other fields already sanitized | | P1 | Anthropic payload log | Yes | Medium | error/usage events written raw |

Fix Action

Fixed

PR fix notes

PR #68136: fix(logging): add sink-level log redaction gate

Description (problem / solution / changelog)

Summary

  • Problem: log redaction was applied inconsistently at logging call sites, so file logs and external transports could still persist raw secrets even when some console-facing paths were masked.
  • Why it matters: #67953 is part of #64046 P0-1 security work; persisted plaintext secrets in logs are higher risk than display-only leaks.
  • What changed: add a shared sink-level redaction gate, sanitize logger file/transport writes, and add regression coverage for console capture, file log writes, subsystem file logging, and the new shared sink helper.
  • What did NOT change (scope boundary): this PR does not attempt the broader trace/JSONL/OTEL follow-up sinks planned for later PRs.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #67953
  • Related #64046
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: redaction lived mostly in upstream call sites instead of a final sink-level write boundary, so file serialization and registered transports could observe unsanitized records.
  • Missing detection / guardrail: there was no regression coverage asserting that persisted file log content and transport payloads were sanitized before write-out.
  • Contributing context (if known): console-facing behavior and read-side log-tail masking reduced visibility of the persistence leak, but did not protect at-rest log content.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/logging/redact-sink.test.ts
    • src/logging/console-capture.test.ts
    • src/logging/log-file-size-cap.test.ts
    • src/logging/subsystem.test.ts
  • Scenario the test should lock in: bearer/api-key-like secrets are masked before file logging and before external log transports receive a record, while existing console override behavior stays intact.
  • Why this is the smallest reliable guardrail: the bug sits in shared logging write boundaries, so focused logging tests catch the regression without requiring live runtime processes.
  • Existing test that already covers this (if any): none fully covered sink-level parity before this PR.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • File logs and registered log transports now receive sanitized records instead of raw secret-bearing payloads.
  • Console capture forwarded into file logs is sanitized before persistence.
  • Subsystem file logging sanitizes message and meta while preserving consoleMessage override behavior for console output.

Diagram (if applicable)

Before:
[log call] -> [optional call-site redaction] -> [file/transport write may persist raw secret]

After:
[log call] -> [shared sink redaction gate] -> [file/transport write persists masked content]

Security Impact (required)

  • New permissions/capabilities? (Yes/No): No
  • Secrets/tokens handling changed? (Yes/No): Yes
  • New/changed network calls? (Yes/No): No
  • Command/tool execution surface changed? (Yes/No): No
  • Data access scope changed? (Yes/No): No
  • If any Yes, explain risk + mitigation: log persistence paths now sanitize secret-like strings before write-out; risk is over-redaction in logs, mitigated by focused regression tests and keeping the existing console override semantics intact.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node.js + corepack pnpm
  • Model/provider: N/A
  • Integration/channel (if any): N/A
  • Relevant config (redacted): file logging enabled with bearer/api-key-like sample values

Steps

  1. Enable file logging and emit log records / console capture / subsystem logs containing bearer or api-key-like secrets.
  2. Inspect the persisted log file and any registered external transport payloads.
  3. Compare pre-fix raw secret persistence vs. post-fix masked values.

Expected

  • Persisted log content and external transport payloads contain masked values instead of raw secrets.

Actual

  • Prior to this change, sink-level writes could persist raw secrets despite partial call-site redaction.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios:
    • corepack pnpm build
    • file/transport redaction regression coverage in console-capture, log-file-size-cap, and subsystem
    • corepack pnpm exec vitest run --config test/vitest/vitest.unit-fast.config.ts for src/logging/redact-sink.test.ts
    • targeted lint/static checks via run-oxlint, check-no-conflict-markers, tool-display --check, generate-host-env-security-policy-swift --check, run-tsgo.mjs
  • Edge cases checked:
    • nested objects/arrays
    • Error payloads and circular references
    • redaction-off short-circuit behavior
    • subsystem consoleMessage override remains console-only
  • What you did not verify:
    • live runtime / docker / full project test matrix in this environment
    • one unrelated local failure remains in src/logging/logger-timestamp.test.ts when running the full logging suite; it is outside this PR's touched files

AI-assisted transparency

  • This PR is AI-assisted.
  • Testing level: lightly tested (targeted build/static checks and focused logging tests only; no live/openclaw-process test runs in this environment).
  • I reviewed and understand the generated code and test coverage.
  • Local agent review was run before opening the PR.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes/No): Yes
  • Config/env changes? (Yes/No): No
  • Migration needed? (Yes/No): No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: sink-level redaction could mask more content than previous call-site-only behavior.
    • Mitigation: keep redaction logic shared with existing patterns and lock behavior with focused regression tests.
  • Risk: this PR does not yet cover later follow-up sinks (trace/JSONL/OTEL).
    • Mitigation: scope is explicitly limited to PR #1 logging sinks; follow-up work remains tracked under #67953 / #64046.

Changed files

  • src/logging/console-capture.test.ts (modified, +16/-0)
  • src/logging/log-file-size-cap.test.ts (modified, +30/-3)
  • src/logging/logger.ts (modified, +4/-2)
  • src/logging/redact-sink.test.ts (added, +69/-0)
  • src/logging/redact-sink.ts (added, +192/-0)
  • src/logging/subsystem.test.ts (modified, +38/-1)
RAW_BUFFERClick to expand / collapse

Sub-issue of #64046

Maintainer Requirements

FieldContent
ScopeFile logs, console logs, diagnostic traces, and all direct log adapters
DeliverableA shared redaction entry point consumed by every log sink
Acceptance CriteriaSensitive fields/tokens are redacted in all sinks under default config; known leak scenarios from related issues have test coverage

Problem Statement

Console log output applies secret redaction, but file logs, diagnostic traces, and other direct log adapters do not go through the same redaction gate. This creates an inconsistency where secrets that are masked on screen are written in plaintext to persistent storage.

Sink Status

PrioritySinkDefault on?SensitivityGap
P0Main file logYesCriticalRaw JSON.stringify(logObj), no redaction
P0External transportsYesCriticalPlugins receive raw logObj
P0Console capture relayYesHighForwarded to file logger unredacted
P0Subsystem file pathYesHighOnly console path has consoleMessage protection
P1ACP spawn streamYesMedium-HighJSONL fire-and-forget, assistant_delta may contain tokens
P1Cache traceYesMediumprompt/note/error unredacted; other fields already sanitized
P1Anthropic payload logYesMediumerror/usage events written raw
P2OTEL log exportNoMediumHas standalone redaction, not shared gate
P2Raw streamNoHighCompletely raw, off by default
P2Config audit / cron logYesLowLow frequency

Core design

  • Shared gate — new redact-sink.ts, all sinks call it at their write boundary
  • Sink-level, not call-site — gate runs before JSON.stringify / appendFile / transport callback
  • Failure-safe — redaction errors fall back to original content, no exceptions on hot path
  • Config-aware — honors logging.redactSensitive; short-circuits when "off"
  • Defense in depthlog-tail read-side redaction retained for old log files

Breakdown

PRScopeSummary
Phase 1src/logging/Shared gate + P0 sinks (file log, transports, console relay, subsystem file path)
Phase 2src/agents/P1 diagnostic traces (acp-stream, cache-trace, anthropic-payload-log)
Phase 3+Extensions + long-tailOTEL unification, raw-stream, config audit, extension sinks — based on maintainer feedback

extent analysis

TL;DR

Implement a shared redaction entry point in redact-sink.ts to ensure consistent secret redaction across all log sinks.

Guidance

  • Identify and prioritize log sinks based on their sensitivity and default configuration, focusing on P0 sinks (Main file log, External transports, Console capture relay, Subsystem file path) first.
  • Develop a shared redaction gate in redact-sink.ts that honors logging.redactSensitive configuration and short-circuits when set to "off".
  • Integrate the shared redaction gate into each log sink, ensuring it runs before JSON.stringify or transport callbacks to prevent sensitive data from being written to persistent storage.
  • Implement failure-safe redaction, allowing redaction errors to fall back to original content without exceptions on the hot path.

Example

// redact-sink.ts
export function redactSink(logObj: any): any {
  if (logging.redactSensitive === 'off') return logObj;
  // Redaction logic here
  return redactedLogObj;
}

// Example usage in a log sink
import { redactSink } from './redact-sink';
const logObj = { sensitiveField: 'secret' };
const redactedLogObj = redactSink(logObj);
JSON.stringify(redactedLogObj); // Redacted log object

Notes

The provided solution focuses on implementing a shared redaction gate and integrating it into log sinks. However, the actual redaction logic is not specified and may vary depending on the specific requirements and sensitivity of the data being logged.

Recommendation

Apply the workaround by implementing the shared redaction gate and integrating it into log sinks, as this will ensure consistent secret redaction across all log sinks and address the identified inconsistency.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING