Ingest Kyverno compliance findings into Dynatrace as security events. With runtime context from Dynatrace, you can analyze Kubernetes policy results together with the services and workloads they affect.
The Dynatrace integration with Kyverno allows you to unify and contextualize Kubernetes policy and compliance findings with other security data on the Dynatrace platform.
Kyverno is a Kubernetes-native policy engine that validates, mutates, and generates resource configurations. When validating policies are deployed in a cluster, Kyverno evaluates targeted resources and produces standardized OpenReports reports.
This integration deploys a custom OpenTelemetry Collector distribution that reads Kyverno OpenReports, transforms policy results into Dynatrace security events, and pushes them to the OpenPipeline security events ingest endpoint.
Dynatrace maps the ingested data to runtime entities that are part of your monitored environment for unified analysis, prioritization, and orchestration.
With the ingested data, you can accomplish various use cases, such as
See below for the Kyverno and Kubernetes and Dynatrace requirements.
kubectl configured with permissions to create ClusterRole and ClusterRoleBinding resources.Enable OpenReports and configure Kyverno controllers to send metrics over OTLP gRPC with the following minimum Helm values:
openreports:enabled: trueinstallCrds: trueadmissionController:metering:disabled: falseconfig: grpcport: 4317collector: otel-collector.dynatrace.svc.cluster.localbackgroundController:metering:disabled: falseconfig: grpcport: 4317collector: otel-collector.dynatrace.svc.cluster.localcleanupController:metering:disabled: falseconfig: grpcport: 4317collector: otel-collector.dynatrace.svc.cluster.localreportsController:metering:disabled: falseconfig: grpcport: 4317collector: otel-collector.dynatrace.svc.cluster.local
For the full list of metrics emitted by Kyverno, see Kyverno metrics. To decide which policy types to deploy, see Kyverno policy types.
Generate a Dynatrace access token and save it for later. For details, see Dynatrace API - Tokens and authentication.
| Token scope | Purpose |
|---|---|
| Ingest security events through |
| Send OTLP metrics to Dynatrace. |
| Send OTLP logs to Dynatrace. |
| Send OTLP traces to Dynatrace. |
To integrate Kyverno OpenReports with Dynatrace, deploy the custom Dynatrace Security Events Collector in your Kubernetes cluster.
The required collector image is available at
ghcr.io/dynatrace-oss/dynatrace-security-events-collector:latest
This collector image can ingest, parse, and transform Kyverno OpenReports into Dynatrace security events that follow the Dynatrace Semantic Dictionary.
Use one of the following deployment approaches.
Recommended
Use this option if you already have the OpenTelemetry Operator installed or if you prefer CRD-based lifecycle management.
Create the namespace.
kubectl create namespace dynatrace
Create a Kubernetes Secret with your Dynatrace endpoint, API token, and cluster name.
kubectl -n dynatrace create secret generic dynatrace-secrets \--from-literal=endpoint=https://<your-environment>.dynatrace.com \--from-literal=api-token=dt0c01.XXXXXXXX \--from-literal=cluster-name=<your-cluster-name>
Replace:
<your-environment> with your Dynatrace environment.dt0c01.XXXXXXXX with the token generated for this integration.<your-cluster-name> with a name that identifies this cluster in Dynatrace (for example, prod-eu-1). The cluster name is optional but recommended for multi-cluster setups.Apply RBAC permissions.
The collector needs read access to OpenReports resources and core Kubernetes objects to enrich security events with workload context. The rbac.yaml manifest creates a ServiceAccount, a ClusterRole, and a ClusterRoleBinding with the required read-only permissions.
curl -O https://raw.githubusercontent.com/dynatrace-oss/dynatrace-security-events-collector/refs/heads/master/manifests/rbac.yamlkubectl apply -f rbac.yaml
Skip this step if the OpenTelemetry Operator is already installed in your cluster.
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-chartshelm install opentelemetry-operator open-telemetry/opentelemetry-operator \--namespace opentelemetry-operator-system --create-namespace
The openTelemetry-manifest_statefulset.yaml file defines an OpenTelemetryCollector custom resource that the operator manages.
curl -O https://raw.githubusercontent.com/dynatrace-oss/dynatrace-security-events-collector/refs/heads/master/manifests/openTelemetry-manifest_statefulset.yamlkubectl apply -f openTelemetry-manifest_statefulset.yaml
Use the custom collector image from ghcr.io/dynatrace-oss/dynatrace-security-events-collector:latest. The default upstream OpenTelemetry Collector image doesn't include the required Security Event Processor and Exporter plugins.
Check pod status.
kubectl -n dynatrace get pods
You should see a pod named security-events-collector-* with the status Running.
Check the logs.
kubectl -n dynatrace logs -l app.kubernetes.io/name=security-events-collector --tail=50
Look for log lines that mention OpenReports being processed and events being exported.
Verify events in Dynatrace.
After the first findings are sent, run the following query in
Notebooks:
fetch security.events| filter dt.system.bucket == "default_securityevents"| filter event.kind == "SECURITY_EVENT"AND event.provider == "Kyverno"AND event.type == "COMPLIANCE_FINDING"
Removing the collector stops new security events from being ingested. It doesn't delete events that have already been stored in Grail. These events are retained according to your environment's data retention policy.
Delete the OpenTelemetryCollector resource.
kubectl -n dynatrace delete opentelemetrycollector otel
Optional Uninstall the OpenTelemetry Operator if it was installed only for this integration.
helm uninstall opentelemetry-operator --namespace opentelemetry-operator-system
Delete the shared resources.
kubectl delete clusterrolebinding otelcontribcolkubectl delete clusterrole otelcontribcolkubectl -n dynatrace delete serviceaccount security-events-collectorkubectl -n dynatrace delete secret dynatrace-secrets

