Skip to the board
Fintech

AI & ML

Kubernetes Workload Identity: How ServiceAccount Tokens and OIDC Federation Work

Michael Carter 494 views

Kubernetes workload identity replaces permanent credentials with short-lived tokens. Its security depends on issuer trust, audience checks, token rotation and precise authorization.

Kubernetes Workload Identity: How ServiceAccount Tokens and OIDC Federation Work

Kubernetes workload identity is more than a way to remove static credentials from Pods. It’s a chain of identity assignment, token issuance, cryptographic verification and authorization. A Pod can hold a valid token and still be denied access if the recipient doesn’t trust its issuer, the audience doesn’t match or the identity lacks the required permissions.

That distinction matters whenever a workload reaches beyond its own container: it might call the Kubernetes API, read from object storage, fetch a secret, publish to a queue or use a cloud service. Each recipient needs a way to determine which workload made the request and what that workload may do. Kubernetes ServiceAccounts, short-lived JSON Web Tokens (JWTs) and, in many cases, OpenID Connect (OIDC) federation provide the pieces of that process.

For teams replacing permanent cloud keys, the practical gain is clear: applications can obtain credentials tied to their runtime identity, with expiration and audience limits. The tradeoff is operational. Kubernetes, the kubelet, signing keys, issuer discovery, external identity configuration and application code all participate in the credential’s life cycle.

Identity and credential are separate

A Kubernetes ServiceAccount is a non-human identity represented by an object in the Kubernetes API. It belongs to a namespace, so its name identifies an account within that namespace rather than a universal identity shared across every cluster. A Pod that doesn’t specify a ServiceAccount uses the namespace’s default account.

The ServiceAccount identifies the workload; it isn’t itself the credential the workload presents. Kubernetes can issue a token representing that identity, with its own expiration, audience and binding information. This separation lets the same logical workload identity persist across Pod replacements while each running instance receives a temporary credential.

It also separates two decisions that are often blurred together. Authentication establishes who is making a request. Authorization determines what that identity may access. For requests to the Kubernetes API, the token authenticates the ServiceAccount, and an authorization mechanism such as RBAC determines whether the request is allowed. The identity doesn’t imply permission by itself.

This distinction carries over to external services. A cloud provider may verify that a token represents a particular Kubernetes ServiceAccount and still deny access to a storage resource if the corresponding cloud identity hasn’t been granted permission. Replacing a static key changes how a workload proves its identity; it doesn’t eliminate the need to design access rules.

How Kubernetes issues and delivers a token

Modern Kubernetes clusters generally use short-lived ServiceAccount tokens requested through the TokenRequest mechanism and delivered to Pods through projected volumes. This model replaced the older pattern of relying on long-lived tokens stored in Secrets. Kubernetes has supported bound tokens and projected volumes as the standard mechanism since version 1.22.

The kubelet is part of the delivery path. When a Pod uses a ServiceAccount, Kubernetes can configure a projected volume for the token. The kubelet obtains a time-limited token through the TokenRequest API, makes it available to the Pod’s containers and refreshes it before it expires.

The application reads the token from the projected location and presents it to the service it needs. Because Kubernetes can replace the token over time, an application shouldn’t assume that a credential read once at startup will remain valid for the entire process lifetime. It needs to reload or otherwise use the refreshed credential according to its client library and application design.

The default token lifetime is one hour, according to Kubernetes documentation. Administrators can configure related limits, and workloads can request different expiration periods within those constraints. The specific settings matter: teams need to know both what lifetime is requested and what the cluster permits.

This creates a runtime dependency that’s easy to overlook. Successful access depends on the Pod specification, ServiceAccount, control-plane token issuance, kubelet refresh behavior and the application’s ability to consume updated credentials. A problem in any one of these can look like an application authentication failure.

What the JWT claims tell a recipient

A ServiceAccount token is a signed JWT. Its claims carry identity and context that a recipient can use when deciding whether to accept it. Kubernetes documentation describes claims including iss, sub, aud, exp, iat and jti, along with Kubernetes-specific information associated with ServiceAccounts, Pods and related objects.

The issuer claim, iss, identifies who created the token. The subject, sub, represents the identity. The audience, aud, identifies the intended recipient or security domain. The expiration claim, exp, limits the token’s lifetime. Kubernetes can also bind a token to an object such as a Pod, linking the credential to part of the workload’s runtime context.

These values are inputs to a trust decision, not decorative fields. A recipient must verify the signature and evaluate the claims against its own rules. A token can be correctly signed and still be unsuitable: it may come from an issuer the recipient doesn’t trust, name a different audience or have expired.

That’s why a JWT is not simply an encoded username and password. Its contents have to be checked in the context of the receiving system’s trust configuration. Cryptographic validity is necessary, but it doesn’t settle whether the token should grant access.

Audience restrictions define where a token belongs

