> ## Documentation Index
> Fetch the complete documentation index at: https://adcp-docs-ja.pier1.co.jp/llms.txt
> Use this file to discover all available pages before exploring further.

# プロトコル tarball の検証

> cosign keyless と Sigstore 透明性ログで AdCP プロトコルバンドルの発行者アイデンティティを検証する。

すべての AdCP リリースは、3 つのサイドカーとともに `{version}.tgz` バンドル（そのバージョンの完全なスキーマ + コンプライアンス + OpenAPI ツリー）を公開します:

| File                   | Role                   |
| ---------------------- | ---------------------- |
| `{version}.tgz.sha256` | SHA-256 チェックサム、転送中の完全性 |
| `{version}.tgz.sig`    | Sigstore 分離署名          |
| `{version}.tgz.crt`    | Fulcio 発行の署名証明書        |

SHA-256 サイドカーは tarball と同じオリジンに存在するため、転送中の改ざんからのみ保護します。`.sig` + `.crt` ペアは、バンドルが AdCP リリースワークフロー自体から来たこと、そしてホストが侵害されても悪意あるものとすり替えられなかったことを証明します。

このページは、それらの署名を正しく検証する方法をカバーします。SDK ユーザー（`@adcp/sdk`、`adcp-client-python`、`adcp-go`）は、すべての `sync-schemas` / `download.sh` 実行でこの検証を無料で得ます。バンドルを直接消費している場合 — CI パイプラインで特定バージョンをピン留め、異なる言語から取り込み、新規採用者を実装 — 読み進めてください。

## 信頼モデル

AdCP は **Sigstore keyless 署名** を使います。長寿命の秘密鍵はありません。リリース時に:

1. `adcontextprotocol/adcp` の `release.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` 呼び出し

```bash theme={null}
# tarball + サイドカーをダウンロード
curl -OL https://adcontextprotocol.org/protocol/3.0.3.tgz
curl -OL https://adcontextprotocol.org/protocol/3.0.3.tgz.sha256
curl -OL https://adcontextprotocol.org/protocol/3.0.3.tgz.sig
curl -OL https://adcontextprotocol.org/protocol/3.0.3.tgz.crt

# まずチェックサムを検証（安価、転送中の破損を捕まえる）
shasum -a 256 -c 3.0.3.tgz.sha256

# Sigstore アイデンティティを検証（発行者を証明）
cosign verify-blob \
  --signature 3.0.3.tgz.sig \
  --certificate 3.0.3.tgz.crt \
  --certificate-identity-regexp '^https://github\.com/adcontextprotocol/adcp/\.github/workflows/release\.yml@refs/(heads|tags)/.*$' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  3.0.3.tgz
```

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

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

```
^https://github\.com/adcontextprotocol/adcp/\.github/workflows/release\.yml@refs/(heads|tags)/.*$
```

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` 許可リスト（現在 `main`、`3.0.x`、`2.6.x`）が、そもそもどの ref が署名を生成できるかを決定します。すべてのコンシューマーの正規表現でそのリストをミラーリングすることは、防御を追加しない保守負債でした。

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

参考のため、各リリースの証明書サブジェクトはこうでした:

| Release | Triggering ref       | Cert subject（サブジェクトのみ、完全 URL プレフィックス省略） |
| ------- | -------------------- | --------------------------------------- |
| v3.0.0  | `main`（初期 3.0 カット）   | `release.yml@refs/heads/main`           |
| v3.0.1  | `3.0.x`（ラインがカットされた後） | `release.yml@refs/heads/3.0.x`          |
| v3.0.2  | `3.0.x`              | `release.yml@refs/heads/3.0.x`          |
| v3.0.3  | `3.0.x`              | `release.yml@refs/heads/3.0.x`          |

将来の保守ブランチ（例: `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                     | Verifies via                                                      |
| ----------------------- | ----------------------------------------------------------------- |
| `@adcp/sdk`（TypeScript） | `scripts/sync-schemas.ts` がサイドカー存在時に `cosign verify-blob` をシェルアウト |
| `adcp-client-python`    | `scripts/sync_schemas.py` が同じことをする                                |
| `adcp-go`               | `adcp/schemas/download.sh` が同じことをする                               |

フォースパーティ SDK を保守する場合、上の正規表現をミラーリングしてください。リテラル許可リストパターンを避けてください — 新しい保守ブランチがカットされるたびに腐ります。

## 生成者側の詳細

仕様ワークフロー自体に貢献する場合: cosign 署名は `release.yml` 内の `npm run version`（`sign-protocol-tarball.sh` ステップから連鎖）中に起こります。OIDC トークンは署名時に鋳造されるため、証明書サブジェクトはそのワークフロー実行のトリガー ref を反映します。タグベースの署名は次のいずれかを必要とします:

* `release: published` で実行され、タグ後 OIDC サブジェクトを使って tarball を再署名する 2 番目のワークフロー、または
* `changeset tag` の後、`refs/tags/*` がアクティブな ref であるコンテキスト内で署名が起こるようリリースパイプラインを再構築する。

今日のブランチから署名する形状は意図的です — すべてのコンシューマーがタグ対ブランチのアイデンティティについて推論せずに単一の正準アーティファクトを検証できます。正規表現の `refs/(heads|tags)/.*` は、それが変わる場合に備えた前方互換です。

## 関連項目

* [スキーマ、コンプライアンスバンドル、SDK](/docs/building/schemas-and-sdks) — これらのサイドカーがより広いバンドル取得フローで記述される場所
* [Sigstore ドキュメント](https://docs.sigstore.dev/) — keyless 署名、透明性ログ、脅威モデル
* [`adcp#2273`](https://github.com/adcontextprotocol/adcp/issues/2273) — cosign 署名を導入した変更
