Automated Threat Modeling

Overview of CVE-2026-122302: Kyverno Generate Rule Privilege Escalation via Controller Permission Check

A brief summary of CVE-2026-122302, a Kyverno flaw that let namespace administrators use namespaced Policy generate rules to create or clone resources beyond their RBAC. Covers the root cause, the fixes in v1.19.2, and configuration-based detection guidance.

CVE Analysis

11 min read

Gaurav Sarraf
Gaurav Sarraf

2026-11-04

Overview of CVE-2026-122302: Kyverno Generate Rule Privilege Escalation via Controller Permission Check
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

In Kubernetes clusters that let tenants author their own Kyverno policies, a namespace administrator could borrow the authority of Kyverno's background controller to create or clone resources far outside their own namespace. The flaw sits in how Kyverno before 1.19.2 authorized generate rules. The admission check asked whether Kyverno itself could create the target resources, not whether the person submitting the policy could.

Kyverno is a Kubernetes-native policy engine for defining, managing and enforcing policy as code. Nirmata originally created it and contributed it to the CNCF in 2020. The project graduated within the CNCF on March 24, 2026, and the graduation announcement names organizations including Bloomberg, Coinbase and Spotify among its users. Because Kyverno sits in the admission path and runs controllers that act on cluster resources with their own service account, mistakes in how it attributes policy authorship translate directly into tenant isolation failures.

The CVE record scores this issue at 9.8 (CVSS 3.1) and 9.3 (CVSS 4.0), both Critical, while the upstream GitHub advisory rates it High. The weakness is classified as CWE-269 (Improper Privilege Management), and the upstream advisory also lists CWE-863 (Incorrect Authorization). Although the supplied data lists the vendor as unknown, the published CVE record names the vendor and product as kyverno, package github.com/kyverno/kyverno.

Technical information

Generate rules and why they matter here

Kyverno generate rules create resources from policy-supplied data or clone existing resources such as ConfigMaps and Secrets. The admission and background controllers handle generation, with an intermediate UpdateRequest queuing the final generation work. These are legitimate automation features. The vulnerability exposes them to authors who should not be able to direct them at arbitrary targets.

Root cause: the SubjectAccessReview runs as the wrong identity

When a Policy or ClusterPolicy containing a generate rule is admitted, Kyverno performs a SubjectAccessReview to confirm that the generated resources can be created. The upstream report traces the problem through the following code locations:

  1. Lines 83 through 91 of pkg/validation/policy/actions.go construct the permission checker using Kyverno's own service account identity.
  2. canIGenerate, at lines 103 through 116 of pkg/policy/generate/validate.go, performs its SubjectAccessReview through lines 41 through 55 of pkg/policy/auth/auth.go, again using that identity.
  3. The webhook handler at line 115 of pkg/webhooks/policy/handlers.go never passes the admission request's UserInfo along, so the author's identity is lost.
  4. When the target Kind is a variable, the check is skipped entirely (lines 104 through 106 of generate/validate.go).

The effective question asked at admission was "can the controller create this?" rather than "can the author create this?". The controller typically holds much broader RBAC than any tenant, so the answer was usually yes.

Configuration facts that widen exposure

The upstream advisory identifies three additional conditions:

  • The Helm chart's policies role carries the aggregate-to-admin label, so every namespace admin can create namespaced Policy objects.
  • No validation ties a namespaced Policy's generate targets to its own namespace, or restricts them to namespaced kinds.
  • A target with an empty namespace is placed into default.

Attack flow

Based on the upstream scenario, exploitation proceeds as follows:

  1. The attacker holds namespace-admin rights in a tenant namespace. Through the admin-aggregated role, they can create a namespaced Policy, but they cannot directly create the resources they actually want.
  2. The attacker writes a Policy with generate (or clone) rules targeting another namespace or a cluster-scoped kind, optionally using a variable for the Kind to bypass the check altogether.
  3. Kyverno's admission webhook runs the SubjectAccessReview as its own service account, sees that the controller is permitted, and admits the policy.
  4. When the policy triggers, the background controller creates or clones the target resources using its own authority. In API audit logs, those writes are attributed to Kyverno's service account, not the tenant.

Scope and severity caveats

An attacker's reach is bounded by whatever the background controller's RBAC permits, so this is not an unconditional grant of every Kubernetes privilege. Kyverno's generate documentation also describes Kubernetes privilege-escalation protections that apply to generated RoleBindings and ClusterRoleBindings.

Both published vectors encode PR:N:

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

The narrative, however, requires a namespace administrator able to create Policy objects. The available material does not demonstrate exploitation by an unauthenticated outsider. NVD displays VulnCheck's 9.3 CVSS 4.0 assessment and notes that NIST has not provided its own score. The upstream advisory is a static-analysis report and explicitly contains no exploit code.

Exploitation status and timeline

