All Products
Search
Document Center

Container Service for Kubernetes:Introduction to kritis-validation-hook

Last Updated:Mar 22, 2024

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 in your cluster. This reduces the risk of malicious code execution. This topic provides examples on how kritis-validation-hook is used to verify signatures.

Prerequisites

A Container Service for Kubernetes (ACK) managed or ACK dedicated cluster is created. For more information, see Create an ACK managed cluster and Create an ACK dedicated cluster.

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:

Important
  • 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:

  1. Create a custom policy and add the following content to the policy. For more information, see Step 1: Create a custom policy.

    {
        "Action": [
            "cr:ListInstance",
            "cr:ListMetadataOccurrences"
        ],
        "Resource": [
            "*"
        ],
        "Effect": "Allow"
    }
  2. Grant permissions to the worker role of the cluster. For more information, see Step 2: Attach the custom policy to the worker RAM role.

    Note

    If you use an ACK dedicated cluster, you must grant the preceding permissions to the master RAM role of the cluster.

Configure the RAM permissions that are required by kritis-validation-hook in an ACK Serverless cluster

An ACK Serverless 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 ACK Serverless cluster, you must use the RAM Roles for Service Accounts (RRSA) feature. For more information, see Use RRSA to authorize different 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.

  1. Run the following command to enable the RRSA feature for the cluster:

    ack-ram-tool rrsa enable -c <clusterId>
  2. 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 about image signing, 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***.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-****.

  1. Create an AttestationAuthority object to declare a trusted authority.

    1. Use the following template to create a file named AttestationAuthority.yaml.

      apiVersion: kritis.grafeas.io/v1beta1
      kind: AttestationAuthority
      metadata:
        name: demo-aa
      spec:
        noteReference: namespaces/demo-aa
        publicKeyData: LS0tLS1CRUdJTiBQ***
        publicKeyId: 4a2ef103-5aa3-4220-****
    2. Run the following command to apply the trusted authority:

      kubectl apply -f AttestationAuthority.yaml
  2. Create a GenericAttestationPolicy object to declare a signature verification policy and use the trusted authority to verify image signatures.

    1. Use the following template to create a file named GenericAttestationPolicy.yaml.

      apiVersion: kritis.grafeas.io/v1beta1
      kind: GenericAttestationPolicy
      metadata:
        name: demo-gap
      spec:
        attestationAuthorityNames:
        - demo-aa
    2. Run the following command to apply the signature verification policy:

      kubectl apply -f GenericAttestationPolicy.yaml
  3. 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***.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***.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.

  4. 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***.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:

  1. Use the following template to create a file named kritis-admission-allowlist-acs.yaml.

    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 ACK.
    - namePattern: 'registry*.*.aliyuncs.com/acs/*'
    - namePattern: 'registry-*.ack.aliyuncs.com/acs/*'
    
    # Images used by ACK in regions within China.
    - namePattern: 'registry*.cn-*.aliyuncs.com/acs/*'
    - namePattern: 'registry-cn-*.ack.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/*'
  2. 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
  3. 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