Skip to content

Commit 4cbaee5

Browse files
sethmlarsonhugovkezio-melotti
authored
Add initial guide for maintaining Software Bill-of-Materials (#1251)
Co-authored-by: Hugo van Kemenade <[email protected]> Co-authored-by: Ezio Melotti <[email protected]>
1 parent 78fc0d7 commit 4cbaee5

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

developer-workflow/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ Development workflow
1313
lang-changes
1414
grammar
1515
porting
16+
sbom

developer-workflow/sbom.rst

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
Software Bill-of-Materials (SBOM)
2+
=================================
3+
4+
Software Bill-of-Materials (abbreviated as "SBOM") is a document for sharing
5+
information about software and how it's been composed. This format is used
6+
most often in the security space for checking software and its dependencies
7+
for vulnerabilities using vulnerability databases like
8+
`CVE <https://www.cve.org/>`_ and `OSV <https://osv.dev/>`_. The SBOM format
9+
that the CPython project uses is `SPDX <https://spdx.github.io/spdx-spec/v2.3/>`_
10+
which can be transformed into other formats if necessary by consumers.
11+
12+
There are multiple sources of third-party dependencies for CPython.
13+
Some are vendored into the source code of CPython itself (like ``mpdecimal``
14+
vendored at :cpy-file:`Modules/_decimal/libmpdec`) or they could be optionally pulled
15+
in during builds like Windows using dependencies from the
16+
`python/cpython-source-deps <https://github.com/python/cpython-source-deps>`_
17+
repository.
18+
19+
Whenever adding or updating a third-party dependency, an update will likely
20+
need to be done to the SBOM in order to track the version and software identifiers.
21+
22+
Updating a dependency
23+
---------------------
24+
25+
The SBOM for CPython's bundled dependencies is kept at
26+
:cpy-file:`Misc/sbom.spdx.json`. When updating a dependency to a new version
27+
you'll need to edit the version and other metadata about this dependency in
28+
the SBOM.
29+
30+
The recommended workflow is:
31+
32+
1. Download the new dependency as an archive. Take note of the new version, download
33+
URL, and checksum of the downloaded archive.
34+
2. Update the vendored code in the CPython source tree.
35+
3. Edit :cpy-file:`Misc/sbom.spdx.json` to add the new ``versionInfo``,
36+
``downloadLocation``, ``checksums``, and ``externalReferences`` for the
37+
corresponding ``package``. For most of these updates all that's needed is to
38+
update the embedded version within URLs and project identifiers.
39+
Don't update any information in ``files`` and ``relationships`` as this will
40+
be generated automatically by the SBOM tool.
41+
4. Run ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``.
42+
Ensure that this doesn't fail with validation errors.
43+
5. Run ``git diff Misc/sbom.spdx.json`` and check the diff matches the
44+
expected changes.
45+
6. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` along with the
46+
update to the dependency code.
47+
48+
Adding a new dependency
49+
-----------------------
50+
51+
When adding a dependency it's important to have the following information:
52+
53+
* Name, version, and download URL of the project
54+
* License of the project as an `SPDX License Expression <https://spdx.org/licenses/>`_
55+
* Software identifiers that match values in vulnerability databases
56+
(`CPE <https://nvd.nist.gov/products/cpe>`_ and
57+
`Package URLs <https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst>`_
58+
or "PURLs")
59+
* Paths to include and exclude in the CPython source tree corresponding to this dependency
60+
61+
After gathering this information:
62+
63+
1. Add the information into a new entry in ``packages`` in the file
64+
:cpy-file:`Misc/sbom.spdx.json`. Don't worry about formatting, the tool will
65+
auto-format your manually written JSON. The fields to fill out include:
66+
67+
* ``name`` for the project name.
68+
* ``SPDXID`` which will be ``"SPDXRef-PACKAGE-{name}"``.
69+
* ``licenseConcluded`` for the SPDX license identifier of the project license.
70+
* ``versionInfo`` for the version of the project.
71+
* ``downloadLocation`` should be an HTTPS URL for the project download as an archive.
72+
* ``checksums[0].checksumValue`` and ``.algorithm`` will be the SHA-256
73+
checksum of the downloaded archive.
74+
* ``originator`` for the original author information, prefix with either an
75+
``Organization:`` or ``Person:`` depending on the author/maintenance situation.
76+
* ``primaryPackagePurpose`` will likely be ``"SOURCE"``.
77+
* ``externalReferences`` is a list of one or more project identifiers,
78+
either CPE or Package URL. The value for ``referenceLocator`` must include
79+
the value in ``versionInfo`` to ensure the identifier
80+
corresponds to the correct release of the software. You can read more about
81+
external references in the `SPDX SBOM specification`_.
82+
2. If a new license ID is to be used, add the license expression to
83+
``ALLOWED_LICENSE_EXPRESSIONS`` in the :cpy-file:`Tools/build/generate_sbom.py`.
84+
3. Add the paths to include and exclude into a ``PackageFiles`` instance
85+
with a key corresponding to the SBOM ID for the package (``SPDXID`` without the
86+
``SPDXRef-PACKAGE-*`` prefix) in :cpy-file:`Tools/build/generate_sbom.py`.
87+
4. Run the tool with ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``.
88+
Ensure that the tool doesn't fail with any validation errors.
89+
5. Compare the changes to :cpy-file:`Misc/sbom.spdx.json` with ``git diff``, check
90+
that all information appears correct.
91+
6. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` and
92+
:cpy-file:`Tools/build/generate_sbom.py`.
93+
94+
.. _SPDX SBOM specification: https://spdx.github.io/spdx-spec/v2-draft/external-repository-identifiers/
95+
96+
Removing a dependency
97+
---------------------
98+
99+
When removing a dependency:
100+
101+
1. Remove the entry from the :cpy-file:`Misc/sbom.spdx.json`
102+
under the ``packages`` field.
103+
2. Remove the corresponding ``PackageFiles`` entry in :cpy-file:`Tools/build/generate_sbom.py`
104+
3. Run the tool with ``make regen-sbom`` or ``python Tools/build/generate_sbom.py``.
105+
Ensure that the tool doesn't fail with any validation errors.
106+
4. Compare the changes to :cpy-file:`Misc/sbom.spdx.json` with ``git diff``, check
107+
that correct package is removed from the SBOM.
108+
5. Commit the changes to :cpy-file:`Misc/sbom.spdx.json` and
109+
:cpy-file:`Tools/build/generate_sbom.py`.

0 commit comments

Comments
 (0)