GitHub SBOM export APIの非同期化とは?コンプライアンス自動化への影響と移行ポイント

GitHub dependency graph / SBOM export API を使ってSBOMを自動取得しているチームは、「APIを1回呼べば同期的にSBOM JSONが返る」前提を見直す必要があります。2026年4月15日時点で重要なのは、GitHubのSBOMエクスポートがリポジトリ画面と新APIで非同期生成に変わったことです。これにより、大規模リポジトリではタイムアウトに強くなる一方、コンプライアンスパイプラインや依存関係レポートでは「生成リクエスト」「完了待ち」「取得」「保管」の制御が必要になります。(The GitHub Blog)

特に、Supply chain security team や platform engineer が運用する監査証跡、リリースゲート、脆弱性管理、依存関係棚卸しの自動化では、SBOM生成を短時間のAPIレスポンス処理ではなく、ジョブ実行として扱う設計に切り替えることが実務上のポイントです。

目次

GitHubのSBOM export API非同期化で何が変わったのか

GitHubは2026年4月14日のChangelogで、リポジトリページからのSBOMエクスポートと新しいAPIエンドポイントが非同期処理になったと発表しました。従来は、リポジトリのDependency graph画面で「Export SBOM」を押す操作や、/repos/{owner}/{repo}/dependency-graph/sbom REST APIへのリクエストに、10秒の固定タイムアウトがありました。大規模リポジトリや依存関係ツリーが複雑なリポジトリでは、この10秒を超えて処理が失敗しやすい状況がありました。(The GitHub Blog)

今回の変更で、新しいUIはSBOM生成ジョブの完了をポーリングする形になり、APIでも生成開始と取得を分けた非同期フローが用意されています。GitHub Docsでは、SBOMはSPDX JSON形式で扱われ、少なくとも対象リポジトリへの読み取りアクセスがあれば、GitHub UIまたはREST APIから依存関係グラフをSPDX互換のSBOMとしてエクスポートできると説明されています。(GitHub Docs)

旧方式と新方式の違い

観点従来のSBOM取得新しい非同期SBOM取得
処理モデルAPI呼び出し中に生成して返す同期処理生成ジョブを開始し、完了後に取得
大規模リポジトリ対応10秒タイムアウトの影響を受けやすいタイムアウトに依存しにくい
自動化の実装1回のHTTPレスポンスを処理ジョブID、ポーリング、リトライ、取得処理が必要
パイプライン設計単一ステップにしやすい非同期ジョブとして状態管理が必要
失敗時の扱いタイムアウトを失敗として扱いがち未完了、権限不足、取得期限切れなどを分けて処理

この変更は単なるAPI仕様の差し替えではありません。SBOMを監査やリリース承認に使っている場合、CI/CDや定期レポートの中で「いつSBOMが生成されたのか」「どのコミット状態を表しているのか」「取得できなかった場合にどう扱うのか」を明確にする必要があります。

新しいSBOM export APIの基本フロー

新しいAPIでは、SBOM取得は大きく2段階になります。

まず、GET /repos/{owner}/{repo}/dependency-graph/sbom/generate-report を呼び出してSBOM生成をリクエストします。このエンドポイントは、生成ジョブが開始されたことを示すレスポンスとして、sbom_urlを返します。GitHub Docsの例では、このURLにSBOM exportの一意識別子であるUUIDが含まれます。(GitHub Docs)

次に、GET /repos/{owner}/{repo}/dependency-graph/sbom/fetch-report/{sbom_uuid} を呼び出して、生成済みSBOMを取得します。GitHub Docsでは、SBOMがまだ処理中の場合は202、完了すると一時的なダウンロードURLへ302リダイレクトされると説明されています。(GitHub Docs)

1. generate-report を呼び出す
2. レスポンスの sbom_url または sbom_uuid を保存する
3. fetch-report を一定間隔で呼び出す
4. 202なら待機して再試行する
5. 302ならリダイレクト先からSPDX JSONを取得する
6. 取得したSBOMを成果物、監査ログ、レポート基盤に保存する

ここで重要なのは、fetch-reportを即時成功前提で実装しないことです。202は失敗ではなく「まだ生成中」です。CI/CDの失敗条件、監視アラート、ログ分類では、未完了と失敗を分けて扱う必要があります。

コンプライアンスパイプラインへの影響

SBOMは、監査対応、顧客提出、ライセンス確認、脆弱性管理、リリース判定に使われます。そのため、SBOM生成が非同期化されると、コンプライアンスパイプラインでは次のような影響が出ます。

リリースゲートに待機時間が発生する

