signed-audit-trails-recipe について
Claude Code のツール呼び出しを Cedar ポリシーで制御し、署名付きレシートを作成する方法を解説するレシピ形式のスキルです。エージェントの操作記録を監査したいチーム向けに、規制対応や CI/CD での検証も扱います。
主な機能
- 01実行前の Cedar ポリシー評価
- 02Ed25519 署名付き呼び出しレシート
- 03オフラインでのレシート検証
- 04改ざん検知の手順
- 05CI/CD での検証ガイダンス
活用シーン
- 01規制対象の業務でポリシー判断を記録
- 02CI で自動ビルドのツール呼び出しを検証
- 03協業先に検証可能なエージェント活動記録を提示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wshobson/ agents --skill signed-audit-trails-recipeインストール後、Claude Code で/signed-audit-trails-recipeを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/cedar-policy.mdci-cd.mdhook-wiring.mdreceipt-format.md詳細
Claude Code ツール呼び出しのための署名付き監査証跡
すべての Claude Code ツール呼び出しに対して暗号学的に署名されたレシートを付与するための、クックブック形式のウォークスルーです。これは教材用のスキルです。ランタイム実装については、protect-mcp プラグインをインストールしてください。
これで得られるもの
すべてのツール呼び出し(Bash、Edit、Write、WebFetch)は次のように処理されます。
- 実行前に Cedar ポリシーに対して評価されます。 ポリシーが呼び出しを拒否した場合、そのツールは実行されません。
- 実行後に Ed25519 レシートとして署名されます。 レシートは JCS 正規化されており、公開鍵を持つ誰でもオフラインで検証できます。
監査人、規制当局、または取引相手は、後からすべてのレシートを検証できます(ステップ 5)。ネットワーク呼び出しも、ベンダーへの問い合わせも、運用者への信頼も不要です。
このパターンを使うべき場面
- 規制環境(金融、医療、重要インフラ)で、エージェントの動作に関する改ざん検知可能な証拠が必要な場合
- CI/CD パイプラインで、自動化されたすべてのビルドステップに対してポリシーゲートが機能したことを証明したい場合
- 複数当事者間のコラボレーションで、取引相手が運用者を信頼せずにあなたのエージェントの動作を検証したい場合
- コンプライアンスの文脈(EU AI 法第 12 条、エージェントが構築したソフトウェアの SLSA 来歴)で、標準的なログでは不十分な場合
ステップ 1: フック設定をインストールする
/plugin install protect-mcp で protect-mcp プラグインをインストールします。そのフックは、各ツール呼び出しの前に evaluate.sh を、後に sign.sh を実行します。Claude Code は TOOL_NAME や TOOL_INPUT 変数を設定しないため、両方のスクリプトは標準入力からフックイベントを読み取ります。フック設定と、各スクリプトが protect-mcp に渡す内容については、references/hook-wiring.md を参照してください。
protect-mcp 0.7.4 は署名鍵を作成しません。鍵がなければレシートは署名されません。./protect-mcp.key を一度作成してください。このコマンドは既存の鍵を置き換えることはありません。
if [ ! -e ./protect-mcp.key ]; then
d=$(mktemp -d) && npx [email protected] init --dir "$d" && mv "$d/keys/gateway.json" ./protect-mcp.key
fi
監査人にはそのファイルの publicKey の値を渡してください。このファイルには秘密鍵も含まれるため、コミットしないでください。
秘密鍵とレシートディレクトリを .gitignore に追加します。
echo "/protect-mcp.key" >> .gitignore
echo "/receipts/" >> .gitignore
ステップ 2: Cedar ポリシーを書く
references/cedar-policy.md の例を基に ./protect.cedar を作成します。これは読み取り専用ツールと少数の Bash コマンドを許可し、シェルの連結と破壊的なコマンドを拒否し、書き込みを .. セグメントを拒否した上でプロジェクト内に制限します。
ステップ 3: Claude Code を通常どおり使う
Claude Code を起動します。すべてのツール呼び出しは両方のフックを通ります。
You: Please read the README and summarize it.
Claude: I will read README.md.
[PreToolUse: Read ./README.md -> allow]
[Tool: Read executes]
[PostToolUse: receipt rcpt-a8f3c9d2 signed to ./receipts/]
... summary of README ...
20 回のツール呼び出しからなるセッションでは、./receipts/receipts.jsonl に 20 件のレシートが追記されます。
ステップ 4: レシートを検査する
protect-mcp 0.7.4 は各レシートを ./receipts/receipts.jsonl の 1 行として追記します。最新のものを出力します。
tail -n 1 ./receipts/receipts.jsonl | python3 -m json.tool
レシートはツールを名指しする署名済みの v2 エンベロープであり、公開鍵は含まれません。サンプルと署名対象フィールドについては、references/receipt-format.md を参照してください。
ステップ 5: レシートを検証する
./protect-mcp.key の publicKey の値を検証ツールに渡します。
PUB=$(node -p 'JSON.parse(require("fs").readFileSync("./protect-mcp.key")).publicKey')
npx @veritasacta/[email protected] --replay-chain ./receipts/receipts.jsonl --key "$PUB"
終了コード:
| コード | 意味 |
|---|---|
0 | すべてのレシートが検証された |
1 | あるレシートの検証が失敗した(改ざん、誤った鍵、または不正な行) |
2 | レシートファイルを読み取れなかった |
ステップ 6: 改ざん検知を実演する
最新のレシートの decision を allow から deny に変更します。
python3 -c "
import json
path = './receipts/receipts.jsonl'
lines = open(path).read().splitlines()
r = json.loads(lines[-1])
r['payload']['decision'] = 'deny'
lines[-1] = json.dumps(r)
open(path, 'w').write('\n'.join(lines) + '\n')
"
npx @veritasacta/[email protected] --replay-chain ./receipts/receipts.jsonl --key "$PUB"
検証ツールは終了コード 1 で終了し、どの行が失敗したかを報告します。Ed25519 署名は、改ざんされたペイロードの JCS 正規化バイト列ともはや一致しません。
フィールドを元に戻すと、検証は再び成功します。
暗号化の仕組み
適合する実装であれば、次の 2 つの不変条件により、レシートをオフラインで検証できます。
- 署名の前に JCS 正規化(RFC 8785) を行います。キーは UTF-16 コード単位でソートされ、空白は最小限に抑えられ、文字列は正規化されません。同じレシート内容であれば、独立した 2 つの実装がバイト単位で同一の署名ペイロードを生成します。
- 正規化したバイト列に対する Ed25519 署名(RFC 8032) を使用します。決定論的で、サイズが固定されており、ノンスに依存しません。
protect-mcp 0.7.4 のレシートには前のレシートへのリンクがないため、レシートが削除されても検知されません。
正式なワイヤ形式については、 draft-farley-acta-signed-receipts を参照してください。
実装間の相互運用性
現在、レシート形式には独立した実装が 4 つあります。
| 実装 | 言語 | 用途 |
|---|---|---|
| protect-mcp | TypeScript | Claude Code、Cursor、MCP ホスト |
| protect-mcp-adk | Python | Google Agent Development Kit |
| sb-runtime | Rust | OS レベルのサンドボックス(Landlock + seccomp) |
| APS governance hook | Python | CrewAI、LangChain |
いずれかの実装が生成したレシートも、
@veritasacta/verify で検証できます。
監査担当者がオペレーターのツール選択を信頼する必要はありません。形式そのものが契約となります。
CI/CD との統合
レシートを CI で検証することで、改ざんされたレシートがある場合にビルドを失敗させられます。
references/ci-cd.md には、デフォルトブランチへのプッシュ時に実行される GitHub Actions ワークフローがあります。ブランチに制限された環境から署名キーをインストールし、エージェントを実行してレシートを検証し、アップロードします。レビューされていないコードにキーを渡してしまうため、プルリクエストでは実行されません。
エージェントが構築するソフトウェアにおける SLSA Provenance との組み合わせ
Claude Code がソフトウェアをビルドしてリリースする場合(ツール呼び出しとして npm install、npm build、npm publish を実行)、レシートチェーンがステップごとのビルドログになります。SLSA Provenance v1 には、このための拡張ポイントがあります。byproducts フィールドで、ビルド証明書とともにレシートチェーンを参照できます。
agent-commit build type では、ResourceDescriptor の形式を使用したパターンについて説明しています。
{
"name": "decision-receipts",
"digest": { "sha256": "..." },
"uri": "oci://registry/org/build-xyz/receipts:sha256-...",
"annotations": {
"predicateType": "https://veritasacta.com/attestation/decision-receipt/v0.1",
"signerRole": "supervisor-hook"
}
}
SLSA provenance はビルダーの ID で署名され、レシート証明は supervisor-hook の ID で署名されます。2 つの信頼ドメインが、生成物レイヤーで相互参照されます。組み合わせに関する議論については、 slsa-framework/slsa#1594 を参照してください。
よくある落とし穴
バージョン管理に秘密鍵を含める。 生成された ./protect-mcp.key をコミットしてはいけません。上記の例では、これを .gitignore に追加しています。誤ってキーをコミットした場合は、直ちにローテーションしてください。キーと ./receipts/receipts.jsonl をアーカイブに移動し、Step 1 のコマンドをもう一度実行します。アーカイブしたレシートは古い公開鍵で検証してください。
標準入力のフックペイロード。 Claude Code は $TOOL_NAME や $TOOL_INPUT の変数を設定しません。--tool "$TOOL_NAME" を渡すフックコマンドは、空のツール名を送信するため、ポリシーによってすべての呼び出しが拒否されます。プラグインのスクリプトと同様に、標準入力からペイロードを読み取ってください。
CI のレシートディレクトリ。 Claude Code を CI で実行する場合は、ジョブの終了時にレシートが失われないよう、ジョブの最後にレシートをアーティファクトとしてアップロードしてください。
ポリシーがない。 ./protect.cedar が存在しない場合、evaluate.sh は標準エラー出力に警告を表示して、呼び出しを許可します。Step 2 でポリシーを作成するまでは、どの呼び出しも制限されません。
このマーケットプレイス内の関連ツール
protect-mcp— ランタイムフックの実装 (本番環境ではこのプラグインを使用してください)review-agent-governance— レビュー対象のアクションの前に人間の承認を必須にします。protect-mcp と組み合わせて使用できます
参考資料
draft-farley-acta-signed-receipts— IETF ドラフト、レシートのワイヤーフォーマット- RFC 8032 — Ed25519
- RFC 8785 — JCS
- Cedar ポリシー言語
- npm の protect-mcp
- npm の @veritasacta/verify
- in-toto/attestation#549 — Decision Receipt 述語の提案
- agent-commit ビルドタイプ — エージェントが作成したコミットに対する SLSA 来歴
- Microsoft Agent Governance Toolkit (
examples/protect-mcp-governed/) - AWS Cedar for Agents