Proof of Concept for SBOM and Provenance

Proposed Solution

When publishing a binary package from GitHub Actions, such as a NuGet package:

  1. Build an SBOM file
  2. Build a provenance file
  3. Publish binary artifact to the relevant artifact repository (e.g. Azure Artifacts for NuGet packages)
  4. If this is a production release
    1. Create a release in GitHub
    2. Attach SBOM to the release
    3. Attach provenance to the release

On step 4, if there is no clear distinction during the build process between pre-release and production release, then simply create a GitHub release every time. 

The SBOM and provenance files can be saved as artifacts on the job; however, they will have a limited availability due to retention policies. The GitHub Release provides permanent storage for these files.

Proof of Concept

SBOM

Microsoft has produced a .NET tool for generating SBOMs, an open sourced it in July, 2022: Microsoft open sources its software bill of materials (SBOM) generation tool. This tool appears to be a good start for our needs, though no doubt we will need to iterate on process - and potentially tool - as we learn more about SBOMs.

To use it:

  1. Create NuGet package(s) that will be covered by the SBOM.
  2. Download the tool.
  3. Generate a manifest list - the list of NuGet packages to be inspected.
  4. Run the tool with proper parameters

The following code will run this in Bash:

curl -Lo sbom-tool https://github.com/microsoft/sbom-tool/releases/latest/download/sbom-tool-linux-x64 --silent
chmod +x sbom-tool
find ./*.nupkg  -printf "%f\n" > buildfilelist.txt
mkdir manifest
sbom-tool generate \
            -b ./ \
            -bl ./buildfilelist.txt \
            -bc ./Application/ \
            -pn AdminApp \
            -pv "0.0.1" \
            -nsb https://ed-fi.org \
            -m manifest -ps "Ed-Fi Alliance"

The pv parameter is the product version; in this demonstration it is hard-coded to "0.0.1".

Provenance

The SLSA community has created a set of tools for use in GitHub to generate provenance information, at https://github.com/slsa-framework/slsa-github-generator. This tool is described in a Google developer blog post, Improving software supply chain security with tamper-proof builds.

The tool is easily integrated into GitHub Actions. Understanding the provenance is non-trivial; since the people defining the standard for provenance is responsible for this tool, we assume it is generating it correctly.

The  tool requires a hash value of the packages file(s):

echo "::set-output name=hashes::$(sha256sum *.nupkg | base64 -w0)"

This value is passed from one job to another within the shared workflow, facilitating secure exchange of information about uploaded artifacts between jobs.

Workflow

For best automation, the files should be uploaded to a release at the time it is generated. This means that the release must already exist, and it implies a workflow where the build process occurs "on release." This sounds straight forward...

... until one thinks about the challenge of needing to pre-release libraries early, without knowing which pre-release will become the actual release.

This suggests a workflow where a merge to the main  branch does not immediately build the software, as is typical before this project. Instead, create a pre-release. And once the pre-release is created, then run the build process, create the SBOM and the provenance, and attach them to the pre-release.

When you are ready to do a full release, either

  1. Transform the pre-release into a full release, or
  2. Create a new release, and trigger a process to important the files from the equivalent pre-release