Summary
Kyverno's apiCall feature in ClusterPolicy automatically attaches the admission controller's ServiceAccount token to outgoing HTTP requests. The service URL has no validation — it can point anywhere, including attacker-controlled servers. Since the admission controller's SA has permissions to patch webhook configurations, a stolen token leads to full cluster compromise.
Impact
Two issues combine. First, the service URL flows from the policy spec straight into http.NewRequestWithContext() — no scheme check, no IP restriction, no allowlist. Second, if the request does not already have an Authorization header, Kyverno reads its own SA token from /var/run/secrets/kubernetes.io/serviceaccount/token and injects it as a Bearer token. With the default Helm install, the kyverno-admission-controller SA can read and PATCH MutatingWebhookConfiguration and ValidatingWebhookConfiguration — so a leaked token gives the attacker the ability to bypass or manipulate cluster-wide admission.
Anyone with permission to create or update ClusterPolicy (a relatively common cluster-admin / platform-team grant) can author a policy whose apiCall.service.url points at an attacker-controlled host and harvest the token from the inbound request.
Detection
Audit ClusterPolicy resources for apiCall references whose service.url resolves to an external host or IP. In particular, look for:
- URLs not pointing at in-cluster services (no
.svcsuffix, no internal DNS suffix, public IP) - URLs with explicit IP literals (especially RFC 1918 / link-local) that the admission controller would still resolve
- Recently-created or recently-modified policies authored by an unexpected subject
Cluster operators should also review the audit log for update/patch actions on MutatingWebhookConfiguration / ValidatingWebhookConfiguration performed by the kyverno admission controller's SA outside of expected reconciliation windows.
Mitigation
Upgrade Kyverno to v1.16.4 or later.
Workarounds until patched:
- Restrict who can create or update
ClusterPolicyresources via tight RBAC. - Audit and remove existing
ClusterPolicydefinitions that useapiCall.service.urlpointing outside the cluster. - If
apiCallis essential, scope the admission controller's SA more tightly (remove webhook-config patch rights where not strictly required) and rotate the SA token after upgrade.