TL;DR

Kubernetes v1.36 ("Haru", released April 22, 2026) graduated fine-grained kubelet API authorization to GA. The KubeletFineGrainedAuthz feature gate is now locked enabled. Instead of one coarse nodes/proxy permission gating the entire kubelet HTTPS API, kubelet now maps each path to a dedicated subresource (nodes/metrics, nodes/stats, nodes/log, nodes/healthz, and more). Existing RBAC keeps working via a fallback check — but you should migrate, because nodes/proxy GET alone has been weaponized into remote code execution on every node.

What's new

Before v1.36, almost every kubelet endpoint authorized against a single subresource: nodes/proxy. A monitoring agent that only needed /metrics had to be granted the same permission as a tool that wanted to exec into pods. That violated least privilege in a cluster-wide, hard-to-fix way.

The new model maps kubelet API paths to dedicated subresources:

Kubelet pathResourceSubresource
/stats/*nodesstats
/metrics/*nodesmetrics
/logs/*nodeslog
/pods, /runningPods/nodespods
/healthznodeshealthz
/configznodesconfigz
/spec/*nodesspec
/checkpoint/*nodescheckpoint
everything elsenodesproxy

The built-in system:kubelet-api-admin ClusterRole has been updated to include all nine subresources, so cluster admins and the API server's kubelet client keep full access without manual edits.

Why it matters

Security researchers have shown that holding read-only nodes/proxy GET is enough to execute commands on any pod on the node, by abusing kubelet's WebSocket /exec endpoint:

websocat --insecure \
  --header "Authorization: Bearer $TOKEN" \
  --protocol v4.channel.k8s.io \
  "wss://$NODE_IP:10250/exec/default/nginx/nginx?output=1&error=1&command=id"
# uid=0(root) gid=0(root) groups=0(root)

In practice that meant every monitoring DaemonSet, log shipper, or third-party observability agent with nodes/proxy was a latent path to root-on-node. Compromise the agent — via a supply-chain pull, a CVE in a sidecar, a leaked ServiceAccount token — and the attacker inherits its kubelet permissions. Read-only sounded safe, but it never was. Fine-grained authorization breaks that link: a Prometheus agent can be scoped to nodes/metrics only, and a compromised credential no longer hands an attacker a shell. This is a textbook least-privilege win, and it lands in a layer where most clusters have been quietly over-permissioned for years.

Technical facts

  • Feature gate KubeletFineGrainedAuthz is locked to enabled in v1.36.
  • Authorization flow: kubelet sends a SubjectAccessReview for the fine-grained subresource first; if denied, it retries against nodes/proxy for backward compatibility.
  • Tracked under KEP-2862.
  • Ships in Kubernetes v1.36 "Haru" alongside 70 enhancements total — 18 GA, 25 beta, 25 alpha.

Comparison: before vs after

Old monitoring RBAC (overly broad):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-agent
rules:
- apiGroups: [""]
  resources: ["nodes/proxy"]
  verbs: ["get"]

New monitoring RBAC (least privilege):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-agent
rules:
- apiGroups: [""]
  resources: ["nodes/metrics", "nodes/stats"]
  verbs: ["get"]

Same workload, drastically smaller blast radius if the credential leaks.

Version journey

  • v1.32 — introduced as opt-in alpha
  • v1.33 — graduated to beta, enabled by default
  • v1.36 — GA, feature gate locked

Use cases

  • Prometheus / node exporters: grant only nodes/metrics + nodes/stats.
  • Fluent Bit, Vector and other log shippers pulling kubelet /logs: grant only nodes/log.
  • External health probes / load balancers hitting /healthz: grant only nodes/healthz.
  • Pod listers and debug tooling: use nodes/pods instead of full proxy.
  • Forensic checkpointing: scope to nodes/checkpoint.

Limitations & migration

The fallback SubjectAccessReview on nodes/proxy is a transition convenience, not a security feature. If your monitoring stack still binds nodes/proxy, the WebSocket RCE path is still wide open — you only realize the security gain once you narrow the grant. There is no immediate breaking change at upgrade time, which is good operationally and risky if it lulls teams into doing nothing.

Recommended migration steps:

  1. Upgrade clusters to v1.36.
  2. Grep ClusterRoleBindings and ClusterRoles for nodes/proxy.
  3. For each binding, replace with the minimal fine-grained subresources actually needed.
  4. Verify monitoring, logging, and probes still work end-to-end.
  5. Remove nodes/proxy from any non-admin principal.

What's next

The feature itself is done — GA means stable. The remaining work is ecosystem: monitoring agents and operators publishing minimal-RBAC manifests that target the new subresources by default, and platform teams running internal audits to drop nodes/proxy from anything that isn't actually a cluster admin. Expect Helm charts for Prometheus, Grafana Agent, Fluent Bit, OpenTelemetry Collector, and the rest of the observability stack to ship fine-grained variants over the coming releases. If you maintain an in-house operator that touches the kubelet, this is the moment to update its RBAC defaults. v1.36 also brought DRA improvements for AI workloads and resource health reporting in pod status, but for security teams — especially anyone running multi-tenant or regulated clusters — the kubelet authz GA is the headline change of the release.

Sources: kubernetes.io announcement, v1.36 release notes, KEP-2862.