Software Bill of Materials (SBOM) is a list of packages that make up software components, this includes open-source and third party libraries present in the system’s code. The SBOM provides key information like package name and version of the building blocks that make up a piece of a software. SBOMs are a key requirement of the Executive Order on Improving the Nation’s Cybersecurity in the United States and Protecting your organization from software supply chain threats in Canada.
Purpose
It has emerged in recent times that SBOM can be used as powerful inventory tool to help track the dependencies, libraries, open source components and licenses for software within an enterprise. In particular it can be very useful to aid with security vulnerability and compliance tracking. In addition it provides software transparency, integrity and identity.
Goal
The goal is to compile SBOMs for your hosted applications and store them in a centralized location for reporting and compliance purposes.
SBOM Tool
As an outcome of the Executive Order on Improving the Nation’s Cybersecurity, Microsoft has created an open source SBOM generation tool.
Microsoft states the following about their SBOM tool:
“Our SBOM tool is a general purpose, enterprise-proven, build-time SBOM generator. It works across platforms including Windows, Linux, and Mac, and uses the standard Software Package Data Exchange (SPDX) format. It can be easily integrated into and auto-detects NPM, NuGet, PyPI, CocoaPods, Maven, Golang, Rust Crates, RubyGems, Linux packages within containers, Gradle, Ivy, GitHub public repositories, and more. As we add more detectors to Component Detection, it will improve our SBOM tool as well.”
Implementation
In order to implement SBOM across a number of applications the SBOM tool needs to be added to all build pipelines. In this implementation, SBOM files are generated on the DevOps agent and copied to a centralized blob storage account where they are consumed via a Power BI report for reporting and compliance purposes.
SBOM Storage
Create an Azure Storage account, we will leverage blob storage for storing all of the SBOMs that are generated for this initiative.
Here is a sample view of what the data will look like. Here is the container view.
Here is a sample blob, we also add some blob tags to help with traceability.
Azure Pipeline
DevOps Service Connection
For SBOM implementation a service connection is required. This is used for copying the SBOM that is generated during the build process to Azure Blob storage.
The service connection requires Storage Blob Data Owner role at the storage account level in order to upload blobs (SBOM file) with tags. The Service Connection and Azure resource setup is not shown here as that sort of thing is covered in other articles.
DevOps Variables and Variable Group
A set of variables and variable group is required to be consumed for SBOM implementation. The variables are used to simplify management of values that may change over time, instead of hard coding values within multiple pipelines.
Add this variables section to the build pipeline.
variables:
- group: 'SBOM' # variable group required for SBOM integration
- name: 'sbomPackageName'
value: '{applicationPackageName}' # update this value
- name: 'sbomPackageVersion'
value: '{applicationPackageVersion}' # update this value
The variable group is a one time configuration, documented here for the implementation.
Name | Value | Description |
---|---|---|
azureServiceConnection | {serviceConnectionName} | Service connection name for copying SBOMs to Azure Storage. |
sbomStorageAccount | {sbomStorageAccount} | Blob storage account to store SBOMs. |
sbomStorageContainer | sbom | Blob storage container to store SBOMs. |
sbomCompany | {companyName} | Company value for SBOM tool. |
sbomNamespaceUri | https://{uriName} | Namespace Uri value for SBOM tool. (eg. https://companyName.com) |
sbomToolUrlLinux | https://github.com/microsoft/sbom-tool/releases/latest/download/sbom-tool-linux-x64 | Url to Microsoft’s SBOM tool for Linux. |
sbomToolUrlWindows | https://github.com/microsoft/sbom-tool/releases/latest/download/sbom-tool-win-x64.exe | Url to Microsoft’s SBOM tool for Windows. |
sbomFileName | manifest.spdx.json | Default file name produced by SBOM tool. |
Task
This Azure Pipelines task is required to be added to the build pipeline. It works with Windows and Linux build agents.
# Generate SBOM and copy the file to Azure Storage.
- task: AzureCLI@2
displayName: Generate SBOM and Copy to Blob
name: AzureFileCopy
inputs:
azureSubscription: $(azureServiceConnection)
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
if ($IsWindows) {
Write-Host "Windows agent detected."
Invoke-WebRequest -Uri "$(sbomToolUrlWindows)" -OutFile "$(Agent.TempDirectory)/sbom-tool.exe"
} elseif ($IsLinux) {
Write-Host "Linux agent detected."
Invoke-WebRequest -Uri "$(sbomToolUrlLinux)" -OutFile "$(Agent.TempDirectory)/sbom-tool"
sudo chmod +x $(Agent.TempDirectory)/sbom-tool
} else {
Write-Host "Unsupported operating system, exiting."
exit 1
}
$dateTime = (Get-Date -Format 'yyyyMMddHHmmss')
New-Item -Path $(Build.ArtifactStagingDirectory) -Name "sbom" -Type Directory -Force
$(Agent.TempDirectory)/sbom-tool generate -b $(Build.ArtifactStagingDirectory)\sbom -bc $(Build.SourcesDirectory) -pn "$(sbomPackageName)" -pv "$(sbomPackageVersion)" -ps "$(sbomCompany)" -nsb $(sbomNamespaceUri) -li True -V Verbose
$sbomFile=Get-ChildItem -Path $(Build.ArtifactStagingDirectory) -Recurse -Include $(sbomFileName)
az storage blob upload --auth-mode login --account-name $(sbomStorageAccount) --container-name $(sbomStorageContainer) --name "$(sbomPackageName)-$dateTime.json" --file $sbomFile --tags packageName="$(sbomPackageName)" packageVersion="$(sbomPackageVersion)" buildDefinitionId="$(System.DefinitionId)" buildId="$(Build.BuildId)" buildNumber="$(Build.BuildNumber)" --overwrite
# Publish SBOM files as an artifact.
- task: PublishPipelineArtifact@1
displayName: Publish SBOM Artifacts
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)/sbom'
artifactName: SoftwareBillOfMaterials
Scanning Docker Images
To scan Docker images use the DockerImagesToScan (-di) switch. The switch supports a comma separated list of docker image names or hashes to be scanned for packages, ex: ubuntu:16.04, 56bab49eef2ef07505f6a1b0d5bd3a601dfc3c76ad4460f24c91d6fa298369ab.
Here is an example:
$(Agent.TempDirectory)/sbom-tool generate -b $(Build.ArtifactStagingDirectory) -bc $(Build.SourcesDirectory) -pn "$(sbomPackageName)" -pv "$(sbomPackageVersion)" -ps "$(sbomCompany)" -nsb $(sbomNamespaceUri) -di testImage:0.0.1,ubuntu:1.9 -li True -V Verbose
Use this within the Azure DevOps Task, simply replace the existing sbom-tool generate command.
Power BI Reporting
You can then author a Power BI report by connecting to the blob storage container where all the SBOMs are being saved. Use Azure blob storage as the data source as shown below.
Once connected you can manipulate the data for your report.
From there you create something useful for real-time consumption.
Sample SBOM
SBOM tool creates a SPDX 2.2 compatible SBOM. You can view a SBOM sample here.
References
- Microsoft open sources its software bill of materials (SBOM) generation tool
- Generating Software Bills of Materials (SBOMs) with SPDX at Microsoft
- Executive Order on Improving the Nation’s Cybersecurity
- Protecting your organization from software supply chain threats
- The Software Package Data Exchange (SPDX)
- microsoft/sbom-tool GitHub repo
- manifest.spdx.json Sample
- microsoft/sbom-tool Command Line Arguments