Skip to main content
AdCP 3.0 は暗号的リクエスト認証のため HTTP Message Signatures (RFC 9421) をサポートします。バイヤーはアウトバウンドリクエストに署名し、セラーが誰が送ったかとペイロードが改ざんされていないことを検証できます。セラーはアウトバウンド webhook に署名し、バイヤーが真正性を検証できます。 署名は AdCP 3.0 ではオプション で、すべての支出コミット操作について AdCP 4.0 で必須 になります。まだ署名しないエージェントも、インバウンドリクエストの署名ヘッダー(SignatureSignature-InputContent-Digest)を壊れることなく許容しなければなりません。
これは実践的実装ガイドです。規範的仕様 — カバードコンポーネント、正準化ルール、完全な検証者チェックリスト、リプレイ dedup サイジング、完全なエラー分類 — については Security: Signed Requests を参照してください。
下のコード例はタブで JavaScript/TypeScriptPythonGo SDK ヘルパーを使います。3 つの SDK すべてが同じ適合性ベクターに対して同じ RFC 9421 プロファイルを実装します — API 表面は異なりますがワイヤー出力は同一です。あなたの言語がリストされていない場合、適合性ベクター規範的仕様 は言語非依存です。

これが必要になるとき

主要概念

署名カバレッジ

AdCP 署名プロファイルは以下のリクエストコンポーネントをカバーします:
  • @method — HTTP メソッド
  • @target-uri — 完全な正準化リクエスト URL
  • @authority — 小文字化されたホストヘッダー
  • content-type — メディアタイプ
  • content-digest — リクエストボディの SHA-256 または SHA-512 ハッシュ(covers_content_digest ケイパビリティを参照)
任意のカバードコンポーネントが署名後に変わると、検証が失敗します。

鍵分離

すべてのエージェントは、明確な kidadcp_use タグを持つ署名鍵を公開します:
  • adcp_use: "request-signing" — アウトバウンドツール呼び出しとアウトバウンド webhook の署名用
  • adcp_use: "webhook-signing" — 非推奨。後方互換性のため依然として webhook パスで受理される
爆発半径分離のため、ツール呼び出しと webhook に同じ鍵素材を再利用するのではなく、webhook 配信用に別の kid の下で 2 つ目の request-signing 鍵を公開してください。

ディスカバリーチェーン

検証者は 3 ステップのチェーンを通じてあなたの公開鍵を見つけます:
@adcp/client SDK は、キャッシングとリフレッシュでこのチェーンを自動的に処理する BrandJsonJwksResolver を提供します。

ステップ 1: 署名鍵を生成する

CLI

これは Ed25519 キーペアを生成し、以下を書き込みます:
  • private.jwk — 秘密鍵(d フィールドを持つ JWK)。これを秘密に保つ。
  • public-jwks.json — JWKS 形式の公開鍵。これを公開する。

プログラマティック

サポートされるアルゴリズム

アルゴリズム名は JWK エントリー("alg": "EdDSA")と RFC 9421 Signature-Input パラメーター(alg="ed25519")で異なります。仕様の アルゴリズム命名テーブル を参照してください。

秘密鍵の保存

あなたのランタイムがサポートする最も強いオプションを選んでください。最も安全なものから最も安全でないものへ:
  • クラウド KMS(GCP Cloud KMS、AWS KMS、Azure Key Vault): 秘密鍵は HSM 内で生成され、決してそれを離れません。署名は KMS API を呼ぶことで実行されます。あなたは鍵バイトではなく JWK 参照のみを保持します。TypeScript SDK は GCP Cloud KMS 用に createKmsSigner を公開します — @adcp/client/signing/kms を参照。支出コミット操作を処理する任意のエージェントに推奨。
  • シークレットマネージャー(GCP Secret Manager、AWS Secrets Manager、HashiCorp Vault): ブート時にロードし、プロセスライフタイムの間メモリに保つ。KMS より簡単だが鍵素材がプロセス内に存在する — メモリダンプ、ロギング、または侵害された依存関係を通じてリークする。
  • 環境変数: ADCP_SIGNING_PRIVATE_KEY='{"kid":"...","kty":"OKP",...}'。開発と小規模デプロイに許容可能。シークレットマネージャーと同じメモリ常駐リスク。
  • ファイル: 開発のみ。決してバージョン管理にコミットしない。既存ファイルが決して上書きされないようモード 0600O_EXCL を使う — Path.write_bytes はプロセス umask(しばしば 0644、world-readable)を継承し、秘密鍵素材には安全でない。
KMS を選ぶと、署名レイテンシーが上がります(リクエストごとに HSM への 1 ラウンドトリップ)。コミットする前に負荷下でプロファイルしてください — TypeScript と Python SDK は JWK メタデータを積極的にキャッシュし、内部テストで GCP KMS に対して毎秒数百の署名を維持できますが、あなたの数字はリージョンと並行性に依存します。

