Browse Source

CI/CD pipeline with roxctl image check

main
Nicolas Massé 4 years ago
parent
commit
5fdf150192
  1. 44
      README.md
  2. 5
      cicd/03-rolebindings.yaml
  3. 56
      cicd/70-tasks.yaml
  4. 24
      cicd/80-pipeline.yaml

44
README.md

@ -64,18 +64,43 @@ On your OpenShift cluster(s):
* Click **Test** and **Save** * Click **Test** and **Save**
### 2. Deploy the CI/CD pipeline ### 2. Expose the registry
Expose the OpenShift registry.
```sh
oc create route reencrypt image-registry --service=image-registry -n openshift-image-registry
REGISTRY=$(oc get route -n openshift-image-registry image-registry -o jsonpath={.spec.host})
```
Set the registry hostname where required.
```sh
sed -i.bak "s/__REGISTRY__/$REGISTRY/" remediation/Dockerfile deployment/kustomization.yaml cicd/80-pipeline.yaml
```
### 3. Deploy the CI/CD pipeline
Deploy the CI/CD pipeline.
```sh ```sh
oc apply -f cicd oc apply -f cicd
``` ```
### 3. Expose the registry Open the Central and:
Expose the OpenShift registry. * Drill down to **Platform configuration** > **Integration**.
* Select **API Token**.
* Click **Generate token**.
* Fill-in the **Token name** with **Tekton**.
* Select the **Role** `Continuous Integration`.
* Click **Generate**.
* Write down the generated token.
Create a Kubernetes secret with this token:
```sh ```sh
oc create route reencrypt image-registry --service=image-registry -n openshift-image-registry oc create secret generic central-apitoken -n vulnerable-cicd --from-literal=rox_api_token=<TOKEN> --from-literal=rox_central_endpoint=central-stackrox.apps.$CLUSTER_DOMAIN_NAME:443
``` ```
Get the registry hostname and default token. Get the registry hostname and default token.
@ -90,11 +115,13 @@ oc serviceaccounts get-token -n vulnerable-cicd default
Create the Docker Registry integration in Central with the above information. Create the Docker Registry integration in Central with the above information.
Set the registry hostname where required. Add an enforcement exception for the `Fixable Severity at least important` policy:
```sh * Drill down to **Platform configuration** > **System policy**
sed -i.bak "s/__REGISTRY__/$REGISTRY/" remediation/Dockerfile deployment/kustomization.yaml * Select the policy `Fixable Severity at least important`
``` * Click **Edit**
* In the excluded image, add `<REGISTRY>/vulnerable-cicd/vulnerable-log4j` (you will have to select the last option of the list: `Create ...`)
* Save the policy
### 4. Deploy the vulnerable app ### 4. Deploy the vulnerable app
@ -105,7 +132,6 @@ oc kustomize deployment | oc apply -f -
Give access to the `vulnerable-cicd` images from the `vulnerable-log4j` namespace. Give access to the `vulnerable-cicd` images from the `vulnerable-log4j` namespace.
```sh ```sh
REGISTRY=$(oc get route -n openshift-image-registry image-registry -o jsonpath={.spec.host})
oc get secrets -n vulnerable-cicd -o json | jq -r '.items[] | select(.metadata.annotations["kubernetes.io/service-account.name"]=="default" and .type=="kubernetes.io/dockercfg") | .data[".dockercfg"]' | base64 -d | jq --arg registry "$REGISTRY" '.["image-registry.openshift-image-registry.svc:5000"] as $conf | { ($registry) : $conf}' > dockercfg oc get secrets -n vulnerable-cicd -o json | jq -r '.items[] | select(.metadata.annotations["kubernetes.io/service-account.name"]=="default" and .type=="kubernetes.io/dockercfg") | .data[".dockercfg"]' | base64 -d | jq --arg registry "$REGISTRY" '.["image-registry.openshift-image-registry.svc:5000"] as $conf | { ($registry) : $conf}' > dockercfg
oc apply -n vulnerable-log4j -f - <<EOF oc apply -n vulnerable-log4j -f - <<EOF
kind: Secret kind: Secret