リリース前にSBOMを必須成果物として生成している場合、従来はAPI呼び出しの成否だけで次工程に進めていたかもしれません。非同期化後は、SBOM生成が完了するまで待つステップが必要です。

たとえば、以下のようなリリースフローでは設計変更が必要です。

ビルド
↓
テスト
↓
SBOM生成
↓
ライセンスチェック
↓
脆弱性チェック
↓
リリース承認

この場合、SBOM生成ステップは「APIを呼ぶだけ」ではなく、「完了まで待つ」「取得できなければタイムアウト扱いにする」「生成されたSBOMを後続ツールに渡す」という処理になります。

実務では、リリースパイプラインの待機上限を決めておくことが重要です。たとえば、通常は数十秒から数分で完了する前提でも、リポジトリ規模や依存関係の複雑さによって変動する可能性があります。固定の短すぎるタイムアウトを設定すると、非同期化のメリットを消してしまいます。

監査証跡として「生成開始時刻」を残す必要がある

GitHubのChangelogでは、SBOM exportはリクエストを開始した時点のリポジトリ状態を表すと説明されています。また、HEAD以外のrefに対するSBOMは利用できないという制約も示されています。(The GitHub Blog)

これは監査対応で重要です。SBOMを後から取得した時刻だけを記録しても、「どの時点の依存関係を表しているのか」が曖昧になります。

最低限、次の情報はログや成果物メタデータに残しておくべきです。

記録項目理由
リポジトリ名どの対象のSBOMかを識別する
デフォルトブランチのHEAD SHASBOMがどのコード状態に対応するかを明確にする
SBOM生成リクエスト時刻GitHubがSBOM状態を固定する基準になる
SBOM取得完了時刻パイプライン上の成果物作成時刻を追跡する
APIレスポンスコード202、302、403、404などの状態判断に使う
保存先パスまたは成果物ID監査時に再取得できるようにする

特にグローバル企業や複数リージョンで開発している組織では、時刻はUTCで保存する運用が無難です。ローカル時刻だけを保存すると、監査やインシデント調査で時系列の整理に手間がかかります。

「HEADのみ」という制約に合わせてリリース運用を調整する

SBOM exportがHEADのみを対象にする点は、リリースブランチやタグ運用をしている組織では注意が必要です。特定のリリースタグや過去のコミットに対してGitHub dependency graphのSBOM export APIを直接指定する運用は、少なくともこの仕様上は前提にできません。(The GitHub Blog)

実務上は、次のいずれかの運用を検討します。

運用パターン向いているケース注意点
デフォルトブランチのHEADをリリース対象にそろえるtrunk-based developmentに近い組織リリース直前のマージ管理が重要
リリース前に対象ブランチをデフォルトブランチへ反映する厳格な承認フローがある組織ブランチ運用との整合性を文書化する
GitHub SBOMとは別にビルド成果物ベースのSBOMも生成するタグ、コンテナ、成果物単位でSBOMが必要な組織複数SBOMの位置づけを明確にする

GitHub dependency graph由来のSBOMは、リポジトリの依存関係可視化や継続的な棚卸しに強みがあります。一方で、リリース済みコンテナイメージ、バイナリ、デプロイ成果物に対するSBOMが必要な場合は、ビルド時にSyft、Microsoft SBOM Tool、Anchoreなどのツールで成果物ベースのSBOMを生成する設計も併用候補になります。GitHub Docsでも、GitHub Actionsを使ったSBOM生成手段としてSPDX Dependency Submission ActionやAnchore SBOM Actionなどが紹介されています。(GitHub Docs)

依存関係レポート自動化への影響

依存関係レポートでは、SBOMを単発で取得するだけでなく、組織内の多数リポジトリから定期的に収集し、ライセンス、パッケージ、バージョン、脆弱性情報と突き合わせることが多くあります。非同期化により、このバッチ処理にも見直しポイントが出ます。

大量リポジトリではキュー管理が必要になる

100件、1,000件単位のリポジトリからSBOMを取得する場合、全リポジトリに対して同時にgenerate-reportを投げ、すぐにfetch-reportを連打する設計は避けるべきです。

理由は3つあります。

1つ目は、APIレート制限やネットワーク負荷の影響を受けやすくなることです。2つ目は、生成ジョブの完了タイミングがリポジトリごとに異なることです。3つ目は、取得失敗時に再実行範囲を切り分けにくくなることです。

現実的には、次のようなキュー型の設計が扱いやすくなります。

