Kubernetes Workload Identity: Secure OIDC Cloud Access

A Kubernetes pod should not need a permanent cloud key to read an object bucket, publish a metric, or retrieve a secret. Yet long-lived credentials still commonly end up in manifests, Secret objects, or node-level configuration, where rotation is difficult and compromise can expand the blast radius across workloads.

Kubernetes workload identity uses OIDC federation and short-lived, projected service account tokens to let a cloud provider verify which workload is requesting access. The kubelet requests a token for a defined audience, refreshes it before expiration, and avoids storing the token in an etcd Secret (Kubernetes documentation). This replaces static credentials with an identity that is scoped to the service account and its workload.

That model fits zero-trust environments, where access decisions should follow workload identity rather than network location. It also gives platform teams a cleaner foundation for securing access across multiple clusters, provided the underlying credential and trust configuration is designed for least privilege.

Get a demo of Plural's self-hosted Kubernetes control plane.

A Kubernetes Secret can make a cloud access key look like ordinary application configuration, but it does not make that key safe. Long-lived credentials remain valid until someone rotates or revokes them. In a large fleet, that creates a standing path from one compromised workload to cloud resources that may span accounts, regions, and production environments.

Consider a reporting service that needs read-only access to an object-storage bucket. An administrator stores an access key in a Secret and injects it into the pod as environment variables. Any identity with permission to run get secrets in that namespace can retrieve the Secret. The key can also appear in an environment dump collected during incident response, a debug bundle, or a crash log produced by an application that prints its configuration. A mistake that begins in one namespace can therefore become a cloud compromise rather than a narrowly contained Kubernetes incident.

Namespace access is not the same as workload identity

RBAC still matters, but it answers a different question. RBAC controls which Kubernetes API objects a human or service account can access. It does not automatically constrain what a copied cloud key can do after it leaves the cluster. If that key is reused by an attacker, the cloud provider sees a valid credential, not the original pod, namespace, deployment, or intended audience. The resulting blast radius is especially serious for regulated organizations, where a single credential may expose sensitive data or cross a control boundary between environments.

Why fleet scale amplifies the failure

Manual rotation becomes difficult across dozens of clusters and hundreds of namespaces. Teams either accept stale credentials, create broad exceptions for emergency access, or distribute the same key across multiple workloads. None of those choices provides a durable identity boundary. Zero-trust architecture moves that boundary from network location to verified identity, as outlined by NIST. Plural's practical zero-trust implementation and zero trust Kubernetes guide provide additional context for applying that model in Kubernetes.

Kubernetes workload identity addresses the underlying problem by allowing a workload to obtain scoped, short-lived cloud access instead of receiving a reusable secret. The next step is understanding how projected service account tokens provide that identity.

How does kubernetes workload identity work with projected service account tokens?

Projected service account tokens give a pod a temporary identity that an external system can verify. Instead of mounting a permanent credential, Kubernetes asks the API server for a token with two deliberate limits: an audience and an expiration time. A cloud security service can then accept a token intended for it, while rejecting the same token if it is presented to a different service.

Audience and expiration are security boundaries

The token request includes the audience that will consume the credential. For example, a workload accessing AWS Security Token Service might receive a token for sts.amazonaws.com. That token is not a general-purpose cloud credential. A different cloud or identity endpoint should reject it because its audience does not match.

Expiration provides a second boundary. A projected volume can request an expirationSeconds value such as 3600, giving the token a one-hour lifetime. The kubelet requests the token from the API server, mounts it into the pod, and refreshes it in place at roughly 80% of its lifetime. Applications can continue reading the mounted file without receiving a long-lived secret. These audience, lifetime, and rotation behaviors are documented in the Kubernetes projected volumes documentation and illustrated with workload identity examples by DevOpsness.

The result is a credential that is narrower in scope and shorter-lived than a static cloud key. It also avoids creating a Kubernetes Secret object for the service account token, so the token is not stored in etcd as a Secret. That distinction matters in clusters where access to the control plane data store must be tightly controlled.

Why projected tokens replaced legacy service account Secrets

Older Kubernetes behavior commonly created a non-expiring JSON Web Token and stored it in a Secret. If that token leaked, its useful lifetime could extend until an operator discovered and revoked it. Rotation required additional operational work, and the token did not inherently express which external audience should accept it.

Projected tokens make those properties explicit at issuance time. The kubelet obtains a bounded token when the pod needs it and keeps it current before expiration. Cloud federation still requires correct trust configuration, service account permissions, and issuer validation, but the credential presented by the workload starts with a substantially smaller blast radius. In a multi-cluster environment, that gives platform teams a consistent primitive for replacing static credentials with verifiable, workload-specific identity.