As of OffSeq's November 5, 2026 snapshot, the CVE was not known to be exploited, no public exploit was indexed in Metasploit or Exploit DB, no Nuclei template existed, and the CVE was not in CISA's Known Exploited Vulnerabilities catalog. No threat actor or campaign is associated with it. Trenyx is credited as the reporter. The timeline matters for patch planning, because the fix was public before the CVE was:

  • October 20, 2026: Kyverno 1.19.2 released
  • October 21, 2026: upstream GitHub advisory published
  • November 4, 2026: VulnCheck advisory date
  • November 5, 2026: CVE and NVD publication

Patch information

The fix ships in Kyverno v1.19.2, published October 20, 2026. The maintainer advisory lists v1.19.2 as its only patched version, and NVD and VulnCheck list every release before 1.19.2 as affected. The v1.19.2 release notes group this advisory with GHSA-hg5v-hwm3-956r and GHSA-493q-9xvg-9xf3 under "Generate authorization, clone namespace confinement, and internal label protections", and name two PRs as the fix: #17937 and #17938. The reporter proposed three changes: an author SubjectAccessReview using the request's UserInfo in addition to the controller check, rejecting variable Kinds in namespaced policies, and confining namespaced Policy targets to their own namespace and to namespaced kinds. The shipped patch covers all three.

PR #17937: legacy generation scope and ownership

Titled [release-1.19] fix: preserve legacy generation scope and ownership and merged October 17, 2026, this PR carries the authorization fix for legacy kyverno.io Policy and ClusterPolicy objects:

  • The PR will "check author and controller permissions separately, preserving admission groups and unchanged policy updates." Kyverno still confirms its controller can do the work, but now also confirms that the submitting user or service account has permission on the generate targets. A policy can no longer use the controller's RBAC as a proxy.
  • Clone namespaces and target scopes are validated after variable substitution and before any clone source is read or anything is generated. This covers stored namespaced policies, references, cloneList, and each foreach element. A dynamic scope that lands outside the policy's validated namespace is rejected. Dynamic resource names still work, and an omitted API version is allowed when discovery confirms the resource is namespaced.
  • Reads of clone sources are authorized separately in the source namespace: get on the named object for clone, and list on each kind for cloneList. Entries that specify only a kind, such as ConfigMap, continue to work because Kyverno resolves the API version through discovery and authorizes the resolved resource.
  • Generated resources carry a provenance annotation with a persistent key plus the policy, trigger and target identities. Only the exact configured admission or background controller usernames may change it, and this guard stays active even when optional managed-resource protection is disabled. The key is stored in an immutable kyverno-generate-provenance Secret. Cleanup after policy deletion uses these recorded identities instead of evaluating live policy rules.
  • For compatibility, a policy update that leaves the spec unchanged goes through normal validation without the new author checks, so existing objects still reconcile. Authors who change a spec need permission on the targets and read access to any clone sources, but no write access to those sources. The PR describes the namespaced scope restrictions as "intentional".

PR #17938: controller-owned generation labels

Titled fix: preserve controller-owned generation labels, merged into main on October 15, 2026 and backported to release-1.19 as #18033, this PR adds a dedicated validating webhook for Kyverno's internal generation routing labels. It rejects changes to those labels, or to the accompanying managed-by label, unless the caller is the exact configured admission or background controller identity. The webhook fails closed for the associated CREATE and UPDATE requests, while ordinary content edits and unrelated label edits remain allowed. This closes a related path in which a user could spoof Kyverno's labels to steer generation rather than attacking the permission check directly.

Operator impact after upgrading

  • Custom background controller roles must grant patch on every generated target kind, in addition to get and create, plus update and delete for synchronized rules. Admission verifies this before accepting a policy.
  • Preserve the kyverno-generate-provenance Secret across upgrades and restarts.
  • Existing unsigned synchronized targets need a trusted trigger or an explicit generateExisting reevaluation before they are adopted.

Verification coverage

#17937 adds three Chainsaw suites under test/conformance/chainsaw/generate/:

  • validation/clusterpolicy/author-authorization: denied and allowed generate creation, plus unchanged-spec compatibility
  • policy/standard/clone/source-namespace: rejection of foreign sources and dynamic scopes
  • clusterpolicy/standard/generated-resource-provenance

No individual commit diffs were available in the sources we reviewed, so we do not reproduce code from the patch.

Upgrade path

Nirmata maps application release 1.19.2 to Helm chart 3.9.2 and publishes this upgrade example:

helm repo update helm upgrade kyverno kyverno/kyverno -n kyverno --version 3.9.2

For deployments on 1.18 or older, Nirmata recommends reading the 1.19.0 release notes and testing policies against 1.19 before upgrading. As of its October 23, 2026 post, no community 1.18.x or 1.17.x security patch had been published. Where an immediate upgrade is not possible, Nirmata's interim control is to remove tenant create and update permissions on every namespaced Kyverno policy kind, treating those permissions as adjacent to cluster-admin authority until the fix is deployed.

