Passwordless Kubernetes Image Pulling with Artifact Keeper via ServiceAccount Tokens

Kubernetes 1.34 and later enables kubelet to forward a pod's ServiceAccount token to an external image credential provider plugin, allowing the plugin to exchange it for short-lived read-only credentials from a compatible registry. Artifact Keeper, an open-source Rust-based OCI and package registry, implements an OIDC provider that validates these tokens and issues temporary credentials without requiring imagePullSecrets in manifests. The approach follows zero-trust principles by eliminating long-lived secrets that can leak across namespaces or clusters. A custom credential provider binary handles the token exchange, enforces audience restrictions, and redacts sensitive data from logs. The solution requires specific ClusterRole permissions for nodes, kubelet flags, and registry-side OIDC mappings that bind Kubernetes namespaces to read-only groups. Testing on kind 1.34.3 confirmed successful pulls for authorized ServiceAccounts and clear 401 errors for unauthorized ones when imagePullPolicy is set to Always.

HabrTranslated from Russian

Read at source

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.

Meridian digestThe week's most consequential security stories, distilled into one briefing.See the digest

More in Supply Chain & Open Source

Malicious Code Injected into LiteLLM Open Source AI Package via Supply Chain Attack
GhostAction Campaign Compromises 790 GitHub Repositories via Malicious Workflows
SberTech Launches Platform V Orchestrator for Security Services to Scan Software Before Corporate Deployment