ステップ 2: 公開鍵を公開する

JWKS エンドポイント

安定した HTTPS URL(デフォルトは /.well-known/jwks.json)で JSON Web Key Set をサーブします:
ここには公開鍵のみ — d フィールドなし。Cache-Control: max-age=3600 または同様を設定してください。webhook 配信に別の鍵素材を使う場合、明確な kid を持つ 2 つ目の request-signing JWK を公開してください。非推奨の webhook-signing JWK は後方互換性のため webhook パスで受理されたままです。

brand.json

あなたのブランドドメインの /.well-known/brand.json でサーブします。jwks_uri は検証者があなたの鍵を見つける方法です:

ステップ 3: アウトバウンドリクエストに署名する(バイヤー / オーケストレーター)

fetch / HTTP クライアントのラッピング

createSigningFetch は任意の fetch 互換関数をラップしてアウトバウンドリクエストに自動的に署名します:

ケイパビリティ対応署名

buildAgentSigningFetch はターゲットセラーが signed-requests をサポートするかをチェックし、サポートされるときのみ署名します。これは本番の推奨アプローチです:
これは署名を期待しないエージェントへの署名送信を避け、ケイパビリティルックアップをキャッシュします。

ステップ 4: インバウンド署名を検証する(セラー)

フレームワークミドルウェア

生の Express ルートには、raw-body ミドルウェアの後に createExpressVerifier をマウントします。resolveOperation コールバックには mcpToolNameResolver を使います — JSON-RPC エンベロープを解析し MCP ツール名を返します:

requireAuthenticatedOrSigned で署名 + bearer 認証を合成する

requireAuthenticatedOrSigned は完全な合成をバンドルします: presence ゲートルーティング(ヘッダー存在時は署名認証、それ以外はフォールバック)と requiredFor 強制 — 署名必須操作の未認証リクエストは、認証情報がまったく供給されなくても 401 request_signature_required を得ます。
MUTATING_TASKS@adcp/client/server からエクスポートされる支出コミットと状態変更操作の完全なリストです — 自身のリストを保守するのではなくそれを使ってください。

JWKS リゾルバーオプション

ステップ 5: インバウンド webhook を検証する(バイヤー / オーケストレーター)

セラーが webhook を送るとき、真正性を確認するため署名を検証してください。webhook プロファイルはリクエスト署名と同じ RFC 9421 メカニクスを使いますが、tag="adcp/webhook-signing/v1"Content-Digest が常にカバーされます(オプトアウトなし)。

ステップ 6: アウトバウンド webhook に署名する(セラー)

createAdcpServersignerKey を渡すと、フレームワークがすべてのアウトバウンド webhook に自動署名します:
webhook 署名公開鍵を "adcp_use": "request-signing" を持つ JWK として公開してください。webhook 検証者は後方互換性のため非推奨の "webhook-signing" 鍵を依然として受理しますが、新しい署名者は request-signing を使うべきです。独立した webhook ローテーションまたは爆発半径分離が欲しい場合、webhook 固有の kid を持つ別の request-signing JWK を公開してください。

ステップ 7: ケイパビリティを宣言する

セラーがインバウンド署名を検証する場合、バイヤーが署名すべきと分かるよう get_adcp_capabilities レスポンスで signed_requests(オンワイヤースキーマでのエイリアス request_signing)を宣言してください:
バイヤーは get_adcp_capabilities を呼び、request_signing.required_forsupported_for を読んで、あなたがどの操作に署名を期待するかを知ります。

鍵ローテーション

JWKS エンドポイントはゼロダウンタイムローテーションのため複数の鍵を同時にサポートします:
  1. 新しい kid を持つ新しいキーペアを生成
  2. 新しい公開鍵を JWKS に追加(古いものと新しいもの両方が公開される)
  3. 新しい秘密鍵を使うよう署名設定を更新
  4. 24〜48 時間後、古い公開鍵を JWKS から削除
緊急ローテーション(鍵侵害)には、古い kid を失効リストの revoked_kids に追加し、即座に新しい鍵にローテートしてください。失効リスト形式については Revocation を参照してください。

Testing

適合性ベクター

仕様は compliance/cache/3.0.0/test-vectors/request-signing/(ソースは static/compliance/source/test-vectors/request-signing/)で 39 個のテストベクター を出荷します:
  • 12 個の正ベクター: 検証者が受理しなければならない有効な署名付きリクエスト(非 4xx)
  • 27 個の負ベクター: 検証者が 401 と正しいエラーコードで拒否しなければならない無効なリクエスト

検証者をグレードする

エラーコード

検証が失敗するとき、WWW-Authenticate: Signature error="<code>" を伴う 401 を返します: 完全なエラーコード分類については Transport error taxonomy を参照してください。

関連