はじめに
コードを書く速度と確認する速度
ここ数年で、コードを書く環境が変わった。
生成AIアシスタントが開発フローに入り込み、コードの補完、依存パッケージの利用例、テストコードの骨格生成などを支援するようになった。
以前であれば自分で調べて追加していたライブラリも、生成AIが提案することが増えている。
Pythonでは、その依存関係は requirements.txt や pyproject.toml に記録される。
ライブラリが増えれば、管理対象も増える。
生成AIが提案したライブラリや依存パッケージに既知の脆弱性が含まれていないかを確認する仕組みが、コード生成と同じ速度で整備されているケースはまだ多くない。
そこで検証環境を作り、成果物の生成、登録、可視化を段階的に自動化した。
この連載では、その過程と確認できた結果を整理する。
何が見えなくなっているのか
ライブラリを追加すると、実際に動くソフトウェア部品も増える。
開発者が追加したライブラリだけでなく、そのライブラリが利用する別のライブラリも一緒に取り込まれるからだ。
結果として、実行環境には多くのサードパーティコードが含まれることになる。
このサードパーティコードに既知の脆弱性(CVE)が報告されたとき、それを把握する仕組みがなければ、脆弱なバージョンを本番で動かし続けることになる。
SBOMとは何か
そこで利用したのがSBOM(Software Bill of Materials)だ。
SBOMはソフトウェアの部品表であり、どのライブラリのどのバージョンがシステムに含まれているかを機械可読な形式で記録する。
今回の検証では、このSBOMを起点として、
Package Inventory、
Package Risk、
License情報の可視化を行った。
この連載でやること
この連載では、PythonマイクロサービスのCIパイプラインに対して、3種類のセキュリティ成果物を継続的に生成し、IBM Concert Protectへ自動投入する仕組みを段階的に構築した過程を記録する。
| 成果物 | 役割 |
|---|---|
| Package SBOM(CycloneDX 1.6) | どのライブラリが含まれているかの部品表 |
| SARIF(CodeQL) | 静的コード解析の結果 |
| Trivy Image Scan | コンテナイメージの脆弱性情報 |
目指したのは次のフローが自動で回ることだ。
mainブランチへのpush
↓
GitHub Actions が成果物を生成
↓
Upload Client が REST API 経由で登録
↓
IBM Concert Protect の表示を更新
フォークから作成された Pull Request など、必要な Repository Secrets を利用できない実行では、Concert への登録処理をスキップする設計とした。
今回の対象は検証環境であり、本番運用設計までは扱わない。以降では、実際に動作した経路と、取り込みに失敗した経路を分けて記録する。
最初の失敗
最初にCycloneDXのSBOMをIBM Concert Protectに投入したとき、失敗した。
入力データが必要な形式に一致しないため、ファイルの解析に失敗しました。
CycloneDX形式で出力しているため動作すると想定していた。失敗したSBOMと取り込みに成功したConcert向けSBOMを比較すると、次の差異があった。
-
metadata.component.typeがapplicationになっていない -
metadata.componentにリポジトリのVCS参照が含まれていない - コンポーネントのtypeが Concert向けに変換されていない
これらを調整したSBOMの取り込みには成功し、76パッケージが認識されてPackage Inventoryが表示された。ただし、どの項目が失敗の直接原因だったかは、今回の検証だけでは個別に特定していない。
標準フォーマットであっても、実際の取り込み可否は投入して確認する必要があった。以降の検証でも、成果物の形式と登録経路を個別に確認した。
検証結果の全体像
成功した経路:
| 成果物 | Concert側の反映 |
|---|---|
concert-package-sbom.json(変換後) |
Package Inventory(76パッケージ)・Package Risk・License情報 |
python.sarif(CodeQL出力) |
SAST Exposure |
trivy-image.json(コンテナスキャン) |
CVEダッシュボード |
取り込みに失敗した経路:
| 成果物 | 観測結果 |
|---|---|
sbom.json(標準出力) |
フォーマット不一致エラー。Concert向けに変換したSBOMでは成功 |
trivy-fs.json(ファイルシステムスキャン) |
パースエラー。Image Scanの成功ファイルと比較すると Results フィールドの欠落や ArtifactType の差異が確認された |
ツールの立ち位置
この連載で登場するツールの役割分担を整理する。
| ツール | この連載での役割 |
|---|---|
| GitHub Actions | SBOM・SARIF・Trivy JSON の継続的生成と自動投入 |
| IBM Concert Protect | 成果物を受け取りリスクを可視化・追跡するプラットフォーム |
| IBM Concert Secure Coder | IDE から脆弱性を検出するアシスタント(第3回で比較対象として登場) |
| IBM Bob | Secure Coder を動かすエージェント環境 |
| CodeQL | GitHub ネイティブの静的解析エンジン |
| Trivy | コンテナイメージの脆弱性スキャナー |
各回の内容
| 回 | タイトル |
|---|---|
| 第1回(本記事) | 生成AIで開発は速くなった。では、脆弱性管理は誰がやるのか? |
| 第2回 | IBM Concert Protect でソフトウェア部品とリスクを可視化してみた |
| 第3回 | CodeQL・Trivy・SBOM変換スクリプトでセキュリティ成果物を生成してみた |
| 第4回 | REST API で IBM Concert への登録を自動化してみた |
| 第5回 | GitHub Actions から IBM Concert Protect にセキュリティ成果物を自動投入してみた |
次回予告
第2回では、IBM Concert Protectへの手動投入結果を整理する。
Package SBOM・CodeQL SARIF・Trivy Image Scan を投入し、Package Inventory・SAST Exposure・CVE Dashboard への反映を確認した。一方、標準出力の SBOM と Trivy Filesystem Scan は取り込みに失敗した。
今回の検証では、Application・Package・SAST・CVE を別々の経路で登録した。次回は、失敗した経路の分析と、各データの関連付けを扱う。
まとめ
冒頭の問いに戻る。「では、脆弱性管理は誰がやるのか?」
脆弱性への対応判断は人が行う。一方、SBOM・静的解析結果・コンテナスキャン結果の生成と登録は、CIパイプラインへ組み込める。
今回の検証では、最初から自動化を行わず、次の順序で進めた。
- 各成果物を手動で投入する
- 成功する形式と失敗する形式を確認する
- REST API による登録を検証する
- GitHub Actions へ統合する
この順序により、成果物の形式に起因する問題と、自動化の設定に起因する問題を分けて確認できた。
以降の記事では、手動投入、成果物の生成、REST API連携、GitHub Actionsへの統合を順に扱う。
検証環境
- Application: Python製マイクロサービス(FastAPI / PostgreSQL)
- IBM Concert: 3.0.x
- Trivy(GitHub Actions側): 0.70.0
- CycloneDX: 1.6
- CodeQL: GitHub Actions で実行


