Skip to content

Commit 609d47c

Browse files
committed
Add blog post for PSAT for Kubelet Image Credential Providers beta
Signed-off-by: Anish Ramasekar <[email protected]>
1 parent 0f2f6d6 commit 609d47c

File tree

1 file changed

+276
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)