All Products
Search
Document Center

Container Service for Kubernetes:Use kritis-validation-hook to automatically verify container image signatures

Last Updated:Mar 26, 2026

Use kritis-validation-hook with Container Registry, Key Management Service (KMS), and Security Center to enforce image signature verification at deploy time. Only images signed by trusted authorities are admitted to the cluster, reducing the risk of running tampered or unauthorized container images.

How it works

Four services work together to deliver end-to-end image signing and verification:

ServiceRole
KMSGenerates and stores the RSA key pair used to sign images
Security CenterManages witnesses (signing authorities) and security policies that bind a witness to a cluster namespace
Container RegistryAutomatically signs images pushed to enabled namespaces using the KMS key via the configured witness
kritis-validation-hookRuns as an admission webhook in your ACK cluster and blocks unsigned or unattested images from being deployed

When signature verification is active, any kubectl deployment request for an unsigned image is denied before the pod is scheduled.

Prerequisites

Before you begin, ensure that you have:

  • An ACK cluster with cluster authorization configured. For details, see Authorize a cluster to access resources

  • An Alibaba Cloud Container Registry (ACR) Enterprise Edition instance with Instance Type set to Advanced. To create one, click Create ACR EE in the Container Registry console and select Advanced

  • Images referenced by digest (format: image@sha256:<hash>). Images referenced by tag are blocked even if signed

Step 1: Install kritis-validation-hook

  1. Log on to the ACK console. In the left-side navigation pane, click Clusters.

  2. On the Clusters page, find the cluster you want to manage and click its name. In the left-side navigation pane, choose Operations > Add-ons.

  3. On the Add-ons page, click the Security tab, find kritis-validation-hook, and click Install.

Step 2: Create a signing key in KMS

Create a Customer Master Key (CMK) in KMS to use for image signing. For instructions, see Manage a key.

Important

Set Key Spec to RSA_2048 and Purpose to Sign/Verify. Other key specs or purposes are not supported for image signing.

Step 3: Create a witness in Security Center

A witness represents a trusted signing authority. Security policies reference witnesses to determine which images are trusted in a given namespace.

  1. Log on to the Security Center consoleSecurity Center console. In the top navigation bar, select the region of the asset you want to manage. Supported regions: China and Outside China.

  2. In the left-side navigation pane, choose Protection Configuration > Container Protection > Container Signature.

  3. On the Witness tab, click Create a witness, configure the parameters, and click OK.

ParameterDescription
WitnessA name that identifies this signing authority. Security policies reference this name to enable signature verification for a cluster namespace.
Select a certificateSelect the KMS CMK you created in Step 2.
DescriptionAn optional description of the witness.

Step 4: Enable image signing in Container Registry

  1. Log on to the Container Registry console. In the top navigation bar, select a region.

  2. In the left-side navigation pane, click Instances.

  3. On the Instances page, find your ACR Enterprise Edition instance and click its name or click Manage.

  4. In the left-side navigation pane, choose Repository > Namespaces. Create a namespace and enable image signing for it. For details, see Manage namespaces.

  5. Enable image signing for the namespace:

    1. In the left-side navigation pane, choose Security and Trust > Image Signature.

    2. On the Image Signature tab, click Create a signature rule. When configuring the rule, select the witness you created in Step 3. For details, see Configure a signature rule for automatic image signing.

Step 5: Enable signature verification in Security Center

Create a security policy to bind the witness to a cluster namespace. Once the policy is enabled, kritis-validation-hook enforces signature verification for all deployments in that namespace.

  1. Log on to the Security Center consoleSecurity Center console.

  2. In the left-side navigation pane, choose Protection Configuration > Container Protection > Container Signature.

  3. On the Security Policy tab, click Add Policy, configure the parameters, and click OK.

ParameterDescription
Policy NameA name for the security policy.
WitnessSelect the witness you created in Step 3.
Application ClusterSelect the cluster group, then select the Cluster Namespace to protect.
Policy EnabledTurn on the switch. The policy is disabled by default and takes effect only after you enable it.
NoteAn optional description of the policy.

Verify signature enforcement

kritis-validation-hook only supports images specified by digest. Images specified by tag are always rejected.

Run the following commands to confirm that signature verification is working.

Test 1: Deploy an unsigned image by tag — expected to be rejected

kubectl -n default create deployment not-sign --image=alpine:3.11 -- sleep 10

Expected output:

Error from server: admission webhook "kritis-validation-hook-deployments.grafeas.io" denied the request: image alpine:3.11 is not attested

Test 2: Deploy an unsigned image by digest — expected to be rejected

kubectl -n default create deployment not-sign --image=alpine@sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45 -- sleep 10

Expected output:

Error from server: admission webhook "kritis-validation-hook-deployments.grafeas.io" denied the request: image alpine@sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45 is not attested

Test 3: Push an image to the signing-enabled namespace, then deploy by digest — expected to succeed

Push the image to trigger automatic signing:

docker push kritis-demo***.cn-hongkong.cr.aliyuncs.com/kritis-demo***/alpine:3.11

Expected output (the digest is recorded after signing):

The push refers to repository [kritis-demo***.cn-hongkong.cr.aliyuncs.com/kritis-demo***/alpine]
5216338b40a7: Pushed
3.11: digest: sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45 size: 528

Deploy using the digest from the push output:

kubectl -n default create deployment is-signed --image=kritis-demo***.cn-hongkong.cr.aliyuncs.com/kritis-demo***/alpine@sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45 -- sleep 10

Expected output:

deployment.apps/is-signed created

Signature verification is working correctly. Unsigned images are blocked, and signed images referenced by digest are admitted.

What's next