対象リポジトリ一覧を取得
↓
リポジトリごとにSBOM生成ジョブを登録
↓
ジョブIDと状態をDBまたはストレージに保存
↓
一定間隔で未完了ジョブをポーリング
↓
完了したSBOMだけを取得して保存
↓
失敗・期限切れ・権限不足を別キューへ送る

この設計にすると、途中でジョブが失敗しても全体を最初からやり直す必要がありません。依存関係レポートの収集基盤として、再実行性と観測性を確保しやすくなります。

ポーリング間隔は短すぎても長すぎても問題になる

非同期APIでは、ポーリング設計が品質を左右します。短すぎる間隔でfetch-reportを呼び続けると、API負荷やレート制限のリスクが高まります。一方で、長すぎる間隔にすると、リリース判定や日次レポートの完了が遅れます。

実務では、固定間隔よりもバックオフを使う設計が扱いやすいです。

状況推奨される考え方
リリース前の単一リポジトリ数秒間隔から開始し、上限時間を決める
日次・週次の多数リポジトリ収集バックオフしながらゆっくり回収する
監査提出用の緊急取得優先キューを分け、対象を絞る
取得失敗が続く場合自動再試行回数を制限し、人が確認できる状態にする

重要なのは、202をエラーとしてアラートしないことです。アラート対象にすべきなのは、一定時間を超えても完了しない、403で権限が不足している、404で対象が見つからない、保存処理に失敗した、といったケースです。

APIレスポンス別の実装判断

GitHub Docs上の新しいSBOM APIでは、generate-reportは生成リクエスト成功時に201 Createdを返し、fetch-reportは処理中に202、完了時に302を返します。権限不足や対象不在では403や404もあり得ます。(GitHub Docs)

自動化では、レスポンスコードごとの扱いを明確にしておくと運用事故を減らせます。

レスポンス意味パイプラインでの扱い
201SBOM生成ジョブの開始に成功sbom_urlまたはUUIDを保存して次へ
202SBOM生成中失敗にせず、待機して再試行
302SBOM取得可能リダイレクト先からSPDX JSONを取得
403権限不足またはアクセス不可即時失敗にして権限設定を確認
404リポジトリ、SBOM、UUIDなどが見つからない対象設定、リポジトリ名、保持期限を確認

特に302の扱いには注意が必要です。HTTPクライアントやCIツールによっては、リダイレクトを自動追跡する設定が必要になります。curlなら-Lを使う実装例が一般的です。GitHub DocsのcURL例でも、curl -Lが使われています。(GitHub Docs)

認証と権限で確認すべきポイント

SBOM export APIを組織で運用する場合、認証方式は個人のPATに依存しないほうが安全です。GitHub Docsでは、SBOM関連エンドポイントがGitHub App user access token、GitHub App installation access token、fine-grained personal access tokenで利用でき、fine-grained tokenではContentsリポジトリ権限のreadが必要と説明されています。公開リソースのみを対象にする場合は認証なしでも利用可能とされています。(GitHub Docs)

実務では、次の基準で選ぶと運用しやすくなります。

認証方式向いている用途注意点
GitHub App installation access token組織横断の自動収集、長期運用Appのインストール範囲と権限設計が必要
fine-grained PAT小規模な検証、一時的な自動化個人アカウント依存になりやすい
認証なし公開リポジトリの単発取得同時実行やアクセス制限の影響を受けやすい

GitHubのChangelogでは、匿名ユーザーはリポジトリごとに同時実行SBOMリクエストが1件に制限され、ログインユーザーはこの制限の対象外と説明されています。(The GitHub Blog)

多数の公開リポジトリを対象に依存関係レポートを作る場合でも、匿名アクセス前提の設計は避けたほうが安定します。企業の監査・コンプライアンス用途では、GitHub Appを使い、どの権限で、どのリポジトリに対して、いつSBOMを生成したかを追跡できる形にするのが現実的です。

SBOMの中身をどうレポートに使うか

GitHubのDependency graphは、マニフェストファイルやロックファイル、Dependency submission APIで送信された依存関係情報をもとに構築されます。各依存関係について、バージョン、ライセンス情報、含まれるマニフェストファイル、既知の脆弱性の有無などを確認できます。(GitHub Docs)

SBOM export APIから取得したSPDX JSONは、単に保存するだけでなく、次のようなレポートに活用できます。

レポート用途見るべき情報活用例
ライセンス監査パッケージ名、バージョン、ライセンス禁止ライセンスの検出、法務レビュー
脆弱性管理パッケージ名、バージョン、purl脆弱性DBとの突合、修正優先度付け
依存関係棚卸しリポジトリ別の依存パッケージ一覧重複ライブラリや古いバージョンの把握
顧客提出SPDX JSON、生成日時、対象リポジトリ納品物のサプライチェーン透明性の説明
内部統制取得ログ、承認ログ、保存先監査時の証跡提示

