---
reviewers:
- timstclair
- deads2k
- liggitt
title: Using Node Authorization
content_type: concept
weight: 34
---

<!-- overview -->
Node authorization is a special-purpose authorization mode that specifically
authorizes API requests made by kubelets.


<!-- body -->
## Overview

The Node authorizer allows a kubelet to perform API operations. This includes:

Read operations:

* services
* endpoints
* nodes
* pods
* secrets, configmaps, persistent volume claims and persistent volumes related
  to pods bound to the kubelet's node

{{< feature-state feature_gate_name="AuthorizeNodeWithSelectors" >}}

Kubelets are limited to reading their own Node objects, and only reading pods bound to their node.

Write operations:

* nodes and node status (enable the `NodeRestriction` admission plugin to limit
  a kubelet to modify its own node)
* pods and pod status (enable the `NodeRestriction` admission plugin to limit a
  kubelet to modify pods bound to itself)
* events

Auth-related operations:

* read/write access to the
  [CertificateSigningRequests API](/docs/reference/access-authn-authz/certificate-signing-requests/)
  for TLS bootstrapping
* the ability to create TokenReviews and SubjectAccessReviews for delegated
  authentication/authorization checks

In future releases, the node authorizer may add or remove permissions to ensure
kubelets have the minimal set of permissions required to operate correctly.

In order to be authorized by the Node authorizer, kubelets must use a credential
that identifies them as being in the `system:nodes` group, with a username of
`system:node:<nodeName>`.
This group and user name format match the identity created for each kubelet as part of 
[kubelet TLS bootstrapping](/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/).

The value of `<nodeName>` **must** match precisely the name of the node as
registered by the kubelet. By default, this is the host name as provided by
`hostname`, or overridden via the
[kubelet option](/docs/reference/command-line-tools-reference/kubelet/)
`--hostname-override`. However, when using the `--cloud-provider` kubelet
option, the specific hostname may be determined by the cloud provider, ignoring
the local `hostname` and the `--hostname-override` option. 
For specifics about how the kubelet determines the hostname, see the
[kubelet options reference](/docs/reference/command-line-tools-reference/kubelet/).

To enable the Node authorizer, start the {{< glossary_tooltip text="API server" term_id="kube-apiserver" >}}
with the `--authorization-config` flag set to a file that includes the `Node` authorizer; for example:

```yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AuthorizationConfiguration
authorizers:
  ...
  - type: Node
  ...
```

Or, start the {{< glossary_tooltip text="API server" term_id="kube-apiserver" >}} with
the `--authorization-mode` flag set to a comma-separated list that includes `Node`;
for example:
```shell
kube-apiserver --authorization-mode=...,Node --other-options --more-options
```

To limit the API objects kubelets are able to write, enable the
[NodeRestriction](/docs/reference/access-authn-authz/admission-controllers#noderestriction)
admission plugin by starting the apiserver with
`--enable-admission-plugins=...,NodeRestriction,...`

## Service account token audience restriction {#service-account-token-audience-restriction}

{{< feature-state feature_gate_name="ServiceAccountNodeAudienceRestriction" >}}

When the `ServiceAccountNodeAudienceRestriction` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
is enabled and the `NodeRestriction` admission plugin is active, the kubelet can only
request service account tokens for audiences that are already referenced by pods running
on that node. This prevents a compromised node from obtaining tokens for arbitrary audiences.

The allowed audiences are determined from the pod spec:

- The default API server audience (empty or the API server's configured audience).
- Audiences set in projected service account token volume sources.
- Audiences configured in CSI driver `spec.tokenRequests` for any CSI driver used by
  the pod, whether through inline CSI volumes, PersistentVolumeClaim-backed volumes,
  or ephemeral volumes.

This is particularly relevant when using [service account tokens for image credential providers](/docs/tasks/administer-cluster/kubelet-credential-provider/#service-account-token-for-image-pulls),
where the kubelet requests tokens with a registry-specific audience on behalf of pods.

### Allowing additional audiences with RBAC {#allowing-additional-audiences}

You can grant kubelets permission to request tokens for audiences beyond what
the pod spec references. When the kubelet requests a token with an audience that
is not found in the pod spec, the NodeRestriction admission plugin checks whether
the kubelet is authorized by performing an authorization check with the following
attributes:

| Attribute  | Value |
| ---------- | ----- |
| Verb       | `request-serviceaccounts-token-audience` |
| API Group  | (empty string, meaning the core API group) |
| Resource   | The requested audience value |
| Name       | The service account name |
| Namespace  | The service account namespace |

You can use standard RBAC rules to authorize these checks. The `resources` field
controls which audiences are allowed, and the `resourceNames` field controls which
service accounts the rule applies to.

For example, to allow the kubelet to request audience `my-registry-audience` for
a specific service account:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-audience-my-registry
rules:
- verbs: ["request-serviceaccounts-token-audience"]
  apiGroups: [""]
  resources: ["my-registry-audience"]
  resourceNames: ["my-service-account"]
```

Omitting `resourceNames` allows the audience for any service account. Using a
wildcard (`"*"`) for `resources` allows any audience:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-audience-unrestricted
rules:
- verbs: ["request-serviceaccounts-token-audience"]
  apiGroups: [""]
  resources: ["*"]  # any audience
  # no resourceNames: any service account
```

Bind the ClusterRole to the `system:nodes` group to apply it to all kubelets:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-audience-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: node-audience-my-registry
subjects:
- kind: Group
  name: system:nodes
  apiGroup: rbac.authorization.k8s.io
```

{{< note >}}
This restriction is part of the NodeRestriction admission plugin and only applies to
node identities (kubelets). It does not restrict which audiences other callers of the
`TokenRequest` API can request. If you need to restrict other callers, consider using a [ValidatingAdmissionPolicy](/docs/reference/access-authn-authz/validating-admission-policy/).
{{< /note >}}

## Migration considerations

### Kubelets outside the `system:nodes` group

Kubelets outside the `system:nodes` group would not be authorized by the `Node`
authorization mode, and would need to continue to be authorized via whatever
mechanism currently authorizes them.
The node admission plugin would not restrict requests from these kubelets.

### Kubelets with undifferentiated usernames

In some deployments, kubelets have credentials that place them in the `system:nodes` group,
but do not identify the particular node they are associated with,
because they do not have a username in the `system:node:...` format.
These kubelets would not be authorized by the `Node` authorization mode,
and would need to continue to be authorized via whatever mechanism currently authorizes them.

The `NodeRestriction` admission plugin would ignore requests from these kubelets,
since the default node identifier implementation would not consider that a node identity.