Detection methods

We found no Sigma rule, YARA rule, IDS signature or published IoC for CVE-2026-122302. Detection consists of auditing Kubernetes configuration and watching what Kyverno's background controller does.

Indicators tied to the bug

  • A namespaced policies.kyverno.io object whose generate (or clone) target names another namespace or a cluster-scoped kind.
  • A generate rule whose target kind or namespace comes from a variable rather than a fixed value.
  • A generate rule with no target namespace, which lands resources in default.
  • Resources in other namespaces, or cluster-scoped resources, created by Kyverno's background controller on behalf of a namespaced policy.

Because the controller acts under its own identity, audit log entries for the resulting writes show Kyverno's service account. Attribution requires tracing those objects back to the namespaced policy and to whoever created it.

Step 1: confirm the running version

Nirmata notes that the image tag of the running pods is what counts, not the chart version you believe you installed. Anything before 1.19.2 is in scope:

kubectl get pods -n kyverno -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'

Step 2: enumerate namespaced policies

Start with all namespaced Policy objects. Nirmata also lists the related policy kinds fixed in the same release:

kubectl get policies.kyverno.io,cleanuppolicies.kyverno.io -A kubectl get namespacedmutatingpolicies,namespacedvalidatingpolicies,namespacedgeneratingpolicies,namespaceddeletingpolicies,namespacedimagevalidatingpolicies -A

Read the generate section of each Policy. Flag targets in a namespace other than the policy's own, cluster-scoped kinds, variable-driven kinds or namespaces, and empty namespaces. Nirmata specifically advises looking for generate targets "whose namespace or kind comes from a variable".

Step 3: identify who could have exploited it

Because of the admin-aggregated role, more identities than expected can usually create namespaced policies. Repeat for each tenant user and service account:

kubectl auth can-i create policies.kyverno.io -n team-a --as=system:serviceaccount:team-a:deployer kubectl auth can-i create cleanuppolicies.kyverno.io -n team-a --as=system:serviceaccount:team-a:deployer

Any identity that receives yes on a vulnerable cluster could have triggered cross-namespace generation. Prioritize their policy creations in audit log review.

Step 4: watch for impact

Nirmata recommends watching kube-system and other sensitive namespaces for new RoleBindings, webhook configurations and NetworkPolicies you did not create. A RoleBinding or admission webhook created by the background controller but not backed by a platform-team ClusterPolicy is a strong sign of abuse. Also review the default namespace for unexplained generated objects. Kyverno's security guide additionally recommends limiting the controller to required permissions and auditing changes to RBAC roles and bindings.

False positives

Legitimate ClusterPolicy generate rules often write across namespaces by design, for example to seed NetworkPolicies or RoleBindings into new namespaces. The suspicious combination is a namespaced Policy, authored by a tenant, producing resources outside its own namespace or at cluster scope. To separate the two, check which kind of policy produced a generated resource.

Affected systems and versions

  • Affected: all Kyverno releases before 1.19.2 (package github.com/kyverno/kyverno), per NVD, VulnCheck and the CVE record.
  • Fixed: Kyverno v1.19.2 (Helm chart 3.9.2 according to Nirmata).
  • No community backports: as of October 23, 2026, no community 1.18.x or 1.17.x security patch existed. Nirmata states its Enterprise product provides backports under Enterprise support. That does not make an arbitrary older community deployment safe.
  • Most exposed configuration: clusters where tenants or namespace admins can create or update namespaced Kyverno policies, which the Helm chart grants by default through the aggregate-to-admin label on its policies role. Practical impact is bounded by the background controller's RBAC.

Vendor security history

  • 2023 third-party audit: Ada Logics, working with the maintainers and the Open Source Technology Improvement Fund under CNCF funding, found 10 issues through manual review, resulting in 6 CVEs. Four were rooted in an unreleased Notary verifier, so users of official releases were not exposed to those four. Another concerned a dependency fixed by Cosign maintainers. Fixes landed in v1.10.6 and v1.11.1.
  • 2023 fuzzing engagement: 15 fuzzers were written and 3 code issues found and fixed: a policy validation type confusion, an assignment to a nil map, and a nil dereference in the PSS handler.
  • March 2026 CNCF graduation: included a security audit, security assessment and governance review.
  • October 2026 v1.19.2 security release: 26 advisories, of which 11 were critical, 14 high and 1 moderate. Nirmata reports that its engineers contributed several of the fixes.

These events have different scopes, and their counts should not be summed. Taken together, they show a project under active scrutiny that continues to find and fix substantive defects. Neither graduation nor an earlier audit is evidence that an unpatched installation is safe.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization