Skip to content

Commit aa71a9c

Browse files
committed
Secure Supply Chain docs for layered-zero-trust
1 parent 9253b91 commit aa71a9c

File tree

2 files changed

+48
-44
lines changed

2 files changed

+48
-44
lines changed

content/patterns/layered-zero-trust/_index.adoc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ The pattern consists of the following key components:
9797
** Provides a management control plane in multi-cluster scenarios.
9898

9999
* link:https://docs.redhat.com/en/documentation/red_hat_quay/3.15[Red{nbsp}Hat Quay]
100-
** Enables a private repository for OCI images within our environment.
100+
** Enables a private repository for OCI images within the environment.
101101

102102
* link:https://docs.redhat.com/en/documentation/red_hat_openshift_container_storage/4.8/html/managing_hybrid_and_multicloud_resources/index[Multicloud Object Gateway]
103103
** Provides an object storage service for {ocp}.
@@ -106,7 +106,7 @@ The pattern consists of the following key components:
106106
** Provides cryptographic signing and verification of software artifacts and container images.
107107

108108
* link:https://docs.redhat.com/es/documentation/red_hat_trusted_profile_analyzer/2.2[Red{nbsp}Hat Trusted Profile Analyzer (RHTPA)]
109-
** Provides the storage and management means for _Software Bills of Materials_ (SBOMs), with cross-referencing capabilities between SBOMs and CVEs/Security Advisories.
109+
** Provides the storage and management means for _Software Bill of Materials_ (SBOMs), with cross-referencing capabilities between SBOMs and CVEs/Security Advisories.
110110

111111
[id="sidecar-pattern"]
112112
==== Sidecar pattern
@@ -141,7 +141,7 @@ The following technologies are used in this solution:
141141
* *Compliance Operator*: Provides ability to scan and remediate cluster hardening based on profiles
142142
* *QTodo application*: Serves as a sample Quarkus-based application to show zero trust principles.
143143
* *PostgreSQL database*: Provides the backend database for the demonstration application.
144-
* *Multicloud Object Gateway*: Lightweight object storage service for {ocp}. Used as storage by Quay.
144+
* *Multicloud Object Gateway*: Lightweight object storage service for {ocp}. Used by Quay for the storage of binary blobs.
145145
* *Red{nbsp}Hat Quay*: Private registry for OCI images.
146-
* *Red{nbsp}Hat Trusted Artifact Signer*: Facilitates signing and verification of binary objects in the cluster.
146+
* *Red{nbsp}Hat Trusted Artifact Signer*: Facilitates signing and verification of software artifacts.
147147
* *Red{nbsp}Hat Trusted Profile Analyzer*: Enables SBOM file analysis and vulnerability detection.

content/patterns/layered-zero-trust/lzt-secure-supply-chain.adoc

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ include::modules/comm-attributes.adoc[]
1313
= Use case: Secure supply chain
1414

1515
[role="_abstract"]
16-
This use case outlines the process of building, signing, and verifying artifacts and images within the Zero Trust Validated Pattern (ZTVP) using the Red{nbsp}Hat Trusted Artifact Signer (RHTAS) and the Red{nbsp}Hat Trusted Profile Analyzer (RHTPA).
16+
A key objective of ZTVP is the comprehensive security of both the platform and the applications deployed on it. This use case outlines the process of building, signing, and verifying artifacts and images within the Zero Trust Validated Pattern (ZTVP) using the Red{nbsp}Hat Trusted Artifact Signer (RHTAS) and the Red{nbsp}Hat Trusted Profile Analyzer (RHTPA). Through the implementation of this supply chain, we can establish a chain of trust and integrity for applications.
1717

1818
[id="clone-app-source"]
1919
== Cloning the app source code
@@ -33,7 +33,7 @@ $ git clone https://github.com/validatedpatterns-demos/qtodo.git
3333
[id="build-app-artifact"]
3434
== Building the app artifact
3535

36-
The application requires *Java 17+* and *maven 3.8.x+* to compile.
36+
The application requires *Java 17+* and *Maven 3.8.x+* to compile.
3737
However, you can use containers and the Makefile that is already present in the repository.
3838

3939
.Procedure
@@ -49,23 +49,23 @@ The artifact is built in the `target/` directory.
4949

5050
.Verification
5151

52-
* List the contents of the `target/` directory to verify that the generated JAR file:
52+
* List the contents of the `target/` directory to verify the generated JAR file:
5353
+
5454
[source,terminal]
5555
----
5656
$ ls -lh target/
5757
total 46M
58-
-rw-r--r-- 1 user user 46M Nov 19 13:42 qtodo-1.0.0-SNAPSHOT-runner.jar
58+
-rw-r--r-- 1 user user 46M Nov 19 13:42 qtodo-1.0.0-runner.jar
5959
----
6060

