Skip to content

Commit bcdb865

Browse files
authored
Merge pull request #51305 from aramase/aramase/d/kep_4412_beta_blog_v1.34
Add blog post for PSAT for Kubelet Image Credential Providers beta
2 parents 208cb5e + 128cdd4 commit bcdb865

File tree

1 file changed

+271
-0
lines changed

1 file changed

+271
-0
lines changed
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
---
2+
layout: blog
3+
title: "Kubernetes v1.34: Service Account Token Integration for Image Pulls Graduates to Beta"
4+
date: 2025-08-15
5+
slug: kubernetes-v1-34-sa-tokens-image-pulls-beta
6+
draft: true
7+
author: >
8+
[Anish Ramasekar](https://github.com/aramase) (Microsoft)
9+
---
10+
11+
The Kubernetes community continues to advance security best practices
12+
by reducing reliance on long-lived credentials.
13+
Following the successful [alpha release in Kubernetes v1.33](/blog/2025/05/07/kubernetes-v1-33-wi-for-image-pulls/),
14+
*Service Account Token Integration for Kubelet Credential Providers*
15+
has now graduated to **beta** in Kubernetes v1.34,
16+
bringing us closer to eliminating long-lived image pull secrets from Kubernetes clusters.
17+
18+
This enhancement allows credential providers
19+
to use workload-specific service account tokens to obtain registry credentials,
20+
providing a secure, ephemeral alternative to traditional image pull secrets.
21+
22+
## What's new in beta?
23+
24+
The beta graduation brings several important changes
25+
that make the feature more robust and production-ready:
26+
27+
### Required `cacheType` field
28+
29+
**Breaking change from alpha**: The `cacheType` field is **required**
30+
in the credential provider configuration when using service account tokens.
31+
This field is new in beta and must be specified to ensure proper caching behavior.
32+
33+
```yaml
34+
# CAUTION: this is not a complete configuration example, just a reference for the 'tokenAttributes.cacheType' field.
35+
tokenAttributes:
36+
serviceAccountTokenAudience: "my-registry-audience"
37+
cacheType: "ServiceAccount" # Required field in beta
38+
requireServiceAccount: true
39+
```
40+
41+
Choose between two caching strategies:
42+
- **`Token`**: Cache credentials per service account token
43+
(use when credential lifetime is tied to the token).
44+
This is useful when the credential provider transforms the service account token into registry credentials
45+
with the same lifetime as the token, or when registries support Kubernetes service account tokens directly.
46+
Note: The kubelet cannot send service account tokens directly to registries;
47+
credential provider plugins are needed to transform tokens into the username/password format expected by registries.
48+
- **`ServiceAccount`**: Cache credentials per service account identity
49+
(use when credentials are valid for all pods using the same service account)
50+
51+
### Isolated image pull credentials
52+
53+
The beta release provides stronger security isolation for container images
54+
when using service account tokens for image pulls.
55+
It ensures that pods can only access images that were pulled using ServiceAccounts they're authorized to use.
56+
This prevents unauthorized access to sensitive container images
57+
and enables granular access control where different workloads can have different registry permissions
58+
based on their ServiceAccount.
59+
60+
When credential providers use service account tokens,
61+
the system tracks ServiceAccount identity (namespace, name, and [UID](/docs/concepts/overview/working-with-objects/names/#uids)) for each pulled image.
62+
When a pod attempts to use a cached image,
63+
the system verifies that the pod's ServiceAccount matches exactly with the ServiceAccount
64+
that was used to originally pull the image.
65+
66+
Administrators can revoke access to previously pulled images
67+
by deleting and recreating the ServiceAccount,
68+
which changes the UID and invalidates cached image access.
69+
70+
For more details about this capability,
71+
see the [image pull credential verification](/docs/concepts/containers/images/#ensureimagepullcredentialverification) documentation.
72+
73+
## How it works
74+
75+
### Configuration
76+
77+
Credential providers opt into using ServiceAccount tokens
78+
by configuring the `tokenAttributes` field:
79+
80+
```yaml
81+
#
82+
# CAUTION: this is an example configuration.
83+
# Do not use this for your own cluster!
84+
#
85+
apiVersion: kubelet.config.k8s.io/v1
86+
kind: CredentialProviderConfig
87+
providers:
88+
- name: my-credential-provider
89+
matchImages:
90+
- "*.myregistry.io/*"
91+
defaultCacheDuration: "10m"
92+
apiVersion: credentialprovider.kubelet.k8s.io/v1
93+
tokenAttributes:
94+
serviceAccountTokenAudience: "my-registry-audience"
95+
cacheType: "ServiceAccount" # New in beta
96+
requireServiceAccount: true
97+
requiredServiceAccountAnnotationKeys:
98+
- "myregistry.io/identity-id"
99+
optionalServiceAccountAnnotationKeys:
100+
- "myregistry.io/optional-annotation"
101+
```
102+
103+
### Image pull flow
104+
105+
At a high level, `kubelet` coordinates with your credential provider
106+
and the container runtime as follows:
107+
108+
- When the image is not present locally:
109+
- `kubelet` checks its credential cache using the configured `cacheType`
110+
(`Token` or `ServiceAccount`)
111+
- If needed, `kubelet` requests a ServiceAccount token for the pod's ServiceAccount
112+
and passes it, plus any required annotations, to the credential provider
113+
- The provider exchanges that token for registry credentials
114+
and returns them to `kubelet`
115+
- `kubelet` caches credentials per the `cacheType` strategy
116+
and pulls the image with those credentials
117+
- `kubelet` records the ServiceAccount coordinates (namespace, name, UID)
118+
associated with the pulled image for later authorization checks
119+
120+
- When the image is already present locally:
121+
- `kubelet` verifies the pod's ServiceAccount coordinates
122+
match the coordinates recorded for the cached image
123+
- If they match exactly, the cached image can be used
124+
without pulling from the registry
125+
- If they differ, `kubelet` performs a fresh pull
126+
using credentials for the new ServiceAccount
127+
128+
- With image pull credential verification enabled:
129+
- Authorization is enforced using the recorded ServiceAccount coordinates,
130+
ensuring pods only use images pulled by a ServiceAccount
131+
they are authorized to use
132+
- Administrators can revoke access by deleting and recreating a ServiceAccount;
133+
the UID changes and previously recorded authorization no longer matches
134+
135+
### Audience restriction
136+
137+
The beta release builds on service account node audience restriction
138+
(beta since v1.33) to ensure `kubelet` can only request tokens for authorized audiences.
139+
Administrators configure allowed audiences using RBAC to enable kubelet to request service account tokens for image pulls:
140+
141+
```yaml
142+
#
143+
# CAUTION: this is an example configuration.
144+
# Do not use this for your own cluster!
145+
#
146+
apiVersion: rbac.authorization.k8s.io/v1
147+
kind: ClusterRole
148+
metadata:
149+
name: kubelet-credential-provider-audiences
150+
rules:
151+
- verbs: ["request-serviceaccounts-token-audience"]
152+
apiGroups: [""]
153+
resources: ["my-registry-audience"]
154+
resourceNames: ["registry-access-sa"] # Optional: specific SA
155+
```
156+
157+
## Getting started with beta
158+
159+
### Prerequisites
160+
161+
1. **Kubernetes v1.34 or later**
162+
2. **Feature gate enabled**:
163+
`KubeletServiceAccountTokenForCredentialProviders=true` (beta, enabled by default)
164+
3. **Credential provider support**:
165+
Update your credential provider to handle ServiceAccount tokens
166+
167+
### Migration from alpha
168+
169+
If you're already using the alpha version,
170+
the migration to beta requires minimal changes:
171+
172+
1. **Add `cacheType` field**:
173+
Update your credential provider configuration to include the required `cacheType` field
174+
2. **Review caching strategy**:
175+
Choose between `Token` and `ServiceAccount` cache types based on your provider's behavior
176+
3. **Test audience restrictions**:
177+
Ensure your RBAC configuration, or other cluster authorization rules, will properly restrict token audiences
178+
179+
### Example setup
180+
181+
Here's a complete example
182+
for setting up a credential provider with service account tokens
183+
(this example assumes your cluster uses RBAC authorization):
184+
185+
```yaml
186+
#
187+
# CAUTION: this is an example configuration.
188+
# Do not use this for your own cluster!
189+
#
190+
191+
# Service Account with registry annotations
192+
apiVersion: v1
193+
kind: ServiceAccount
194+
metadata:
195+
name: registry-access-sa
196+
namespace: default
197+
annotations:
198+
myregistry.io/identity-id: "user123"
199+
---
200+
# RBAC for audience restriction
201+
apiVersion: rbac.authorization.k8s.io/v1
202+
kind: ClusterRole
203+
metadata:
204+
name: registry-audience-access
205+
rules:
206+
- verbs: ["request-serviceaccounts-token-audience"]
207+
apiGroups: [""]
208+
resources: ["my-registry-audience"]
209+
resourceNames: ["registry-access-sa"] # Optional: specific ServiceAccount
210+
---
211+
apiVersion: rbac.authorization.k8s.io/v1
212+
kind: ClusterRoleBinding
213+
metadata:
214+
name: kubelet-registry-audience
215+
roleRef:
216+
apiGroup: rbac.authorization.k8s.io
217+
kind: ClusterRole
218+
name: registry-audience-access
219+
subjects:
220+
- kind: Group
221+
name: system:nodes
222+
apiGroup: rbac.authorization.k8s.io
223+
---
224+
# Pod using the ServiceAccount
225+
apiVersion: v1
226+
kind: Pod
227+
metadata:
228+
name: my-pod
229+
spec:
230+
serviceAccountName: registry-access-sa
231+
containers:
232+
- name: my-app
233+
image: myregistry.example/my-app:latest
234+
```
235+
236+
## What's next?
237+
238+
For Kubernetes v1.35, we - Kubernetes SIG Auth - expect the feature to stay in beta,
239+
and we will continue to solicit feedback.
240+
241+
You can learn more about this feature
242+
on the [service account token for image pulls](/docs/tasks/administer-cluster/kubelet-credential-provider/#service-account-token-for-image-pulls)
243+
page in the Kubernetes documentation.
244+
245+
You can also follow along on the
246+
[KEP-4412](https://kep.k8s.io/4412)
247+
to track progress across the coming Kubernetes releases.
248+
249+
## Call to action
250+
251+
In this blog post,
252+
I have covered the beta graduation of ServiceAccount token integration
253+
for Kubelet Credential Providers in Kubernetes v1.34.
254+
I discussed the key improvements,
255+
including the required `cacheType` field
256+
and enhanced integration with Ensure Secret Pull Images.
257+
258+
We have been receiving positive feedback from the community during the alpha phase
259+
and would love to hear more as we stabilize this feature for GA.
260+
In particular, we would like feedback from credential provider implementors
261+
as they integrate with the new beta API and caching mechanisms.
262+
Please reach out to us on the [#sig-auth-authenticators-dev](https://kubernetes.slack.com/archives/C04UMAUC4UA) channel on Kubernetes Slack.
263+
264+
## How to get involved
265+
266+
If you are interested in getting involved in the development of this feature,
267+
share feedback, or participate in any other ongoing SIG Auth projects,
268+
please reach out on the [#sig-auth](https://kubernetes.slack.com/archives/C0EN96KUY) channel on Kubernetes Slack.
269+
270+
You are also welcome to join the bi-weekly [SIG Auth meetings](https://github.com/kubernetes/community/blob/master/sig-auth/README.md#meetings),
271+
held every other Wednesday.

0 commit comments

Comments
 (0)