Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion evergreen/download-augmented-sbom.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ echo "KONDUKTO_TOKEN=$kondukto_token" > ${PWD}/kondukto_credentials.env
docker run --platform="linux/amd64" --rm -v ${PWD}:/pwd \
--env-file ${PWD}/kondukto_credentials.env \
artifactory.corp.mongodb.com/release-tools-container-registry-public-local/silkbomb:2.0 \
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
Copy link
Contributor

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}

12 changes: 12 additions & 0 deletions evergreen/evergreen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,18 @@ functions:
params:
file: mo-expansion.yml

generate-sbom:
- command: shell.exec
params:
working_dir: "mongo-csharp-driver"
env:
GITHUB_USER: ${github_user}
GITHUB_APIKEY: ${github_apikey}
PACKAGE_VERSION: ${PACKAGE_VERSION}
script: |
${PREPARE_SHELL}
./evergreen/generate-sbom.sh

download-and-promote-augmented-sbom-to-s3-bucket:
- command: ec2.assume_role
params:
Expand Down
87 changes: 87 additions & 0 deletions evergreen/generate-sbom.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash
set -o errexit # Exit the script with error if any of the commands fail

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# 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.

# Accommodate Git Bash or MSYS2 on Windows
export MSYS_NO_PATHCONV=1

echo -e "\n************************************************"

# Get Packages Version if variable is empty
if [[ -z "$PACKAGE_VERSION" ]]; then
PACKAGE_VERSION=$(bash ./evergreen/get-version.sh)
fi

echo "Package Version: ${PACKAGE_VERSION}"

# Get array of Package Names
source ./evergreen/packages.sh
echo "Packages: ${PACKAGES[*]}"

# Run a restore that will set the package version in the Directory.Build.props file, otherwise it is set to "0.0.0-local"
# This will also cause the Choose...When conditions in the .csproj files to use PackageReference instead of ProjectReference
echo "Restoring solution with version set to ${PACKAGE_VERSION}"
dotnet restore /p:Version=${PACKAGE_VERSION}

# Install cyclonedx-dotnet using latest version tested with this script
echo "Installing cyclonedx-dotnet"
dotnet tool install --global CycloneDX --version 5.3.1 --allow-downgrade

echo -e "\nGenerating SBOMs"
echo "************************************************"

# Track SBOM file paths for merging
SBOM_FILES=""

for package in ${PACKAGES[*]}; do
echo -e "\n+++++++++++++++++++++++++++++++++++++"
echo "Processing: ${package}"

SBOM_FILE="sbom.${package}.cdx.json"
SBOM_FILES="${SBOM_FILES} /pwd/${SBOM_FILE}"

echo "SBOM file: ${SBOM_FILE}"

# 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(",")')
Copy link
Contributor

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?

echo "Excluded Private Package References: ${EXCLUDE_FILTER}"

# The ProjectReference items do not resolve as the Nuget packages they represent. This causes duplicate components when the SBOMs are merged. To address this
# we add the Nuget PURL to the JSON. This command lists the ProjectReferences for processing.
PURL_PATCHES=$(dotnet msbuild ./src/${package}/${package}.csproj -getItem:ProjectReference | jq -r '[.Items.ProjectReference[] | .Filename] | join(",")')
echo "Project References requiring added PURL: ${PURL_PATCHES}"

echo "+++++++++++++++++++++++++++++++++++++"

## 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})
Copy link
Contributor

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

fi

echo "dotnet-CycloneDX src/${package}/${package}.csproj --disable-package-restore --set-type library --set-nuget-purl --exclude-dev --include-project-references --set-name ${package} --set-version ${PACKAGE_VERSION} --filename ${SBOM_FILE} --exclude-filter ${EXCLUDE_FILTER} ${github_options[@]}"
dotnet-CycloneDX src/${package}/${package}.csproj \
--disable-package-restore --set-type library --set-nuget-purl --exclude-dev --include-project-references \
--set-name ${package} --set-version ${PACKAGE_VERSION} --filename ${SBOM_FILE} \
--exclude-filter "${EXCLUDE_FILTER}" \
"${github_options[@]}"

# 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})
Copy link
Contributor

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.")?

echo -E "${contents}" >${SBOM_FILE}
done

done

echo -e "\n================================="
echo "Merging SBOMs using cyclonedx-cli"
echo "================================="

# 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 \
Copy link
Contributor

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?

merge --input-files ${SBOM_FILES} --output-file /pwd/sbom.cdx.json \
--hierarchical --group mongodb --name mongo-csharp-driver --version ${PACKAGE_VERSION}