The audience claim is especially important when a token leaves the Kubernetes API’s own trust domain. A Pod might request a token intended for a vault. If the token names that service as its audience, the vault can check that it was the intended recipient. Another service should reject it if the token wasn’t issued for that service.

The signature answers whether a trusted issuer signed the token and whether it has been altered. The audience answers a different question: was this credential intended for this recipient? If a system accepts tokens without checking the audience, a credential issued for one service could be accepted in a setting it wasn’t meant to serve.

Kubernetes recommends that applications define the audiences they accept and verify that an incoming token’s audience matches those expectations. This check helps keep credentials scoped to a particular trust boundary. It also makes configuration a shared responsibility: the workload must request the right audience, and the recipient must enforce it.

When access fails, audience mismatch is one of the first details worth checking. A token may be fresh, correctly signed and associated with the expected ServiceAccount, yet still be rejected because its audience doesn’t match the receiving service’s configuration.

Signatures make issuer and key management operational concerns

A JWT’s signature connects the token to its issuer. Kubernetes configures a ServiceAccount token issuer and signing key, while verification depends on corresponding public key material. The private key creates the signature; a verifier uses public verification material to check that the token came from a trusted issuer and wasn’t modified.

The workload may never handle the signing key directly, but the cluster still relies on it. Issuer configuration, key storage, verification material, rotation procedures and external trust settings all become part of the identity system. They need ownership and a life cycle, just as other security infrastructure does.

External systems need enough information to validate tokens from the Kubernetes issuer. OIDC discovery can provide issuer information that relying parties use to find the details needed for verification. A relying party still needs an explicit trust configuration; it shouldn’t accept a token merely because the token contains a familiar ServiceAccount name.

Issuer changes or signing key changes can break federation if external verifiers can’t discover or use the updated verification material. The workload itself might be running normally while requests fail at the trust boundary. That makes issuer and key management part of production readiness, not a background implementation detail.

What validation involves

Token validation is more than a signature check. Kubernetes documents checks that include the signature, expiration, audience, current validity and references to Kubernetes objects. Together, these checks help determine whether a token is authentic, still usable and appropriate for the request.

Object binding adds a connection between the token and the workload that uses it. Modern ServiceAccount tokens can be bound to objects such as Pods. Kubernetes states that deleting a bound object can make the associated token invalid. The credential’s useful life can therefore follow the workload’s life cycle instead of continuing as an independent, long-lived secret.

A Deployment may replace one Pod with another while continuing to use the same ServiceAccount. The logical identity can remain stable, but the new Pod receives its own projected credential over its lifetime. A token associated with the earlier Pod doesn’t automatically become the credential for its replacement.

This separation makes rolling updates easier to reason about: permissions can stay attached to the ServiceAccount while Kubernetes issues and refreshes credentials for running instances. It also limits the value of a stolen token when that token is short-lived, audience-restricted and tied to a workload context.

Federating Kubernetes identity with cloud IAM

Kubernetes, AWS, Azure and Google Cloud each have their own identity and authorization models. Workload identity federation connects those systems so a Pod can use a Kubernetes-issued token as evidence of its identity without carrying a permanent cloud credential.

In a typical federation flow, an external identity provider validates the token’s issuer, signature, audience and relevant claims. Its trust configuration then maps the verified Kubernetes identity to an identity in the external system. That external identity has its own permissions, which determine what resources the workload can access.

The Kubernetes token doesn’t turn into a cloud credential on its own. The external provider has to trust the Kubernetes issuer and define how a verified subject maps into its authorization model. This is where implementation policy matters: teams need to decide which namespaces, ServiceAccounts or workloads can use which external identities.

OIDC gives relying parties a standard way to discover and validate issuer information. Kubernetes can expose discovery information for ServiceAccount tokens, allowing external systems to act as relying parties and federate with Kubernetes-issued identities. The trust configuration still has to name the issuer and specify the expected claims and permissions.

Federation therefore has two linked parts: cryptographic trust and authorization mapping. A provider must validate the token, and its own access rules must grant the mapped identity the needed permissions. Either part can fail even when the other is configured correctly.

For background on why workloads need identities of their own, see Machines and workloads need identities too, not just humans.

ServiceAccount tokens and Secrets solve different problems

A Kubernetes Secret is a way to store sensitive data, including passwords, API keys, certificates and tokens. Workload identity is a way to establish which workload is making a request and, in some designs, let another system issue or accept credentials based on that identity.

Teams can store a permanent cloud key in a Secret and make it available to an application, but then they have to manage that credential’s distribution, protection, rotation and removal. A projected ServiceAccount token instead has a limited lifetime and can be refreshed by the kubelet. When an external service supports federation, the workload can present its Kubernetes identity for validation rather than holding a permanent cloud key.

This doesn’t make Secrets obsolete. Applications may still need them for data that has no identity-based delivery path. The useful design question is whether a static credential is necessary for a particular connection, or whether the receiving system can verify a workload identity and grant access through federation.

