diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 490093811..942bae514 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -56,6 +56,7 @@ github_checks_aliases: # Include files that contain various tasks, task groups, and build variant definitions include: - filename: .evergreen/config/functions.yml + - filename: .evergreen/config/sbom.yml - filename: .evergreen/config/build-task-groups.yml - filename: .evergreen/config/build-variants.yml diff --git a/.evergreen/config/functions.yml b/.evergreen/config/functions.yml index 8a7608859..37869a516 100644 --- a/.evergreen/config/functions.yml +++ b/.evergreen/config/functions.yml @@ -1,4 +1,50 @@ functions: + "generate-sbom": + - command: subprocess.exec + type: setup + display_name: Generate SBOM + params: + working_dir: src + binary: bash + args: + - .evergreen/generate-sbom.sh + + "upload-sbom": + - command: ec2.assume_role + display_name: Assume ECR readonly IAM role + params: + role_arn: &ecr_ro_role_arn arn:aws:iam::901841024863:role/ecr-role-evergreen-ro + - command: subprocess.exec + type: setup + display_name: Log in to ECR + params: + working_dir: src + binary: bash + include_expansions_in_env: + - AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY + - AWS_SESSION_TOKEN + args: + - -c + - aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 901841024863.dkr.ecr.us-east-1.amazonaws.com + - command: ec2.assume_role + display_name: Assume Silkbomb IAM role + params: + role_arn: &silkbomb_role_arn arn:aws:iam::901841024863:role/silkbomb + - command: subprocess.exec + type: test + display_name: Upload SBOM via Silkbomb + params: + working_dir: src + binary: bash + include_expansions_in_env: + - branch_name + - AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY + - AWS_SESSION_TOKEN + args: + - .evergreen/upload-sbom.sh + "fetch source": # Executes git clone and applies the submitted patch, if any - command: git.get_project diff --git a/.evergreen/config/sbom.yml b/.evergreen/config/sbom.yml new file mode 100644 index 000000000..6e73b90e3 --- /dev/null +++ b/.evergreen/config/sbom.yml @@ -0,0 +1,24 @@ +tasks: + - name: upload-sbom + tags: ["ssdlc"] + allowed_requesters: ["commit"] + exec_timeout_secs: 600 + # pre_error_fails_task: false allows the task to proceed even if pre steps such as + # "fetch extension" fail. PHP and Composer (needed by generate-sbom.sh) are available + # from the earlier "install dependencies" and "install composer" pre steps. + pre_error_fails_task: false + commands: + - func: "generate-sbom" + - func: "upload-sbom" + +buildvariants: + - name: sbom + display_name: "SBOM" + allowed_requesters: ["commit"] + stepback: false + paths: + - composer.json + run_on: + - ubuntu2004-small + tasks: + - name: upload-sbom diff --git a/.evergreen/generate-sbom.sh b/.evergreen/generate-sbom.sh new file mode 100755 index 000000000..2ccf02f16 --- /dev/null +++ b/.evergreen/generate-sbom.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Environment Variables: +# None required — all inputs are derived from the repository. +set -eo pipefail + +SERIAL_NUMBER="urn:uuid:dc42a43b-4ace-4c42-9a6e-0b9e28fdd100" + +# composer require modifies composer.json. Save and restore it so the cyclonedx +# plugin is not added to the project's dependencies. +cp composer.json composer.json.bak +trap 'mv composer.json.bak composer.json' EXIT + +echo "Installing CycloneDX PHP Composer plugin" +composer config allow-plugins.cyclonedx/cyclonedx-php-composer true +composer require --dev cyclonedx/cyclonedx-php-composer:6.2.0 --no-update + +echo "Updating dependencies" +# --ignore-platform-reqs: SBOM generation doesn't need to run the code, so extension +# availability and exact PHP patch versions don't matter here. +# --no-scripts: skip git submodule updates and other scripts that require a full dev setup. +composer update --ignore-platform-reqs --no-scripts + +echo "Generating SBOM" +composer CycloneDX:make-sbom \ + --spec-version=1.5 \ + --output-format=JSON \ + --output-file=sbom.cdx.json \ + --omit dev \ + --no-validate +# --no-validate: skips the plugin's built-in schema validation. Silkbomb will +# reject a malformed SBOM on upload. + +jq --argjson v 1 --arg serial "$SERIAL_NUMBER" \ + '.version = $v | .serialNumber = $serial' sbom.cdx.json > sbom.json +rm sbom.cdx.json + +echo "Generated sbom.json" diff --git a/.evergreen/upload-sbom.sh b/.evergreen/upload-sbom.sh new file mode 100755 index 000000000..2b5da72e2 --- /dev/null +++ b/.evergreen/upload-sbom.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -eo pipefail + +: "${branch_name:?}" +: "${AWS_ACCESS_KEY_ID:?}" +: "${AWS_SECRET_ACCESS_KEY:?}" +: "${AWS_SESSION_TOKEN:?}" + +silkbomb="901841024863.dkr.ecr.us-east-1.amazonaws.com/release-infrastructure/silkbomb:2.0" +docker pull "${silkbomb}" + +docker run --rm -v "$(pwd):/pwd" \ + --user "$(id -u):$(id -g)" \ + --env 'AWS_ACCESS_KEY_ID' --env 'AWS_SECRET_ACCESS_KEY' --env 'AWS_SESSION_TOKEN' \ + "${silkbomb}" upload \ + --repo mongodb/mongo-php-library \ + --branch "${branch_name}" \ + --sbom-in /pwd/sbom.json diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d771b123a..2666daea8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,5 +1,12 @@ version: 2 updates: + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "daily" + allow: + - dependency-type: "production" + - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/sbom.json b/sbom.json deleted file mode 100644 index 4dce69b3b..000000000 --- a/sbom.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "serialNumber": "urn:uuid:dc42a43b-4ace-4c42-9a6e-0b9e28fdd100", - "version": 1, - "metadata": { - "timestamp": "2024-05-08T09:51:01Z", - "tools": [ - { - "name": "composer", - "version": "2.7.6" - }, - { - "vendor": "cyclonedx", - "name": "cyclonedx-php-composer", - "version": "v5.2.0", - "externalReferences": [ - { - "type": "distribution", - "url": "https://api.github.com/repos/CycloneDX/cyclonedx-php-composer/zipball/f3a3cdc1a9e34bf1d5748e4279a24569cbf31fed", - "comment": "dist reference: f3a3cdc1a9e34bf1d5748e4279a24569cbf31fed" - }, - { - "type": "vcs", - "url": "https://github.com/CycloneDX/cyclonedx-php-composer.git", - "comment": "source reference: f3a3cdc1a9e34bf1d5748e4279a24569cbf31fed" - }, - { - "type": "website", - "url": "https://github.com/CycloneDX/cyclonedx-php-composer/#readme", - "comment": "as detected from Composer manifest 'homepage'" - }, - { - "type": "issue-tracker", - "url": "https://github.com/CycloneDX/cyclonedx-php-composer/issues", - "comment": "as detected from Composer manifest 'support.issues'" - }, - { - "type": "vcs", - "url": "https://github.com/CycloneDX/cyclonedx-php-composer/", - "comment": "as detected from Composer manifest 'support.source'" - } - ] - }, - { - "vendor": "cyclonedx", - "name": "cyclonedx-library", - "version": "v3.3.1", - "externalReferences": [ - { - "type": "distribution", - "url": "https://api.github.com/repos/CycloneDX/cyclonedx-php-library/zipball/cad0f92b36c85f36b3d3c11ff96002af5f20cd10", - "comment": "dist reference: cad0f92b36c85f36b3d3c11ff96002af5f20cd10" - }, - { - "type": "vcs", - "url": "https://github.com/CycloneDX/cyclonedx-php-library.git", - "comment": "source reference: cad0f92b36c85f36b3d3c11ff96002af5f20cd10" - }, - { - "type": "website", - "url": "https://github.com/CycloneDX/cyclonedx-php-library/#readme", - "comment": "as detected from Composer manifest 'homepage'" - }, - { - "type": "documentation", - "url": "https://cyclonedx-php-library.readthedocs.io", - "comment": "as detected from Composer manifest 'support.docs'" - }, - { - "type": "issue-tracker", - "url": "https://github.com/CycloneDX/cyclonedx-php-library/issues", - "comment": "as detected from Composer manifest 'support.issues'" - }, - { - "type": "vcs", - "url": "https://github.com/CycloneDX/cyclonedx-php-library/", - "comment": "as detected from Composer manifest 'support.source'" - } - ] - } - ] - } -}