5
cicd/03-rolebindings.yaml

@ -1,7 +1,7 @@
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding kind: RoleBinding
metadata: metadata:
name: deployment-can-pull-vulnerable-log4j name: vulnerable-log4j-puller
namespace: vulnerable-cicd namespace: vulnerable-cicd
roleRef: roleRef:
apiGroup: rbac.authorization.k8s.io apiGroup: rbac.authorization.k8s.io
@ -11,3 +11,6 @@ subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: default name: default
namespace: vulnerable-log4j namespace: vulnerable-log4j
- kind: ServiceAccount
name: pipeline
namespace: vulnerable-cicd

56
cicd/70-tasks.yaml

@ -52,27 +52,41 @@ spec:
apiVersion: tekton.dev/v1beta1 apiVersion: tekton.dev/v1beta1
kind: Task kind: Task
metadata: metadata:
name: oc-annotate name: roxctl-image-check
namespace: vulnerable-cicd
spec: spec:
params: params:
- name: namespace - description: >-
default: default Secret containing the StackRox API token with CI permissions and the
description: The kubernetes namespace address:port tuple for StackRox Central (example: rox.stackrox.io:443)
- name: componentName name: roxctlSecret
default: sample type: string
description: The name of the component - description: 'Full name of image to scan (example -- gcr.io/rox/sample:5.0-rc1)'
- name: annotation name: image
description: The annotation (key=value) type: string
results:
- description: Output of `roxctl image check`
name: check_output
steps: steps:
- name: oc-annotate - env:
image: quay.io/openshift/origin-cli:latest - name: ROX_API_TOKEN
command: valueFrom:
- "/usr/bin/oc" secretKeyRef:
args: key: rox_api_token
- annotate name: $(params.roxctlSecret)
- -n - name: ROX_CENTRAL_ENDPOINT
- $(inputs.params.namespace) valueFrom:
- deploy secretKeyRef:
- $(inputs.params.componentName) key: rox_central_endpoint
- $(inputs.params.annotation) name: $(params.roxctlSecret)
image: quay.io/skopeo/stable:v1.5.2
name: roxctl-image-check
resources: {}
script: |
#!/bin/bash
set -Eeuo pipefail
TOKEN=`cat /var/run/secrets/kubernetes.io/serviceaccount/token`
DIGEST=`skopeo inspect "docker://$(params.image)" --format '{{.Digest}}' --creds token:$TOKEN`
NAME=`skopeo inspect "docker://$(params.image)" --format '{{.Name}}' --creds token:$TOKEN`
curl -s -k -L -H "Authorization: Bearer $ROX_API_TOKEN" "https://$ROX_CENTRAL_ENDPOINT/api/cli/download/roxctl-linux" --output /tmp/roxctl > /dev/null
chmod +x /tmp/roxctl
/tmp/roxctl image check --insecure-skip-tls-verify -e "$ROX_CENTRAL_ENDPOINT" --image "$NAME@$DIGEST"

24
cicd/80-pipeline.yaml

@ -13,25 +13,23 @@ spec:
value: vulnerable-log4j value: vulnerable-log4j
- name: namespace - name: namespace
value: vulnerable-cicd value: vulnerable-cicd
- name: roxctl-image-check
taskRef:
name: roxctl-image-check
runAfter:
- build-image
params:
- name: roxctlSecret
value: central-apitoken
- name: image
value: __REGISTRY__/vulnerable-cicd/vulnerable-log4j:latest
- name: deploy - name: deploy
taskRef: taskRef:
name: oc-deploy name: oc-deploy
runAfter: runAfter:
- build-image - roxctl-image-check
params: params:
- name: componentName - name: componentName
value: settlement-app value: settlement-app
- name: namespace - name: namespace
value: vulnerable-log4j value: vulnerable-log4j
# - name: remediate
# taskRef:
# name: oc-annotate
# runAfter:
# - deploy
# params:
# - name: componentName
# value: settlement-app
# - name: namespace
# value: vulnerable-log4j
# - name: annotation
# value: cve.log4shell.remediate=true

Loading…
Cancel
Save