Kyverno compliance findings flow from OpenReports through the Dynatrace Security Events Collector to the OpenPipeline security events endpoint, where Dynatrace stores them in Grail as security events.
k8sobjects receiver in the OpenTelemetry Collector reads reports and clusterreports resources from the openreports.io API group on a configured interval.securityevent processor parses each OpenReport, extracts individual policy results, and maps them to the Dynatrace security event semantic data model. The mapping adds severity, risk score, compliance status, finding title, product vendor, and Kubernetes context.k8sattributes processor adds Kubernetes metadata, such as cluster UID and namespace. The resource processor adds the cluster name.securityevent exporter sends batched HTTP POST requests to /platform/ingest/v1/security.events, authenticated with a Dynatrace API token.default_securityevents bucket. The events become queryable in
Notebooks,
Investigations, and
Dashboards, and you can use them in workflows.The Dynatrace Security Events Collector is a custom OpenTelemetry Collector distribution that chains three components in a logs pipeline to transform Kubernetes policy compliance data into Dynatrace security events.
k8sobjects receiver securityevent processor securityevent exporter(pulls OpenReports) -> (transforms to events) -> (posts to Dynatrace)
The pipeline type is logs because the k8sobjects receiver emits Kubernetes objects as log records. The processor and exporter operate on these log records.
The k8sobjects receiver watches or pulls Kubernetes custom resources and emits them as log records. This integration uses it to pull OpenReports from Kyverno and other policy engines that implement the OpenReports specification.
receivers:k8sobjects:auth_type: serviceAccountobjects:- name: clusterreportsgroup: openreports.iomode: pullinterval: 10m- name: reportsgroup: openreports.iomode: pullinterval: 10m
| Parameter | Description |
|---|---|
| Authentication method. Use |
| Kubernetes resource name to collect. Use |
| API group. OpenReports use |
| Collection mode. |
| How often to pull reports. The default is |
By default, the processor handles all Kyverno result statuses: pass, fail, error, and skip. To reduce event volume and ingest cost, you can process only specific statuses.
processors:securityevent:processors:openreports:enabled: truestatus_filter:- "fail"- "error"
For billing information, see Events powered by Grail.
The collector ingests compliance finding events: one security event per policy result and Kubernetes resource evaluated by Kyverno. Each event represents a single pass, fail, error, or skip verdict from a Kyverno policy rule applied to a specific resource.
Dynatrace categorizes these events as COMPLIANCE_FINDING with category COMPLIANCE in the security event schema.
The integration is push-based from the Kubernetes cluster to Dynatrace. The custom collector periodically reads OpenReports from the Kubernetes API and pushes transformed security events to the Dynatrace security events ingest endpoint.
The k8sobjects receiver queries reports and clusterreports resources at a fixed interval. Each pull fetches existing reports. The processor uses SHA256-based deduplication to prevent previously sent results from creating duplicate events in Dynatrace.
Kyverno's background scanner runs on its own schedule, which is 1 hour by default. The collector interval and Kyverno scan schedule are independent.
One OpenReport typically contains many individual policy results, with one result per evaluated resource. For example, if a policy targets 50 Deployments, the report contains 50 results, and the processor expands this into 50 individual security events.
You can monitor this expansion with the processor metrics:
processor_securityevent_incoming_logs_total: reports receivedprocessor_securityevent_outgoing_logs_total: events emittedOnly validating policy types produce OpenReports that can be ingested. Mutating, generating, deleting, and cleanup policies don't produce reports and don't appear in Dynatrace through this integration.
| Policy type | Scope | Report type |
|---|---|---|
| Cluster-wide |
|
| Namespaced |
|
| Cluster-wide |
|
| Namespaced |
|
| Cluster-wide |
|
| Cluster-wide |
|
| Namespaced |
|
Dynatrace maps risk levels and scores from the original Kyverno policy severity. If no severity is specified in the policy, Dynatrace uses MEDIUM.
dt.security.risk.level (mapped from finding.severity) | dt.security.risk.score |
|---|---|
critical → CRITICAL | 10.0 |
high → HIGH | 8.9 |
medium → MEDIUM | 6.9 |
low → LOW | 3.9 |
missing or unknown → NONE | 0.0 |
No. This integration requires the Security Event Processor and Security Event Exporter plugins. These plugins aren't part of the upstream OpenTelemetry Collector or Collector Contrib distributions. Use the pre-built image from ghcr.io/dynatrace-oss/dynatrace-security-events-collector:latest or build a custom collector that includes these plugins.
The collector reads all existing OpenReports on the next interval. The processor's SHA256-based deduplication prevents duplicate events from being sent to Dynatrace. No data is lost.
Yes. Each cluster's collector should set a unique k8s.cluster.name value through the CLUSTERNAME environment variable or the cluster-name key in the Kubernetes Secret.
You can then filter events per cluster in DQL:
fetch security.events| filter event.type == "COMPLIANCE_FINDING"| filter k8s.cluster.name == "production-eu-west-1"