diff --git a/task/rhacs-image-scan/4.0/README.md b/task/rhacs-image-scan/4.0/README.md new file mode 100644 index 00000000..e16d611b --- /dev/null +++ b/task/rhacs-image-scan/4.0/README.md @@ -0,0 +1,181 @@ +# Red Hat Advanced Cluster Security Image Scan Task + +Scan an image for vulnerabilities and metadata against RHACS build and deploy +lifecycle policies to validate a pipeline run using `roxctl`. + +This tasks allows you to return full vulnerability scan results for an image in +JSON, CSV, or Pretty format. It's a companion to the rhacs-image-check task. + +**Note: this Task is not backwards compatible with the `3.71` version as it +changes the parameters and token configuration.** + +**Note: this Task requires a 4.4.2 roxctl image (task default) or a more recent +image version.** + +## Prerequisites + +This task requires an active installation of [Red Hat Advanced Cluster Security (RHACS)](https://www.redhat.com/en/resources/advanced-cluster-security-for-kubernetes-datasheet) +or [StackRox](https://www.stackrox.io/). It also requires configuration of an +authorization token with at least CI privileges. + + + +## Install the Task + +```bash +kubectl apply -f https://api.hub.tekton.dev/v1/resource/tekton/task/rhacs-image-scan/4.0/raw +``` + +## Parameters + +- **`image`**: Full name of image to scan. Examples: _gcr.io/rox/sample:5.0-rc1, +**$(params.IMAGE)**, $(params.IMAGE)@$(tasks.buildah.results.IMAGE_DIGEST)_ +- **`output_format`**: Examples: _**json**, csv, pretty_ + +- **`rox_central_endpoint`**: The address:port tuple for StackRox Central. +Default: **central.stackrox.svc:443** +- **`insecure-skip-tls-verify`**: Skip verification the TLS certs of the Central +endpoint and registry. Examples: _"true", **"false"**_. +- **`rox_config_dir`**: Path to the roxctl config directory within the +`roxctl-config` workspace (if machine to machine authentication is used). +Mutually exclusive with **`rox_token_file`**. The path must be prefixed with +`/roxctl-config`. Examples: _"/roxctl-config", **""**_. +- **`rox_token_file`**: Path to the API Token file (if API Token authentication +is used). Mutually exclusive with **`rox_config_dir`**. The path must be +prefixed with `/rox-api-token-auth`. +Examples: _**""**, "/rox-api-token-auth/rox_api_token"_. +- `rox_image`: The image providing the roxctl tool (optional). +Default: quay.io/stackrox-io/roxctl:4.4.2 +(this is also the minimum version working with this task). +- `output_file`: path to a file where to redirect roxctl standard output. +Default: "" (redirects to stdout). +- `error_file`: path to a file where to redirect roxctl standard error. +Default: "" (redirects to stderr). + +One of the **`rox_config_dir`** or **`rox_token_file`** parameter is required +for the authentication against the remote Central to work. + +## Workspaces + +- **roxctl-config**: An [optional workspace](https://github.com/tektoncd/pipeline/blob/main/docs/workspaces.md#optional-workspaces) +containing the configuration for roxctl. Used to authenticate with the remote +central using short-lived tokens. The content of this workspace has to be +populated by a rhacs-m2m-authenticate TaskRun. This workspace is mutually +exclusive with the `rox-api-token-auth` workspace. +- **rox-api-token-auth**: An [optional workspace](https://github.com/tektoncd/pipeline/blob/main/docs/workspaces.md#optional-workspaces) +containing a rox token file. Used to authenticate with the remote central. It is +**strongly** recommended that this workspace be bound to a Kubernetes `Secret`. +This workspace is mutually exclusive with the `roxctl-config` workspace. + +## Usage + +Scans images that have been pushed to a registry. This enables scanning +regardless of whether the build is using traditional Docker-based approaches, +hosted/SaaS-based approaches where the Docker socket may not be directly +available, or rootless approaches like `kaniko` and `buildah`. + +If the image violates one or more enforced policies, this task will return a +failure and cause the pipeline run to fail. + +### Configure using machine to machine authentication + +Check the [documentation](https://docs.openshift.com/acs/operating/manage-user-access/configure-short-lived-access.html#configure-short-lived-access_configure-short-lived-access) +to configure the trust with the OIDC token issuer. This +[example](../../rhacs-m2m-authenticate/0.1/samples/configure-m2m.md) describes +a possible RHACS machine-to-machine integration configuration. + +The token exchange itself is taken care of by the +[rhacs-m2m-authenticate](../../rhacs-m2m-authenticate) task. + +**Example task use:** + +The task configuration in that case must provide the `roxctl-config` workspace +and the `rox_config_dir` parameter with values pointing at the location where +the roxctl configuration is made available. + +```yaml + tasks: + - name: image-scan + taskRef: + name: rhacs-image-scan + kind: Task + workspaces: + - name: roxctl-config + workspace: shared-workspace + params: + - name: image + value: "$(params.image)@$(tasks.build-image.results.IMAGE_DIGEST)" + - name: rox_central_endpoint + value: central.stackrox.svc:443 + - name: rox_config_dir + value: /roxctl-config + runAfter: + - build-image +``` + +**Samples:** + +* [pipeline.yaml](samples/with-m2m-token/pipeline.yaml) demonstrates use in a +pipeline. +* [pipelinerun.yaml](samples/with-m2m-token/pipelinerun.yaml) demonstrates use +in a pipelinerun. + +### Configure using secret holding API token + +**Example secret creation:** + +Check the [documentation](https://docs.openshift.com/acs/configuration/configure-api-token.html) +for API token creation. + +```bash +kubectl create secret generic rox-api-token \ + --from-literal=rox_api_token="$ROX_API_TOKEN" +``` + +**Example task use:** + +The task configuration in that case must provide the `rox-api-token-auth` +workspace and the `rox_token_file` parameter with values pointing at the +location where the API token is made available. + +```yaml + tasks: + - name: image-scan + taskRef: + name: rhacs-image-scan + kind: Task + workspaces: + - name: rox-api-token-auth + secret: + secretName: rox-api-token + params: + - name: image + value: "$(params.IMAGE)@$(tasks.build-image.results.IMAGE_DIGEST)" + - name: rox_central_endpoint + value: central.stackrox.svc:443 + - name: rox_token_file + value: /rox-api-token-auth/rox_api_token + runAfter: + - build-image +``` + +**Samples:** + +- [secrets.yaml](samples/with-api-token/secrets.yaml) example secret +- [pipeline.yaml](samples/with-api-token/pipeline.yaml) demonstrates use in a +pipeline. +- [pipelinerun.yaml](samples/with-api-token/pipelinerun.yaml) demonstrates use +in a pipelinerun. + +# Known Issues + +* Skipping TLS Verify is currently required. TLS trust bundle not working for +quay.io etc. +* Saving scan output as a 'result' does not work, because it is often larger +than 4KB. This also would require container invocation via script. + + ``` + STEP-ROX-IMAGE-SCAN + + {"level":"fatal","ts":1659318163.069173,"caller":"entrypoint/entrypointer.go:188","msg":"Error while handling results: Termination message is above max allowed size 4096, caused by large task result.","stacktrace":"github.com/tektoncd/pipeline/pkg/entrypoint.Entrypointer.Go\n\t/opt/app-root/src/go/src/github.com/tektoncd/pipeline/pkg/entrypoint/entrypointer.go:188\nmain.main\n\t/opt/app-root/src/go/src/github.com/tektoncd/pipeline/cmd/entrypoint/main.go:154\nruntime.main\n\t/usr/lib/golang/src/runtime/proc.go:225"} + ``` diff --git a/task/rhacs-image-scan/4.0/rhacs-image-scan.yaml b/task/rhacs-image-scan/4.0/rhacs-image-scan.yaml new file mode 100644 index 00000000..d53f58a0 --- /dev/null +++ b/task/rhacs-image-scan/4.0/rhacs-image-scan.yaml @@ -0,0 +1,121 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: rhacs-image-scan + labels: + app.kubernetes.io/version: "4.0" + annotations: + tekton.dev/tags: security + tekton.dev/categories: Security + tekton.dev/displayName: "Scan an image for vulnerabilities with Red Hat Advanced Cluster Security" + tekton.dev/platforms: "linux/amd64,linux/arm64,linux/ppc64le,linux/s390x,darwin/amd64,darwin/arm64,windows/amd64" + tekton.dev/pipelines.minVersion: "0.50.0" +spec: + description: >- + Scan an image with Red Hat Advanced Cluster Security. + + This task allows you to return full vulnerability scan results for an image + in CSV, Table, or JSON formats. + The companion rhacs-image-check task checks an image against build-time policies. + params: + - name: rox_central_endpoint + type: string + description: The address:port tuple for RHACS Stackrox Central. + default: central.stackrox.svc:443 + - name: rox_image + description: Image providing the roxctl tool. + default: quay.io/stackrox-io/roxctl:4.4.2 + - name: image + type: string + description: | + Full name of image to scan. + + SHA 256 digest may be included to ensure scan of sequental runs with same tag. + Examples: 'gcr.io/rox/sample:5.0-rc1', '$(params.IMAGE)', '$(params.IMAGE)@$(tasks.buildah.results.IMAGE_DIGEST)' + default: '$(params.IMAGE)' + - name: output_format + type: string + description: Results output format (json | csv | table) + default: json + - name: insecure-skip-tls-verify + type: string + description: | + Do not verify TLS certificates. + + When set to "true", skip verifying the TLS certs of the Central endpoint and registry. + default: "false" + - name: rox_config_dir + type: string + description: | + Path to the roxtl config directory within the roxctl-config workspace (if machine to machine authentication is used). + Mutually exclusive with token_file. + The path must be prefixed with "/roxctl-config". + default: "" + - name: rox_token_file + description: | + Path to the API Token file (if authentication through API token). + Mutually exclusive with rox_config_dir. + The path must be prefixed with "/rox-api-token-auth". + Example "/rox-api-token-auth/rox_api_token" + type: string + default: "" + - name: output_file + type: string + description: | + Path to a file where to write the roxctl standard output stream. + If empty, the output stream goes to the container standard output. + default: "" + - name: error_file + type: string + description: | + Path to a file where to write the roxctl standard error stream. + If empty, the error stream goes to the container standard error. + default: "" + workspaces: + - name: roxctl-config + description: | + A workspace containing the configuration for roxctl. Used to authenticate with the remote central using short-lived tokens. + Mutually exclusive with rox-api-token-auth workspace. + The workspace has to be populated by a rhacs-m2m-authenticate TaskRun. + optional: true + readOnly: true + mountPath: /roxctl-config + - name: rox-api-token-auth + description: | + A workspace containing a rox token file. Used to authenticate with the remote central. + Mutually exclusive with roxctl-config. + It is strongly recommended that this workspace be bound to a Kubernetes secret. + optional: true + readOnly: true + mountPath: /rox-api-token-auth + steps: + - name: rox-image-scan + image: $(params.rox_image) + env: + - name: HOME + value: /tekton/home + - name: IMAGE + value: $(params.image) + - name: INSECURE + value: $(params.insecure-skip-tls-verify) + - name: OUTPUT + value: $(params.output_format) + - name: ROX_CONFIG_DIR + value: $(params.rox_config_dir) + - name: ROX_API_TOKEN_FILE + value: $(params.rox_token_file) + - name: ROX_ENDPOINT + value: $(params.rox_central_endpoint) + - name: ROX_EXECUTION_ENV + value: Tekton + - name: ROX_OUTPUT_FILE + value: $(params.output_file) + - name: ROX_ERROR_FILE + value: $(params.error_file) + args: + - image + - scan + - --insecure-skip-tls-verify=$(INSECURE) + - --output=$(OUTPUT) + - --image=$(IMAGE) diff --git a/task/rhacs-image-scan/4.0/samples/with-api-token/pipeline.yaml b/task/rhacs-image-scan/4.0/samples/with-api-token/pipeline.yaml new file mode 100644 index 00000000..3d439695 --- /dev/null +++ b/task/rhacs-image-scan/4.0/samples/with-api-token/pipeline.yaml @@ -0,0 +1,140 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: rox-pipeline +spec: + + workspaces: + - name: shared-workspace + - name: rox-api-token-auth + + params: + - name: deployment-name + type: string + description: name of the deployment resource to be patched + - name: deployment + type: string + description: filename of the deployment to be patched + - name: git-url + type: string + description: url of the git repo for the code of deployment + - name: git-revision + type: string + description: revision to be used from repo of the code for deployment + default: main + - name: IMAGE + type: string + description: image to be build from the code + - name: TLSVERIFY + type: string + description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) (default "true") + default: "true" + - name: rox_central_endoint + type: string + description: The address:port tuple for RHACS Stackrox Central. + default: central.stackrox.svc:443 + - name: rox_token_file + type: string + description: The location of the ROX API token file + default: /rox-api-token-auth/rox_api_token + - name: rox_image + type: string + description: The Red Hat Advanced Cluster Security container image + default: quay.io/stackrox-io/roxctl:4.4.2 + + tasks: + # checkout source code + - name: fetch-repository + taskRef: + name: git-clone + kind: ClusterTask + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: $(params.git-url) + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + - name: revision + value: $(params.git-revision) + + # validate deployment against defined RHACS policies + - name: police-deployment + taskRef: + name: rhacs-deployment-check + kind: Task + workspaces: + - name: source + workspace: shared-workspace + - name: rox-api-token-auth + workspace: rox-api-token-auth + params: + - name: deployment + value: $(params.deployment) + - name: insecure-skip-tls-verify + value: "true" + - name: rox_token_file + value: $(params.rox_token_file) + - name: rox_image + value: $(params.rox_image) + runAfter: + - fetch-repository + + - name: build-image + taskRef: + name: buildah + kind: ClusterTask + params: + - name: IMAGE + value: $(params.IMAGE) + - name: TLSVERIFY + value: $(params.TLSVERIFY) + workspaces: + - name: source + workspace: shared-workspace + runAfter: + - fetch-repository + + # scan image for vulns using RHACS + - name: scan-image + taskRef: + name: rhacs-image-scan + kind: Task + workspaces: + - name: rox-api-token-auth + workspace: rox-api-token-auth + params: + - name: image + value: "$(params.IMAGE)@$(tasks.build-image.results.IMAGE_DIGEST)" + - name: insecure-skip-tls-verify + value: "true" # stackrox to OCP image registry x509 fail... + - name: rox_token_file + value: $(params.rox_token_file) + - name: rox_image + value: $(params.rox_image) + runAfter: + - build-image + + # validate image against RHACS policies + - name: police-image + taskRef: + name: rhacs-image-check + kind: Task + workspaces: + - name: rox-api-token-auth + workspace: rox-api-token-auth + params: + - name: image + value: "$(params.IMAGE)@$(tasks.build-image.results.IMAGE_DIGEST)" + - name: insecure-skip-tls-verify + value: "true" + - name: rox_token_file + value: $(params.rox_token_file) + - name: rox_image + value: $(params.rox_image) + runAfter: + - scan-image diff --git a/task/rhacs-image-scan/4.0/samples/with-api-token/pipelinerun.yaml b/task/rhacs-image-scan/4.0/samples/with-api-token/pipelinerun.yaml new file mode 100644 index 00000000..8448eb8e --- /dev/null +++ b/task/rhacs-image-scan/4.0/samples/with-api-token/pipelinerun.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: PipelineRun +metadata: + name: rox-pipelinerun +spec: + pipelineRef: + name: rox-pipeline + params: + - name: deployment-name + value: pipelines-vote-api + - name: deployment + value: k8s/deployment.yaml + - name: git-url + value: https://github.com/openshift/pipelines-vote-api.git + - name: git-revision + value: pipelines-1.7 + - name: IMAGE + value: image-registry.openshift-image-registry.svc:5000/$(context.pipelineRun.namespace)/pipelines-vote-ui + - name: TLSVERIFY + value: "false" + - name: insecure-skip-tls-verify + value: "true" + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 500Mi + - name: rox-api-token-auth + secret: + secretName: rox-api-token diff --git a/task/rhacs-image-scan/4.0/samples/with-api-token/secrets.yaml b/task/rhacs-image-scan/4.0/samples/with-api-token/secrets.yaml new file mode 100644 index 00000000..304f9b0d --- /dev/null +++ b/task/rhacs-image-scan/4.0/samples/with-api-token/secrets.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: rox-api-token +data: + rox_api_token: EXAMPLE +--- +apiVersion: v1 +kind: Secret +type: Opaque +data: + rox_central_endpoint: Y2VudHJhbC5zdGFja3JveC5zdmM6NDQz +metadata: + name: rox-central-endpoint diff --git a/task/rhacs-image-scan/4.0/samples/with-m2m-token/pipeline.yaml b/task/rhacs-image-scan/4.0/samples/with-m2m-token/pipeline.yaml new file mode 100644 index 00000000..60c996fd --- /dev/null +++ b/task/rhacs-image-scan/4.0/samples/with-m2m-token/pipeline.yaml @@ -0,0 +1,150 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: rox-pipeline +spec: + + workspaces: + - name: shared-workspace + + params: + - name: deployment-name + type: string + description: name of the deployment resource to be patched + - name: deployment + type: string + description: filename of the deployment to be patched + - name: git-url + type: string + description: url of the git repo for the code of deployment + - name: git-revision + type: string + description: revision to be used from repo of the code for deployment + default: main + - name: IMAGE + type: string + description: image to be build from the code + - name: rox_central_endoint + type: string + description: The address:port tuple for RHACS Stackrox Central. + default: central.stackrox.svc:443 + - name: rox_config_dir + type: string + description: The path to the roxctl configuration directory + default: /roxctl-config + - name: rox_image + type: string + description: The Red Hat Advanced Cluster Security container image + default: quay.io/stackrox-io/roxctl:4.4.2 + + tasks: + - name: rhacs-authenticate + taskRef: + name: rhacs-m2m-exchange + kind: Task + params: + - name: insecure-skip-tls-verify + value: "true" + - name: rox_config_dir + value: $(params.rox_config_dir) + workspaces: + - name: roxctl-config + workspace: shared-workspace + + # checkout source code + - name: fetch-repository + taskRef: + name: git-clone + kind: ClusterTask + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: $(params.git-url) + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + - name: revision + value: $(params.git-revision) + runAfter: + - rhacs-authenticate + + # validate deployment against defined RHACS policies + - name: police-deployment + taskRef: + name: rhacs-deployment-check + kind: Task + workspaces: + - name: source + workspace: shared-workspace + - name: roxctl-config + workspace: shared-workspace + params: + - name: deployment + value: $(params.deployment) + - name: insecure-skip-tls-verify + value: "true" + - name: rox_config_dir + value: $(params.rox_config_dir) + - name: rox_image + value: $(params.rox_image) + runAfter: + - fetch-repository + + - name: build-image + taskRef: + name: buildah + kind: ClusterTask + params: + - name: IMAGE + value: $(params.IMAGE) + - name: TLSVERIFY + value: "false" + workspaces: + - name: source + workspace: shared-workspace + runAfter: + - fetch-repository + + # scan image for vulns using RHACS + - name: scan-image + taskRef: + name: rhacs-image-scan + kind: Task + workspaces: + - name: roxctl-config + workspace: shared-workspace + params: + - name: image + value: "$(params.IMAGE)@$(tasks.build-image.results.IMAGE_DIGEST)" + - name: insecure-skip-tls-verify + value: "true" # stackrox to OCP image registry x509 fail... + - name: rox_config_dir + value: $(params.rox_config_dir) + - name: rox_image + value: $(params.rox_image) + runAfter: + - build-image + + # validate image against RHACS policies + - name: police-image + taskRef: + name: rhacs-image-check + kind: Task + workspaces: + - name: roxctl-config + workspace: shared-workspace + params: + - name: image + value: "$(params.IMAGE)@$(tasks.build-image.results.IMAGE_DIGEST)" + - name: insecure-skip-tls-verify + value: "true" + - name: rox_config_dir + value: $(params.rox_config_dir) + - name: rox_image + value: $(params.rox_image) + runAfter: + - scan-image diff --git a/task/rhacs-image-scan/4.0/samples/with-m2m-token/pipelinerun.yaml b/task/rhacs-image-scan/4.0/samples/with-m2m-token/pipelinerun.yaml new file mode 100644 index 00000000..ccdfa5ff --- /dev/null +++ b/task/rhacs-image-scan/4.0/samples/with-m2m-token/pipelinerun.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: PipelineRun +metadata: + name: rox-pipelinerun +spec: + pipelineRef: + name: rox-pipeline + params: + - name: deployment-name + value: pipelines-vote-api + - name: deployment + value: k8s/deployment.yaml + - name: git-url + value: https://github.com/openshift/pipelines-vote-api.git + - name: git-revision + value: pipelines-1.7 + - name: IMAGE + value: image-registry.openshift-image-registry.svc:5000/$(context.pipelineRun.namespace)/pipelines-vote-ui + - name: insecure-skip-tls-verify + value: "true" + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 500Mi