Skip to navigation

Kubernetes Workload Identity

Kubernetes can mount a short-lived, automatically rotated ServiceAccount JWT into a Pod. Mixlayer verifies that JWT through the cluster’s OIDC issuer and exchanges it for a short-lived Mixlayer access token.

Use projected ServiceAccount tokens rather than legacy Secret-backed tokens.

1. Inspect the cluster issuer

Get the cluster’s OIDC discovery document:

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

Record its issuer value. Mixlayer must be able to reach the issuer and its jwks_uri over public HTTPS to use OIDC discovery.

For a private issuer, download the cluster’s public JWKS and upload it as a static JWKS when configuring the provider:

kubectl get --raw /openid/v1/jwks > kubernetes-jwks.json

When using a static JWKS, add a new signing key to the Mixlayer provider before the cluster starts issuing tokens with it.

2. Configure the Mixlayer provider

Create an OIDC provider in Workload Identity with these values:

SettingValue
Issuer URIThe exact issuer from the discovery document
Allowed audiencehttps://api.mixlayer.com
JWKS sourceOIDC discovery for a public issuer; static JWKS for a private issuer

Map the ServiceAccount subject:

mixlayer.subject = assertion.sub

Kubernetes subjects use this format:

system:serviceaccount:<namespace>:<service-account-name>

Admit only the dedicated ServiceAccount:

mixlayer.subject == "system:serviceaccount:production:mixlayer-client"

Use true as the final authorization rule and grant only the permissions the Pod needs, such as inference.

3. Project a ServiceAccount token

The following manifest creates a dedicated ServiceAccount and mounts its token at /var/run/secrets/mixlayer/token:

file=mixlayer-workload.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: mixlayer-client
namespace: production
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mixlayer-client
namespace: production
spec:
replicas: 1
selector:
matchLabels:
app: mixlayer-client
template:
metadata:
labels:
app: mixlayer-client
spec:
serviceAccountName: mixlayer-client
containers:
- name: app
image: example/mixlayer-client:latest
env:
- name: MIXLAYER_IDENTITY_PROVIDER_ID
value: wi_replace_me
volumeMounts:
- name: mixlayer-identity
mountPath: /var/run/secrets/mixlayer
readOnly: true
volumes:
- name: mixlayer-identity
projected:
sources:
- serviceAccountToken:
path: token
audience: https://api.mixlayer.com
expirationSeconds: 3600

Apply it with:

kubectl apply -f mixlayer-workload.yaml

Do not mount the projected token using subPath; Kubernetes cannot rotate that mount.

4. Exchange the projected token

Read the token file each time you exchange so your application picks up rotations:

file=exchange-kubernetes-workload-identity.sh
MIXLAYER_SUBJECT_TOKEN=$(cat /var/run/secrets/mixlayer/token)
MIXLAYER_ACCESS_TOKEN=$(
jq -n \
--arg provider "$MIXLAYER_IDENTITY_PROVIDER_ID" \
--arg token "$MIXLAYER_SUBJECT_TOKEN" \
'{
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
subject_token_type: "urn:ietf:params:oauth:token-type:jwt",
subject_token: $token,
identity_provider_id: $provider
}' |
curl --fail-with-body --silent --show-error \
https://api.mixlayer.com/v1/workload_identity/token \
-H "Content-Type: application/json" \
--data-binary @- |
jq -er .access_token
)

Use MIXLAYER_ACCESS_TOKEN as a bearer token with the Mixlayer APIs. Cache it in memory until shortly before it expires, then reread the projected token and exchange again.

Troubleshooting

  • Decode a sample token locally and compare its iss, aud, sub, iat, and exp claims with the provider. Decoding does not verify its signature.
  • If discovery fails, confirm the issuer and JWKS endpoints are publicly reachable. Otherwise use a static JWKS.
  • If exchange breaks after cluster signing-key rotation, update the provider’s static JWKS.
  • If the ServiceAccount, namespace, or cluster changes, update the admission policy or create a separate provider for the new trust boundary.

Amazon EKS and Google Kubernetes Engine can use this same projected-token flow with their cluster-specific issuer URLs.