Skip to content

[Bug] Unable to generate K8s events with attestation data based on verifyImages requests

Kyverno Version

1.15.0

Description

I want to generate Kubernetes events for the success or failure of verifyImages rule. The reason I want to capture the verifyImages policy results as K8s events is because we have Datadog, where we can create reports/dashboards using these K8s events, without having to use Kyverno reports directly.

I'm struggling to understand, based on the docs and examples policies, if I can pass the image attestation details and/or results from the verifyImages rule to the generate rule, and if I'm using the context in the below policy correctly as a bridge between two rules?

Or is the recommendation to use something like reportProperties and then generate events from the ClusterPolicyReport ? Unfortunately, there aren't many examples of using the reportProperties feature.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  annotations:
    policies.kyverno.io/category: Security
    policies.kyverno.io/description: >-
      This policy verifies that container images are signed with cosign before
      allowing them to be deployed to production namespaces.
    policies.kyverno.io/severity: high
    policies.kyverno.io/subject: Pod
    policies.kyverno.io/title: Verify Image Signatures
  name: verify-image-signatures
spec:
  admission: true
  background: false
  emitWarning: true
  rules:
    - match:
        resources:
          kinds:
            - Pod
          namespaces:
            - default
          operations:
            - CREATE
            - UPDATE
      name: verify-image-signature
      skipBackgroundRequests: true
      verifyImages:
        - attestations:
            - attestors:
                - count: 1
                  entries:
                    - keys:
                        ctlog:
                          ignoreSCT: true
                        kms: >-
                          awskms://kms.<region>.amazonaws.com/arn:aws:kms:us-east-1:<account-id>:alias/key
                        rekor:
                          ignoreTlog: true
                    - keys:
                        ctlog:
                          ignoreSCT: true
                        kms: >-
                          awskms://kms.<region>.amazonaws.com/arn:aws:kms:us-east-1:<account-id>:alias/key
                        rekor:
                          ignoreTlog: true
              predicateType: https://cosign.sigstore.dev/attestation/v1
          attestors:
            - count: 1
              entries:
                - keys:
                    ctlog:
                      ignoreSCT: true
                    kms: >-
                      awskms://kms.<region>.amazonaws.com/arn:aws:kms:us-east-1:<account-id>:alias/key
                    rekor:
                      ignoreTlog: true
                    signatureAlgorithm: sha256
                  signatureAlgorithm: sha256
                - keys:
                    ctlog:
                      ignoreSCT: true
                    kms: >-
                      awskms://kms.<region>.amazonaws.com/arn:aws:kms:us-east-1:<account-id>:alias/key
                    rekor:
                      ignoreTlog: true
                    signatureAlgorithm: sha256
                  signatureAlgorithm: sha256
          imageReferences:
            - <account-id>.dkr.ecr.*
          mutateDigest: false
          required: true
          skipImageReferences:
            - <account-id>.dkr.ecr.<region>.amazonaws.com/exclude/*
          type: Cosign
          useCache: true
          verifyDigest: false
    - context:
        - name: imageVerificationFailed
          variable:
            default: 0
            jmesPath: >-
              request.object.status.conditions[?type=='ImageVerificationFailed']
              | length(@)
        - name: podName
          variable:
            jmesPath: request.object.metadata.name || 'unknown'
        - name: podNamespace
          variable:
            jmesPath: request.object.metadata.namespace || 'default'
        - name: images
          variable:
            jmesPath: request.object.spec.containers[].image
        - name: attestationData
          variable:
            default: '{}'
            jmesPath: >-
              request.object.metadata.annotations."kyverno.io/attestations" ||
              '{}'
      generate:
        apiVersion: v1
        data:
          action: ImageVerificationEnforcement
          eventTime: '{{ time_now_utc() }}'
          message: >
            Image signature verification failed for Pod {{
            request.object.metadata.name }} in namespace {{
            request.object.metadata.namespace }}.
            data: {{ request }}
          metadata:
            labels:
              app.kubernetes.io/managed-by: kyverno
              kyverno.io/policy-name: verify-image-signature-with-events
              security.compliance/issue: image-verification-failed
          reason: ImageVerificationFailed
          regarding:
            apiVersion: v1
            kind: Pod
            name: '{{ request.object.metadata.name }}'
            namespace: '{{ request.object.metadata.namespace }}'
          reportingController: kyverno.io/policy-controller
          reportingInstance: kyverno-admission-controller
          type: Warning
        generateExisting: true
        kind: Event
        name: image-verification-failure
        namespace: '{{ request.object.metadata.namespace }}'
        synchronize: false
      match:
        any:
          - resources:
              kinds:
                - Pod
              operations:
                - CREATE
                - UPDATE
      name: generate-event-on-verification-failure
      preconditions:
        all:
          - key: '{{ request.operation }}'
            operator: AnyIn
            value:
              - CREATE
              - UPDATE
      skipBackgroundRequests: true
  validationFailureAction: Audit

Slack discussion

No response

Troubleshooting

  • I have read and followed the documentation AND the troubleshooting guide.
  • I have searched other issues in this repository and mine is not recorded.