依存関係
依存関係グラフとは?
依存関係グラフは、ソフトウェアが依存するすべてのパッケージと、それを取り込んだパッケージを示します。一覧はソフトウェアに何が含まれているかを教えてくれます。グラフは、なぜそれがあり、ほかに何に影響するかを教えてくれます。脆弱性が見つかったときに知りたいのは、まさにその点です。
更新日
ノード、エッジ、経路
依存関係グラフでは、各パッケージがノード、「依存する」という関係の1つひとつが、あるパッケージから別のパッケージへのエッジです。最上位には自社のプロジェクトがあります。直接の依存関係はエッジ1本分の距離にあり、それより下にあるものはすべて推移的依存関係です。プロジェクトから任意のパッケージへのルートがその依存経路で、1つのパッケージが複数の経路を持つこともあります。
グラフ、ツリー、一覧
同じ依存関係を3通りの方法で表示でき、それぞれ答えられる問いが異なります。
| 表示形式 | 示すもの | 失われるもの |
|---|---|---|
| フラットな一覧 | すべてのパッケージを1回ずつ、バージョンとともに | 各パッケージがなぜ含まれているか |
| ツリー | パッケージマネージャーが出力する、プロジェクトからのすべての経路 | 共有パッケージが重複するため、実際より大きく見える |
| グラフ | すべてのパッケージを1回ずつ、各親からのエッジとともに | ビューアーなしでは目で読み取りにくい |
グラフが重要なのは、共有パッケージがあるからです。2つの依存関係が同じパッケージを必要とすると、ダイヤモンド、つまり2つの親を持つ1つのノードができます。そのパッケージの脆弱性を修正するには両方の経路を把握する必要があります。どちらの親も古いバージョンを固定している可能性があるためです。
依存関係グラフの用途
- 修正経路を見つける。脆弱な推移的パッケージは、その経路上の何かをアップグレードまたはオーバーライドすることで修正します。グラフを見れば、どの直接の依存関係を更新すべきかが分かります。
- 影響範囲を測る。アドバイザリが公開されたとき、グラフはどの直接の依存関係、サービス、製品が影響を受けるパッケージにつながっているかを示します。
- ライセンスを確認する。グラフの深い階層にあるコピーレフトライセンスも、最上位にあるものと同じように適用されます。経路を見れば、どの依存関係がそれを持ち込んだかが分かります。
- アップグレードを計画する。あるパッケージのメジャーアップグレードは、その下にあるすべてに影響します。グラフを見れば、ツリーのどれだけが変わるかが分かります。
- リスクの集中を見つける。多くの経路が通過する、小規模でメンテナンスされていないパッケージは、単一障害点になります。
依存関係グラフの取得方法
パッケージマネージャーから。どのパッケージマネージャーも解決済みのツリーを出力でき、多くは特定のパッケージがなぜ含まれているかを説明できます。npm、pnpm、Python、Go、Rust、Maven、Gradleのコマンドは推移的依存関係のページにまとめています。
GitHubから。リポジトリのInsightsタブにある依存関係グラフは、リポジトリ内のマニフェストとロックファイル、およびdependency submission APIから送信された依存関係をまとめたものです。対応するエコシステムでは、GitHubは各依存関係を取り込んだ推移的な経路を表示し、グラフをSBOMとしてエクスポートすることもできます。
SBOMから。CycloneDXはグラフをdependenciesセクションに記録し、各コンポーネントが依存するものを列挙します。SPDXはパッケージ間のDEPENDS_ON関係を使います。Expressアプリの一部についてのCycloneDXグラフは次のようになります。
"dependencies": [
{ "ref": "my-app", "dependsOn": ["express"] },
{ "ref": "express", "dependsOn": ["body-parser", "send"] },
{ "ref": "body-parser", "dependsOn": ["raw-body", "debug"] },
{ "ref": "send", "dependsOn": ["mime-types", "debug"] }
] ここではdebugが2つの親の下に現れています。これがダイヤモンドです。多くのSBOMは関係を省略してコンポーネントだけを列挙するため、インベントリは残りますが、すべての経路が失われます。
グラフの質はその情報源で決まる
ほとんどの依存関係グラフはマニフェストとロックファイルから作られるため、パッケージマネージャーが計画したツリーを示します。CIキャッシュから復元されたパッケージ、セットアップステップでインストールされたビルドツール、インストールスクリプトやダウンロードで取得されたコードは表示されず、ビルドがロックファイルどおりにインストールしたかどうかも分かりません。ロックファイルが出荷内容の記録にならない理由をご覧ください。
CRACIの依存関係グラフ
CRACIはビルドそのものからグラフを作成します。CRACIはGitHub Actionsランナーであり、各ジョブが取得するすべてのパッケージを、ツリーのあらゆる階層で、CIキャッシュから復元されたパッケージも含めて記録し、自らの完全性を明示するSBOMにまとめます。
- SBOMのグラフ表示。依存関係ビューでは、SBOMの依存関係の階層をPivot、Graph、Blob、Chord、Sunburstの各ビューで表示し、深さと深刻度で絞り込めます。
- ツリー全体を含むエクスポート。CycloneDXとSPDXのエクスポートには推移的依存関係が含まれ、それぞれに宣言ライセンスが付きます。
- 影響を受けたビルドを時系列で把握。新たな脆弱性が見つかると、ビルド履歴から、脆弱なパッケージを直接または推移的に含んでいた過去のビルドが分かります。
CRACIのSBOM生成をご覧いただくか、デモを予約して自社のビルドのグラフをご確認ください。
依存関係グラフに関するよくあるご質問
依存関係グラフとは何ですか?
依存関係グラフとは、ソフトウェアが依存するすべてのパッケージを、各パッケージから必要とするパッケージへの矢印で結んだ地図です。ソフトウェアに何が含まれているかだけでなく、なぜ含まれているか、つまり自社のコードから各推移的依存関係に至る経路を示します。
依存関係ツリーと依存関係グラフの違いは何ですか?
ツリーは経路を1つずつ別々に示すため、2つの親から必要とされるパッケージは2回現れます。グラフは各パッケージを1回だけ示し、それを必要とするすべての親からエッジを引きます。パッケージマネージャーは読みやすさを優先してツリーを出力しますが、影響を分析するツールはグラフを使います。
SBOMには依存関係グラフが含まれますか?
含めることができます。CycloneDXにはdependenciesセクションがあり、各コンポーネントが依存するコンポーネントを列挙します。SPDXは同じ内容をDEPENDS_ON関係で表現します。ただし多くのSBOMは関係を省略してコンポーネントだけを列挙するため、経路が失われます。
GitHubリポジトリの依存関係グラフはどう見ればよいですか?
リポジトリのInsightsタブを開き、Dependency graphを選択します。GitHubはリポジトリ内のマニフェストとロックファイル、およびdependency submission APIから送信された内容をもとにグラフを作成し、対応するエコシステムでは各推移的依存関係を取り込んだ経路を表示します。
ダイヤモンド依存関係とは何ですか?
2つの依存関係がどちらも同じパッケージに依存しているため、グラフがひし形(ダイヤモンド)になる状態です。両者がそのパッケージの互換性のないバージョンを必要とする場合、パッケージマネージャーは2つのコピーをインストールするか、失敗するしかありません。グラフが見た目以上に管理しにくくなる理由の1つです。