6161
[id="build-image"]
6262
== Building the image
6363

64-
To create an image that has the JAR file that you built, you can use `make` command.
64+
To create an image that has the JAR file that you built, use the `make` command.
6565

6666
.Procedure
6767

68-
* Run the following command to build the container image:
68+
* Run the following commands to set details related to the qtodo application and then build the container image:
6969
+
7070
[source,terminal]
7171
----
@@ -76,7 +76,7 @@ $ make build-image-binary
7676

7777
.Verification
7878

79-
* The resulting image is available in the local image store. You can verify its presence by listing the images.
79+
* The resulting image is available in the local image store. Verify its presence by listing the images.
8080
+
8181
[source,terminal]
8282
----
@@ -123,7 +123,7 @@ $ podman push "${IMAGE}" # --tls-verify=false
123123

124124
To ensure the security and integrity of the qtodo artifact within the supply chain, sign the artifact file (binary) by using *RHTAS*.
125125

126-
RHTAS relies on the `Sigstore` open source project standards. It comprises three core services that work together to provide keyless signing, transparency, and verification:
126+
RHTAS uses the `Sigstore` open source project standards. It consists of three core services that work together to provide keyless signing, transparency, and verification:
127127

128128
* `Fulcio` (Certificate Authority)
129129
* `Rekor` (Transparency Log)
@@ -140,11 +140,11 @@ For more information about these products, see the following documentation topic
140140
[id="download-cosign"]
141141
=== Downloading cosign
142142

143-
Install the cosign binary that is provided by the RHTAS solution, which is accessible within the `cli-server` pod.
143+
Install the `cosign` binary that RHTAS provides. This binary is accessible within the `cli-server` pod.
144144

145145
.Procedure
146146

147-
. Get the cli-server hostname by using the `oc` client:
147+
. Obtain the hostname of the cli-server by using the `oc` client which contains the CLI tools provided by RHTAS:
148148
+
149149
[source,terminal]
150150
----
@@ -156,7 +156,7 @@ $ export CLI_SERVER_URL="https://$(oc get route -n trusted-artifact-signer -l ap
156156
Using disparate versions of `cosign` might lead to incompatibility issues with the RHTAS services. To ensure compatibility, always download the `cosign` binary directly from the `cli-server` pod of your specific RHTAS deployment.
157157
====
158158

159-
. Set the appropriate operating system and architecture and download the `cosign` binary:
159+
. Specify the appropriate operating system and architecture and download the `cosign` binary:
160160
+
161161
[source,terminal]
162162
----
@@ -186,7 +186,7 @@ Configure `cosign` to use the TUF root of your RHTAS instance before signing any
186186

187187
.Procedure
188188

189-
. Get the TUF root:
189+
. Obtain the URL of the TUF instance:
190190
+
191191
[source,terminal]
192192
----
@@ -215,9 +215,9 @@ $ cosign initialize \
215215
----
216216

217217
[id="oidc-credentials"]
218-
=== OIDC credentials
218+
=== OpenID Connect credentials
219219

220-
Signing requires an OIDC identity issuer and the URLs for the Fulcio and Rekor services. This configuration uses *Keycloak*; however, you can substitute this component based on your specific environment.
220+
Signing requires an OpenID Connect (OIDC) identity issuer and the URLs for the Fulcio and Rekor services. This configuration uses *Keycloak*; however, you can substitute this component based on your specific environment.
221221

222222
The following example illustrates the procedure for obtaining an identification token by using Keycloak.
223223

@@ -256,31 +256,36 @@ $ export OIDC_TOKEN="$(curl -sk ${OIDC_TOKEN_URL} \
256256
--data-urlencode 'scope=openid email profile' \
257257
| jq -r .access_token)"
258258
----
259+
+
260+
[NOTE]
261+
====
262+
OIDC tokens have a limited lifespan and might expire during this procedure. If you encounter authentication errors in subsequent steps, re-run this command to get a fresh token.
263+
====
259264

260265
[id="create-signature-bundle"]
261266
=== Creating a signature bundle
262267

263-
Run the signing command. This generates a `.bundle` file that has the signature and the transparency log entry.
268+
Run the signing command. This command generates a `.bundle` file that has the signature and the transparency log entry.
264269

265270
.Procedure
266271

267-
. Get the Fulcio service hostname:
272+
. Obtain the URL of the Fulcio service:
268273
+
269274
[source,terminal]
270275
----
271276
# Get Fulcio service hostname
272277
$ export FULCIO_URL="https://$(oc get route -n trusted-artifact-signer -l app.kubernetes.io/component=fulcio -o jsonpath='{.items[0].spec.host}')"
273278
----
274279

