Support sanitized replacement output for ReadTool
## Summary
Please add a supported way for hooks or plugins to replace/sanitize Read / file-read tool output before Codex renders it, stores it in the transcript, or passes it to the model.
This is related to #31015, but this issue is specifically about the native file-read surface. For privacy/security middleware, the best UX is not to block every Read call. The ideal behavior is:
- ordinary source files keep the normal Codex
Read/ file preview UI - files containing credentials or private values are read, sanitized, and shown as masked content
- masked placeholders remain usable by later tool calls where the local middleware can resolve them
- raw file content never appears in the transcript/model/logs before sanitization
Current problem
Today a middleware can either:
- block
ReadinPreToolUseand tell the model to use a shell/proxy command, which hurts UX and makes the transcript noisy, or - allow
Readand try to clean up inPostToolUse, which is unsafe if the raw file content is rendered or persisted before the hook can replace it.
That makes file reads much harder to protect than shell output, even though the native Read UI is exactly the UX users expect from Codex.
Requested behavior
Please add and document one of these contracts:
PostToolUsereplacement forReadoutput, applied before transcript/model/log persistence.- A pre-render / pre-model hook for tool results that can return sanitized
Readcontent. - A
PreToolUsecontract that lets a hook provide a synthetic sanitizedReadresult and skip the original file read.
Any of these would let security middleware preserve the native ReadTool UI while masking only the risky content.
Example desired flow
- Model calls
Readon a file. - Codex reads the file or asks a hook/plugin to inspect it.
- Middleware detects a fake credential-like value and replaces it with a handle such as
<<OPENAI_API_KEY_...>>. - Codex renders the normal Read result UI, but with the sanitized content only.
- Later write/shell tool calls can still use that handle; the local middleware resolves it without exposing the raw value back to the model.
Why this matters
Blocking all direct file reads is technically safer but makes Codex feel broken: users see deny/block messages and the agent has to switch to proxy shell commands for normal file inspection. A safe replacement contract would keep the native Codex experience while still allowing local privacy middleware to prevent credential leakage.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