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, and oc binary files installed.

Procedure

  1. Log in to your OpenShift cluster:

    Syntax

    oc login --token=TOKEN --server=SERVER_URL_AND_PORT

    Example

    oc login --token=sha256~ZvFDBvoIYAbVECixS4-WmkN4RfnNd8Neh3y1WuiFPXC --server=https://example.com:6443

    Note

    To 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.

  2. Log in to RHTAS. Make sure to configure your RHTAS shell environment to sign and verify container images; for example:

    Copy to Clipboard Toggle word wrap
    cd sigstore-ocp
    source tas-env-variables.sh

    You also have the option to set the environment variables manually; for example:

    Copy to Clipboard Toggle word wrap
    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_SUBDOMAIN

    Example

    Copy to Clipboard Toggle word wrap
    $ source ./tas-env-vars.sh

  3. Log out of your OpenShift cluster by running this command: oc logout.
  4. Identify the container image you want to sign and attest; for example: IMAGE=quay.io/lucarval/rhtas-test@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359.
  5. 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.
  6. Sign your container image with the following command:

    Copy to Clipboard Toggle word wrap
    cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL \
         --oidc-issuer=$OIDC_ISSUER_URL $IMAGE
  7. 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:

  1. Create a SLSA provenance attestation and associate it with your container image.
  2. Validate your container image with the Red Hat Enterprise Contract.

Additional resources

4.1. Generating a signing key to sign and attest a container image

You must have a signing key before you can sign and attest a container image.

Prerequisites

  • A workstation with the cosign binary files installed.

Procedure

  1. In your CLI, run this command: cosign generate-key-pair.
  2. 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.pub file and a cosign.key file.

    • The cosign.pub file contains your public signing key. You can share this key with any collaborator who needs to validate the container image.
    • The cosign.key file is your private key for signing content. Only the person responsible for signing and attesting images should have access to the cosign.key file.

4.2. Validating container image signatures with Enterprise Contract and Red Hat Trusted Artifact Signer

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 cosign and oc binary files installed.

Procedure

  1. Download the ec binary file from the OpenShift cluster:

    1. Log in to the OpenShift web console. From the home page, click the ? icon in the upper right, then select Command Line Tools.
    2. From the ec download section, click the link for your platform.
    3. Open a terminal, decompress the .gz file, and set the execute bit on the ec binary file:

      Examples for Linux and macOS

      • $ gunzip ec-amd64.gz
      • $ chmod +x ec-amd64
    4. Move the ec binary file to a directory within your $PATH environment:

      Example

      $ sudo mv ec-amd64 /usr/local/bin/ec

Tip

Run the ec validate image --help command to see all the image validation command options.

  1. Configure your shell environment for container image signing and verification.

    1. Open a terminal and run the tas-env-variables.sh script from the sigstore-ocp directory:

      Example

      Copy to Clipboard Toggle word wrap
      cd sigstore-ocp
      source tas-env-variables.sh

    2. (Optional) Set the environment variables manually:

      Example

      Copy to Clipboard Toggle word wrap
      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_SUBDOMAIN

      Example

      $ source ./tas-env-vars.sh

  2. Initialize The Update Framework (TUF) system:

    Example

    cosign initialize --mirror=$TUF_URL --root=$TUF_URL/root.json

  3. Sign your container image:

    Syntax

    cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL --oidc-issuer=$OIDC_ISSUER_URL IMAGE_NAME

    Example

    cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL --oidc-issuer=$OIDC_ISSUER_URL example-hello-world@sha256:2788a47fd0ef1ece30898c1e608050ea71036d3329b9772dbb3d1f69313f745c

    In the web browser that opens, sign the container image with an email address.

  4. Create a predicate.json file:

    Example

    Copy to Clipboard Toggle word wrap
    {
      "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": []
    }

  5. Associate the predicate.json file with your container image:

    Syntax

    Copy to Clipboard Toggle word wrap
    cosign attest -y --predicate ./predicate.json \
    --type slsaprovenance IMAGE_NAME:TAG

    Example

    Copy to Clipboard Toggle word wrap
    $ cosign attest -y --predicate ./predicate.json \
    --type slsaprovenance example.io/hello-world:latest

  6. Verify that the container image has at least one attestation and signature:

    Syntax

    cosign tree IMAGE_NAME:TAG

    Example

    Copy to Clipboard Toggle word wrap
    $ 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:f32171250715d4538aec33adc40fac2343f5092631d4fc2457e2116a489387b7

  7. Verify the container image with Enterprise Contract:

    Syntax

    Copy to Clipboard Toggle word wrap
    ec validate image --image IMAGE_NAME:TAG \
    --certificate-identity-regexp 'SIGNER_EMAIL_ADDR' \
    --certificate-oidc-issuer-regexp 'keycloak-keycloak-system' \
    --output yaml --show-successes

    Example

    Copy to Clipboard Toggle word wrap
    $ 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: true

    Enterprise Contract generates a pass/fail report with details about any security violations. When you add the --info flag, the report includes more details and possible solutions for any violations.

Additional resources

Back to top
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2025 Red Hat, Inc.