On behalf of Kubernetes SIG Auth and SIG Node, we are pleased to announce the
graduation of fine-grained kubelet
API authorization to General Availability
(GA) in Kubernetes v1.36!
The KubeletFineGrainedAuthz
feature gate was introduced as an opt-in alpha
feature in Kubernetes v1.32, then graduated to beta (enabled by default) in
v1.33. Now, the feature is generally available and the feature gate is locked
to enabled. This feature enables more precise, least-privilege access control
over the kubelet
's HTTPS API, replacing the need to grant the overly broad
nodes/proxy
permission for common monitoring and observability use cases.
Motivation: the nodes/proxy
problem
The kubelet
exposes an HTTPS endpoint with several APIs that give access to data
of varying sensitivity, including pod listings, node metrics, container logs,
and, critically, the ability to execute commands inside running containers.
Prior to this feature, kubelet
authorization used a coarse-grained model. When
webhook authorization was enabled, almost all kubelet
API paths were mapped to a
single nodes/proxy
subresource. This meant that any workload needing to read
metrics or health status from the kubelet
required nodes/proxy
permission,
the same permission that also grants the ability to execute arbitrary commands
in any container running on the node.
What's wrong with that?
Granting nodes/proxy
to monitoring agents, log collectors, or health-checking
tools violates the principle of least privilege. If any of those workloads were
compromised, an attacker would gain the ability to run commands in every
container on the node. The nodes/proxy
permission is effectively a node-level
superuser capability, and granting it broadly dramatically increases the blast
radius of a security incident.
This problem has been well understood in the community for years (see kubernetes/kubernetes#83465), and was the driving motivation behind this enhancement KEP-2862.
The nodes/proxy GET
WebSocket RCE risk
The situation is more severe than it might appear at first glance. Security
researchers demonstrated in early 2026
that nodes/proxy GET
alone, which is the minimal read-only permission routinely
granted to monitoring tools, can be abused to execute commands in any pod on
reachable nodes.
The root cause is a mismatch between how WebSocket connections work and how the
kubelet
maps HTTP methods to RBAC verbs. The
WebSocket protocol (RFC 6455)
requires an HTTP GET
request for the initial connection handshake. The kubelet
maps this GET
to the RBAC get
verb and authorizes the request without
performing a secondary check to confirm that CREATE
permission is also present
for the write operation that follows. Using a WebSocket client like websocat
,
an attacker can reach the kubelet
's /exec
endpoint directly on port 10250 and
execute arbitrary commands:
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)
Fine-grained kubelet
authorization: how it works
With KubeletFineGrainedAuthz
, the kubelet
now performs an additional, more
specific authorization check before falling back to the nodes/proxy
subresource. Several commonly used kubelet
API paths are mapped to their own
dedicated subresources:
kubelet API | Resource | Subresource |
|---|---|---|
/stats/* | nodes | stats |
/metrics/* | nodes | metrics |
/logs/* | nodes | log |
/pods | nodes | pods, proxy |
/runningPods/ | nodes | pods, proxy |
/healthz | nodes | healthz, proxy |
/configz | nodes | configz, proxy |
/spec/* | nodes | spec |
/checkpoint/* | nodes | checkpoint |
| all others | nodes | proxy |
For the endpoints that now have fine-grained subresources (/pods
,
/runningPods/
, /healthz
, /configz
), the kubelet
first sends a
SubjectAccessReview
for the specific subresource. If that check succeeds, the
request is authorized. If it fails, the kubelet
retries with the coarse-grained
nodes/proxy
subresource for backward compatibility.
This dual-check approach ensures a smooth migration path. Existing workloads
with nodes/proxy
permissions continue to work, while new deployments can adopt
least-privilege access from day one.
What this means in practice
Consider a Prometheus node exporter or a monitoring DaemonSet
that needs to
scrape /metrics
from the kubelet
. Previously, you would need an RBAC
ClusterRole
like this:
Old approach: overly broad
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-agent
rules:
- apiGroups: [""]
resources: ["nodes/proxy"]
verbs: ["get"]
This grants the monitoring agent far more access than it needs. With fine-grained authorization, you can now scope the permissions precisely:
New approach: least privilege
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-agent
rules:
- apiGroups: [""]
resources: ["nodes/metrics", "nodes/stats"]
verbs: ["get"]
The monitoring agent can now read metrics and stats from the kubelet
without
ever being able to execute commands in containers.
Updated system:kubelet-api-admin
ClusterRole
When RBAC authorization is enabled, the built-in system:kubelet-api-admin
ClusterRole
is automatically updated to include permissions for all the new
fine-grained subresources. This ensures that cluster administrators who already
use this role, including the API server's kubelet
client, continue to have
full access without any manual configuration changes.
The role now includes permissions for:
nodes/proxy
nodes/stats
nodes/metrics
nodes/log
nodes/spec
nodes/checkpoint
nodes/configz
nodes/healthz
nodes/pods
Upgrade considerations
Because the kubelet
performs a dual authorization check (fine-grained first,
then falling back to nodes/proxy
), upgrading to v1.36 should be seamless for
most clusters:
- Existing workloads with
nodes/proxy
permissions continue to work without changes. The fallback tonodes/proxy
ensures backward compatibility. - The API server always has
nodes/proxy
permissions viasystem:kubelet-api-admin
, sokube-apiserver
-to-kubelet
communication is unaffected regardless of feature gate state. - Mixed-version clusters are handled gracefully. If a
kubelet
supports fine-grained authorization but the API server does not (or vice versa),nodes/proxy
permissions serve as the fallback.
Verifying the feature is enabled
You can confirm that the feature is active on a given node by checking the
kubelet
metrics endpoint. Since the metrics endpoint on port 10250 requires
authorization, you'll first need to create appropriate RBAC bindings for the pod
or ServiceAccount
making the request.
Step 1: Create a ServiceAccount
and ClusterRole
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubelet-metrics-checker
namespace: default
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kubelet-metrics-reader
rules:
- apiGroups: [""]
resources: ["nodes/metrics"]
verbs: ["get"]
Step 2: Bind the ClusterRole
to the ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubelet-metrics-checker
subjects:
- kind: ServiceAccount
name: kubelet-metrics-checker
namespace: default
roleRef:
kind: ClusterRole
name: kubelet-metrics-reader
apiGroup: rbac.authorization.k8s.io
Apply both manifests:
kubectl apply -f serviceaccount.yaml
kubectl apply -f clusterrole.yaml
kubectl apply -f clusterrolebinding.yaml
Step 3: Run a pod with the ServiceAccount
and check the feature flag
kubectl run kubelet-check \
--image=curlimages/curl \
--serviceaccount=kubelet-metrics-checker \
--restart=Never \
--rm -it \
-- sh
Then from within the pod, retrieve the node IP and query the metrics endpoint:
Get the token
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
Query the kubelet metrics and filter for the feature gate
curl -sk \
--header "Authorization: Bearer $TOKEN" \
https://$NODE_IP:10250/metrics \
| grep kubernetes_feature_enabled \
| grep KubeletFineGrainedAuthz
If the feature is enabled, you should see output like:
kubernetes_feature_enabled{name="KubeletFineGrainedAuthz",stage="GA"} 1
Note: Replace
$NODE_IP
with the IP address of the node you want to check. You can retrieve node IPs withkubectl get nodes -o wide
.
The journey from alpha to GA
| Release | Stage | Details |
|---|---|---|
| v1.32 | Alpha | Feature gate KubeletFineGrainedAuthz introduced, disabled by default |
| v1.33 | Beta | Enabled by default; fine-grained checks for /pods , /runningPods/ , /healthz , /configz |
| v1.36 | GA | Feature gate locked to enabled; fine-grained kubelet authorization is always active |
What's next?
With fine-grained kubelet
authorization now GA, the Kubernetes community can
begin recommending and eventually enforcing the use of specific subresources
instead of nodes/proxy
for monitoring and observability workloads. The urgency
of this migration is underscored by
research showing that nodes/proxy GET
can be abused for unlogged remote code execution via the WebSocket protocol. This risk is present in the default RBAC
configurations of dozens of widely deployed Helm charts. Over time, we expect:
- Ecosystem adoption: Monitoring tools like Prometheus, Datadog agents, and
other
DaemonSets
can update their default RBAC configurations to usenodes/metrics
,nodes/stats
, andnodes/pods
instead ofnodes/proxy
. This directly eliminates the WebSocket RCE attack surface for those workloads. - Policy enforcement: Admission controllers and policy engines can flag or
reject RBAC bindings that grant
nodes/proxy
when fine-grained alternatives exist, helping organizations adopt least-privilege access at scale. - Deprecation path: As adoption grows,
nodes/proxy
may eventually be deprecated for monitoring use cases, further reducing the attack surface of Kubernetes clusters.
Getting involved
This enhancement was driven by SIG Auth and SIG Node. If you are interested in contributing to the security and authorization features of Kubernetes, please join us:
- SIG Auth
- SIG Node
- Slack:
#sig-auth
and#sig-node
- KEP-2862: Fine-Grained Kubelet API Authorization
We look forward to hearing your feedback and experiences with this feature!
Facts Only
Kubernetes v1.36 graduates fine-grained kubelet API authorization to General Availability (GA).
The feature was introduced as alpha in v1.32 and beta in v1.33.
The `KubeletFineGrainedAuthz` feature gate is now locked to enabled.
The kubelet exposes an HTTPS API with endpoints for pod listings, metrics, logs, and container execution.
Previously, most kubelet API paths were mapped to the `nodes/proxy` subresource.
Security researchers demonstrated in early 2026 that `nodes/proxy GET` could be abused for remote code execution via WebSocket.
Fine-grained authorization maps specific kubelet API paths to dedicated subresources (e.g., `/metrics/*` to `nodes/metrics`).
The kubelet performs dual authorization checks: first for fine-grained subresources, then falling back to `nodes/proxy`.
The built-in `system:kubelet-api-admin` ClusterRole includes permissions for all new subresources.
Upgrading to v1.36 is seamless due to backward compatibility with `nodes/proxy`.
Verification requires checking kubelet metrics with appropriate RBAC bindings.
The feature was developed by SIG Auth and SIG Node under KEP-2862.
Executive Summary
Kubernetes v1.36 introduces fine-grained kubelet API authorization as a generally available feature, replacing the previously coarse-grained authorization model. This enhancement addresses a long-standing security concern where monitoring tools required overly broad permissions, such as `nodes/proxy`, which could be exploited for remote code execution via WebSocket connections. The new model maps specific kubelet API paths to dedicated subresources, enabling least-privilege access control. For example, monitoring agents can now be granted permissions for `nodes/metrics` and `nodes/stats` without needing broader access. The feature ensures backward compatibility by performing dual authorization checks, first for fine-grained subresources and then falling back to `nodes/proxy` if needed. This change is critical for reducing the attack surface in Kubernetes clusters, as demonstrated by security research showing that even read-only `nodes/proxy` permissions could be abused for unlogged command execution. The Kubernetes community expects ecosystem tools to adopt these fine-grained permissions, eventually phasing out the use of `nodes/proxy` for monitoring workloads.
The feature was developed by SIG Auth and SIG Node, progressing from alpha in v1.32 to beta in v1.33, and now GA in v1.36. The built-in `system:kubelet-api-admin` ClusterRole has been updated to include all new subresources, ensuring seamless upgrades for existing clusters. Verification of the feature can be done by checking kubelet metrics, though this requires appropriate RBAC bindings. The long-term goal is to encourage policy enforcement and deprecation of broad permissions, improving cluster security across the ecosystem.
Full Take
This announcement marks a significant step in Kubernetes security, addressing a well-documented vulnerability where overly broad permissions could lead to remote code execution. The strongest version of this narrative highlights the collaborative effort by SIG Auth and SIG Node to implement a least-privilege model, reducing the blast radius of compromised monitoring tools. The feature’s progression from alpha to GA reflects careful testing and community feedback, ensuring backward compatibility while encouraging adoption of finer-grained permissions.
However, the pattern scan reveals a subtle tension between security best practices and operational inertia. The article acknowledges that many Helm charts and monitoring tools still rely on `nodes/proxy`, creating a potential adoption gap. The urgency of migration is underscored by the WebSocket RCE risk, yet the dual-check mechanism ensures no immediate breaking changes. This could lead to complacency, where organizations delay adopting least-privilege permissions despite the clear security benefits.
The root cause of this issue lies in the historical trade-off between convenience and security in Kubernetes RBAC design. The `nodes/proxy` permission was a pragmatic solution for early adopters but became a liability as clusters grew in complexity and attack surfaces expanded. The shift to fine-grained authorization reflects a broader industry trend toward zero-trust architectures, where permissions are scoped to the minimum necessary for functionality.
Implications for human agency include empowering cluster administrators to enforce stricter access controls without disrupting existing workflows. The long-term goal of deprecating `nodes/proxy` for monitoring use cases could significantly reduce the attack surface, but success depends on ecosystem adoption. Second-order consequences may include increased complexity in RBAC management, requiring better tooling and documentation to avoid misconfigurations.
Bridge questions:
1. How can organizations balance the immediate security benefits of fine-grained permissions with the operational overhead of updating legacy RBAC configurations?
2. What mechanisms could accelerate ecosystem adoption, such as automated policy enforcement or Helm chart updates?
3. What other Kubernetes components might benefit from similar least-privilege refinements?
Counterstrike scan: If this were part of a coordinated influence campaign, the playbook would emphasize the urgency of adoption while downplaying migration challenges. However, the article transparently acknowledges backward compatibility and the gradual deprecation path, aligning with genuine security improvements rather than manipulation.
Patterns detected: none
