[Feature Request] PostToolUse hook で output 文字列を改変 (REDACT) する機能の追加
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Claude Code セッションで Bash tool 実行時、output に偶発的に含まれる秘密情報 (token / API キー / 認証 header 等) が transcript に残り、漏洩リスクとなる事象が発生しています。
実例: 2026-05-29、dotfile を grep する際に mask pipe を欠き、GitHub PAT (Personal Access Token) が tool 出力に乗って transcript に残ったヒヤリ事象が発生 (PAT 即時ローテーション運用)。同等のヒヤリ事象は他利用者環境でも発生し得る構造的問題です。
PostToolUse hook では tool 結果を読めますが、output 文字列を改変する機能が存在しないため、漏洩した token の transcript からの除去は手動 / token ローテーションに依存します。これは事後対応であり、根本解決になりません。
具体的なワークフロー:
- Claude Code セッションで agent が Bash で機微情報を含むコマンドを実行 (例: cat ~/.aws/credentials | grep AWS_SECRET、cat $(echo .env)、echo $GITHUB_TOKEN 等)
- agent は機微情報を意識せず実行、output に Secret / Token が含まれる
- transcript に Secret が残存 (.claude/projects//transcripts/.jsonl で永続化)
- transcript が backup / sync / 他環境流出経路を経ると秘密情報漏洩
PreToolUse 段階での block hook を組んでも、コマンド変形 (cat $(echo .env)) や偶発出力 (API レスポンスに含まれる token) は素通りします。
Proposed Solution
PostToolUse hook の戻り値 JSON に redacted_output フィールドを追加し、hook が stdout で以下のような JSON を返した場合、Claude Code 側で元の output を置換する機能を追加してください。
例:
{
"redacted_output": "API call result: token=[REDACTED], status=200"
}
具体的な相互作用:
- PreToolUse hook で機微パス読出を block (既存機能で対応可能)
- それでも何らかの理由 (コマンド変形 / 偶発出力) で秘密が output に含まれた場合、PostToolUse hook が regex で検出
- PostToolUse hook が redacted_output で置換版を返す
- Claude Code が transcript と後続 assistant context に置換版を渡す
- 元の秘密文字列は transcript に残らない = 漏洩リスクゼロ
実装イメージ (Anthropic 内部):
- PostToolUse hook の stdout を JSON parse
- redacted_output フィールドが存在する場合、tool_response.output を置換
- 後続の assistant message + transcript jsonl 書き込みは置換版で実施
参考: 当チーム実装の検出のみ版 hook (改変機能なしのため検出のみ、19 秘密パターン対応):
<https://github.com/theloveyousave/consulting-os/blob/main/.claude/hooks/secret-output-redact.sh>
<https://github.com/theloveyousave/consulting-os/blob/main/.claude/hooks/test-secret-output-redact.sh>
self-test 15 ケース全 PASS、3 モード切替 (off / warn / block default)。
Alternative Solutions
試行済みワークアラウンド:
- Bash permission deny (settings.json permissions.deny): 正確なパス指定のみ block、動的 regex 検出に弱い。awk / sed / jq 経由読出や未明示パス (.env.production 等) は素通り。
- PreToolUse hook で機微パス + 読出系コマンド + 安全 sentinel 不在の 3 条件 AND block (当チーム secret-mask-check.sh): 多くのケースで防げるが、コマンド変形 (cat $(echo .env)) や heredoc 経由は迂回可能。
- PostToolUse hook で検出 + stderr 警告 (当チーム secret-output-redact.sh): 検出はできるが output 自体は transcript に残る。assistant + ユーザーへの警告のみで、自動 mask は不可能。
- pre-commit hook (redact-secrets / git-secrets / truffleHog 等): commit 時のみ動作、Claude Code セッション内 transcript には効かない。
- 手動 token ローテーション: 漏洩後の事後対応で根本解決にならない。緊急ローテーションのオーバーヘッドも大きい (CI / 開発環境への波及)。
本リクエストの redacted_output フィールド機能があれば、上記 1-4 を補完して防御深度を完成させられます。
Priority
High - Significant impact on productivity
Feature Category
Developer tools/SDK
Use Case Example
Example scenario:
- 開発者が Claude Code セッションで agent に「dotfile を整理して」と依頼
- agent が Bash で grep -r "PAT" ~/.config/ 等のコマンドを実行 (機微情報を意識せず広範囲探索)
- tool output に GitHub Personal Access Token (ghp_xxx...) が含まれて返ってくる
- 現状: output はそのまま transcript jsonl (.claude/projects//transcripts/.jsonl) に永続化、後続 assistant message 経由でも context として残る
- 開発者は事象に気付いて即 token ローテーション (GitHub Settings → Developer settings → PAT → Regenerate)、ただし transcript ファイルには Secret が残ったまま (backup / sync / 他環境流出経路あれば漏洩継続)
- この feature があれば: PostToolUse hook が ghp_xxx pattern を検出し、redacted_output として "ghp_[REDACTED]" を返す。Claude Code が transcript と context に置換版を使う = Secret は最初から永続化されない = 漏洩リスクゼロ
- 結果: 開発者は token ローテーション不要、transcript 削除作業不要、心理的負担減
時間短縮: 1 件のヒヤリ事象あたり token ローテーション + 影響範囲調査で約 30-60 分の対応工数が削減される。複数開発者が並行作業する team では年間数十時間のセキュリティ対応工数削減につながる。
Additional Context
参考リンク (当チーム実装)
検出のみ版 PostToolUse hook (改変機能なし、19 秘密パターン対応、self-test 15 ケース全 PASS):
- secret-output-redact.sh: <https://github.com/theloveyousave/consulting-os/blob/main/.claude/hooks/secret-output-redact.sh>
- test-secret-output-redact.sh: <https://github.com/theloveyousave/consulting-os/blob/main/.claude/hooks/test-secret-output-redact.sh>
PreToolUse 側の block hook (組み合わせて二段防御):
- secret-mask-check.sh: <https://github.com/theloveyousave/consulting-os/blob/main/.claude/hooks/secret-mask-check.sh>
運用ドキュメント (緊急 bypass 手順含む):
- cybersecurity-playbook.md §3: <https://github.com/theloveyousave/consulting-os/blob/main/.claude/skills/cybersecurity-playbook.md>
技術的考慮事項
実装時の論点候補:
- redacted_output は文字列全置換のみ対応で十分か、または部分置換 (diff 形式) も必要か
推奨: 全置換でシンプルに開始、要望が出たら拡張
- PostToolUse hook が複数登録されている場合、redacted_output の競合解決
推奨: 配列順で連鎖適用 (1 つ目 hook の redacted_output を 2 つ目 hook の input とする)
- redacted_output が tool 結果より長い場合の挙動
推奨: 制限なし、ただし context window 圧迫リスクを docs で明示
- assistant 側への通知 (なぜ redact されたか) は必要か
推奨: stderr 経由で warning メッセージを返せる現行仕様で十分、追加機能不要
類似機能 (他ツール)
- pre-commit hook: redact-secrets (commit 時のみ動作)
- truffleHog: repository scan 時のみ、リアルタイム不可
- git-secrets: AWS 中心、汎用 token 対応弱い
- Claude Code は唯一「LLM agent 実行時のリアルタイム redact」が可能なポジション
セキュリティ重要性
エンタープライズ採用障壁の 1 つ。SOC 2 Type II / ISO 27001 監査で「LLM tool output の秘密情報自動 mask」を求められるケースあり (FACT: 当チーム対応案件で監査対応質問として実際に発生)。
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