From e51a45d0fa7e2870c7622e19f1fe545ab24aa644 Mon Sep 17 00:00:00 2001 From: Sascha Grunert Date: Tue, 13 Jun 2023 10:16:40 +0200 Subject: [PATCH] Add container image signature verification blog Signed-off-by: Sascha Grunert --- .../flow.mmd | 6 + .../flow.png | Bin 0 -> 71661 bytes .../index.md | 266 ++++++++++++++++++ 3 files changed, 272 insertions(+) create mode 100644 content/en/blog/_posts/2023-06-29-container-image-signature-verification/flow.mmd create mode 100644 content/en/blog/_posts/2023-06-29-container-image-signature-verification/flow.png create mode 100644 content/en/blog/_posts/2023-06-29-container-image-signature-verification/index.md diff --git a/content/en/blog/_posts/2023-06-29-container-image-signature-verification/flow.mmd b/content/en/blog/_posts/2023-06-29-container-image-signature-verification/flow.mmd new file mode 100644 index 0000000000..3d1a7514d8 --- /dev/null +++ b/content/en/blog/_posts/2023-06-29-container-image-signature-verification/flow.mmd @@ -0,0 +1,6 @@ +flowchart TD + A(Create Policy\ninstance) -->|annotate namespace\nto validate signatures| B(Create Pod) + B --> C[policy evaluation] + C --> D[fa:fa-check Admitted] + C --> E[fa:fa-xmark Not admitted] + D --> |if necessary| F[Image Pull] diff --git a/content/en/blog/_posts/2023-06-29-container-image-signature-verification/flow.png b/content/en/blog/_posts/2023-06-29-container-image-signature-verification/flow.png new file mode 100644 index 0000000000000000000000000000000000000000..1e4efc89294c54336007381c3650371a37839c60 GIT binary patch literal 71661 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%0DwoSuU=VC^)5o-PL+wI27+Hs9F{eH?Kl?T5Tzre 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 literal 0 HcmV?d00001 diff --git a/content/en/blog/_posts/2023-06-29-container-image-signature-verification/index.md b/content/en/blog/_posts/2023-06-29-container-image-signature-verification/index.md new file mode 100644 index 0000000000..98479a56fa --- /dev/null +++ b/content/en/blog/_posts/2023-06-29-container-image-signature-verification/index.md @@ -0,0 +1,266 @@ +--- +layout: blog +title: "Verifying container image signatures within CRI runtimes" +date: 2023-06-29 +slug: container-image-signature-verification +--- + +**Author**: Sascha Grunert + +The Kubernetes community has been signing their container image based artifacts +since release v1.24. While the graduation of the [corresponding enhancement][kep] +from `alpha` to `beta` in v1.26 introduced signatures for the binary artifacts, +other projects followed the approach by providing image signatures for their +releases, too. This means that they either create the signatures within their +own CI/CD pipelines, for example by using GitHub actions, or rely on the +Kubernetes [image promotion][promo] process to automatically sign the images by +proposing pull requests to the [k/k8s.io][k8s.io] repository. A requirement for +using this process is that the project is part of the `kubernetes` or +`kubernetes-sigs` GitHub organization, so that they can utilize the community +infrastructure for pushing images into staging buckets. + +[kep]: https://github.com/kubernetes/enhancements/issues/3031 +[promo]: https://github.com/kubernetes-sigs/promo-tools/blob/e2b96dd/docs/image-promotion.md +[k8s.io]: https://github.com/kubernetes/k8s.io/tree/4b95cc2/k8s.gcr.io + +Assuming that a project now produces signed container image artifacts, how can +one actually verify the signatures? It is possible to do it manually like +outlined in the [official Kubernetes documentation][docs]. The problem with that +approach is that it involves no automation at all and should be only done for +testing purposes. In production environments, tools like the [sigstore +policy-controller][policy-controller] can help with the automation. They +provide a higher level API by using [Custom Resource Definitions (CRD)][crd] as +well as an integrated [admission controller and webhook][admission] to verify +the signatures. + +[docs]: /docs/tasks/administer-cluster/verify-signed-artifacts/#verifying-image-signatures +[policy-controller]: https://docs.sigstore.dev/policy-controller/overview +[crd]: /docs/concepts/extend-kubernetes/api-extension/custom-resources +[admission]: /docs/reference/access-authn-authz/admission-controllers + +The general usage flow for an admission controller based verification is: + +![flow](flow.png "Admission controller flow") + +Key benefit of this architecture is simplicity: A single instance within the +cluster validates the signatures before any image pull can happen in the +container runtimes on the nodes, which gets initiated by the kubelet. This +benefit also incorporates the drawback of separation: The node which should pull +the container image is not necessarily the same which does the admission. This +means that if the controller is compromised, then a cluster-wide policy +enforcement could not be possible any more. + +One way to solve that issue is doing the policy evaluation directly within the +[Container Runtime Interface (CRI)][cri] compatible container runtime. The +runtime is directly connected to the [kubelet][kubelet] on a node and does all +the tasks like pulling images. [CRI-O][cri-o] is one of those available runtimes +and will feature full support for container image signature verification in the +upcoming v1.28 release. + +[cri]: /docs/concepts/architecture/cri +[kubelet]: /docs/reference/command-line-tools-reference/kubelet +[cri-o]: https://github.com/cri-o/cri-o + +How does it work? CRI-O reads a file called [`policy.json`][policy.json], which +contains all the rules defined for container images. For example, I can define a +policy which only allows signed images `quay.io/crio/signed` for any tag or +digest like this: + +[policy.json]: https://github.com/containers/image/blob/b3e0ba2/docs/containers-policy.json.5.md#sigstoresigned + +```json +{ + "default": [{ "type": "reject" }], + "transports": { + "docker": { + "quay.io/crio/signed": [ + { + "type": "sigstoreSigned", + "signedIdentity": { "type": "matchRepository" }, + "fulcio": { + "oidcIssuer": "https://github.com/login/oauth", + "subjectEmail": "sgrunert@redhat.com", + "caData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUI5ekNDQVh5Z0F3SUJBZ0lVQUxaTkFQRmR4SFB3amVEbG9Ed3lZQ2hBTy80d0NnWUlLb1pJemowRUF3TXcKS2pFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUkV3RHdZRFZRUURFd2h6YVdkemRHOXlaVEFlRncweQpNVEV3TURjeE16VTJOVGxhRncwek1URXdNRFV4TXpVMk5UaGFNQ294RlRBVEJnTlZCQW9UREhOcFozTjBiM0psCkxtUmxkakVSTUE4R0ExVUVBeE1JYzJsbmMzUnZjbVV3ZGpBUUJnY3Foa2pPUFFJQkJnVXJnUVFBSWdOaUFBVDcKWGVGVDRyYjNQUUd3UzRJYWp0TGszL09sbnBnYW5nYUJjbFlwc1lCcjVpKzR5bkIwN2NlYjNMUDBPSU9aZHhleApYNjljNWlWdXlKUlErSHowNXlpK1VGM3VCV0FsSHBpUzVzaDArSDJHSEU3U1hyazFFQzVtMVRyMTlMOWdnOTJqCll6QmhNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUlkKd0I1ZmtVV2xacWw2ekpDaGt5TFFLc1hGK2pBZkJnTlZIU01FR0RBV2dCUll3QjVma1VXbFpxbDZ6SkNoa3lMUQpLc1hGK2pBS0JnZ3Foa2pPUFFRREF3TnBBREJtQWpFQWoxbkhlWFpwKzEzTldCTmErRURzRFA4RzFXV2cxdENNCldQL1dIUHFwYVZvMGpoc3dlTkZaZ1NzMGVFN3dZSTRxQWpFQTJXQjlvdDk4c0lrb0YzdlpZZGQzL1Z0V0I1YjkKVE5NZWE3SXgvc3RKNVRmY0xMZUFCTEU0Qk5KT3NRNHZuQkhKCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" + }, + "rekorPublicKeyData": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFMkcyWSsydGFiZFRWNUJjR2lCSXgwYTlmQUZ3cgprQmJtTFNHdGtzNEwzcVg2eVlZMHp1ZkJuaEM4VXIvaXk1NUdoV1AvOUEvYlkyTGhDMzBNOStSWXR3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==" + } + ] + } + } +} +``` + +CRI-O has to be started to use that policy as global source of truth: + +```console +> sudo crio --log-level debug --signature-policy ./policy.json +``` + +CRI-O is now able to pull the image while verifying its signatures. This can be +done by using [`crictl` (cri-tools)][cri-tools], for example: + +[cri-tools]: https://github.com/kubernetes-sigs/cri-tools + +```console +> sudo crictl -D pull quay.io/crio/signed +DEBU[…] get image connection +DEBU[…] PullImageRequest: &PullImageRequest{Image:&ImageSpec{Image:quay.io/crio/signed,Annotations:map[string]string{},},Auth:nil,SandboxConfig:nil,} +DEBU[…] PullImageResponse: &PullImageResponse{ImageRef:quay.io/crio/signed@sha256:18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a,} +Image is up to date for quay.io/crio/signed@sha256:18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a +``` + +The CRI-O debug logs will also indicate that the signature got successfully +validated: + +```console +DEBU[…] IsRunningImageAllowed for image docker:quay.io/crio/signed:latest +DEBU[…] Using transport "docker" specific policy section quay.io/crio/signed +DEBU[…] Reading /var/lib/containers/sigstore/crio/signed@sha256=18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a/signature-1 +DEBU[…] Looking for sigstore attachments in quay.io/crio/signed:sha256-18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a.sig +DEBU[…] GET https://quay.io/v2/crio/signed/manifests/sha256-18b42e8ea347780f35d979a829affa178593a8e31d90644466396e1187a07f3a.sig +DEBU[…] Content-Type from manifest GET is "application/vnd.oci.image.manifest.v1+json" +DEBU[…] Found a sigstore attachment manifest with 1 layers +DEBU[…] Fetching sigstore attachment 1/1: sha256:8276724a208087e73ae5d9d6e8f872f67808c08b0acdfdc73019278807197c45 +DEBU[…] Downloading /v2/crio/signed/blobs/sha256:8276724a208087e73ae5d9d6e8f872f67808c08b0acdfdc73019278807197c45 +DEBU[…] GET https://quay.io/v2/crio/signed/blobs/sha256:8276724a208087e73ae5d9d6e8f872f67808c08b0acdfdc73019278807197c45 +DEBU[…] Requirement 0: allowed +DEBU[…] Overall: allowed +``` + +All of the defined fields like `oidcIssuer` and `subjectEmail` in the policy +have to match, while `fulcio.caData` and `rekorPublicKeyData` are the public +keys from the upstream [fulcio (OIDC PKI)][fulcio] and [rekor +(transparency log)][rekor] instances. + +[fulcio]: https://github.com/sigstore/fulcio +[rekor]: https://github.com/sigstore/rekor + +This means if I now invalidate the `subjectEmail` of the policy, for example to +`wrong@mail.com`: + +```console +> jq '.transports.docker."quay.io/crio/signed"[0].fulcio.subjectEmail = "wrong@mail.com"' policy.json > new-policy.json +> mv new-policy.json policy.json +``` + +Then removing the image, because it already exists locally: + +```console +> sudo crictl rmi quay.io/crio/signed +``` + +Now when pulling the image, CRI-O complains that the required email is wrong: + +```console +> sudo crictl pull quay.io/crio/signed +FATA[…] pulling image: rpc error: code = Unknown desc = Source image rejected: Required email wrong@mail.com not found (got []string{"sgrunert@redhat.com"}) +``` + +It is also possible to test an unsigned image against the policy. For that we +have to modify the key `quay.io/crio/signed` to something like +`quay.io/crio/unsigned`: + +```console +> sed -i 's;quay.io/crio/signed;quay.io/crio/unsigned;' policy.json +``` + +If I now pull the container image, CRI-O will complain that no signature exists +for it: + +```console +> sudo crictl pull quay.io/crio/unsigned +FATA[…] pulling image: rpc error: code = Unknown desc = SignatureValidationFailed: Source image rejected: A signature was required, but no signature exists +``` + +The error code `SignatureValidationFailed` got [recently added to +Kubernetes][pr-117717] and will be available from v1.28. This error code allows +end-users to understand image pull failures directly from the kubectl CLI. For +example, if I run CRI-O together with Kubernetes using the policy which requires +`quay.io/crio/unsigned` to be signed, then a pod definition like this: + +[pr-117717]: https://github.com/kubernetes/kubernetes/pull/117717 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: pod +spec: + containers: + - name: container + image: quay.io/crio/unsigned +``` + +Will cause the `SignatureValidationFailed` error when applying the pod manifest: + +```console +> kubectl apply -f pod.yaml +pod/pod created +``` + +```console +> kubectl get pods +NAME READY STATUS RESTARTS AGE +pod 0/1 SignatureValidationFailed 0 4s +``` + +```console +> kubectl describe pod pod | tail -n8 + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Scheduled 58s default-scheduler Successfully assigned default/pod to 127.0.0.1 + Normal BackOff 22s (x2 over 55s) kubelet Back-off pulling image "quay.io/crio/unsigned" + Warning Failed 22s (x2 over 55s) kubelet Error: ImagePullBackOff + Normal Pulling 9s (x3 over 58s) kubelet Pulling image "quay.io/crio/unsigned" + Warning Failed 6s (x3 over 55s) kubelet Failed to pull image "quay.io/crio/unsigned": SignatureValidationFailed: Source image rejected: A signature was required, but no signature exists + Warning Failed 6s (x3 over 55s) kubelet Error: SignatureValidationFailed +``` + +This overall behavior provides a more Kubernetes native experience and does not +rely on third party software to be installed in the cluster. + +There are still a few corner cases to consider: For example, what if we want to +allow policies per namespace in the same way the policy-controller supports it? +Well, there is an upcoming CRI-O feature in v1.28 for that! CRI-O will support +the `--signature-policy-dir` / `signature_policy_dir` option, which defines the +root path for pod namespace-separated signature policies. This means that CRI-O +will lookup that path and assemble a policy like `/.json`, +which will be used on image pull if existing. If no pod namespace is being +provided on image pull ([via the sandbox config][sandbox-config]), or the +concatenated path is non-existent, then CRI-O's global policy will be used as +fallback. + +[sandbox-config]: https://github.com/kubernetes/cri-api/blob/e5515a5/pkg/apis/runtime/v1/api.proto#L1448 + +Another corner case to consider is cricital for the correct signature +verification within container runtimes: The kubelet only invokes container image +pulls if the image does not already exist on disk. This means, that a +unrestricted policy from Kubernetes namespace A can allow pulling an image, +while namespace B is not able to enforce the policy because it already exits on +the node. Finally, CRI-O has to verify the policy not only on image pull, but +also on container creation. This fact makes things even a bit more complicated, +because the CRI does not really pass down the user specified image reference on +container creation, but more an already resolved iamge ID or digest. A [small +change to the CRI][pr-118652] can help with that. + +[pr-118652]: https://github.com/kubernetes/kubernetes/pull/118652 + +Now that everything happens within the container runtime, someone has to +maintain and define the policies to provide a good user experience around that +feature. The CRDs of the policy-controller are great, while I could imagine that +a daemon within the cluster can write the policies for CRI-O per namespace. This +would make any additional hook obsolete and moves the responsibility of +verifying the image signature to the actual instance which pulls the image. [I +was evaluating][thread] other possible paths towards a better container image +signature verification within plain Kubernetes, but I could not find a great fit +for a native API. This means that I believe that a CRD is the way to go, but we +still need an instance which actually serves it. + +[thread]: https://groups.google.com/g/kubernetes-sig-node/c/kgpxqcsJ7Vc/m/7X7t_ElsAgAJ + +Thank you for reading this blog post! If you're interested in more, providing +feedback or asking for help, then feel free to get in touch with us directly via +[Slack (#crio)][slack] or the [SIG node mailing list][mail]. + +[slack]: https://kubernetes.slack.com/messages/crio +[mail]: https://groups.google.com/forum/#!forum/kubernetes-sig-node