Skip to main content

Workload Identity Federation

Authenticate agents using the cryptographic identity of the platform they run on — Kubernetes ServiceAccount, AWS IAM role, GCP Service Account, Azure Managed Identity, or any OIDC provider — instead of storing a static client secret. A workload identity is an identity token issued by the platform itself (a K8s ServiceAccount JWT, an AWS-signed identity, a GCP metadata-server token, or an Azure Managed Identity token). LumoAuth trusts that token and issues its own access token in exchange via RFC 8693 — OAuth 2.0 Token Exchange (swap one token for another, recording the subject).

Token exchange flow

The agent retrieves a signed JWT from its environment (the subject token) and sends it to LumoAuth. LumoAuth verifies the signature against the provider's JWKS and, if valid, issues a LumoAuth access token.

Configuration

To enable workload identity for an agent:

  1. Open AI Agents in the Organization Portal dashboard.
  2. Start agent setup — click Create Agent, or select an existing agent and click Edit.
  3. Select identity method — choose Workload Identity.
  4. Choose provider — Kubernetes, AWS, GCP, Azure.
  5. Configure trust — fill in the provider-specific fields below.

Provider guides

Kubernetes

Authenticate a pod running in a Kubernetes cluster.

FieldDescription
Cluster Issuer URLPrimary OIDC issuer (e.g., EKS OIDC URL)
NamespaceK8s namespace where the agent runs
Service AccountName of the ServiceAccount

AWS

Authenticate EC2, Lambda, or ECS via IAM Role.

FieldDescription
Role ARNarn:aws:iam::123:role/name
Region(Optional) Specific AWS region

Google Cloud

Authenticate via a GCP service account.

FieldDescription
Service Account Emailagent@project.iam.gserviceaccount.com
Project IDGCP project identifier

Azure

Authenticate via Managed Identity.

FieldDescription
Client IDApplication (Client) ID
Organization IDDirectory (Organization) ID

Custom OIDC provider

Use any standard OpenID Connect provider (Auth0, Okta, Keycloak).

FieldDescription
Issuer URLThe iss claim value
SubjectExpected sub claim
AudienceExpected aud claim

API usage (token exchange)

Once configured, your agent can exchange its platform token for a LumoAuth token:

POST /orgs/{org_id}/api/v1/oauth/token HTTP/1.1
Host: your-lumoauth-domain.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=<PLATFORM_TOKEN>
&subject_token_type=urn:ietf:params:oauth:token-type:jwt
&subject_issuer=<PROVIDER>

Parameters

ParameterRequiredDescription
subject_tokenYesThe identity token (JWT) from your cloud provider. Kubernetes: content of /var/run/secrets/.../token. AWS: signed sts.get_caller_identity() response. GCP: metadata-server identity response. Azure: Managed Identity token.
subject_issuerYesProvider identifier: kubernetes, aws, gcp, azure, or oidc.
subject_token_typeYesMust be urn:ietf:params:oauth:token-type:jwt.
grant_typeYesMust be urn:ietf:params:oauth:grant-type:token-exchange.

Example: Python

import requests

def get_access_token(org_id, subject_token):
url = f"https://app.lumoauth.dev/orgs/{org_id}/api/v1/oauth/token"
payload = {
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"subject_token": subject_token,
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt"
}

response = requests.post(url, data=payload)
response.raise_for_status()
return response.json()["access_token"]

# 1. Read the Kubernetes ServiceAccount token
with open('/var/run/secrets/kubernetes.io/serviceaccount/token') as f:
k8s_token = f.read().strip()

# 2. Exchange for a LumoAuth token
token = get_access_token("acme-corp", k8s_token)
print(f"Got Access Token: {token}")
Audience validation

LumoAuth validates that the aud claim in the subject token matches the expected audience configured for the agent.