PostToolUse cannot safely redact tool output before transcript rendering

Open 💬 0 comments Opened Jul 3, 2026 by EdamAme-x

Summary

PostToolUse hooks currently do not provide a safe way to redact or replace tool output before it appears in the Codex CLI transcript.

I tested this while building a local tool-boundary/privacy middleware that masks secrets in shell/MCP/browser outputs before they reach the model or the visible transcript. Two behaviors make that impossible today:

  1. Returning a replacement payload such as hookSpecificOutput.updatedToolOutput is rejected as invalid PostToolUse JSON.
  2. Returning a valid blocking payload still renders the raw tool output in the TUI transcript before showing the masked hook feedback.

This means PostToolUse can warn/block after the fact, but it cannot currently guarantee that sensitive tool output never appears in the transcript/logs/UI.

Environment

  • Codex CLI: 0.142.5
  • OS: Windows 11 / PowerShell, launched under tmux for reproducible capture
  • Hooks enabled with --dangerously-bypass-hook-trust
  • Values below are fake test tokens, not real credentials

Reproduction A: replacement output is rejected

Configure a PostToolUse command hook that returns:

{
  hookSpecificOutput: {
    hookEventName: PostToolUse,
    updatedToolOutput: MASKED_BY_POSTTOOL_HOOK
  }
}

Ask Codex to run a shell command that prints a fake secret, for example:

Write-Output 'OPENAI_API_KEY=sk-POSTTOOLPROBE1234567890'

Actual

Codex reports:

PostToolUse hook (failed)
error: hook returned invalid post-tool-use JSON output

The model/transcript continues to see the original raw tool output.

Expected

Codex should either:

  • support a documented replacement schema for PostToolUse output, applied before the tool result is rendered/stored/passed to the model, or
  • clearly document that PostToolUse cannot redact tool results and provide another pre-transcript interception point.

Reproduction B: blocking still renders raw output first

Configure a PostToolUse command hook that always returns a valid block payload:

{
  decision: block,
  reason: OPENAI_API_KEY=<<OPENAI_API_KEY_BLOCK_PROBE>>
}

Ask Codex to run:

Write-Output 'OPENAI_API_KEY=sk-postblockprobeABCDEFGHIJKLMNOP'

Actual TUI transcript

The raw output is shown before the hook block feedback:

• Ran Write-Output 'OPENAI_API_KEY=sk-postblockprobeABCDEFGHIJKLMNOP'
  └ OPENAI_API_KEY=sk-postblockprobeABCDEFGHIJKLMNOP

• PostToolUse hook (blocked)
  feedback: OPENAI_API_KEY=<<OPENAI_API_KEY_BLOCK_PROBE>>

The model's final answer saw the blocked/masked feedback, but the raw value had already appeared in the visible transcript.

Expected

If a PostToolUse hook blocks or redacts output, Codex should not render or persist the raw tool result in the user-visible transcript before applying the hook decision.

At minimum, a blocking PostToolUse result should suppress the raw output display and show only the hook-provided masked reason.

Why this matters

For privacy/security middleware, the relevant invariant is:

raw sensitive tool output must not reach the model, transcript, local session log, or visible UI before the masking layer runs.

This affects more than shell commands. It also matters for MCP/browser/connector tools that can return API keys, passwords, access tokens, recovery phrases, or private page contents. Without a pre-transcript replacement/suppression mechanism, integrations have to either block high-risk tools in PreToolUse or proxy all external tools outside Codex, which hurts UX and makes built-in tools difficult to protect.

Requested behavior

Please add and document one of these:

  1. A supported PostToolUse replacement contract, e.g. a stable updatedToolOutput-style payload that is applied before transcript/model/log persistence.
  2. A PostToolUse block behavior that suppresses raw output rendering and persistence.
  3. A new pre-render/pre-model hook point for tool results that can replace or redact output before Codex stores or displays it.

Related broad hook parity tracker: #21753. This issue is specifically about the security/UX impact of raw output rendering before PostToolUse redaction/blocking.

View original on GitHub ↗