毎々お世話になっております、株式会社 日立ソリューションズの明石と申します。本日は今年からSBOMフォーマットの国際標準として認定された、SPDXに準拠して作成されたSBOM、SPDX Documentについてご紹介したいと思います。
免責事項
当記事の内容については、できる限り正確な情報を提供するように努めておりますが、正確性や安全性を保証するものではなく、筆者独自の解釈も含むことをご了承ください。掲載しているリンク先についても確認などは行っていますが、遷移先で提供される情報、サービスなどについては一切の責任を負いません。
また、掲載内容の活用は読者自身の自由と主体性の元に行うものとし、万が一損害が発生したとしても一切の責任を負いかねます。ご了承ください。
そもそも、SPDXって何?
SPDXという単語の由来は「Software Package Data Exchange」の頭文字から来ており、直訳すると「ソフトウェアパッケージのデータ交換」になりますが、これだけでこのSPDXがどういう意味を持つのかを理解するのは少し厳しいと思います(少なくとも筆者はそうでした)。なので、まずはこのSPDXの意味について、背景を交えて簡単に解説します。
背景として、近年のアプリケーションソフトウェアは、多くの部分(一説によると8~9割)がOSS、つまり自前成果物ではない部品で構成されています。これはソフトウェア開発において、OSSの使用がさまざまなメリットをもたらしていることが認知された結果であり、現在のソフトウェア開発はOSSなしに成り立たないといってもよいでしょう。しかしながら、こういった外部の成果物を取り込んで使用するという行為にはリスクを伴います。OSS利用に関するリスクとして最も典型的な例が、ライセンス違反に関するリスクです。OSSには、それぞれ固有のライセンスが適用されています。ライセンスには、そのOSSを利用する際の条件が記されており、これに違反した場合、利用者に対して何らかの法的な措置が取られるケースがあります。ほかにも脆弱性、信頼性といったさまざまなリスクがあり、ソフトウェア開発ではOSSの利用に伴って発生するこれらのリスクに対応する必要性が増しています。
ここでそのリスク対応において必要となってくるのがソフトウェア部品表、SBOM(Software Bill of Materials)です。SBOMにはアプリケーションに含まれるソフトウェア部品が何であるかを特定する情報、その出所やライセンス、セキュリティについて情報を詳細に記録します。こういった情報を持つSBOMを作成、管理しておくことで、ソフトウェアが抱えている問題やリスクを事前に把握し、どう対処するか判断材料として参照、活用できる、という訳です。また、サプライチェーン全体でソフトウェアの構成部品を追跡する場合にもこのSBOMを使用することができるといったメリットもあります。
このSBOMを標準的な規格で作成し、業界内の異なるチームや企業間での情報交換をやりやすくしよう、というのがSPDXプロジェクトの目的であり、そこで策定されたSBOMの規格、フォーマットがSPDX Specificationと呼ばれています。 (つまり、SPDXという単語はプロジェクトを指すときと仕様を指すときがあります。本記事では前者を示す際はSPDXプロジェクト、後者を示す際はSPDX Specと呼称することにします)
SPDXプロジェクトは、具体的な成果物としては以下を提供しています。
SPDX License List
SPDXプロジェクトが一般的に適用されるライセンスをリスト化したもの。本文や参照先などのライセンスに関する情報がまとめてある。「GPL」や「MIT」などのよく見るライセンスはおおむねカバーされている。
SPDX Specification
SPDXプロジェクトが提供するSBOMフォーマット。これに準拠したファイルをSPDX Documentと呼び、本記事で概要を解説する。なお、執筆時点での最新版はv2.2.1。
SPDX DocumentやSPDX License Listに関するツール、ライブラリ
SPDXプロジェクトが提供している、SPDX Specificationに対応したファイルに関するツール、ライブラリ。代表的なものとしてSPDXファイルを操作する「spdx-tools」が上げられる。
今回はこのSPDX Specification、SPDX Specが今年国際標準として認定されたということで、それにしたがって作成されるSBOM、SPDX Documentはどういう構造をしており、どのような情報を持つのかについて簡単に解説したいと思います。
SPDX Documentとは
SPDX Specificationにしたがって作成された、ソフトウェアパッケージに関連するコンポーネントやライセンス、コピーライトなどの情報が記された文書のことを指します。具体的には以下の形式かつ、SPDX Specificationが規定した情報が記載されたファイルです。
Tag:Value(txt)
RDF
xls
json
YAML
xml
情報は属性(keyやTag)に対応する値(Value)を記述することで表現します。最初の3つは具体例も示されているので、気になる方は直接こちらをご覧になってください。
特徴、何がうれしいか
冒頭で説明した通りですが、ほかにも特筆すべき点があります。SPDX Specificationの策定にあたって、SPDXプロジェクトが念頭に置いていることの一つに「ソフトウェアで読み書きできること」というものがあります。つまり、SPDX Documentは、ソフトウェアを介して操作されることを想定しているのです。この仕様に準拠してさえいれば、例えばあるソフトウェアパッケージが依存しているソフトウェアパッケージのそのまた先が依存しているソフトウェアのライセンスを確認したい、といった状況でも手段としてひたすら目で参照先を追いかける以外に、ソフトウェアで参照先を抽出するという選択肢を取ることが可能になるわけです。
当然、ソフトウェアによってこのSPDX Documentそのものが作成されることも想定されています。最終的な確認は人の手によって行う必要がありますが、近年の複雑化しているソフトウェア開発において自動でSBOMを生成、取得できるというのであれば、非常にありがたいことです(残念ながら現段階では「SBOM生成するならコレ!」といった立ち位置のソフトウェアはまだ存在しないようですが)。
また、デファクトスタンダードとして仕様が広まれば広まるほど、お互いの情報交換がしやすくなるというメリットがあります。この状況の実現をめざしSPDXプロジェクトがこのSPDX Specの普及に尽力してきた結果、国際標準としての地位を得ることとなりました。
対象スコープ
SPDX Documentは作成時点のソフトウェアパッケージにおけるSBOMです。あくまでファイルの作成時点なので、この文書は基本的に作成された当時のソフトウェアパッケージについての情報のみを保持しています。逆に、一度作ったSPDX Documentを作成した後、時間が経ってからそれを編集することは想定されておらず、編集履歴を記録することを前提とした属性は存在しません。したがって、SPDX DocumentをSBOMとして使用していく際は、都度必要性が生じる(例:バージョンアップして構成が変更された)たびにSPDX Documentを生成して保管するという運用になります。
構造
この文書がどのように構成されているかを見ていきましょう。細かく見てしまうと筆者側は仕様の日本語訳をしたうえに大量の注釈をつけることになり、読む側の労力もあまりに大きくなるので、今回はざっくり解説するに留め、あくまでSPDX Documentがどのように構成されているのかを把握することをを目標にしたいと思います。
1. 前提
SPDX Documentはファイルそのもののほかに前提となるものが存在しています。これらはSPDXプロジェトがSPDX Specificationのほかに成果物として提供しています。
- SPDX License List
- spdx-tools
これらがどういった際に使用されるのかについては後述します。今はこれらの存在が前提でSPDX Specが成り立っているとだけ覚えておいてください。
SPDX Documentは、セクションという関連する属性のまとまりで構成されています。公式ではイメージとして、以下のような図が提示されています。
Image via What this specification covers
SPDX Specをある程度読み込むと図の意味は理解できるのですが、個人的にはこの図で構造をイメージするのは難しいと思いましたので、より構造的に解釈した図を以下のとおり用意しました。こちらの図を理解していただくことが今回のゴールになります。
- ※あくまで筆者の解釈です。公式に確認を取ったわけではありません。
この図は公式イメージ図に対し、以下のような点を意識して作成しました。
- Annotationはほかのセクションに付随する形を取っている。
- Relationshipは一方向の矢印(何かを示す文字列付き)、ほかのセクションを結び付けている。
- Other Licensing Informationの矢印はRelationshipと異なる。Package Informationにしか伸びていない。
上記は、SPDX Specificationについて理解していくことでこうした形での解釈、表現ができることに納得していただけるかと思います。
それではなぜこのような解釈となるのか、これから各セクションが持つ情報や役割とともに説明していきます。
セクションのうち、以下のセクションは実際のディレクトリだったり、ファイルやスニペットに対応しています。したがって、ほかのセクションに関係なく独立して存在することができます。
- SPDX Document Creation Information
- Package Information
- File Information
- Snippet Information
また、これらは実際のディレクトリ、ファイルやスニペットに関する以下の情報を持ちます。
2. SPDX Document Creation Information
SPDX Documentそのものに関する情報のセクション。いつ、どこで、誰が何のSPDX Documentを作成したといった情報を保持する。SPDX Documentが外部の情報を参照している場合は、その参照先についての情報も保持する。
このセクションはSPDX Document1つにつき必ず1つ存在する。
3. Package Information
ソフトウェアパッケージを構成するパッケージ(コンポーネント)についての情報をもつセクション。パッケージ名やバージョン、ライセンス、パッケージの供給者や入手先などの情報を保持する。
ソフトウェアパッケージを構成するパッケージの数だけこのセクションのインスタンスが存在する。
4. File Information
ソフトウェアパッケージを構成するファイルについての情報を持つセクション。存在できるインスタンスのカーディナリティはPackage Informationと同様。
保持する情報はPackage Informationのもつ属性のうち、ファイル単位で必要な分だけといった具合。
5. Snippet Information
ソフトウェアパッケージを構成するスニペットについての情報を持つセクション。存在できるインスタンスのカーディナリティはPackage Informationと同様。
保持する情報はスニペットの位置を示す属性を除いてFile Informationと同じ。
ex. Review Information
SPDX Documentをレビューした際の情報をもつセクション。非推奨かつ削除予定の項目であり、構造的にも関連性は薄いのでこれ以上は言及しない。
対して残る3つのセクションは、上記4つのセクションのインスタンスの存在を前提として存在するようになっています。その中でも、SPDX Documentの構造を理解するうえで一番重要なのが次のセクションになります。
6. Relationships between SPDX elements information
このセクションの役割を理解するには、まずSPDX Identifierという概念を頭に入れておく必要があります。
ex. SPDX Identifier
SPDX Document内にて、対象を一意に特定できる識別子。Package Information、File Information、Snippet Informationセクションのインスタンスは複数存在する可能性があるため、どのセクションのどのインスタンスを特定するために保持する。 RDBで例えると、あるテーブルにおけるレコードを特定する主キーのような立ち位置。
SPDX Identifierの説明とこのセクションの名前でなんとなく予想がついたかもしれませんが、このRelationshipsセクションの役割はSPDX Identifierを使って各セクションの関係性を示すことです。
このセクションが持つRelationshipという属性の値は、「○○ △△ ××」という文字列で表現します。○○と××は先ほどのSPDX Identifierです。そして△△の部分が「Relationship」という、SPDX Specのこちらの項で規定された43種類の文字列のいずれかを記入します(属性そのものとは異なるので注意)。これらの文字列には関係性が定義されており、Relationshipsを記入する際は前後のセクションの関係性としてふさわしいものを選んで使うというわけです。
例えば、「○○は××を含む」という関係を示したい場合、SPDX Specを見ると"含む"という関係性が定義された"CONTAINS"という文字列があるのでこれを使って「○○ CONTAINS ××」というように表現します。図で表すとこのような形です。
Relationship「CONTAINS」イメージ
SPDX Document内には、それぞれのセクション同士、1対1の関係性の数だけ、このRelationshipsのインスタンスが存在します。つまり、SPDX Documentでは内に存在する「このパッケージはこのファイルを内包する」といった構造的な関係性を含め、「あるパッケージがどのファイルに依存する」、「あるパッケージによってこのファイルは生成される」といった関係性すべてをこのインスタンスとして記述する形で表現するということです(逆に言えば、すでに説明したほかのセクションは、SPDX Document内部における関係性を記録するような属性は一切持たないということです)。
- ※例外として外部参照先(例:URI)の情報はSPDX Document内ではなく外部を指し示すので、Relationshipsではなく各インスタンスの中に参照先の情報を保持しています。
残る2つは、これまで説明したセクションのインスタンスに対し情報を補完するセクションとなります。SPDX Documentによっては存在しない場合もあり、またインスタンスに対する関係性も決まっているのでRelationshipsのインスタンスで関係性を示す必要もありません。
7. Annotations
文字通り注釈です。各セクションは情報を記載する複数の属性が最初から用意されているわけですが、記しておきたい情報の種類がこの属性のいずれにも合致しなかったり、あくまで参考程度にしておきたいが文書の中に情報として記録したい場合にこのセクションを利用します。したがって、このセクションはほかのセクションに付随する形で存在することができます。
8. Other Licensing Information Detected
ライセンスについての「追加情報が必要な場合」のみ存在するセクションです。この「追加情報」が必要な場合というのは、SPDX Document内のあるセクションがもつライセンスの情報が前述したSPDX License Listに記載されていないという状況です。SPDX Specでは、SPDX License Listに記載されているライセンスについての情報はListが持っているからSPDX Document内に記載せずこれを参照しましょう、という決まりになっています。しかし、すべてのライセンスがここに登録されているわけではないので、記載のないものについてはライセンス名やライセンス本文、参照先の情報をSPDX Document内に持つ必要があります。それがこのセクションの役割です。
したがって、SPDX Document内で参照されるライセンスがすべてSPDX License Listに載っている場合、このセクションのインスタンスは存在しません。
これですべてのセクションの役割について説明が終わりました。ここでゴールとして提示した画像を再度確認してください。
伝わるとよいのですが...
これまで説明してきた通り、図では複数の「Package Informationが存在」していたり、「Annotationはほかのセクションに付随」していたり、「Relationshipがインスタンス同士を結び付けて」います。
SPDX Documentの構造イメージがこのように表現できることがお分かりいただけたでしょうか?
SPDX Documentとして成立するには
では最後に、何をもってファイルがSPDX Documentであると判断するのかについて説明します。SPDX Documentとしての成立性を確認したい場合は、SPDXプロジェクトが提供しているOSS、spdx-toolsを使用します。このspdx-toolsのVerifyというコマンドが構造のところで説明した規則のすべてを機械的に確認してくれるので、人力で確認する必要はありません。
このあたりで「よし、それでは早速SPDX Documentを作ろう!」という気持ちになった方がいらっしゃいましたら、この記事を書いた身としては非常にうれしい限りなのですが、現状では作成するにあたって考慮すべき点があることを喚起しておきます。
そもそも、昨今新しく開発したソフトウェアパッケージにはさまざまなOSSソフトウェア、コンポーネントが含まれていることがほとんどです。つまり、これに対応したSPDX Documentを作成しようとするとそれなりの数のPackage、File、Snippetと大量のRelationships(そして場合によってはAnnotationとOther Licensing Information)を記述しなければならなくなる場合がほとんどだと思います。したがって、手作業でSPDX Documentを作成するのは現実的ではありません。しかしながら、冒頭で述べたようにSPDX Documentを自動生成できるスキャンツールとしてデファクトスタンダードにあたるものは、残念ながらまだ存在しません(仕様を普及している段階なので当然と言えば当然ではありますが)。SPDXを扱えるツール自体はいくつか存在しますが、どれもまだ発展途上といった状態です。こういったSPDXを取り巻く状況はしっかり踏まえたうえで検討した方がよいでしょう。
参考として、いくつかSPDXに関連したOSSのリンクを貼っておきます。もしSPDX Documentの運用を検討されている場合は、こちらについても調査してみるとよいかと思います。
(これらの詳細はこれまた長くなるので割愛します。)
SPDX-Lite~手作業でSBOMを作成したい方に~
手入力でSPDX Documentを作成することを想定した、SPDX Specificationの中でSPDX-Liteという仕様が定義されています。 これはSPDX Specification のAppendix Hで規定されている、簡略化されたSPDXの仕様です。SPDXから最低限の必須情報のみを記述するだけで成立するよう定義されており、ここに規定されたセクションについて記述するだけでSPDX Documentとして成立します。SPDXと比較して扱う情報がかなり少なく済むので、手入力でSBOMを作成する場合はこちらの利用を考えてみてはいかがでしょうか?
ちなみに、このフォーマットで作成したファイルもSPDX Documentとして扱うことになっているので、spdx-toolsのVerifyコマンドで確認が可能です。
作成から確認までの一連の作業については別記事でまとめています。ご興味があればこちら「OSS管理ブログ SPDX-LiteでSBOMを作ってみよう」もご覧ください。
まとめ
- SPDXとはSPDXプロジェクトが策定しているSPDX Specificationのことであり、SPDX Documentとはそれにしたがって記述された文書ファイルのことを指す。
- SPDX Documentはあるソフトウェアパッケージに対するSBOMであり、ソフトウェアパッケージに関する包括的な情報を記載した文書である。単なる情報を集約した文書ではなく、ソフトウェアによる操作を前提としている。
- 手作業で作成する場合はより簡略化されたSPDX-Liteというフォーマットも存在する。
終わりに
いかがでしたでしょうか?自分がSPDXについて調査したとき、まったく分からない状態で参照するのに適した情報源がなかったので、それならばと思い書いてみました。この記事が何かの一助になりましたら幸いです。