Kubernetes continues to support manually created long-lived ServiceAccount token Secrets, but recommends TokenRequest for time-limited credentials. The operational improvement comes with an application requirement: the workload must be able to handle token refresh and the recipient must validate the new credential correctly.

SPIFFE and PKI widen the identity options

Kubernetes ServiceAccounts are one way to represent workload identities, but they aren’t the only approach. SPIFFE defines a broader framework for workload identity. A SPIFFE Verifiable Identity Document (SVID) can use an X.509 certificate, which can support mutual TLS and other certificate-based authentication. Kubernetes documentation identifies SPIFFE-based mechanisms, including the SPIFFE CSI driver for providing certificate pairs to Pods.

ServiceAccount tokens are a natural fit when the target understands Kubernetes identities or OIDC federation. SPIFFE can suit environments that need a shared workload identity approach across Kubernetes clusters, virtual machines, service meshes and other infrastructure. The right choice depends on which systems need to recognize the identity and how broadly the organization wants to standardize its trust model.

These approaches can coexist. A Kubernetes control plane may use signed JWTs, a cloud provider may rely on OIDC federation, and a service mesh may issue X.509 certificates for mutual TLS. Each mechanism brings its own trust relationships, credential delivery and rotation needs.

PKI remains relevant wherever certificate identities are part of the design. Certificate authorities, trust anchors, private keys and rotation become dependencies that teams must manage alongside JWT signing keys and issuer configuration. For more on those operational issues, see PKI for Kubernetes: Are you set up for security and scale? and this overview of client certificate authentication.

Where failures appear

From inside a Pod, the identity mechanism may look like a token file. But access depends on a longer chain: the ServiceAccount must be assigned, the token must be issued and delivered, the application must read the current credential, the recipient must trust the issuer and audience, and the identity must have permission for the requested action.

A Pod can be healthy and able to read its token while an external request still fails. The issuer may not be trusted, the audience may be wrong, the token may have expired, a signing key may not be available to the verifier or the mapping to external permissions may be incorrect. Correct Kubernetes RBAC alone won’t fix a cloud-side authorization failure.

Ownership can span several teams. Platform engineering may operate Kubernetes, security may define identity policy, cloud teams may manage external permissions and application teams may own credential reload behavior. If those boundaries aren’t clear, diagnosing a failure becomes a cross-team search through components that each appear healthy on their own.

A useful troubleshooting path follows the protocol: confirm which ServiceAccount the Pod uses; inspect the token’s issuer, audience and expiration; check that the intended recipient trusts the issuer and can verify its signature; then confirm that the authenticated identity maps to the needed permissions. Application behavior matters too: a process that holds an expired token after rotation may fail even when the kubelet has supplied a replacement.

Design choices for production workloads

Start by defining identity boundaries. Decide which workloads share a ServiceAccount and which need separate identities. Namespace, application, environment and tenant boundaries can all affect that choice. A broad shared identity may be easier to configure, but it can make permission boundaries harder to understand.

Prefer short-lived credentials where the receiving system supports them. Kubernetes already provides TokenRequest and projected volumes, and the kubelet refreshes projected tokens before expiration. Application clients need to consume the refreshed credential rather than treating the initial token as permanent.

Set and validate audiences deliberately. A token issued for one service shouldn’t become a general-purpose credential accepted by unrelated recipients. Match the requested audience to the intended service, and make the recipient enforce that expectation.

Keep authorization separate and narrow. Kubernetes RBAC, cloud IAM and permissions on external resources should grant the workload the capabilities it needs. Federation establishes a relationship between identities; it doesn’t determine that every authenticated identity should be trusted with broad access.

Finally, give the identity infrastructure clear owners. Issuer configuration, signing and verification keys, discovery information, external mappings and certificate authorities need maintained life cycles. When an external service depends on Kubernetes as an identity provider, changes in that trust system can affect workloads beyond the cluster itself.

The practical takeaway

Kubernetes workload identity replaces the idea of a permanent credential embedded in a Pod with a process: a ServiceAccount names the workload, Kubernetes issues a signed and time-limited token, the runtime delivers and refreshes it, and the recipient validates its claims before applying authorization rules. Federation extends that process into cloud IAM and other external systems.

That model can reduce exposure from stolen static credentials and make access follow the workload’s identity and life cycle. Its reliability depends on details that an abstraction can hide: audience checks, expiration, object binding, key rotation, issuer discovery, external trust configuration and permission mapping.

Teams adopting it should plan for both sides of the change. Applications need to handle rotating credentials, while platform and security teams need to operate the trust relationships that make those credentials meaningful. Once Kubernetes identities are accepted by services outside the cluster, issuer and key management become part of the environment’s security architecture.

Techstrong Gang Youtube
Source: Michael Carter · cloudnativenow.com

From the same roll