There are basically two ways to interface with ACS. The UI, which focuses on the needs of the security team, and a separate “interface” for developers to integrate into their existing toolset (CI/CD pipeline, consoles, ticketing systems etc): The roxctl
commandline tool. This way ACS provides a familiar interface to understand and address issues that the security team considers important.
ACS policies can act during the CI/CD pipeline to identify security risk in container images before they are started.
You should have created and build a custom policy in ACS and tested it to trigger violations. Now you will integrate it into the build pipeline.
roxctl
cliBuild-time policies require the use of the roxctl
command-line tool which is available for download from the ACS Central UI, in the upper right corner of the dashboard. You don’t need to to download this now as our Tekton task will do this automatically.
roxctl
needs to authenticate to ACS Central to do anything. You can use either username and password or API tokens to authenticate against ACS Central. It’s good practice to use a token so that’s what we’ll do.
roxctl
tokenIn the ACS portal:
pipeline
for the token and select the role Admin.Change to the OpenShift Web Console and create a secret with the API token in the project your pipeline lives in:
workshop-int
ProjectSecret
named roxsecretsDOMAIN
placeholder was automatically replaced it should be: central-stackrox.apps.<DOMAIN>:443Even if the form says Drag and drop file with your value here… you can just paste the text.
There is one more thing you have to do before integrating the image scanning into your build pipeline:
When you created your deployment, a trigger
was automatically added that deploys a new version when the image referenced by the ImageStream
changes.
This is not what we want! Because this way a newly build image would be deployed immediately even if the roxctl
scan detects a policy violation and terminates the pipeline.
Have a look for yourself:
workshop
Deploymentimage.openshift.io/triggers
.Remove exactly this lines and click Save:
image.openshift.io/triggers: >-
[{"from":{"kind":"ImageStreamTag","name":"workshop2:latest","namespace":"workshop-int"},"fieldPath":"spec.template.spec.containers[?(@.name==\"workshop2\")].image","pause":"false"
This way we make sure that a new image won’t be deployed automatically right after the build
task which also updates the ImageStream.
You are now ready to create a new pipeline task that will use roxctl
to scan the image build in your pipeline before the deploy step:
roxsecrets
apiVersion: tekton.dev/v1beta1
kind: ClusterTask
metadata:
name: rox-image-check
spec:
params:
- description: >-
Secret containing the address:port tuple for StackRox Central (example -
rox.stackrox.io:443)
name: rox_central_endpoint
type: string
- description: Secret containing the StackRox API token with CI permissions
name: rox_api_token
type: string
- description: "Full name of image to scan (example -- gcr.io/rox/sample:5.0-rc1)"
name: image
type: string
- description: Use image digest result from s2i-java build task
name: image_digest
type: string
results:
- description: Output of `roxctl image check`
name: check_output
steps:
- env:
- name: ROX_API_TOKEN
valueFrom:
secretKeyRef:
key: rox_api_token
name: $(params.rox_api_token)
- name: ROX_CENTRAL_ENDPOINT
valueFrom:
secretKeyRef:
key: rox_central_endpoint
name: $(params.rox_central_endpoint)
image: registry.access.redhat.com/ubi8/ubi-minimal:latest
name: rox-image-check
resources: {}
script: >
#!/usr/bin/env bash
set +x
curl -k -L -H "Authorization: Bearer $ROX_API_TOKEN"
https://$ROX_CENTRAL_ENDPOINT/api/cli/download/roxctl-linux --output
./roxctl > /dev/null; echo "Getting roxctl"
chmod +x ./roxctl > /dev/null
./roxctl image check -c Workshop --insecure-skip-tls-verify -e $ROX_CENTRAL_ENDPOINT
--image $(params.image)@$(params.image_digest)
Take your time to understand the Tekton task definition:
roxctl
binary into the pipeline workspace so you’ll always have a version compatible with your ACS version.roxctl
execution, of course:
image check
commandNow add the rox-image-check task to your pipeline between the build and deploy steps.
Remember how we edited the pipeline directly in yaml before? OpenShift comes with a graphical Pipeline editor that we will use this time.
build
task and click the + at the right side of it, to add a taskroxsecrets
roxsecrets
quay-quay-quay.apps.<DOMAIN>/openshift_workshop-int/workshop
(if the DOMAIN
placeholder hasn’t been replaced automatically, do it manually)As you remember we removed the trigger that updates the Deployment on ImageStream changes. Now the Deployment will never be updated and our new Image version will never be deployed to workshop-int
.
To fix this we will add a new oc client Task that updates the Deployment, only after the Scan Task has run.
deploy
Taskopenshift
and select the openshift-client from Red Hatopenshift-client
Taskoc patch deploy/workshop -p '{"spec":{"template":{"spec":{"containers":[{"name":"workshop","image":"$(params.QUAY_URL)/openshift_workshop-int/workshop@$(tasks.build.results.IMAGE_DIGEST)"}]}}}}'
With our custom System Policy still not set to enforce
we first are going to test the pipeline integration. Go to Pipelines and next to your pipeline click on the three dots and then Start. Now in the pipeline startform enter java-old-image
in the Version field.
rox-image-check
task should succeed, but if you have a look at the output (click the task in the visual representation) you should see that the build violated our policy!The last step is to enforce the System Policy. If the policy is violated the pipeline should be stopped and the application should not be deployed.
Workshop RHSA-2021:4904
in ACS Portal and set Response Method to Inform and enforce and then switch on Build and Deploy below.java-old-image
and then with Version openjdk-11-el7
(default)