Commit 335dd27f authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

Merge branch 'feat/trivy' into 'master'

feat(Trivy): add Trivy scan support

See merge request to-be-continuous/s2i!21
parents e76ef6ec 7166ee25
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -153,6 +153,45 @@ This job produces _output variables_ that are propagated to downstream jobs (usi

They may be freely used in downstream jobs (for instance to deploy the upstream built image, whatever the branch or tag).

### `s2i-trivy` job

This job performs a Vulnerability Static Analysis with [Trivy](https://aquasecurity.github.io/trivy) on your built image.

Without any configuration Trivy will run in [standalone](https://aquasecurity.github.io/trivy/latest/docs/references/modes/standalone/) mode.

If you want to run Trivy in client/server mode, you need to set the `TRIVY_SERVER` environment variable.

```yaml
variables:
  TRIVY_SERVER: "https://trivy.acme.host"
```

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

| Input / Variable                                                           | Description                                                                                                            | Default value                                                       |
| -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `trivy-image` / `S2I_TRIVY_IMAGE`                                       | The docker image used to scan images with Trivy                                                                        | `docker.io/aquasec/trivy:latest`<br/>[![Trivy Badge](https://to-be-continuous.gitlab.io/doc/secu/trivy-badge-S2I_TRIVY_IMAGE.svg)](https://to-be-continuous.gitlab.io/doc/secu/trivy-S2I_TRIVY_IMAGE)|
| `trivy-disabled` / `S2I_TRIVY_DISABLED`                                 | Set to `true` to disable Trivy analysis                                                                                | _(none)_                                                            |
| `trivy-args` / `S2I_TRIVY_ARGS`                                         | Additional [`trivy image` options](https://aquasecurity.github.io/trivy/latest/docs/references/configuration/cli/trivy_image/#options) | `--ignore-unfixed --pkg-types os --exit-on-eol 1 --detection-priority comprehensive --disable-telemetry --skip-version-check`                                   |

Other Trivy parameters shall be configured using [Trivy environment variables](https://aquasecurity.github.io/trivy/latest/docs/references/configuration/cli/trivy_image/#options).
Examples:

* `TRIVY_SEVERITY`: severities of security issues to be displayed (comma separated values: `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`)
* `TRIVY_SERVER`: server address (enables client/server mode)
* `TRIVY_DB_REPOSITORY`: OCI repository to retrieve Trivy Database from
* `TRIVY_JAVA_DB_REPOSITORY`: OCI repository to retrieve Trivy Java Database from

It's possible to ignore some CVE by adding a `.trivyignore` file at the root of the project (see [official documentation](https://trivy.dev/latest/docs/configuration/filtering/#trivyignore) for syntax).

In addition to a textual report in the console, this job produces the following reports, kept for one day and only available for download by users with the Developer role or higher:

| Report                                    | Format                                                                                                                                    | Usage                                                                                                                                                                     |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `reports/s2i-trivy-*.native.json`      | Native Trivy report format (json)                                                                                                         | [DefectDojo integration](https://docs.defectdojo.com/en/connecting_your_tools/parsers/file/trivy/)<br/>_This report is generated only if DefectDojo template is detected_ |
| `reports/s2i-trivy-*.gitlab.json`      | [Trivy report format for GitLab Container Security](https://aquasecurity.github.io/trivy/latest/tutorials/integrations/gitlab-ci/) format | [GitLab Container Security](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportscontainer_scanning)                                                        |
| `reports/s2i-trivy-*.gitlab-codequality.json` | [Trivy report format for GitLab Code Quality](https://aquasecurity.github.io/trivy/latest/tutorials/integrations/gitlab-ci/) format       | [GitLab Code Quality](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportscodequality)                                                                     |

### `s2i-publish` job

This job pushes (_promotes_) the built image as the _release_ image using [skopeo](https://github.com/containers/skopeo).
+22 −0
Original line number Diff line number Diff line
@@ -82,5 +82,27 @@
      "description": "Disable integration with the [semantic release template](https://gitlab.com/to-be-continuous/semantic-release/)",
      "type": "boolean"
    }
  ],
  "features": [
    {
      "id": "trivy",
      "name": "Trivy",
      "description": "[Trivy](https://aquasecurity.github.io/trivy) vulnerability analysis",
      "disable_with": "S2I_TRIVY_DISABLED",
      "variables": [
        {
          "name": "S2I_TRIVY_IMAGE",
          "description": "The docker image used to scan images with Trivy",
          "default": "docker.io/aquasec/trivy:latest",
          "advanced": true
        },
        {
          "name": "S2I_TRIVY_ARGS",
          "description": "Additional [`trivy image` options](https://aquasecurity.github.io/trivy/latest/docs/references/configuration/cli/trivy_image/#options)",
          "default": "--ignore-unfixed --pkg-types os --exit-on-eol 1 --detection-priority comprehensive --disable-telemetry --skip-version-check",
          "advanced": true
        }
      ]
    }
  ]
}
+71 −0
Original line number Diff line number Diff line
@@ -43,6 +43,16 @@ spec:
    release-image:
      description: S2I release image
      default: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
    trivy-disabled:
      description: Disable Trivy
      type: boolean
      default: false
    trivy-image:
      description: The docker image used to scan images with Trivy
      default: docker.io/aquasec/trivy:latest
    trivy-args:
      description: Additional [`trivy image` options](https://aquasecurity.github.io/trivy/latest/docs/references/configuration/cli/trivy_image/#options)
      default: --ignore-unfixed --pkg-types os --exit-on-eol 1 --detection-priority comprehensive --disable-telemetry --skip-version-check
    publish-args:
      description: Additional [`skopeo copy` arguments](https://github.com/containers/skopeo/blob/master/docs/skopeo-copy.1.md#options)
      default: ''
@@ -145,6 +155,11 @@ variables:
  # Relative path to the application source code base directory in your repository
  S2I_ROOT_DIR: $[[ inputs.root-dir ]]

  # Trivy configuration
  S2I_TRIVY_IMAGE: $[[ inputs.trivy-image ]]
  S2I_TRIVY_ARGS: $[[ inputs.trivy-args ]]
  S2I_TRIVY_DISABLED: $[[ inputs.trivy-disabled ]]

  # default: one-click publish
  S2I_PROD_PUBLISH_STRATEGY: $[[ inputs.prod-publish-strategy ]]
  S2I_BUILDER_IMAGE: $[[ inputs.builder-image ]]
@@ -559,6 +574,62 @@ s2i-build:
      dotenv:
        - s2i.env

# Security audit with trivy
s2i-trivy:
  extends: .s2i-base
  image:
    name: $S2I_TRIVY_IMAGE
    entrypoint: [""]
  stage: package-test
  variables:
    TRIVY_CACHE_DIR: ".trivycache/"
  script:
  - log_info "Scanning vulnerabilities from ${S2I_SNAPSHOT_IMAGE}..."
  - |
    log_info "Trivy version:"
    trivy version
  - |
    # cache cleanup is needed when scanning images with the same tags, it does not remove the database
    trivy clean --scan-cache || trivy image --clear-cache
  - |
    export TRIVY_USERNAME=${S2I_REGISTRY_SNAPSHOT_USER:-${S2I_REGISTRY_USER:-$CI_REGISTRY_USER}}
    export TRIVY_PASSWORD=${S2I_REGISTRY_SNAPSHOT_PASSWORD:-${S2I_REGISTRY_PASSWORD:-$CI_REGISTRY_PASSWORD}}
    basename=$(echo "${S2I_SNAPSHOT_IMAGE}" | sed 's|[/:]|_|g')
    mkdir -p ./reports
    if [[ -z "$TRIVY_SERVER" ]]; then
      log_warn "\\e[93mYou are using Trivy in standalone mode. To get faster scans, consider setting the TRIVY_SERVER variable to the address of a Trivy server. More info here: https://aquasecurity.github.io/trivy/latest/docs/references/modes/client-server/\\e[0m"
    fi
    # Generate the native JSON report that can later be converted to other formats
    trivy image --no-progress ${S2I_TRIVY_ARGS} --exit-code 1 --format json --output reports/s2i-trivy-${basename}.native.json $S2I_SNAPSHOT_IMAGE || exit_code=$?

    # Generate a report in the GitLab format
    trivy convert --format template --template "@/contrib/gitlab.tpl" --output reports/s2i-trivy-${basename}.gitlab.json reports/s2i-trivy-${basename}.native.json
    # Generate a report in the Code Quality format
    trivy convert --format template --template "@/contrib/gitlab-codequality.tpl" --output reports/s2i-trivy-${basename}.gitlab-codequality.json reports/s2i-trivy-${basename}.native.json

    # console output
    trivy convert --format table reports/s2i-trivy-${basename}.native.json
    
    exit $exit_code
  artifacts:
    name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
    expire_in: 1 day
    access: developer
    when: always
    paths:
    - "reports/s2i-trivy-*"
    reports:
      container_scanning: "reports/s2i-trivy-*.gitlab.json"
      codequality: "reports/s2i-trivy-*.gitlab-codequality.json"
  cache:
    - key: "$CI_COMMIT_REF_SLUG-trivy"
      paths:
        - .trivycache/
  rules:
    - if: '$S2I_TRIVY_DISABLED == "true"'
      when: never
    - !reference [.test-policy, rules]

s2i-publish:
  extends: .s2i-base
  stage: publish