275-
. Get the Rekor service hostname:
280+
. Obtain the URL Rekor service:
276281
+
277282
[source,terminal]
278283
----
279284
# Get Rekor service hostname
280285
$ export REKOR_URL="https://$(oc get route -n trusted-artifact-signer -l app.kubernetes.io/component=rekor-server -o jsonpath='{.items[0].spec.host}')"
281286
----
282287

283-
. Set the path to the artifact:
288+
. Set the path to the previously created artifact (JAR):
284289
+
285290
[source,terminal]
286291
----
@@ -302,7 +307,7 @@ $ cosign sign-blob "${ARTIFACT_PATH}" \
302307

303308
.Verification
304309

305-
To verify the signed artifact, you can use the generated bundle and the artifact itself. Ensure `cosign` still points to the RHTAS TUF root.
310+
To verify the signed artifact, you can use the generated bundle and the artifact itself.
306311

307312
* Verify the artifact by using the following command:
308313
+
@@ -321,17 +326,17 @@ Beyond command-line verification, you can locate the record by using the Rekor s
321326
You can get the URL for the Rekor Search UI by using the following command:
322327
[source,terminal]
323328
----
324-
$ oc get route -n trusted-artifact-signer -l app.kubernetes.io/component=rekor-ui -o jsonpath='{.items[0].spec.host}'
329+
$ echo https://$(oc get route -n trusted-artifact-signer -l app.kubernetes.io/component=rekor-ui -o jsonpath='{.items[0].spec.host}')
325330
----
326331