How do clouds trust the OIDC issuer of your cluster?

A projected service account token is useful to a cloud provider only if the provider can verify who issued it. The cluster's OpenID Connect (OIDC) issuer supplies that trust boundary. The Kubernetes API server publishes an OIDC discovery document at /.well-known/openid-configuration. The document identifies the issuer and points consumers to the JSON Web Key Set (JWKS) endpoint, which contains the public signing keys needed to validate service account tokens.

Start by checking the issuer your API server advertises:

kubectl get --raw /.well-known/openid-configuration | jq .issuer

The returned URL becomes part of the cloud trust configuration. When a workload presents a token, the cloud verifies the token's issuer, signature, audience, and claims against the issuer's published metadata and keys. That lets the cloud authorize a Kubernetes service account without trusting a node IP address or storing a long-lived cloud secret in the cluster. For a deeper treatment of projected tokens and OIDC validation, see the DevOpsness explanation of Kubernetes workload identity.

Managed and self-managed clusters publish discovery differently

Managed services generally provide the issuer as part of the platform. In Amazon EKS, for example, the issuer uses an address such as https://oidc.eks.<region>.amazonaws.com/id/<identifier>. AWS can use that endpoint as an OIDC provider when configuring IAM Roles for Service Accounts.

With a self-managed cluster, the platform team owns the entire publication path. Configure --service-account-issuer on the API server, then make the discovery document and JWKS endpoint reachable to the cloud provider that will validate tokens. The issuer URL must remain stable, and its public keys must be available for verification and rotation. A configured flag alone is not enough: if external validators cannot resolve discovery or retrieve the JWKS, federation fails even when the token itself is correctly minted.

This separation is important in multi-cluster environments. Each cluster should have a deliberate issuer identity and narrowly scoped trust relationships, so a token from one cluster cannot silently satisfy a policy intended for another. Teams managing many clusters can apply the same discipline described in Plural's Kubernetes multi-tenancy guide to keep identity and workload boundaries explicit.

Talk to the Plural team about workload identity for your fleet.

How do you configure OIDC federation for AWS, Azure, and GCP?

The federation pattern is consistent across clouds: Kubernetes issues a short-lived service account token, and the cloud provider validates its issuer, audience, and claims before returning temporary credentials. The implementation details differ, so platform teams should standardize the identity model while documenting each provider's trust configuration.

Choose the provider mechanism that matches your cluster model

On AWS, the established option is IAM Roles for Service Accounts (IRSA). Annotate the Kubernetes service account with the IAM role ARN. Then configure an IAM trust policy that accepts tokens from the cluster's OIDC provider and restricts the subject to the intended namespace and service account. For EKS, AWS also offers EKS Pod Identity. It associates an IAM role with a Kubernetes service account without requiring an OIDC provider, delivers credentials through environment variables, and provides CloudTrail audit visibility. It can also reduce per-pod configuration overhead. See the EKS Pod Identity documentation.

Azure takes a native Kubernetes federation approach through Microsoft Entra Workload ID on AKS. The workload identity webhook projects the service account token and injects the configuration required for an Azure identity client. The federated identity credential then maps the token's issuer, subject, and audience to the Microsoft Entra application or managed identity. This supports access to resources such as Azure Key Vault without embedding application credentials in the workload. See Microsoft's AKS Workload ID overview.

Cloud workload identity mechanisms
CloudPrimary mechanismOIDC provider needed?Credential delivery
AWSIRSA, or EKS Pod IdentityIRSA: yes. EKS Pod Identity: noTemporary AWS credentials, exposed to the workload through the SDK credential chain or injected environment configuration.
AzureMicrosoft Entra Workload ID on AKSNative federation on AKSProjected token plus injected identity configuration; the workload exchanges it for Microsoft Entra access tokens.
GCPWorkload Identity binding between a Kubernetes service account and a Google service accountYes, through the cluster's workload identity federation configurationProjected token exchanged for short-lived Google credentials.

GCP binds the Kubernetes service account to a Google service account and requires Kubernetes 1.20 or later. Follow Google's Workload Identity Federation guide when configuring the binding and provider trust. In every cloud, keep the trust conditions narrow: bind the exact issuer, audience, namespace, and service account rather than trusting every token from a cluster. For cluster setup patterns that depend on the control plane, see Plural's Kubernetes Cluster API guide.

How do you roll out workload identity across a multi-cluster fleet safely?