SBOMは「生成したら終わり」ではありません。どのレポートに使うのか、誰が確認するのか、どの状態ならリリースを止めるのかまで決めておくことで、セキュリティチームと開発チームのやり取りが減ります。

CI/CDでの実装イメージ

GitHub Actionsや外部CIからSBOM export APIを呼ぶ場合は、非同期ジョブとして扱う小さなスクリプトを用意すると運用しやすくなります。

#!/usr/bin/env bash
set -euo pipefail

OWNER="your-org"
REPO="your-repo"
TOKEN="${GITHUB_TOKEN:?GITHUB_TOKEN is required}"
API_VERSION="2026-03-10"

generate_response=$(curl -sS -L \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "X-GitHub-Api-Version: ${API_VERSION}" \
  "https://api.github.com/repos/${OWNER}/${REPO}/dependency-graph/sbom/generate-report")

sbom_url=$(echo "$generate_response" | jq -r '.sbom_url')

if [ -z "$sbom_url" ] || [ "$sbom_url" = "null" ]; then
  echo "Failed to start SBOM generation"
  echo "$generate_response"
  exit 1
fi

echo "SBOM generation started: ${sbom_url}"

max_attempts=30
sleep_seconds=10

for attempt in $(seq 1 "$max_attempts"); do
  status=$(curl -sS -o sbom.json -w "%{http_code}" -L \
    -H "Accept: application/vnd.github+json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -H "X-GitHub-Api-Version: ${API_VERSION}" \
    "$sbom_url")

  if [ "$status" = "200" ]; then
    echo "SBOM downloaded to sbom.json"
    exit 0
  fi

  if [ "$status" = "202" ]; then
    echo "SBOM is still processing. attempt=${attempt}/${max_attempts}"
    sleep "$sleep_seconds"
    continue
  fi

  echo "Unexpected response status: ${status}"
  cat sbom.json || true
  exit 1
done

echo "Timed out waiting for SBOM generation"
exit 1

この例は考え方を示すためのものです。実際の運用では、APIレスポンスやリダイレクト後のステータスを利用環境に合わせて検証し、jqの有無、プロキシ、レート制限、監査ログ出力などを加えてください。

CI/CDで特に重要なのは、生成開始後すぐに失敗扱いにしないことです。202を待機状態として扱い、一定時間を超えた場合だけ失敗にすることで、大規模リポジトリでも安定して処理できます。

移行時に失敗しやすいポイント

従来APIの同期レスポンス前提を残してしまう

既存のスクリプトが/dependency-graph/sbomのレスポンスをそのままファイル保存するだけの場合、新しい非同期APIの恩恵を受けられません。タイムアウト問題を解消したいなら、generate-reportとfetch-reportを使ったジョブ型の処理に切り替える必要があります。

ただし、既存エンドポイントがすぐに使えなくなると断定するのは避けるべきです。移行では、現行の動作を確認したうえで、非同期APIへの切り替え計画を立てるのが安全です。

リリース対象コミットとSBOM対象がずれる

SBOMがHEAD時点を表す以上、リリース対象のコミットSHAとSBOM生成時のHEAD SHAがずれると、監査で説明しにくくなります。

たとえば、SBOM生成後に依存関係を含む別PRがマージされ、その後にリリースタグを切ると、SBOMとリリース成果物の関係が曖昧になります。

対策として、リリース直前に次のチェックを入れるとよいでしょう。

現在のHEAD SHAを取得
↓
SBOM生成開始
↓
SBOM取得完了
↓
取得後もHEAD SHAが変わっていないか確認
↓
変わっていればSBOMを再生成するか、リリースを止める

この確認を入れるだけで、「SBOMはあるが、どのリリースを表しているか分からない」という監査上の弱点を減らせます。

SBOM取得期限や一時URLを長期保存先と誤解する

GitHub Docsでは、生成されたSBOM reportは元のリクエストから最大1週間保持される可能性があり、fetch-reportで返される一時ダウンロードURLには別途有効期限があると説明されています。(GitHub Docs)

そのため、sbom_urlや一時ダウンロードURLを長期的な証跡として保存するだけでは不十分です。コンプライアンス用途では、取得したSPDX JSON自体を自社の成果物ストレージ、監査ログ基盤、リリースアーティファクトなどに保存してください。

権限エラーをリポジトリ不具合として扱ってしまう

403は、リポジトリ側の問題ではなく、トークン権限、GitHub Appのインストール範囲、プライベートリポジトリへのアクセス権不足が原因であることが多くあります。

自動化では、403を単なる「SBOM生成失敗」としてまとめず、権限チェック用のエラー分類に入れるべきです。大量リポジトリを扱う場合は、権限不足のリポジトリ一覧を出力し、GitHub Appのインストール対象や権限をまとめて見直せるようにします。

Platform engineer向けの実装チェックリスト

GitHub dependency graph / SBOM export APIの非同期化に対応する際は、次のチェックリストを使うと抜け漏れを減らせます。

チェック項目確認内容
APIフローgenerate-reportとfetch-reportの2段階になっているか
状態管理UUID、対象repo、HEAD SHA、生成開始時刻を保存しているか
ポーリング202を待機状態として扱っているか
タイムアウトパイプライン全体の待機上限を決めているか
リダイレクト302と一時URLの扱いをHTTPクライアントで検証したか
認証GitHub Appまたは適切なfine-grained tokenを使っているか
保存SPDX JSON本体を長期保管しているか
監査証跡生成対象、生成時刻、取得時刻、保存先を追跡できるか
エラー分類202、403、404、タイムアウトを分けて扱っているか
リリース整合性SBOM生成時のHEADとリリース対象の関係を確認しているか

このチェックリストは、単一リポジトリよりも、組織全体の依存関係レポート基盤で効果を発揮します。特に、毎日または毎週のSBOM収集を自動化している場合、状態管理と再実行性を最初に設計しておくと、後から運用が安定します。

Supply chain security team向けの判断基準

セキュリティチームは、API変更そのものよりも、SBOMをどう統制に組み込むかを決める必要があります。

判断基準は次の3つです。

リリースを止める条件を明確にする

SBOM生成に失敗した場合、必ずリリースを止めるのか、重要システムだけ止めるのか、一定時間後に例外承認へ進めるのかを決めておきます。

たとえば、顧客提出が契約上必須の製品では、SBOM未生成のままリリースしない運用が妥当です。一方、内部ツールでは、生成失敗をチケット化し、後追い修正にする判断もあり得ます。

SBOMの種類を分けて扱う

GitHub dependency graphのSBOMは、リポジトリの依存関係を可視化するうえで有用です。一方、コンテナイメージ、OSパッケージ、ビルド時に混入する成果物まで含めたい場合は、別のSBOM生成手段が必要になることがあります。

そのため、社内ルールでは次のように用途を分けると混乱しません。

SBOMの種類主な目的
GitHub dependency graph由来のSBOMソースリポジトリの依存関係棚卸し
ビルド時SBOMリリース成果物に含まれるコンポーネント確認
コンテナSBOMイメージ内のOSパッケージやライブラリ確認
提出用SBOM顧客・監査向けに整形した正式成果物

レポートの鮮度を定義する

SBOMは時間とともに古くなります。依存パッケージの脆弱性情報は後から追加されるため、過去に問題なしだったSBOMでも、後日リスクが見つかることがあります。

依存関係レポートでは、次のような鮮度ルールを定義すると運用しやすくなります。

重要リポジトリ: 毎日SBOMを再取得
通常リポジトリ: 週1回SBOMを再取得
リリース対象: リリース直前にSBOMを再取得
監査提出: 提出前に対象リポジトリと生成日時を確認

このように基準を明文化しておくと、「いつのSBOMを見ればよいのか」という問い合わせを減らせます。

まとめ:SBOM exportの非同期化は、安定化と設計変更の両方を意味する

GitHub dependency graph / SBOM export APIの非同期化は、大規模リポジトリでのタイムアウトを避けやすくする前向きな変更です。一方で、コンプライアンスパイプラインや依存関係レポートの自動化では、APIを1回呼んで終わる設計から、生成ジョブを管理する設計へ移行する必要があります。

まず取り組むべきことは、既存スクリプトやCI/CDでSBOM取得を同期処理として扱っていないか確認することです。次に、generate-reportで生成を開始し、fetch-reportで202を待機、完了後にSPDX JSONを保存する流れへ置き換えます。最後に、HEAD SHA、生成開始時刻、取得完了時刻、保存先を監査証跡として残してください。

SBOMは、単なる依存関係一覧ではなく、サプライチェーンリスクを説明するための証拠です。非同期化に合わせて自動化を見直せば、タイムアウトに強いだけでなく、監査やリリース判断にも耐えられる依存関係レポート基盤を作れます。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次