Kubernetes clusters often require copying registry passwords into every namespace that pulls private images, repeating the process on every rotation. Dynamic cluster creation makes this routine endless, and copied secrets can expire or leak.
Kubernetes 1.34 introduces a cleaner path. The kubelet can now pass a pod’s ServiceAccount token to an image credential provider plugin. The plugin exchanges the token at the registry for short-lived, read-only credentials. The token is issued only for that specific pod and never appears in any manifest.
Artifact Keeper is an open-source (MIT) Rust registry that stores Docker/OCI images and Maven, PyPI, npm, Cargo, Go, and Helm packages, with metadata in PostgreSQL. Its OIDC provider accepts Kubernetes ServiceAccount tokens and returns temporary credentials scoped to read access only.
How the kubelet invokes the plugin
The credential provider runs on every node. Kubelet sends the image name and, since 1.34 (KEP-4412), the pod’s ServiceAccount token. The plugin returns username, password, and cache duration. Configuration uses tokenAttributes with a dedicated audience such as “artifact-keeper” to avoid conflicts with the API server audience.
Nodes require a ClusterRole granting the “request-serviceaccounts-token-audience” verb for the chosen audience. Without it, kubelet logs “is not authorized to request tokens for this audience” and falls back to unauthenticated pulls.
Registry-side configuration
Administrators create an OIDC provider of type “kubernetes” and supply the cluster’s JWKS keys. They then define mappings that filter claims (for example, namespace equals “team”) and bind matching ServiceAccounts to a read-only group. All ServiceAccounts covered by one mapping share the same registry identity while remaining distinguishable in logs by namespace, ServiceAccount, pod, and node.
Security controls in the plugin
- The 1.7 MB static Rust binary rejects http URLs and follows no redirects.
- Any token appearing in registry error responses is replaced with [REDAUTED].
- A single 10-second timeout covers the entire exchange.
- With cacheType set to ServiceAccount, credentials are cached per ServiceAccount, reducing repeated token exchanges.
Tests on kind 1.34.3 showed authorized pods pulling images on the first attempt, while unauthorized namespaces received 401 errors containing “CI JWT did not match any identity mapping” in the kubelet journal. Push operations and API-token creation are denied because the issued token carries only read scope.
The plugin and installation manifests are published in the artifact-keeper-kubelet-provider repository with cosign signatures. An open issue requests moving the code into the main Artifact Keeper organization and adding a web UI form for OIDC providers.

