-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CSHARP-5626 Add evergreen script to generate CycloneDX SBOM #1718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
CSHARP-5626 Add evergreen script to generate CycloneDX SBOM #1718
Conversation
Added a bash script to generate a 'build' lifecycle CycloneDX SBOM using the cyclonedx-dotnet tool. The script installed a fixed version of cyclonedx-dotnet, runs a versioned dotnet restore, and generates an SBOM for each of the 4 MongoDB.Driver Nuget packages. To ensure accurate results, two queries are run against each of the .csproj files to ensure all development packages are excluded and that any local <ProjectReference> items are marked in the SBOM as Nuget packages. Once all 4 SBOMs are created, they are merged into a single heirarchical SBOM file. The file is saved as sbom.cdx.json (as opposed to the current sbom.json) which is the preferred file extention for CycloneDX files. There is not yet any code to commit the new SBOM to the repo. This is to allow for evaluation of the new SBOM first without intefering with the current workflow to upload the current static sbom.json file to Kondukto. There is also a line added to download-augmented-sbom.sh to copy the augmented SBOM to ./vex.cdx.json (also not yet committed to repo) after it has been uploaded to the release artifacts bucket, as this is how we should be storing the augmented SBOM for public consumption. Once the SBOM generation process has been approved, I will add commit code for both of the cdx.json files, remove th sbom.json file and update download-augmented-sbom.sh to use the new sbom.cdx.json file.
Undoing unintended changes to evergreen.yml
|
To generate the SBOM, run |
| # Patch JSON file with PURLs, as needed | ||
| for patch in $PURL_PATCHES; do | ||
| echo "Patching ${patch} with Nuget PURL" | ||
| contents=$(jq --arg package "$patch" --arg version "$PACKAGE_VERSION" '.components |= map(if [.name | startswith("MongoDB.")] and has("purl") == false then .purl = "pkg:nuget/\($package)@\($version)" else . end)' ${SBOM_FILE}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: If a package has multiple ProjectReferences (e.g., MongoDB.Driver references both MongoDB.Bson and MongoDB.Driver.Core), won't this logic:
- Loop 1: Match ALL components starting with "MongoDB." that lack PURLs, assign all of them pkg:nuget/MongoDB.Bson@VERSION
- Loop 2: All MongoDB components now have PURLs, so nothing gets patched with MongoDB.Driver.Core
Should the condition be .name == $package instead of .name | startswith("MongoDB.")?
| @@ -0,0 +1,87 @@ | |||
| #!/usr/bin/env bash | |||
| set -o errexit # Exit the script with error if any of the commands fail | |||
|
|
|||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # Environment Variables: | |
| # PACKAGE_VERSION (optional) - Version to use for SBOM generation | |
| # Defaults to output of get-version.sh | |
| # GITHUB_USER (optional) - GitHub username for license resolution | |
| # GITHUB_APIKEY (optional) - GitHub API token for license resolution |
Add a comment block to describe variables used in the script.
| augment --repo mongodb/mongo-csharp-driver --branch main --sbom-in /pwd/sbom.json --sbom-out /pwd/${SSDLC_PATH}/augmented-sbom.json | ||
| augment --repo mongodb/mongo-csharp-driver --branch main --sbom-in /pwd/sbom.json --sbom-out /pwd/${SSDLC_PATH}/augmented-sbom.json | ||
|
|
||
| cp /pwd/${SSDLC_PATH}/augmented-sbom.json ./vex.cdx.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think /pwd/ is available in this context since we are outside the docker command. I think it should be ${PWD}
| ## Run cyclonedx-dotnet | ||
| # Attempt GitHub license resolution only if GITHUB_USER and GITHUB_APIKEY are both set | ||
| if [[ -v GITHUB_USER && -v GITHUB_APIKEY ]]; then | ||
| github_options=(--enable-github-licenses --github-username ${GITHUB_USER} --github-token ${GITHUB_APIKEY}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add some echo messages to indicate whether github license resolution is enabled or not
|
|
||
| # Use cyclonedx-cli to merge the SBOMs into 1 hierarchical SBOM | ||
| docker run --platform="linux/amd64" --rm -v ${PWD}:/pwd \ | ||
| cyclonedx/cyclonedx-cli:0.28.2 \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we should be using latest here or not. But if we use a specific version as now, should we include the digest as well for security?
| # There are nuances to how cyclonedx-dotnet handles <PackageReference> items in Directory.Build.props that lead to private packages being included in SBOM | ||
| # results even when PrivateAssets is set to "All". As a safeguard, this command lists the PackageReferences and adds the references with PrivateAssets="All" | ||
| # to an exclusion filter variable to be fed into cyclonedx-dotnet | ||
| EXCLUDE_FILTER=$(dotnet msbuild ./src/${package}/${package}.csproj -getItem:PackageReference | jq -r '[.Items.PackageReference[] | select(.PrivateAssets != null) | select(.PrivateAssets | test ("All"; "i")) | .Identity + "@" + .Version] | join(",")') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the option --exclude-dev doesn't help with this?
Added a bash script to generate a
buildlifecycle CycloneDX SBOM using thecyclonedx-dotnettool. The script installs a fixed version ofcyclonedx-dotnet, runs a versioneddotnet restore, and generates an SBOM for each of the 4 MongoDB.Driver Nuget packages.To ensure accurate results, two queries are run against each of the
.csprojfiles to ensure all development packages are excluded and that any local<ProjectReference>items are marked in the SBOM as Nuget packages. Once all 4 SBOMs are created, they are merged into a single hierarchical SBOM file.The file is saved as
sbom.cdx.json(as opposed to the currentsbom.json) which is the preferred file extension for CycloneDX files. There is not yet any code to commit the new SBOM to the repo. This is to allow for evaluation of the new SBOM first without interfering with the current workflow to upload the current staticsbom.jsonfile to Kondukto.There is also a line added to download-augmented-sbom.sh to copy the augmented SBOM to
vex.cdx.json(also not yet committed to repo) after it has been uploaded to the release artifacts bucket, as this is how we should be storing the augmented SBOM for public consumption.Once the SBOM generation process has been approved, I will add commit code for both of the
cdx.jsonfiles, remove thesbom.jsonfile and updatedownload-augmented-sbom.shto use the newsbom.cdx.jsonfile.