bom: The SBOM Multitool を使ってSPDXファイルを作成してみる

## はじめに

ソフトウェア開発において、依存関係やライセンス情報の管理は非常に重要です。特に、セキュリティやコンプライアンスに関する要求が高まる中、ソフトウェア部品表（SBOM: Software Bill of Materials）は、プロジェクトの透明性を高め依存関係の管理に不可欠なツールとなる。

ここでは、Kubernetesによって開発されたSBOM生成ツール `bom` を使って、SBOMを作成し、ライセンス情報や依存関係を確認する方法について確認する。また、`bom` を利用してSPDX形式のSBOMを生成し、それを基にプロジェクトの依存関係やライセンス情報を検索する方法も確認する。


## 公式サイト

- [bomのインストール](https://github.com/kubernetes-sigs/bom)
- [bomのマニュアル](https://kubernetes-sigs.github.io/bom/)
- [Go言語のインストール](
https://go.dev/doc/install)


## インストール

### Go言語のインストール

bomツールを使用するためにはGo言語の環境が必要だ。Goのバージョンが1.23以上でないとエラーが発生した。

```bash
# apt で go パッケージをインストールする場合
sudo apt-get install golang-go

# 最新の go をインストールする場合
# 筆者の環境では bom は 1.23 以上でないとエラーが発生した
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz
export PATH="$PATH:/usr/local/go/bin"
```

### bom のインストール

```bash
go install sigs.k8s.io/bom/cmd/bom@latest
export PATH="$PATH:$HOME/go/bin"
```


## bom でSBOMを作成する

bomツールを使って、プロジェクトのSBOMを作成する方法を確認する。以下では、bomのソースコードディレクトリからSBOMを生成する。

### Tag:Value 形式のSPDXファイルを作成する

`--format`の指定なし、もしくは`tag-value`を指定してSPDXを作成する

```bash
git clone https://github.com/kubernetes-sigs/bom.git
bom generate -n 'http://myproject.org/spdx-docs/v1.2.3'  --output=bom.spdx -d ./bom
```

生成されたSPDXファイルの例は次のとおり

```YAML: bom.spdx
SPDXVersion: SPDX-2.3
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: SBOM-SPDX-3bcb8d9e-1bc7-4d82-a2ff-e619608ae5f6
DocumentNamespace: http://myproject.org/spdx-docs/v1.2.3
Creator: Organization: Kubernetes Release Engineering
Creator: Tool: bom-v0.6.0
LicenseListVersion: 3.21
Created: 2024-09-14T05:04:50Z


##### Package: bom

PackageName: bom
SPDXID: SPDXRef-Package-bom
PackageDownloadLocation: NONE
```

### JSON 形式のSPDXファイルを作成する

次に、`--format json` オプションを使って、JSON形式のSPDXファイルを作成する。

```bash
bom generate -n 'http://myproject.org/spdx-docs/v1.2.3' --format=json --output=bom_spdx.json -d ./bom
```

生成されたJSON形式のSBOM

```json:bom_spdx.json
{
  "SPDXID": "SPDXRef-DOCUMENT",
  "name": "SBOM-SPDX-84882a7f-b91f-49a0-9eea-de4654ebe678",
  "spdxVersion": "SPDX-2.3",
  "creationInfo": {
    "created": "2024-09-14T05:02:13Z",
    "creators": [
      "Tool: bom-v0.6.0"
    ],
    "licenseListVersion": "3.21"
  },
  "dataLicense": "CC0-1.0",
  "documentNamespace": "http://myproject.org/spdx-docs/v1.2.3",
  "documentDescribes": [
    "SPDXRef-Package-bom"
  ],
  "files": [
```

## SPDXファイル作成にかかる時間
bomツールを用いてSPDXファイルを作成する時間について確認する。184ファイルで約7秒ほど掛かっている。単純に比例すると仮定した場合、50,000ファイルで構成されるプロジェクトの場合には30分ほど処理にかかる計算となる。

```bash
$ find ./bom -type f | wc -l
184
$ time bom generate -n 'http://myproject.org/spdx-docs/v1.2.3'  --output=bom.spdx -d ./bom
...
real	0m7.001s
user	0m4.190s
sys	0m0.529s
```


## SPDXファイルの構造を表示する

生成されたSPDXファイルの構造を確認するには、bom document outlineコマンドを使用する。このコマンドは、SBOMに含まれるファイルや依存関係のリストを表示する。

```bash
bom document outline bom_spdx.json 
```

```plaintext:bom document outline bom_spdx.json 
               _      
 ___ _ __   __| |_  __
/ __| '_ \ / _` \ \/ /
\__ \ |_) | (_| |>  < 
|___/ .__/ \__,_/_/\_\
    |_|               

 📂 SPDX Document SBOM-SPDX-d513daf4-813f-4422-9ed4-d1a906777c5a
  │ 
  │ 📦 DESCRIBES 1 Packages
  │ 
  ├ bom
  │  │ 🔗 210 Relationships
  │  ├ CONTAINS FILE .github/SECURITY.md (.github/SECURITY.md)
  │  ├ CONTAINS FILE .github/ISSUE_TEMPLATE/feature.md (.github/ISSUE_TEMPLATE/feature.md)
  │  ├ CONTAINS FILE .bom-config.yaml (.bom-config.yaml)
...
  │  ├ CONTAINS FILE pkg/license/data/license-list-v3.25.0.zip (pkg/license/data/license-list-v3.25.0.zip)
  │  ├ DEPENDS_ON PACKAGE github.com/opencontainers/go-digest@v1.0.0
  │  ├ DEPENDS_ON PACKAGE github.com/klauspost/compress@v1.17.8
  │  ├ DEPENDS_ON PACKAGE golang.org/x/mod@v0.21.0
...
  │  └ DEPENDS_ON PACKAGE github.com/spf13/cobra@v1.8.1
  │ 
  └ 📄 DESCRIBES 0 Files
```

## SBOM情報を検索する

`bom document query`コマンドを使って、生成されたSBOMから特定の情報を検索することができる。例えば、パッケージのライセンス情報を検索する場合、次のコマンドを使用する。

```bash
bom document query bom.spdx "name:bom" --fields name,version,license,supplier,originator,url
```
```bash:
bom _ Apache-2.0 _ _ _
```

同様に、JSON形式のSBOMからもライセンス情報を取得することができるが、以下の結果ではライセンスが正しく表示されていない。これは、bomツールのバグによるものかもしれない。

```bash
bom document query bom_spdx.json "name:bom" --fields name,version,license,supplier,originator,url
```
```bash:
bom _ _ _ _ NONE
```

現時点では、`bom document query`コマンドには不具合があるようだ。