Skip to main content
すべての AdCP リリースは、3 つのサイドカーとともに {version}.tgz バンドル(そのバージョンの完全なスキーマ + コンプライアンス + OpenAPI ツリー)を公開します: SHA-256 サイドカーは tarball と同じオリジンに存在するため、転送中の改ざんからのみ保護します。.sig + .crt ペアは、バンドルが AdCP リリースワークフロー自体から来たこと、そしてホストが侵害されても悪意あるものとすり替えられなかったことを証明します。 このページは、それらの署名を正しく検証する方法をカバーします。SDK ユーザー(@adcp/sdkadcp-client-pythonadcp-go)は、すべての sync-schemas / download.sh 実行でこの検証を無料で得ます。バンドルを直接消費している場合 — CI パイプラインで特定バージョンをピン留め、異なる言語から取り込み、新規採用者を実装 — 読み進めてください。

信頼モデル

AdCP は Sigstore keyless 署名 を使います。長寿命の秘密鍵はありません。リリース時に:
  1. adcontextprotocol/adcprelease.yml ワークフローが GitHub Actions ランナーで実行される。
  2. ランナーは、実行を生成したワークフローと ref を識別するサブジェクトを持つ短命の OIDC トークンを鋳造する。
  3. cosign sign-blob --yes が、その OIDC トークンを Sigstore の Fulcio CA で短命の X.509 証明書と交換し、証明書の一時秘密鍵を使って分離署名を生成する。
  4. 署名、証明書、透明性ログエントリが Sigstore の Rekor 公開ログに着地する。
  5. リリースパイプラインが .sig.crt を tarball の隣にコミットし、GitHub Release にアップロードする。
コンシューマー側の検証は次に 2 つのバインドプロパティ を確認します:
  • 署名の真正性.sig.crt が証明する秘密鍵によって生成された。標準の Sigstore 数学。AdCP 固有ではない。
  • アイデンティティバインド.crt のサブジェクトが AdCP リリースワークフローを具体的に名指しし、発行者は GitHub Actions の OIDC プロバイダーである。これが AdCP 固有の部分。
両方が成立すれば、AdCP リリースワークフロー実行がこの正確な tarball を生成したという証明を持ちます — adcontextprotocol.org 自体を信頼せずにエンドツーエンドで証明可能。

推奨される cosign verify-blob 呼び出し

抽出前に両方がゼロで終了しなければなりません。cosign verify-blob は、SHA が一致し TLS が有効でも、署名が AdCP リリースワークフロー以外のものによって作られた場合、非ゼロを返します。

アイデンティティ正規表現の説明

3 つの部分が重要です:
  • https://github.com/adcontextprotocol/adcp/.github/workflows/release.yml — ワークフローファイルパス。これが証明書を AdCP 固有にするものです。異なるリポジトリのワークフロー、またはこのリポジトリの異なるワークフローファイルは一致しません。
  • refs/(heads|tags)/.* — ワークフローが実行された ref。ブランチ ref が今日使われるものです(cosign は push トリガーの実行中に署名するため、OIDC サブジェクトは release.yml@refs/heads/<branch>)。タグ ref は、将来のタグ後再署名フローの前方互換です。
  • --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' — OIDC 発行者は GitHub Actions 自体でなければなりません。正しいリポジトリとワークフローパスでも、非 GitHub-Actions 発行者はこのチェックに失敗します。

なぜ正確な ref ではなく正規表現か

この正規表現の最初のバージョンは ^...refs/heads/(main|2\.6\.x)$ — リリースブランチのリテラル許可リストでした。それらのリリースが refs/heads/3.0.x(3.0 ラインがカットされたときに追加された保守ブランチ)に移動したとき、v3.0.1+ を黙って拒否しました。任意の新しい保守ブランチは、各 SDK がパッチされるまですべてのコンシューマーで検証を壊しました。 ブランチコンポーネントのワイルドカード化は信頼モデルを弱めません: 上流の release.yml ワークフロー自身の on.push.branches 許可リスト(現在 main3.0.x2.6.x)が、そもそもどの ref が署名を生成できるかを決定します。すべてのコンシューマーの正規表現でそのリストをミラーリングすることは、防御を追加しない保守負債でした。

過去のリリースの証明書サブジェクト

参考のため、各リリースの証明書サブジェクトはこうでした: 将来の保守ブランチ(例: 2.7.x)は、コンシューマーの変更を必要とせずに release.yml@refs/heads/2.7.x を追加します。

検証が利用できないとき

一部のリリースは正当に .sig/.crt なしで出荷されます:
  • v3.0.0 以前(cosign 署名がまだ配線されていなかった)。 チェックサムのみとして扱う。SDK は失敗ではなく完全性のみの検証に劣化する。
  • 帯域外の再公開。 tarball が release.yml ワークフロー外で再生成される場合(例: 一回限りの再ビルド)、Sigstore アイデンティティを持たない。cosign サイドカーは欠如する。信頼できないものとして扱う。
コンシューマーは「サイドカー欠如」(チェックサムのみに劣化)と「サイドカー存在だが検証失敗」(ハード失敗)を区別すべきです。それらを混同しないでください — 存在するが無効な署名は、署名がまったくないよりも強い否定的シグナルです。

SDK の動作

3 つすべてのファーストパーティ SDK は、プロトコルバンドルを取得するときこの正規表現を使います: フォースパーティ SDK を保守する場合、上の正規表現をミラーリングしてください。リテラル許可リストパターンを避けてください — 新しい保守ブランチがカットされるたびに腐ります。

生成者側の詳細

仕様ワークフロー自体に貢献する場合: cosign 署名は release.yml 内の npm run versionsign-protocol-tarball.sh ステップから連鎖)中に起こります。OIDC トークンは署名時に鋳造されるため、証明書サブジェクトはそのワークフロー実行のトリガー ref を反映します。タグベースの署名は次のいずれかを必要とします:
  • release: published で実行され、タグ後 OIDC サブジェクトを使って tarball を再署名する 2 番目のワークフロー、または
  • changeset tag の後、refs/tags/* がアクティブな ref であるコンテキスト内で署名が起こるようリリースパイプラインを再構築する。
今日のブランチから署名する形状は意図的です — すべてのコンシューマーがタグ対ブランチのアイデンティティについて推論せずに単一の正準アーティファクトを検証できます。正規表現の refs/(heads|tags)/.* は、それが変わる場合に備えた前方互換です。

関連項目