Chapter 4. Signing a container image
Prerequisites
- Access to the OpenShift web console.
- A working Red Hat Trusted Artifact Signer (RHTAS) installation running on OpenShift version 4.13 or later.
-
A workstation with the
ec,cosign, andocbinary files installed.
Procedure
Log in to your OpenShift cluster:
Syntax
oc login --token=TOKEN --server=SERVER_URL_AND_PORTExample
oc login --token=sha256~ZvFDBvoIYAbVECixS4-WmkN4RfnNd8Neh3y1WuiFPXC --server=https://example.com:6443NoteTo find your command line login token and URL, log in to the OpenShift web console. Click your user name, then click Copy login command. If prompted, enter your user name and password again, then click Display Token.
Log in to RHTAS. Make sure to configure your RHTAS shell environment to sign and verify container images; for example:
cd sigstore-ocp source tas-env-variables.shYou also have the option to set the environment variables manually; for example:
export OPENSHIFT_APPS_SUBDOMAIN=apps.$(oc get dns cluster -o jsonpath='{ .spec.baseDomain }') export OIDC_AUTHENTICATION_REALM=sigstore export FULCIO_URL=https://fulcio.$OPENSHIFT_APPS_SUBDOMAIN export OIDC_ISSUER_URL=https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/$OIDC_AUTHENTICATION_REALM export REKOR_URL=https://rekor.$OPENSHIFT_APPS_SUBDOMAIN export TUF_URL=https://tuf.$OPENSHIFT_APPS_SUBDOMAINExample
$ source ./tas-env-vars.sh-
Log out of your OpenShift cluster by running this command:
oc logout. -
Identify the container image you want to sign and attest; for example:
IMAGE=quay.io/lucarval/rhtas-test@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359. -
Indicate to RHTAP that you want to sign and attest your container image with Red Hat Trusted Artifact Signer instead of the public Sigstore deployment. Enter this command:
cosign initialize --mirror=$TUF_URL --root=$TUF_URL/root.json. Sign your container image with the following command:
cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL \ --oidc-issuer=$OIDC_ISSUER_URL $IMAGE- When prompted, log in to the Keycloak instance that RHTAP installed when you installed RHTAS. This is so Keycloak can authenticate you.
Next steps
Your image is now signed. Now you can:
- Create a SLSA provenance attestation and associate it with your container image.
- Validate your container image with the Red Hat Enterprise Contract.
4.1. Generating a signing key to sign and attest a container image Copy linkLink copied to clipboard!
You must have a signing key before you can sign and attest a container image.
Prerequisites
-
A workstation with the
cosignbinary files installed.
Procedure
-
In your CLI, run this command:
cosign generate-key-pair. - When prompted, enter a new password for the key-pair. Make sure your password is memorable and strong.
Verification
You should now have two new files in your working directory: a
cosign.pubfile and acosign.keyfile.-
The
cosign.pubfile contains your public signing key. You can share this key with any collaborator who needs to validate the container image. -
The
cosign.keyfile is your private key for signing content. Only the person responsible for signing and attesting images should have access to thecosign.keyfile.
-
The
4.2. Validating container image signatures with Enterprise Contract and Red Hat Trusted Artifact Signer Copy linkLink copied to clipboard!
When you install the Red Hat Trusted Artifact Signer (RHTAS) service, you can use the ec binary file to validate the attestation and signature of container images that use the RHTAS service’s keyless signing framework. For more information about installing RHTAS, see Installing Red Hat Trusted Artifact Signer using the Operator Lifecycle Manager.
Prerequisites
- A working RHTAS installation running on OpenShift version 4.13 or later.
- Access to the OpenShift web console.
-
A workstation with the
cosignandocbinary files installed.
Procedure
Download the
ecbinary file from the OpenShift cluster:- Log in to the OpenShift web console. From the home page, click the ? icon in the upper right, then select Command Line Tools.
- From the ec download section, click the link for your platform.
Open a terminal, decompress the
.gzfile, and set the execute bit on theecbinary file:Examples for Linux and macOS
-
$ gunzip ec-amd64.gz -
$ chmod +x ec-amd64
-
Move the
ecbinary file to a directory within your$PATHenvironment:Example
$ sudo mv ec-amd64 /usr/local/bin/ec
Run the ec validate image --help command to see all the image validation command options.
Configure your shell environment for container image signing and verification.
Open a terminal and run the
tas-env-variables.shscript from thesigstore-ocpdirectory:Example
cd sigstore-ocp source tas-env-variables.sh(Optional) Set the environment variables manually:
Example
export OPENSHIFT_APPS_SUBDOMAIN=apps.$(oc get dns cluster -o jsonpath='{ .spec.baseDomain }') export OIDC_AUTHENTICATION_REALM=sigstore export FULCIO_URL=https://fulcio.$OPENSHIFT_APPS_SUBDOMAIN export OIDC_ISSUER_URL=https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/$OIDC_AUTHENTICATION_REALM export REKOR_URL=https://rekor.$OPENSHIFT_APPS_SUBDOMAIN export TUF_URL=https://tuf.$OPENSHIFT_APPS_SUBDOMAINExample
$ source ./tas-env-vars.sh
Initialize The Update Framework (TUF) system:
Example
cosign initialize --mirror=$TUF_URL --root=$TUF_URL/root.jsonSign your container image:
Syntax
cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL --oidc-issuer=$OIDC_ISSUER_URL IMAGE_NAMEExample
cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL --oidc-issuer=$OIDC_ISSUER_URL example-hello-world@sha256:2788a47fd0ef1ece30898c1e608050ea71036d3329b9772dbb3d1f69313f745cIn the web browser that opens, sign the container image with an email address.
Create a
predicate.jsonfile:Example
{ "builder": { "id": "https://localhost/dummy-id" }, "buildType": "https://example.com/tekton-pipeline", "invocation": {}, "buildConfig": {}, "metadata": { "completeness": { "parameters": false, "environment": false, "materials": false }, "reproducible": false }, "materials": [] }Associate the
predicate.jsonfile with your container image:Syntax
cosign attest -y --predicate ./predicate.json \ --type slsaprovenance IMAGE_NAME:TAGExample
$ cosign attest -y --predicate ./predicate.json \ --type slsaprovenance example.io/hello-world:latestVerify that the container image has at least one attestation and signature:
Syntax
cosign tree IMAGE_NAME:TAGExample
$ cosign tree example.io/hello-world:latest 📦 Supply Chain Security Related artifacts for an image: example.io/hello-world@sha256:7de5fa822a9d1e507c36565ee0cf50c08faa64505461c844a3ce3944d23efa35 └── 💾 Attestations for an image tag: example.io/hello-world:sha256-7de5fa822a9d1e507c36565ee0cf50c08faa64505461c844a3ce3944d23efa35.att └── 🍒 sha256:40d94d96a6d3ab3d94b429881e1b470ae9a3cac55a3ec874051bdecd9da06c2e └── 🔐 Signatures for an image tag: example.io/hello-world:sha256-7de5fa822a9d1e507c36565ee0cf50c08faa64505461c844a3ce3944d23efa35.sig └── 🍒 sha256:f32171250715d4538aec33adc40fac2343f5092631d4fc2457e2116a489387b7Verify the container image with Enterprise Contract:
Syntax
ec validate image --image IMAGE_NAME:TAG \ --certificate-identity-regexp 'SIGNER_EMAIL_ADDR' \ --certificate-oidc-issuer-regexp 'keycloak-keycloak-system' \ --output yaml --show-successesExample
$ ec validate image --image example.io/hello-world:latest \ --certificate-identity 'jdoe@example.com' \ --certificate-oidc-issuer 'keycloak-keycloak-system' \ --output yaml --show-successes success: true successes: - metadata: code: builtin.attestation.signature_check msg: Pass - metadata: code: builtin.attestation.syntax_check msg: Pass - metadata: code: builtin.image.signature_check msg: Pass ec-version: v0.1.2427-499ef12 effective-time: "2024-01-21T19:57:51.338191Z" key: "" policy: {} success: trueEnterprise Contract generates a pass/fail report with details about any security violations. When you add the
--infoflag, the report includes more details and possible solutions for any violations.