Verifying image signing for Red Hat Container Registry

Updated -

Disclaimer: Links contained herein to external website(s) are provided for convenience only. Red Hat has not reviewed the links and is not responsible for the content or its availability. The inclusion of any link to an external website does not imply endorsement by Red Hat of the website or their entities, products or services. You agree that Red Hat is not responsible or liable for any loss or expenses that may result due to your use of (or reliance on) the external site or content.

Overview

Red Hat delivers signatures for the images in the Red Hat Container Registry. The files /etc/containers/policy.json, and yaml files under the /etc/containers/registry.d/ directory define the signature verification policy.

Defining trust

Trust is defined using three parameters:

  1. The registry or registry/repository name
  2. One or more public GPG keys. Here we're using the Red Hat release public key that is also used to verify RPMs.
  3. A signature server. Red Hat serves signatures from these URI:

    https://access.redhat.com/webassets/docker/content/sigstore
    https://registry.redhat.io/containers/sigstore
    

Enabling signature verification

Note: For verifying Red Hat container images mirrored in custom registries, refer to Unable to verify UBI GPG signatures when the images are pulled from a local registry.

Here are the commands to enable signature verification when container images are pulled to a host system:

RHEL 8 & 9:

# podman image trust set -f /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release registry.access.redhat.com
# podman image trust set -f /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release registry.redhat.io
# cat << EOF > /etc/containers/registries.d/registry.access.redhat.com.yaml
docker:
     registry.access.redhat.com:
         sigstore: https://access.redhat.com/webassets/docker/content/sigstore
EOF
# cat << EOF > /etc/containers/registries.d/registry.redhat.io.yaml
docker:
     registry.redhat.io:
         sigstore: https://registry.redhat.io/containers/sigstore
EOF

RHEL 7:

# atomic trust add \
    --pubkeys /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \
    --sigstore https://access.redhat.com/webassets/docker/content/sigstore \
    registry.access.redhat.com
# atomic trust add \
    --pubkeys /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \
    --sigstore https://registry.redhat.io/containers/sigstore \
    registry.redhat.io

Verifying configuration

Let's take a look at the files the commands modify:

RHEL 8 & 9:

  1. Adds a section to the /etc/containers/policy.json file. Here is the section which was created:

        "docker": {
            "registry.access.redhat.com": [
                {
                    "type": "signedBy",
                    "keyType": "GPGKeys",
                    "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                }
            ],
            "registry.redhat.io": [
                {
                    "type": "signedBy",
                    "keyType": "GPGKeys",
                    "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                }
            ]
        },
    

RHEL 7

  1. Adds a section to the /etc/containers/policy.json file. Here is the section they added:

                "docker": {
                    "registry.access.redhat.com": [
                        {
                            "keyType": "GPGKeys",
                            "type": "signedBy",
                            "keyData": "VGhlIGZvbGxvd2luZyBw...BQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCg=="
                        }
                    ],
                    "registry.redhat.io": [
                        {
                            "keyType": "GPGKeys",
                            "type": "signedBy",
                            "keyData": "VGhlIGZvbGxvd2luZyBw...BQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCg=="
                        }
                    ]
                }
    
  2. Adds signature server files in directory /etc/containers/registries.d/. Filenames are arbitrary but they must end in .yaml. Here is the contents of the file registry.access.redhat.com.yaml:

        docker:
          registry.access.redhat.com:
            sigstore: https://access.redhat.com/webassets/docker/content/sigstore
    
  3. And the registry.redhat.io.yaml file:

        docker:
          registry.redhat.io:
            sigstore: https://registry.redhat.io/containers/sigstore
    

Display Trust Configuration

Trust configuration is dynamic so no service restart is required. The trust configuration may be displayed with this command:

RHEL 8 & 9

# podman image trust show
                             insecureAcceptAnything                                             
default                      accept                                                             
registry.access.redhat.com   signedBy                 security@redhat.com,security@redhat.com   https://access.redhat.com/webassets/docker/content/sigstore
registry.redhat.io           signedBy                 security@redhat.com,security@redhat.com   https://registry.redhat.io/containers/sigstore

RHEL 7

# atomic trust show
* (default)                         accept
registry.access.redhat.com          signed security@redhat.com,security@redhat.com

Notes:
For robust security the default trust policy should be set to reject by default using:

$ podman image trust set -t reject default

For more details on configuring trust policies in RHEL-8 see the man 5 policy.json file and the upstream containers-registry.d documents.

Read more about simple signing implemented by the Red Hat container registries here
To enable signature-verification in docker-latest, see this bugzilla.
For more on docker-latest see this article

Comments