327332
image::/images/layered-zero-trust/rekor-web-ui.png[Rekor's Search UI]
328333

329334
[id="sign-container-image"]
330335
== Signing the image
331336

332-
To sign the image, use RHTAS services again. For this step, you must also be logged in to the Quay service, because you write the digital signature to the repository.
337+
To sign the image, use RHTAS services again. For this step, you must also be logged in to the Quay service as the digital signature is published to the repository.
333338

334-
To reference the image you intend to sign, you must use its digest rather than its tag. You can obtain the digest of the image by using `skopeo` or by checking the Quay repository.
339+
To reference the image you intend to sign, you must use its digest rather than its tag. Get the digest of the image by using `skopeo` or by checking the Quay repository.
335340

336341
.Procedure
337342

@@ -367,7 +372,7 @@ $ cosign sign "${IMAGE_REF}" \
367372

368373
.Verification
369374

370-
To verify the image, you can use `cosign` and check the output to see if it matches your identity and OIDC.
375+
To verify the image signature, you can use `cosign` and check the output to see if it matches your identity and OIDC issuer.
371376

372377
* Verify the image by using the following command:
373378

@@ -411,7 +416,7 @@ $ syft scan registry:"${IMAGE}" -o spdx-json=qtodo-sbom.json
411416
[id="attach-sbom"]
412417
== Attaching the SBOM to the image
413418

414-
You must attach the generated SBOM file to the image, which enables verification by third parties if required. For this task, use the `cosign` tool again.
419+
You must attach the generated SBOM file to the image which enables verification by third parties if required. For this task, use the `cosign` tool again.
415420

416421
Although direct attachment of the SBOM to the image is feasible, the recommended approach involves encapsulating the SBOM within a signed envelope, thereby generating an attestation. This method ensures the integrity of the SBOM, guaranteeing its provenance and confirming that it has not been subjected to unauthorized modifications.
417422

@@ -429,32 +434,23 @@ $ cosign attest \
429434
--type spdxjson \
430435
--fulcio-url="${FULCIO_URL}" \
431436
--rekor-url="${REKOR_URL}" \
437+
--identity-token "${OIDC_TOKEN}" \
432438
--oidc-client-id="${RHTAS_CLIENT_ID}" \
433-
--oidc-issuer "${OIDC_ISSUER_URL}" \
434439
--yes \
435440
"${IMAGE}"
436441
----
437442

438443
[id="upload-sbom-rhtpa"]
439444
== Uploading the SBOM to RHTPA
440445

441-
To analyze the SBOM and detect Common Vulnerabilities and Exposures (CVEs) in the image, use RHTPA.
446+
To analyze the SBOM and detect Common Vulnerabilities and Exposures (CVEs) in the image, use Red Hat Trusted Profile Analyzer (RHTPA).
442447

443448
The RHTPA system provides an API that enables the direct upload of the SBOM by an HTTP request. To use this API, you need a token authorized by the OIDC.
444449

445450
This following commands illustrates the process for obtaining the token when using Keycloak, which serves as the default OIDC for the Zero Trust Validated Pattern (ZTVP).
446451

447452
.Procedure
448453

449-
. Get the OIDC Issuer URL from Keycloak and set the token URL:
450-
+
451-
[source,terminal]
452-
----
453-
# Get the OIDC Issuer URL from Keycloak route
454-
$ export OIDC_ISSUER_URL="https://$(oc get route -n keycloak-system -l app=keycloak -o jsonpath='{.items[0].spec.host}')/realms/ztvp"
455-
$ export OIDC_TOKEN_URL="${OIDC_ISSUER_URL}/protocol/openid-connect/token"
456-
----
457-
458454
. Obtain the client secret for the RHTPA OIDC client:
459455
+
460456
[source,terminal]
@@ -463,7 +459,7 @@ $ export OIDC_TOKEN_URL="${OIDC_ISSUER_URL}/protocol/openid-connect/token"
463459
$ export RHTPA_CLIENT_SECRET="$(oc get secret rhtpa-oidc-cli-secret -n trusted-profile-analyzer -o jsonpath='{.data.client-secret}' | base64 -d)"
464460
----
465461

466-
. Set the client ID:
462+
. Set the Client ID associated with RHTPA:
467463
+
468464
[source,terminal]
469465
----
@@ -484,11 +480,11 @@ $ export RHTPA_TOKEN=$(curl -sSfk -X POST "${OIDC_TOKEN_URL}" \
484480
-d "client_secret=${RHTPA_CLIENT_SECRET}" | jq -r .access_token)
485481
----
486482

487-
. Get the RHTPA API URL:
483+
. Obtain the RHTPA API URL:
488484
+
489485
[source,terminal]
490486
----
491-
# Get the RHTPA API hostname
487+
# Get the RHTPA API URL
492488
$ export RHTPA_URL="https://$(oc get route -n trusted-profile-analyzer -l app.kubernetes.io/name=server -o jsonpath='{.items[0].spec.host}')"
493489
----
494490
. Upload the SBOM to RHTPA using the API with the Keycloak token:
@@ -503,7 +499,7 @@ $ curl -sk -X POST \
503499
"${RHTPA_URL}/api/v2/sbom"
504500
----
505501

506-
Upon publication, you can view the SBOM on the RHTPA web UI. The access URL is same as the one used for the API. Similar to the API, the RHTPA web UI uses OIDC for user authentication. In our specific deployment, you can view the RHTPA web UI by logging in with the credentials. Use the following commands to get the username and password:
502+
Once the SBOM has been published, it can be viewed within the RHTPA web UI. The URL is same as the value obtained previously for the RHTPA API. Similar to the API, the RHTPA web UI uses OIDC for user authentication. In our specific deployment, you can view the RHTPA web UI by logging in with the credentials associated with the user. Use the following commands to obtain the username and password:
507503

508504
[source,terminal]
509505
----
@@ -516,12 +512,15 @@ $ oc get secret keycloak-users -n keycloak-system \
516512
base64 -d
517513
----
518514

515+
To review the newly generated SBOM within the web UI, navigate to the "SBOMs" section via the left-hand menu, and select the entry corresponding to the name of the container image from the list of available SBOMs.
516+
519517
image::/images/layered-zero-trust/rhtpa-web-ui.png[RHTPA Web UI]
520518

521519
[id="validate-sbom"]
522520
== Validating the SBOM
523521

524-
To verify the integrity and provenance of the SBOM file, specifically confirming that its signature originates from a trusted source and was securely generated, use the `ec` tool.
522+
To verify the integrity and provenance of the SBOM file, specifically confirming that its signature originates from a trusted source and was securely generated, use the `ec` tool. Beyond the verification of attestation and container signatures, Enterprise Contract (`ec`) offers additional capabilities for monitoring supply chain security. Comprehensive details are available within link:https://docs.redhat.com/en/documentation/red_hat_trusted_artifact_signer/1.3/html-single/deployment_guide/index#verifying-signatures-on-container-images-with-conforma-openshift_deploy[Red{nbsp}Hat Trusted Artifact Signer Deployment Guide].
523+
525524

526525
You can install the `ec` tool by directly downloading it from the `cli-server` pod.
527526

@@ -555,3 +554,8 @@ $ ec validate image \
555554
--rekor-url "${REKOR_URL}" \
556555
--show-successes
557556
----
557+
558+
[id="conclusion"]
559+
== Conclusion
560+
561+
This concludes our implementation of a Secure Supply Chain leveraging Red{nbsp}Hat Trusted Artifact Signer (RHTAS) and the Red{nbsp}Hat Trusted Profile Analyzer (RHTPA). We have demonstrated the complete process, which encompasses building an application from source code, generating a container image, cryptographically signing the resulting binaries, and subsequently verifying that these binaries have been signed by an authorized entity. Future work may focus on the automation of this process and its integration into a Continuous Integration/Continuous Delivery (CI/CD) solution.

0 commit comments

Comments
 (0)