kritis-validation-hook is a key component that is used to verify the signatures of
container images. You can use signature verification to ensure that only images signed
by trusted authorities are deployed. This reduces the risk of malicious code execution.
This topic provides examples on how kritis-validation-hook is used to verify signatures.
Background information
kritis-validation-hook is developed based on the open source project kritis and is integrated with Container Registry. You can use kritis-validation-hook to verify the signatures of images that are signed
by Key Management Service (KMS). You can also use kritis-validation-hook together with Security Center, KMS, and Container Registry to automate image signing and signature verification.
This helps you build a secure environment for clusters. For more information about
how to enable automatic signature verification for container images, see Use kritis-validation-hook to automatically verify the signatures of container images.
Authorize a cluster to access resources
To ensure that kritis-validation-hook works as normal, you must grant the following
permissions to the Resource Access Management (RAM) role of the cluster:
Notice
- If you use an ACK managed cluster, you must grant the following permissions to the
worker RAM role of the cluster.
- If you use an ACK dedicated cluster, you must grant the following permissions to the
master RAM role and the worker RAM role of the cluster.
"cr:ListInstance",
"cr:ListMetadataOccurrences"
If you want to grant the preceding permissions to the RAM role of your cluster, perform
the following steps:
- Log on to the ACK console and click Clusters in the left-side navigation pane.
- On the Clusters page, click the name of a cluster and click Cluster Information in the left-side navigation pane.
- On the Cluster Information page, click the Cluster Resources tab and find the RAM role of the cluster.
- If the cluster is an ACK managed cluster, click the name of the RAM role to the right
of the Worker RAM Role field.
- If the cluster is an ACK dedicated cluster, you must click the name of the RAM role
to the right of Master RAM Role and also the name of the RAM role to the right of Worker RAM Role.
- On the RAM role details page, click the Permissions tab, and then click k8s******RolePolicy-**** in the Policy column.
- On the policy details page, click the Policy Document tab, and then click Modify Policy Document.
- In the editor, add the following content and click Next: Edit Basic Information. Then, click OK.
{
"Action": [
"cr:ListInstance",
"cr:ListMetadataOccurrences"
],
"Resource": [
"*"
],
"Effect": "Allow"
}
Configure the RAM permissions required by kritis-validation-hook in ASK clusters
A serverless Kubernetes (ASK) cluster does not have a master RAM role or worker RAM
role. To configure the RAM permissions that are required by kritis-validation-hook
in an ASK cluster, you must use the RAM Roles for Service Accounts (RRSA) feature.
For more information, see Use RRSA to authorize pods to access different cloud services.
You can use ack-ram-tool to configure RRSA-related configurations that are required
by kritis-validation-hook. For more information, see ack-ram-tool. Perform the following operations:
Note Replace <clusterId>
with the ID of the cluster that you want to manage.
- Run the following command to enable the RRSA feature for the cluster:
ack-ram-tool rrsa enable -c <clusterId>
- Run the following command to configure the RAM permissions that are required by kritis-validation-hook:
ack-ram-tool rrsa setup-addon -a kritis-validation-hook -c <clusterId>
Example on how to enable signature verification
The following example demonstrates how kritis-validation-hook is used to enable signature
verification for the
default namespace.
Note This example does not include further details about image signing because you cannot
use kritis-validation-hook to sign images. For more information, see
Sign container images. The following information specifies the address of the image that is signed in this
example. Replace it with the address of the image that you want to use.
- The signed image:
kritis-demo-registry.cn-hangzhou.cr.aliyuncs.com/kritis-demo/alpine@sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45
.
If no immutable tag is added to the image, you must specify the image by using the
digest of the image. For more information, see Configure a repository to be immutable.
- The witness name (image signature key) that is used to sign the image: demo-aa.
- Run the
cat publickey.txt | base64 | tr -d '\n'
command to generate a public key that is encoded by using Base64: LS0tLS1CRUdJTiBQ***
.
The public key that corresponds to the KMS key is stored in the publickey.txt file.
- The ID of the KMS key:
4a2ef103-5aa3-4220-****
.
- Create an AttestationAuthority object to declare a trusted authority.
- Use the following template to create an AttestationAuthority.yaml file:
apiVersion: kritis.grafeas.io/v1beta1
kind: AttestationAuthority
metadata:
name: demo-aa
spec:
noteReference: namespaces/demo-aa
publicKeyData: LS0tLS1CRUdJTiBQ***
publicKeyId: 4a2ef103-5aa3-4220-****
- Run the following command to apply the trusted authority:
kubectl apply -f AttestationAuthority.yaml
- Create a GenericAttestationPolicy object to declare a signature verification policy and use the trusted authority to
verify image signatures.
- Use the following template to create a GenericAttestationPolicy.yaml file:
apiVersion: kritis.grafeas.io/v1beta1
kind: GenericAttestationPolicy
metadata:
name: demo-gap
spec:
attestationAuthorityNames:
- demo-aa
- Run the following command to apply the signature verification policy:
kubectl apply -f GenericAttestationPolicy.yaml
- Use an image that is not signed by the specified trusted authority to test the signature
verification feature.
- Run the following command to test signature verification:
kubectl create deployment test-denied --image=alpine:3.11
Expected output:
Error from server: admission webhook "kritis-validation-hook-deployments.grafeas.io" denied the request: image alpine:3.11 is not attested
- Run the following command to test signature verification:
kubectl create deployment test-denied --image=kritis-demo-registry.cn-hangzhou.cr.aliyuncs.com/kritis-demo/alpine:3.11
Expected output:
Error from server: admission webhook "kritis-validation-hook-deployments.grafeas.io" denied the request: image kritis-demo-registry.cn-hangzhou.cr.aliyuncs.com/kritis-demo/alpine:3.11 is not attested
The output indicates that the image fails to pass the verification and the request
to deploy a pod from the image is denied.
- Use an image that is signed by the specified trusted authority to test the signature
verification feature.
Run the following command to test signature verification:
kubectl create deployment test-allow --image=kritis-demo-registry.cn-hangzhou.cr.aliyuncs.com/kritis-demo/alpine@sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45
Expected output:
deployment.apps/test-allow created
The output indicates that the image passes the verification and a pod is deployed
from the image.
Configure a signature verification whitelist
In middleware or service mesh scenarios, the images of sidecar containers injected
by third-party components may fail to pass signature verification. To resolve this
issue, kritis-validation-hook allows you to configure a signature verification whitelist.
After you configure a signature verification whitelist, kritis-validation-hook verifies
only the signatures of images that are not included in the whitelist. The signatures
of images that are included in the whitelist are not verified.
You can configure a signature verification whitelist by defining the
admissionallowlists.kritis.grafeas.io
resource. The resource is defined in the following custom resource definition (CRD):
apiVersion: kritis.grafeas.io/v1beta1 # This is the default value. Do not change the value.
kind: AdmissionAllowlist # This is the default value. Do not change the value.
metadata:
name: kritis-allowlist # The name of the resource. The name must be unique within the cluster.
spec:
patterns: # The content of the whitelist. You can add one or more images to the whitelist.
- namePattern: 'registry*.*.aliyuncs.com/acs/*' # The name of the image whose signature you do not want the system to verify.
- namePattern: 'registry-vpc.cn-beijing.aliyuncs.com/arms-docker-repo/*'
namespace: 'default' # Optional. The namespace to which the whitelist is applied. If you do not specify a namespace, the whitelist is applied to all namespaces.
To add a system image of ACK to the whitelist, perform the following steps:
- Use the following template to create a
kritis-admission-allowlist-acs.yaml
file: apiVersion: kritis.grafeas.io/v1beta1
kind: AdmissionAllowlist
metadata:
name: allow-acs-images
spec:
patterns:
- namePattern: 'registry*.*.aliyuncs.com/acs/*'
The
namePattern parameter supports exact match and fuzzy match by using asterisks (*).
- If the value of namePattern does not contain asterisks, exact match is performed.
For example, a value of
nginx:v0.1.0
matches only nginx:v0.1.0
.
- You must pay attention to the following limits before you use asterisks for fuzzy
match:
- If an asterisk appears at the end of an expression, the asterisk matches all characters
except forward slashes (/). For example,
a.com/nginx*
matches a.com/nginx:v0.1.0
but does not match a.com/nginx/test:v0.1.0
.
- If an asterisk does not appear at the end of an expression, the asterisk matches letters,
digits, hyphens (-), and underscores (_). For example,
registry-vpc.cn-*.aliyuncs.com/acs/pause:3.2
matches both registry-vpc.cn-hangzhou.aliyuncs.com/acs/pause:3.2
and registry-vpc.cn-beijing.aliyuncs.com/acs/pause:3.2
.
The following list shows the images that you can add to the whitelist in most cases:
# Images used by Container Service for Kubernetes (ACK).
- namePattern: 'registry*.*.aliyuncs.com/acs/*'
# Images used by ACK in regions within China.
- namePattern: 'registry*.cn-*.aliyuncs.com/acs/*'
# Images used by Application Real-Time Monitoring Service (ARMS).
- namePattern: 'registry*.*.aliyuncs.com/arms-docker-repo/*'
# Images used by ARMS in regions within China.
- namePattern: 'registry*.cn-*.aliyuncs.com/arms-docker-repo/*'
- Run the following command to configure a whitelist:
kubectl apply -f kritis-admission-allowlist-acs.yaml
Expected output:
admissionallowlist.kritis.grafeas.io/allow-acs-images created
- Run the following command to check whether the whitelist takes effect:
kubectl get admissionallowlists.kritis.grafeas.io
Expected output:
NAME AGE
allow-acs-images 2m22s