Containers signing#
Messaging signer#
Messaging signer works as client which communicates with the server via messaging bus. User data to be signed are wrapped into signing requests and sent to the server. The server replies with signed requests which are composed from the original signing request and the JSON signature encrypted by gpg and base64 encoded. (See Atomic signature JSON data format).
Signature then needs to be uploaded to signature store. Tooling for that is not included in this project as it may vary depending on the signature store implementation.
Validation#
Signatures are served by sigstore via following api:
https://sigstore.com/<any-extra-path>/<container-image-name>@sha256=<container-image-digest>/signature-<N>
where N
is positive integer starting from 1.
Validation of the container image is shown in the following diagram
sequenceDiagram
autonumber
Client->>Registry: Pull a container image
Note left of Client: sets N to 1
loop
Client->>Sigstore: pull signature N from the signature store
alt Signature is valid according to validation policy
Note right of Client: Finished validation
else Signature is not valid
Note right of Client: increate N by 1 and continue the cycle
else No more signatures (404 returned)
Note right of Client: Validation failed, no valid signature found
end
end
Validation policy is defined in /etc/containers/policy.json
. To lean more about validation policies you
can check [https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md#policy-requirements].
Here's exapmle of policy.json set to validate signatures for registry.redhat.io
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports": {
"docker": {
"registry.redhat.io": [
{
"type": "signedBy",
"keyType": "GPGKeys",
"keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release",
"signedIdentity": {
"type": "matchRepoDigestOrExact"
}
}
]
},
"docker-daemon": {
"": [
{
"type": "insecureAcceptAnything"
}
]
}
}
}
/etc/containers/registries.d/
on client
machine.
Here's example of configuration file registry.redhat.io.yaml
:
docker:
registry.redhat.io:
sigstore: https://registry.redhat.io/containers/sigstore
sigstore
attribute is base url to the sigstore server as mentioned above https://sigstore.com/<any-extra-path>/
.
Example#
pubtools-sign-msg-container-sign \
--signing-key testing \
--config-file ~/.config/pubtools-sign/conf-hacbs.yaml \
--reference registry.redhat.io/ubi9/ubi:latest \
--digest sha256:1d15a69724bdf0fba6fda9baaf5f3e10e562324964d0c12664f4412f549b755d \
--task-id 32e729ee-62ae-4d17-b067-d86f6d89939f
Cosign signer#
Validation#
Validation of signatures signed by cosign can be done in two ways:
Cosign verify#
You can use cosign
binary to validate the signature. The command is as follows:
cosign verify <IMAGE>
Validation during podman/docker pull#
You can configure registry on the client machine to use use sigstore attachements. Here's example:
docker:
registry.redhat.io:
use-sigstore-attachments: true