Skip to content

Commit 65a8302

Browse files
committed
Add documentation for ServiceAccountNodeAudienceRestriction feature
Signed-off-by: Anish Ramasekar <anish.ramasekar@gmail.com>
1 parent 8af7916 commit 65a8302

4 files changed

Lines changed: 126 additions & 0 deletions

File tree

‎content/en/docs/concepts/security/service-accounts.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,23 @@ following methods:
186186
(which was enabled by default from Kubernetes v1.24 to v1.26), prevented Kubernetes from automatically creating these tokens for
187187
ServiceAccounts. The feature gate is removed in v1.27, because it was elevated to GA status; you can still create indefinite service account tokens manually, but should take into account the security implications.
188188

189+
#### Node audience restriction for service account tokens {#node-audience-restriction}
190+
191+
{{< feature-state feature_gate_name="ServiceAccountNodeAudienceRestriction" >}}
192+
193+
When the `ServiceAccountNodeAudienceRestriction` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
194+
is enabled, the [NodeRestriction](/docs/reference/access-authn-authz/admission-controllers#noderestriction)
195+
admission plugin limits which audiences a kubelet can request when creating service
196+
account tokens via the `TokenRequest` API. By default, the kubelet can only request
197+
tokens for audiences already referenced by pods on that node (through projected service
198+
account token volumes or CSI driver token requests). Administrators can grant
199+
kubelets access to additional audiences using RBAC rules with the
200+
`request-serviceaccounts-token-audience` verb.
201+
202+
This restriction applies only to kubelets (node identities) and does not affect other
203+
callers of the `TokenRequest` API. For details and RBAC examples,
204+
see [Service account token audience restriction](/docs/reference/access-authn-authz/node/#service-account-token-audience-restriction).
205+
189206
{{< note >}}
190207
For applications running outside your Kubernetes cluster, you might be considering
191208
creating a long-lived ServiceAccount token that is stored in a Secret. This allows authentication, but the Kubernetes project recommends you avoid this approach.

‎content/en/docs/reference/access-authn-authz/admission-controllers.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,14 @@ and enforces kubelet modification of labels under the `kubernetes.io/` or `k8s.i
616616
Use of any other labels under the `kubernetes.io` or `k8s.io` prefixes by kubelets is reserved,
617617
and may be disallowed or allowed by the `NodeRestriction` admission plugin in the future.
618618

619+
When the `ServiceAccountNodeAudienceRestriction` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
620+
is enabled, this admission plugin also restricts the audiences for which a kubelet can
621+
request service account tokens via the `TokenRequest` API. The kubelet can only request
622+
tokens for audiences already referenced by pods on that node (through projected service
623+
account token volumes or CSI driver token requests), or for audiences explicitly granted
624+
through RBAC using the `request-serviceaccounts-token-audience` verb. For more details,
625+
see [Service account token audience restriction](/docs/reference/access-authn-authz/node/#service-account-token-audience-restriction).
626+
619627
Future versions may add additional restrictions to ensure kubelets have the minimal set of
620628
permissions required to operate correctly.
621629

‎content/en/docs/reference/access-authn-authz/node.md‎

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,99 @@ To limit the API objects kubelets are able to write, enable the
9090
admission plugin by starting the apiserver with
9191
`--enable-admission-plugins=...,NodeRestriction,...`
9292

93+
## Service account token audience restriction {#service-account-token-audience-restriction}
94+
95+
{{< feature-state feature_gate_name="ServiceAccountNodeAudienceRestriction" >}}
96+
97+
When the `ServiceAccountNodeAudienceRestriction` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
98+
is enabled and the `NodeRestriction` admission plugin is active, the kubelet can only
99+
request service account tokens for audiences that are already referenced by pods running
100+
on that node. This prevents a compromised node from obtaining tokens for arbitrary audiences.
101+
102+
The allowed audiences are determined from the pod spec:
103+
104+
- The default API server audience (empty or the API server's configured audience).
105+
- Audiences set in projected service account token volume sources.
106+
- Audiences configured in CSI driver `spec.tokenRequests` for any CSI driver used by
107+
the pod, whether through inline CSI volumes, PersistentVolumeClaim-backed volumes,
108+
or ephemeral volumes.
109+
110+
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),
111+
where the kubelet requests tokens with a registry-specific audience on behalf of pods.
112+
113+
### Allowing additional audiences with RBAC {#allowing-additional-audiences}
114+
115+
You can grant kubelets permission to request tokens for audiences beyond what
116+
the pod spec references. When the kubelet requests a token with an audience that
117+
is not found in the pod spec, the NodeRestriction admission plugin checks whether
118+
the kubelet is authorized by performing an authorization check with the following
119+
attributes:
120+
121+
| Attribute | Value |
122+
| ---------- | ----- |
123+
| Verb | `request-serviceaccounts-token-audience` |
124+
| API Group | (empty string, meaning the core API group) |
125+
| Resource | The requested audience value |
126+
| Name | The service account name |
127+
| Namespace | The service account namespace |
128+
129+
You can use standard RBAC rules to authorize these checks. The `resources` field
130+
controls which audiences are allowed, and the `resourceNames` field controls which
131+
service accounts the rule applies to.
132+
133+
For example, to allow the kubelet to request audience `my-registry-audience` for
134+
a specific service account:
135+
136+
```yaml
137+
apiVersion: rbac.authorization.k8s.io/v1
138+
kind: ClusterRole
139+
metadata:
140+
name: node-audience-my-registry
141+
rules:
142+
- verbs: ["request-serviceaccounts-token-audience"]
143+
apiGroups: [""]
144+
resources: ["my-registry-audience"]
145+
resourceNames: ["my-service-account"]
146+
```
147+
148+
Omitting `resourceNames` allows the audience for any service account. Using a
149+
wildcard (`"*"`) for `resources` allows any audience:
150+
151+
```yaml
152+
apiVersion: rbac.authorization.k8s.io/v1
153+
kind: ClusterRole
154+
metadata:
155+
name: node-audience-unrestricted
156+
rules:
157+
- verbs: ["request-serviceaccounts-token-audience"]
158+
apiGroups: [""]
159+
resources: ["*"] # any audience
160+
# no resourceNames: any service account
161+
```
162+
163+
Bind the ClusterRole to the `system:nodes` group to apply it to all kubelets:
164+
165+
```yaml
166+
apiVersion: rbac.authorization.k8s.io/v1
167+
kind: ClusterRoleBinding
168+
metadata:
169+
name: node-audience-binding
170+
roleRef:
171+
apiGroup: rbac.authorization.k8s.io
172+
kind: ClusterRole
173+
name: node-audience-my-registry
174+
subjects:
175+
- kind: Group
176+
name: system:nodes
177+
apiGroup: rbac.authorization.k8s.io
178+
```
179+
180+
{{< note >}}
181+
This restriction is part of the NodeRestriction admission plugin and only applies to
182+
node identities (kubelets). It does not restrict which audiences other callers of the
183+
`TokenRequest` API can request. If you need to restrict other callers, consider using a [ValidatingAdmissionPolicy](/docs/reference/access-authn-authz/validating-admission-policy/).
184+
{{< /note >}}
185+
93186
## Migration considerations
94187

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

‎content/en/docs/tasks/administer-cluster/kubelet-credential-provider.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@ the following fields are required:
225225
* `serviceAccountTokenAudience`:
226226
the intended audience for the projected service account token.
227227
This cannot be the empty string.
228+
When the `ServiceAccountNodeAudienceRestriction`
229+
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled,
230+
the kubelet must be authorized to request tokens for this audience;
231+
otherwise the credential provider will not be invoked. You must grant
232+
the `system:nodes` group permission to use the
233+
`request-serviceaccounts-token-audience` verb on this audience via RBAC.
234+
For details and examples, see
235+
[Service account token audience restriction](/docs/reference/access-authn-authz/node/#service-account-token-audience-restriction).
228236
* `cacheType`:
229237
the type of cache key used for caching the credentials returned by the plugin
230238
when the service account token is used.

0 commit comments

Comments
 (0)