Commit e2945e23 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

Merge branch 'add-sbom' into 'master'

feat: add a job generating software bill of materials

Closes #40

See merge request to-be-continuous/python!63
parents 76ef58bb 4c56888e
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -234,6 +234,24 @@ In addition to a textual report in the console, this job produces the following
| -------------- | ---------------------------------------------------------------------------- | ----------------- |
| `$PYTHON_PROJECT_DIR/reports/py-trivy.trivy.json` | [JSON](https://aquasecurity.github.io/trivy/latest/docs/vulnerability/examples/report/#json) | [DefectDojo integration](https://defectdojo.github.io/django-DefectDojo/integrations/parsers/#trivy)<br/>_This report is generated only if DefectDojo template is detected_ |

### `py-sbom` job

This job generates a [SBOM](https://cyclonedx.org/) file listing all dependencies using [syft](https://github.com/anchore/syft).

It is bound to the `test` stage, and uses the following variables:

| Name                  | description                            | default value     |
| --------------------- | -------------------------------------- | ----------------- |
| `PYTHON_SBOM_DISABLED` | Set to `true` to disable this job | _none_ |
| `PYTHON_SBOM_SYFT_URL` | Url to the `tar.gz` package for `linux_amd64` of Syft to use (ex: `https://github.com/anchore/syft/releases/download/v0.62.3/syft_0.62.3_linux_amd64.tar.gz`)<br/>_When unset, the latest version will be used_ | _none_ |
| `PYTHON_SBOM_OPTS` | Options for syft used for SBOM analysis | `--catalogers python-index-cataloger` |

In addition to logs in the console, this job produces the following reports, kept for one week:

| Report         | Format                                                                       | Usage             |
| -------------- | ---------------------------------------------------------------------------- | ----------------- |
| `$PYTHON_PROJECT_DIR/reports/py-sbom.cyclonedx.json` | [CycloneDX JSON](https://cyclonedx.org/docs/latest/json/) | [Security & Compliance integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscyclonedx) |

### SonarQube analysis

If you're using the SonarQube template to analyse your Python code, here is a sample `sonar-project.properties` file:
+19 −0
Original line number Diff line number Diff line
@@ -150,6 +150,25 @@
        }
      ]
    },
    {
      "id": "sbom",
      "name": "Software Bill of Materials",
      "description": "This job generates a file listing all dependencies using [syft](https://github.com/anchore/syft)",
      "disable_with": "PYTHON_SBOM_DISABLED",
      "variables": [
        {
          "name": "PYTHON_SBOM_SYFT_URL",
          "description": "Url to the `tar.gz` package for `linux_amd64` of Syft to use\n\n_When unset, the latest version will be used_",
          "advanced": true
        },
        {
          "name": "PYTHON_SBOM_OPTS",
          "description": "Options for syft used for SBOM analysis",
          "default": "--catalogers python-index-cataloger",
          "advanced": true
        }
      ]
    },
    {
      "id": "release",
      "name": "Release",
+46 −0
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ variables:
  PYTHON_TRIVY_IMAGE: aquasec/trivy:latest
  PYTHON_TRIVY_ARGS: "--vuln-type library"

  PYTHON_SBOM_OPTS: "--catalogers python-index-cataloger"

  PYTHON_RELEASE_NEXT: "minor"

  # By default, publish on the Packages registry of the project
@@ -835,6 +837,50 @@ py-trivy:
      when: never
    - !reference [.test-policy, rules]

py-sbom:
  extends: .python-base
  stage: test
  # force no dependency
  dependencies: []
  needs: []
  script:
    - mkdir -p -m 777 reports
    - install_requirements
    - |
      case "$PYTHON_BUILD_SYSTEM" in
        setuptools* | reqfile)
          _pip freeze > "${PYTHON_REQS_FILE}"
          ;;
      esac
    - |
      if [[ -z "$PYTHON_SBOM_SYFT_URL" ]]
      then
        log_info "Syft version unset: retrieve latest version..."
        PYTHON_SBOM_SYFT_URL=$(curl -sSf "https://api.github.com/repos/anchore/syft/releases?per_page=1" | \
          python3 -c 'import json,sys;resp=json.load(sys.stdin);print(next(filter(lambda a: a["browser_download_url"].endswith("_linux_amd64.tar.gz"),resp[0]["assets"]))["browser_download_url"]);')
        log_info "... use latest Syft version: \\e[32m$PYTHON_SBOM_SYFT_URL\\e[0m"
      fi
      python_sbom_syft="$PIP_CACHE_DIR/syft-$(echo "$PYTHON_SBOM_SYFT_URL" | md5sum | cut -d" " -f1)"
      if [ ! -f $python_sbom_syft ]; then
        wget -q -O syft.tar.gz $PYTHON_SBOM_SYFT_URL
        tar zxf syft.tar.gz syft
        mkdir -p $PIP_CACHE_DIR
        mv ./syft $python_sbom_syft
      fi
    - $python_sbom_syft dir:${PYTHON_PROJECT_DIR} $PYTHON_SBOM_OPTS -o cyclonedx-json > reports/py-sbom.cyclonedx.json
    - chmod a+r reports/py-sbom.cyclonedx.json
  artifacts:
    name: "Python SBOM from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
    expire_in: 1 week
    when: always
    paths:
      - "$PYTHON_PROJECT_DIR/reports/py-sbom.cyclonedx.json"
  rules:
    # exclude if disabled
    - if: '$PYTHON_SBOM_DISABLED == "true"'
      when: never
    - !reference [.test-policy, rules]

# (manual from master branch): triggers a release (tag creation)
py-release:
  extends: .python-base