A safe rollout treats identity bindings as application dependencies, not as a one-time cluster configuration. Start by inventorying every workload that accesses a cloud API or external service, then map each one to a dedicated Kubernetes service account. Bind that account to only the permissions the service needs. Namespace-level separation helps, but it is not a substitute for reviewing the cloud role or policy attached to the account.

Use staged migration and explicit audiences

Do not replace every legacy Secret credential in one change window. Select a small set of low-risk services, provision their projected service account tokens, and validate authentication, authorization, rotation, and rollback before expanding the migration. Keep the old credential available only for the defined transition period, with an owner and removal date. Once the workload is using federation successfully, revoke the legacy key and delete the associated Secret.

Token audiences are another important boundary. A token issued for one relying party should not be accepted by another. Define the expected audience for each integration and reject tokens with a different audience. This prevents a credential intended for one cloud service from becoming a general-purpose credential across the fleet. Standardize on one OIDC issuer per cluster, publish its discovery and JWKS endpoints reliably, and verify that every federation trust references the intended issuer. An issuer change is a security-sensitive migration that requires coordinated updates to cloud trust policies.

Monitor the rollout as an identity change. Record which service account requested access, which audience was used, which cloud role was assumed, and whether the request succeeded or failed. Alert on unexpected role assumptions, authentication failures, issuer changes, and continued use of legacy Secrets. These audit records give platform teams a way to investigate access without relying on network location as the primary signal. NIST describes this broader zero-trust shift as moving controls away from IP addresses, subnets, and perimeter assumptions toward identities: NIST's zero-trust architecture guidance.

For the Kubernetes permissions underneath this design, document the service-account bindings alongside Kubernetes roles and RBAC. Plural's self-hosted, agent-based pull architecture complements this model by keeping execution close to each workload cluster. Agents use local permissions and egress-only connections, while the control plane does not require central storage of cluster credentials. Teams can also review agent-based Kubernetes security and Plural's infrastructure automation guide when standardizing the operating model across clusters.

Start today: Book a Plural demo for fleet-scale workload identity.

Frequently Asked Questions

What is Kubernetes workload identity?

Kubernetes workload identity lets a pod prove which workload it is, then exchange that identity for short-lived access to a cloud resource. The pod uses a projected service account token, while the cloud provider validates the cluster's OIDC issuer and applies an IAM policy. This removes the need to place long-lived cloud keys in Kubernetes Secrets.

What is the difference between IRSA and EKS Pod Identity?

Both AWS approaches associate a Kubernetes service account with permissions for an IAM role, but they establish trust differently. IRSA uses an EKS OIDC provider and a role trust policy keyed to the service account. EKS Pod Identity associates the role directly with the service account and does not require an OIDC provider. AWS documents that Pod Identity supplies credentials through environment variables and supports CloudTrail auditing: AWS EKS Pod Identity documentation.

Do projected service account tokens expire and rotate?

Yes. A projected token has a configurable audience and expiration, and the kubelet refreshes it before it expires. For example, an expirationSeconds value of 3600 represents a one-hour lifetime, with refresh occurring at roughly 80 percent of that lifetime. The token is scoped to its audience, so a token minted for one cloud service should not be accepted by another.

Can workload identity work on a self-managed Kubernetes cluster?

Yes, but the cluster must expose a usable OIDC issuer, discovery document, and JWKS endpoint. A self-managed API server typically needs --service-account-issuer configured, and the endpoints must be reachable by the identity provider or cloud trust configuration. Validate the issuer with kubectl get --raw /.well-known/openid-configuration before configuring federation.

Is OIDC federation the same as SPIFFE or SPIRE?

No. OIDC federation is a trust and token-exchange mechanism based on OpenID Connect claims. SPIFFE defines a workload identity standard, and SPIRE is one implementation that issues and manages SPIFFE identities. They can complement each other, but adopting OIDC federation does not automatically create a SPIFFE or SPIRE deployment.

Secure workload identity at fleet scale with Plural

Workload identity is one part of a defensible Kubernetes foundation. But adopting it across a multi-cluster enterprise fleet means standardizing OIDC issuers, least-privilege service accounts, and rollout controls across clouds and environments. Plural is built as a self-hosted, agent-based control plane for exactly this kind of day-2 work. It converges Kubernetes CD, IaC management, and a single-pane-of-glass console so platform teams can manage identity, security, and upgrades consistently across fleets without centralizing credentials. Managing that unified control plane at enterprise scale follows the same principles as Plural's unified control plane guide.

Contact the Plural team to map workload identity onto a fleet you can secure, audit, and scale with confidence.