Verifying image signing for Red Hat Container Registry

Updated -

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

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

RHEL-8:

# sudo podman image trust set -f /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release registry.access.redhat.com
# sudo 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:

  1. Adds a section to the /etc/containers/policy.json file. Here is the section they added:
        "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
  1. And the registry.redhat.io.yaml file:
        docker:
          registry.redhat.io:
            sigstore: https://registry.redhat.io/containers/sigstore

Display Trust Configuration

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

RHEL-8

# 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

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