Configure and test kritis-validation-hook in a Container Service for Kubernetes (ACK) cluster to block unsigned container images at admission time, allowing only images signed by a trusted authority and reducing the risk of unexpected or malicious code.
Prerequisites
You have an ACK managed cluster or ACK dedicated cluster (Discontinued).
Background
kritis-validation-hook is built on the open source kritis software, with deep integration with Container Registry (ACR) and support for verifying container images signed with Key Management Service (KMS). Through collaboration with Security Center, KMS, and ACR, it fully automates image signing and verification for a more secure cluster runtime environment.
See Verify container image signatures with kritis-validation-hook.
Configure resource access permissions
Ensure the RAM role used by the cluster has the following permissions:
"cr:ListInstance",
"cr:ListMetadataOccurrences"For ACK managed clusters, grant these permissions to the Worker RAM role. For ACK dedicated clusters, grant them to the Master RAM role and the Worker RAM role.
Add missing permissions as follows.
Create a custom policy with the following content:
{ "Statement": [ { "Action": [ "cr:ListInstance", "cr:ListMetadataOccurrences" ], "Effect": "Allow", "Resource": "*" } ], "Version": "1" }Grant the policy to the cluster Worker RAM role.
For ACK dedicated clusters, also grant the policy to the Master RAM role.
Enable image signature verification
This example configures image signature verification for the default namespace. Image signing is outside the scope of kritis-validation-hook — this example assumes images are already signed. See Use container image signing for signing steps.
The example uses this signing information. Replace the sample values with actual values.
Signing information | Example value | How to get | YAML field |
KMS public key (Base64) |
|
| |
KMS key ID |
|
| |
Witness name |
|
| |
Signed image |
| — | — |
Declare the trusted authority
Create AttestationAuthority.yaml with the following content:
apiVersion: kritis.grafeas.io/v1beta1
kind: AttestationAuthority
metadata:
name: demo-aa
spec:
noteReference: namespaces/demo-aa
publicKeyData: LS0tLS1CRUdJTiBQ***
publicKeyId: key-4a2ef103-5aa3-4220-****Apply the resource.
kubectl apply -f AttestationAuthority.yamlCreate a signature verification policy
Create GenericAttestationPolicy.yaml with the following content. The policy references the AttestationAuthority from the previous step.
apiVersion: kritis.grafeas.io/v1beta1
kind: GenericAttestationPolicy
metadata:
name: demo-gap
spec:
attestationAuthorityNames:
- demo-aaApply the resource.
kubectl apply -f GenericAttestationPolicy.yamlTest with an unsigned image
Deploy an unsigned image.
kubectl create deployment test-denied --image=anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6Expected output:
error: failed to create deployment: admission webhook "kritis-validation-hook-deployments.grafeas.io" denied the request: "ACROpenAPIError detail: <image anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 is not attested because of get resource url for anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6: ListInstance failed, instanceName: "anolis", regionId: "cn-zhangjiakou", requstURL:error:****The admission webhook denies the deployment because the image lacks a valid attestation from demo-aa.
Test with a signed image
Deploy a signed image. Replace the image address with the actual signed image address.
kubectl create deployment test-allow --image=kritis-demo***.cn-hangzhou.cr.aliyuncs.com/kritis-demo***/alpine@sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45Expected output:
deployment.apps/test-allow createdThe deployment succeeds because the image is attested by the trusted authority demo-aa.
Configure an image signature verification allowlist
By default, kritis-validation-hook verifies every container image in its enforcement scope. In middleware or service mesh environments, sidecars injected by third-party add-ons may be unsigned, causing pod creation to fail. Configure an allowlist to skip signature verification for specific images.
Define an admissionallowlists.kritis.grafeas.io resource to specify images that bypass verification.
apiVersion: kritis.grafeas.io/v1beta1 # Default value. Do not modify.
kind: AdmissionAllowlist # Default value. Do not modify.
metadata:
name: kritis-allowlist # Must be unique within the cluster.
spec:
patterns: # Define one or more allowlist entries.
- namePattern: 'registry*.*.aliyuncs.com/acs/*'
- namePattern: 'registry-vpc.cn-beijing.aliyuncs.com/arms-docker-repo/*'
namespace: 'default' # Optional. If omitted, the entry applies to all namespaces.namePattern matching rules
Each namePattern value matches the full image reference, including registry host, repository path, and tag or digest. These matching rules apply:
Rule | Description | Example |
Exact match | A value without |
|
Trailing | Matches any character except |
|
Mid-string | Matches letters, digits, hyphens ( |
|
Add ACK system images to the allowlist
Create
kritis-admission-allowlist-acs.yamlwith the following content:apiVersion: kritis.grafeas.io/v1beta1 kind: AdmissionAllowlist metadata: name: allow-acs-images spec: patterns: - namePattern: 'registry*.*.aliyuncs.com/acs/*' - namePattern: 'registry-*.ack.aliyuncs.com/acs/*'Common allowlist patterns:
# Images used by ACK - namePattern: 'registry*.*.aliyuncs.com/acs/*' - namePattern: 'registry-*.ack.aliyuncs.com/acs/*' # Images used by ACK (China regions only) - namePattern: 'registry*.cn-*.aliyuncs.com/acs/*' - namePattern: 'registry-cn-*.ack.aliyuncs.com/acs/*' # Images used by ARMS - namePattern: 'registry*.*.aliyuncs.com/arms-docker-repo/*' # Images used by ARMS (China regions only) - namePattern: 'registry*.cn-*.aliyuncs.com/arms-docker-repo/*'Apply the allowlist.
kubectl apply -f kritis-admission-allowlist-acs.yamlExpected output:
admissionallowlist.kritis.grafeas.io/allow-acs-images createdVerify the allowlist:
kubectl get admissionallowlists.kritis.grafeas.ioExpected output:
NAME AGE allow-acs-images 2m22s