Modifying Policies

Cosign, verification of signatures, control of vulnerabilities in images.

Kyverno supports the implementation of modification policies that allow you to modify objects before launch, including preventing the launch of vulnerable containers.

Cosign is used to check image signatures and block containers with critical vulnerabilities.

Using Cosign, you can ensure that only images signed with trusted keys are included in the cluster. In open and closed loops, key sources and registries are different.

In open loop, keys and signature metadata are typically downloaded from public sources (OCI registry, URL). In a closed loop, keys and signature verification policy configuration (for example, for Cosign) must be delivered to the environment manually or through an approved channel.

Note: When configuring a policy, add namespaces of system components to exceptions.

Preparation

To sign images you need:

  1. Install Cosign:
curl -sSL https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign
  1. Generate a key pair, which will subsequently be used to sign images (you can use an existing one):
cosign generate-key-pair

If your organization has multiple teams using the same cluster, use separate key pairs for image signatures. In that case, repeat this and the following steps for each team that runs workloads in the cluster, and list all public keys in the policies. Verification passes if the signature matches at least one public key.

  1. Sign the container image using the private key created in the previous step:
cosign sign --key cosign.key --tlog-upload=false $IMAGE

When using local image registries, the --allow-insecure-registry=true flag may be needed.

Add the public key to the policy manifest. Give the private key to developers for image signing or to DevOps for use in the pipeline.

  1. Scan the image and get a report:
trivy image --ignore-unfixed --format cosign-vuln --output $FILE_NAME.json $IMAGE
  1. Add an attestation (report from the previous step):
cosign attest --key cosign.key --tlog-upload=false --type vuln --predicate $FILE_NAME.json $IMAGE 

When using local image registries, the --allow-insecure-registry=true flag may be needed.

Install the policy in the target cluster using the steps of manifest import in the security policy manager.

Container signature verification

Instead of the text “public key”, insert the public key obtained in step 3. In the imageReferences block, enter the address of your registry (image registry).

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  annotations:
    policies.kyverno.io/category: infosec
    policies.kyverno.io/description: Image signature verification allows
      monitor its integrity and launch containers only from
      verified and trusted images
    policies.kyverno.io/severity: High
    policies.kyverno.io/title: Image Signature Checker
  name: image-sign-check
spec:
  validationFailureAction: Enforce
  background: false
  rules:
    - name: check-image
      match:
        any:
        - resources:
            kinds:
              - Pod
      verifyImages:
      - imageReferences:
        - "*"
        attestors:
        - count: 1
          entries:
          -keys:
              publicKeys: |-
                -----BEGIN PUBLIC KEY-----
                public key
                -----END PUBLIC KEY-----                
              rekor:
                ignoreTlog: true
                url: https://rekor.sigstore.dev
              ctlog:
                ignoreSCT: true
          -keys:
              publicKeys: |-
                -----BEGIN PUBLIC KEY-----
                public key
                -----END PUBLIC KEY-----                
              rekor:
                ignoreTlog: true
                url: https://rekor.sigstore.dev
              ctlog:
                ignoreSCT: true

After this, at startup, the images will be checked before launching.

Blocking pods with critical vulnerabilities

Instead of the text “public key”, insert the public key obtained in step 3. In the imageReferences block, enter the address of your registry (image registry).

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: image-vuln-check
  annotations:
    policies.kyverno.io/title: Image Vulnerability Checker
    policies.kyverno.io/category: "infosec"
    policies.kyverno.io/severity: High
    policies.kyverno.io/description: >-
      It is good practice not to run container images that contain vulnerabilities.
      for example, High and Critical levels. Using this policy, you can controllyate as much as possible
      the acceptable CVSSv3 Score level that vulnerabilities in the running container may have.      
spec:
  validationFailureAction: "Enforce"
  background: true
  schemaValidation: true
  failurePolicy: "Fail"
  webhookTimeoutSeconds: 10
  rules:
    - name: image-vuln-check
      match:
        any:
        - resources:
            kinds:
            - Pod
      verifyImages:
      - imageReferences:
        - my.test.registry/*
        mutateDigest: false
        verifyDigest: false
        attestations:
          - type: https://cosign.sigstore.dev/attestation/vuln/v1
            attestors:
            - entries:
              -keys:
                  publicKeys: |-
                      -----BEGIN PUBLIC KEY-----
                      public key
                      -----END PUBLIC KEY-----                      
                  rekor:
                    ignoreTlog: true
                    url: https://rekor.sigstore.dev
                    pubkey: |-
                      -----BEGIN PUBLIC KEY-----
                      public key
                      -----END PUBLIC KEY-----                      
                  ctlog:
                    pubkey: |-
                      -----BEGIN PUBLIC KEY-----
                      public key
                      -----END PUBLIC KEY-----                      
            conditions:
              - any:
                - key: "{{ scanner.result.Results[].Vulnerabilities[?CVSS.nvd.V3Score > `7`][] | length(@) }}"
                  message: "The following were found: {{ scanner.result.Results[].Vulnerabilities[?CVSS.nvd.V3Score > `7`][] | length(@) | to_string(@) }} vulnerability(s) with a score greater than 7 on the CVSSv3 Score"
                  operator: Equals
                  value: 0