|
| 1 | +--- |
| 2 | +title: Secure supply chain - Automated approach |
| 3 | +weight: 40 |
| 4 | +aliases: /layered-zero-trust/lzt-automated-secure-supply-chain/ |
| 5 | +--- |
| 6 | + |
| 7 | +:toc: |
| 8 | +:imagesdir: /images |
| 9 | +:_mod-docs-content-type: ASSEMBLY |
| 10 | +include::modules/comm-attributes.adoc[] |
| 11 | + |
| 12 | +[id="lzt-automated-secure-supply-chain"] |
| 13 | += Use case: Automating the secure supply chain |
| 14 | + |
| 15 | +[role="_abstract"] |
| 16 | +The xref:/patterns/layered-zero-trust/lzt-secure-multitier/index.html [Secure multitiered applications] use case describes how to implement a secure supply chain for application development by using Red{nbsp}Hat Trusted Artifact Signer (RHTAS) and the Red{nbsp}Hat Trusted Profile Analyzer (RHTPA). This use case demonstrates automation of the secure supply chain for application development by using link:https://docs.redhat.com/en/documentation/red_hat_openshift_pipelines/1.20[{rh-pipelines-first}]. |
| 17 | + |
| 18 | +{pipelines-short} orchestrates the application building and certification process. The Zero Trust Validated Pattern (ZTVP) creates a pipeline in the cluster named `qtodo-supply-chain`. |
| 19 | + |
| 20 | +[id="pipeline-tasks"] |
| 21 | +== Pipeline tasks |
| 22 | + |
| 23 | +The pipeline includes the following tasks: |
| 24 | + |
| 25 | +* **qtodo-clone-repository**: Clones the `qtodo` repository. |
| 26 | +* **qtodo-build-artifact**: Builds an `uber-jar` of the `qtodo` application. |
| 27 | +* **qtodo-sign-artifact**: Signs the generated JAR file. |
| 28 | +* **qtodo-verify-artifact**: Verifies the JAR signature. |
| 29 | +* **qtodo-build-image**: Builds a container image and uploads it to a registry. |
| 30 | +* **qtodo-sign-image**: Signs the container image. |
| 31 | +* **qtodo-generate-sbom**: Generates an SBOM from the image. |
| 32 | +* **qtodo-sbom-attestation**: Creates a signed attestation and attaches it to the image. |
| 33 | +* **qtodo-upload-sbom**: Uploads the SBOM file to RHTPA. |
| 34 | +* **qtodo-verify-image**: Verifies the attestation and signature. |
| 35 | + |
| 36 | +[id="run-pipeline"] |
| 37 | +== Running the pipeline |
| 38 | + |
| 39 | +Start the pipeline by using the {ocp} web console or the CLI. |
| 40 | + |
| 41 | +[id="run-pipeline-console"] |
| 42 | +=== Running the pipeline from the web console |
| 43 | + |
| 44 | +To start a pipeline execution from the {ocp} Web console: |
| 45 | + |
| 46 | +.Procedure |
| 47 | + |
| 48 | +. Log in to the {ocp} web console. |
| 49 | +. From the left navigation bar, select **Pipelines** -> **Pipelines**. |
| 50 | +. In the **layered-zero-trust-hub** project, find the **qtodo-supply-chain** pipeline. |
| 51 | +. Click the **Options** menu (⋮) and select **Start**. |
| 52 | +. Verify the parameters. Most default values are correct for single-cluster mode. |
| 53 | +. Configure the following workspaces: |
| 54 | + |
| 55 | +* For **qtodo-source**, select **PersistentVolumeClaim** and ensure the PVC name is **qtodo-workspace-source**. |
| 56 | +* For **registry-auth-config**, select **Secret** and ensure the secret name is **qtodo-registry-auth**. |
| 57 | +. Click **Start**. |
| 58 | + |
| 59 | +[id="run-pipeline-cli"] |
| 60 | +=== Running the pipeline from the CLI |
| 61 | + |
| 62 | +Start a pipeline execution by creating a `PipelineRun` resource that references the `qtodo-supply-chain` pipeline. |
| 63 | + |
| 64 | +.Procedure |
| 65 | + |
| 66 | +. Create a file named `qtodo-pipeline.yaml` with the following content: |
| 67 | ++ |
| 68 | +[source,yaml] |
| 69 | +---- |
| 70 | +apiVersion: tekton.dev/v1 |
| 71 | +kind: PipelineRun |
| 72 | +metadata: |
| 73 | + generateName: qtodo-manual-run- |
| 74 | + namespace: layered-zero-trust-hub |
| 75 | +spec: |
| 76 | + pipelineRef: |
| 77 | + name: qtodo-supply-chain |
| 78 | + taskRunTemplate: |
| 79 | + serviceAccountName: pipeline |
| 80 | + timeouts: |
| 81 | + pipeline: 1h0m0s |
| 82 | + workspaces: |
| 83 | + - name: qtodo-source |
| 84 | + persistentVolumeClaim: |
| 85 | + claimName: qtodo-workspace-source |
| 86 | + - name: registry-auth-config |
| 87 | + secret: |
| 88 | + secretName: qtodo-registry-auth |
| 89 | +---- |
| 90 | ++ |
| 91 | +Verify the values for the PVC storage and registry configuration. |
| 92 | + |
| 93 | +. Create the `PipelineRun` resource: |
| 94 | ++ |
| 95 | +[source,terminal] |
| 96 | +---- |
| 97 | +$ oc create -f qtodo-pipeline.yaml |
| 98 | +---- |
| 99 | + |
| 100 | +.Verification |
| 101 | + |
| 102 | +* Review the pipeline logs using the Tekton CLI: |
| 103 | ++ |
| 104 | +[source,terminal] |
| 105 | +---- |
| 106 | +$ tkn pipeline logs -n layered-zero-trust-hub -L -f |
| 107 | +---- |
| 108 | + |
| 109 | +[id="inspect-results"] |
| 110 | +== Inspecting pipeline results |
| 111 | + |
| 112 | +Verify the status and output of the pipeline by using the web console or the CLI. |
| 113 | + |
| 114 | +[id="inspect-results-ui"] |
| 115 | +=== Inspecting results from the web console |
| 116 | + |
| 117 | +You can inspect the results of the pipeline execution from the {ocp} web console. |
| 118 | + |
| 119 | +.Procedure |
| 120 | + |
| 121 | +. Log in to the {ocp} web console. |
| 122 | +. From the left navigation bar, select **Pipelines** -> **Pipelines**. |
| 123 | +. In the **layered-zero-trust-hub** project, find the **qtodo-supply-chain** pipeline. |
| 124 | +. Click the *PipelineRun* link in the *Last run* column. |
| 125 | +. In the *Details* tab, view the summary of the pipeline execution and tasks. |
| 126 | +. Click on a task or the *Logs* tab to see the output of specific tasks. |
| 127 | + |
| 128 | +[id="inspect-results-cli"] |
| 129 | +=== Inspecting results from the CLI |
| 130 | + |
| 131 | +You can inspect the results of the pipeline execution by using the CLI. |
| 132 | + |
| 133 | +.Procedure |
| 134 | + |
| 135 | +. Verify that the pipeline completed successfully: |
| 136 | ++ |
| 137 | +[source,terminal] |
| 138 | +---- |
| 139 | +$ oc get pipelinerun -n layered-zero-trust-hub |
| 140 | +
|
| 141 | +NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME |
| 142 | +qtodo-manual-run-p46f7 True Succeeded 7m4s 2m12s |
| 143 | +---- |
| 144 | + |
| 145 | +. Review the `TaskRuns` to see the results of each step: |
| 146 | ++ |
| 147 | +[source,terminal] |
| 148 | +---- |
| 149 | +$ oc get taskruns -n layered-zero-trust-hub |
| 150 | +
|
| 151 | +NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME |
| 152 | +qtodo-manual-run-p46f7-qtodo-build-artifact True Succeeded 7m44s 5m17s |
| 153 | +qtodo-manual-run-p46f7-qtodo-build-image True Succeeded 4m55s 4m4s |
| 154 | +qtodo-manual-run-p46f7-qtodo-clone-repository True Succeeded 7m55s 7m44s |
| 155 | +... |
| 156 | +---- |
| 157 | + |
| 158 | +. Identify the pods associated with the tasks in the `layered-zero-trust-hub` namespace: |
| 159 | ++ |
| 160 | +[source,terminal] |
| 161 | +---- |
| 162 | +$ oc get pods -n layered-zero-trust-hub |
| 163 | +
|
| 164 | +NAME READY STATUS RESTARTS AGE |
| 165 | +qtodo-manual-run-p46f7-qtodo-build-artifact-pod 0/1 Completed 0 10m |
| 166 | +qtodo-manual-run-p46f7-qtodo-build-image-pod 0/1 Completed 0 7m21s |
| 167 | +... |
| 168 | +---- |
| 169 | + |
| 170 | +. Review the pod logs to view the output of a specific step. For example, to view image verification messages: |
| 171 | ++ |
| 172 | +[source,terminal] |
| 173 | +---- |
| 174 | +$ oc logs -n layered-zero-trust-hub qtodo-manual-run-p46f7-qtodo-verify-image-pod |
| 175 | +
|
| 176 | +Success: true |
| 177 | +Result: SUCCESS |
| 178 | +Violations: 0, Warnings: 0, Successes: 3 |
| 179 | +Component: Unnamed |
| 180 | +ImageRef: quay-registry-quay-quay-enterprise.apps.example.com/ztvp/qtodo@sha256:df6506e93a141cfcaeb3b4686b558cddd963410a146b10c3cbd1319122f5f880 |
| 181 | +
|
| 182 | +Results: |
| 183 | +✓ [Success] builtin.attestation.signature_check |
| 184 | +... |
| 185 | +✓ [Success] builtin.image.signature_check |
| 186 | +... |
| 187 | +---- |
| 188 | + |
| 189 | +[id="review-services"] |
| 190 | +== Reviewing integrated services |
| 191 | + |
| 192 | +The supply chain results are visible in the services used during the build process. |
| 193 | + |
| 194 | +[id="review-quay"] |
| 195 | +=== Reviewing images in Quay |
| 196 | + |
| 197 | +If you used Quay as the image registry, you can review the built image inside the registry. |
| 198 | + |
| 199 | +.Procedure |
| 200 | + |
| 201 | +. Obtain the credentials for the Quay web interface: |
| 202 | + |
| 203 | +* *Quay URL*: |
| 204 | ++ |
| 205 | +[source,terminal] |
| 206 | +---- |
| 207 | +$ echo "https://$(oc get route -n quay-enterprise \ |
| 208 | + -l quay-component=quay-app-route \ |
| 209 | + -o jsonpath='{.items[0].spec.host}')" |
| 210 | +---- |
| 211 | +* *Quay username*: Use the value specified in `values-hub.yaml` or `quay-user`. |
| 212 | +* *Quay password*: |
| 213 | ++ |
| 214 | +[source,terminal] |
| 215 | +---- |
| 216 | +$ oc get secret -n layered-zero-trust-hub qtodo-quay-password -o json | jq '.data["password"] | @base64d' |
| 217 | +---- |
| 218 | + |
| 219 | +. Log in to the Quay web interface. |
| 220 | +. Select the **ztvp/qtodo** repository. |
| 221 | +. In the navigation menu, select **Tags**. |
| 222 | +. Verify that the `latest` tag is signed and that the `.att` attestation file is present. |
| 223 | + |
| 224 | +image::/images/layered-zero-trust/quay-web-ui.png[Quay Web UI] |
| 225 | + |
| 226 | +[id="review-rekor"] |
| 227 | +=== Reviewing Rekor verification records |
| 228 | + |
| 229 | +Use the Rekor search interface to check verification records. Search by email address or record index. |
| 230 | + |
| 231 | +.Procedure |
| 232 | + |
| 233 | +* Get the URL for the Rekor search interface: |
| 234 | ++ |
| 235 | +[source,terminal] |
| 236 | +---- |
| 237 | +$ echo "https://$(oc get route -n trusted-artifact-signer -l app.kubernetes.io/component=rekor-ui -o jsonpath='{.items[0].spec.host}')" |
| 238 | +---- |
| 239 | + |
| 240 | +image::/images/layered-zero-trust/rekor-web-ui.png[Rekor's Search UI] |
| 241 | + |
| 242 | +[id="review-rhtpa"] |
| 243 | +=== Reviewing RHTPA results |
| 244 | + |
| 245 | +The RHTPA web UI uses OIDC for user authentication. If you are using *Keycloak* integrated with the pattern, use the following commands to obtain the credentials. |
| 246 | + |
| 247 | +.Procedure |
| 248 | + |
| 249 | +. Get the credentials: |
| 250 | +* *RHTPA URL*: |
| 251 | ++ |
| 252 | +[source,terminal] |
| 253 | +---- |
| 254 | +$ echo "https://$(oc get route -n trusted-profile-analyzer \ |
| 255 | + -l app.kubernetes.io/name=server \ |
| 256 | + -o jsonpath='{.items[0].spec.host}')" |
| 257 | +---- |
| 258 | +* *RHTPA user*: `rhtpa-user` |
| 259 | +* *RHTPA user password*: |
| 260 | ++ |
| 261 | +[source,terminal] |
| 262 | +---- |
| 263 | +$ oc get secret keycloak-users -n keycloak-system -o json \ |
| 264 | + | jq '.data["rhtpa-user-password"] | @base64d' |
| 265 | +---- |
| 266 | + |
| 267 | +. Review the SBOM in the RHTPA web interface: |
| 268 | +.. Log in to the RHTPA web interface using Keycloak credentials. |
| 269 | +.. In the navigation menu, select **SBOMs**. |
| 270 | +.. Select the container image name from the list of available SBOMs. |
| 271 | + |
| 272 | +image::/images/layered-zero-trust/rhtpa-web-ui.png[RHTPA Web UI] |
0 commit comments