Workload Identity Federation
Authenticate WarpStream Agents to the control plane with short-lived, federated OIDC tokens instead of a long-lived static Agent Key.
By default, a WarpStream Agent authenticates to the control plane with a long-lived Agent Key (aks_...) that you provision and set via WARPSTREAM_AGENT_KEY. Long-lived secrets have to be distributed, rotated, and revoked out of band, and a leaked key is valid until you notice and rotate it.
Workload Identity Federation removes the static secret. Instead, the Agent proves its identity using a token minted by its own cloud platform (AWS or GCP) and exchanges it with the control plane for a short-lived, cluster-scoped credential. There is no static secret to store on the Agent, and access is tied to the cloud IAM identity the Agent already runs as.
How it works
Section titled “How it works”- On startup, the Agent asks its cloud platform for a signed OIDC token identifying the workload:
- AWS — the Agent calls STS
GetWebIdentityTokenusing its ambient IAM role. The role’s ARN ends up in the token’ssubclaim. - GCP — the Agent fetches an identity token from the instance metadata server. The workload’s service account email ends up in the token’s
emailclaim.
- AWS — the Agent calls STS
- The Agent exchanges that OIDC token with the WarpStream control plane. The requested audience is always your Virtual Cluster ID (
vci_...). - The control plane looks up the federation binding(s) you configured on that Virtual Cluster and, for the first binding whose issuer and claim rules match the token, mints a short-lived Agent credential (a
wsa_token) scoped to that cluster. - The Agent uses the
wsa_token exactly like an Agent Key and refreshes it automatically in the background before it expires.
A binding never grants access on a valid signature alone — every configured claim rule must match, so only the specific IAM role or service account you name can authenticate.
Supported identity providers
Section titled “Supported identity providers”Workload Identity Federation currently supports the following token sources, selected with the WARPSTREAM_AGENT_WORKLOAD_IDENTITY_TOKEN_SOURCE Agent environment variable:
| Provider | WARPSTREAM_AGENT_WORKLOAD_IDENTITY_TOKEN_SOURCE |
OIDC issuer |
|---|---|---|
| AWS | aws |
https://<uuid>.tokens.sts.global.api.aws |
| GCP | gcp |
https://accounts.google.com |
Support for additional providers will be added over time. Reach out if you need one that isn’t listed yet.
Before you begin
Section titled “Before you begin”You will need:
- A Virtual Cluster (note its
vci_...ID). - Permission to create bindings on that cluster: a WarpStream Application Key for the API/Terraform, generated in the admin console. See Secrets Overview.
- Agents running in a cloud environment with an identity you control — an AWS IAM role (for example an EKS IRSA / Pod Identity role) or a GCP service account.
Setup is three steps: prepare the cloud identity, create the federation binding, then point the Agent at Workload Identity.
Step 1 — Prepare the cloud identity
Section titled “Step 1 — Prepare the cloud identity”1. Enable outbound identity federation on your AWS account. This is a one-time, account-wide action that provisions your account’s OIDC issuer URL. See Getting started with outbound identity federation.
aws iam enable-outbound-web-identity-federationThe response contains your account-specific issuer URL, which looks like https://<uuid>.tokens.sts.global.api.aws. You’ll need it in Step 2. If you enabled the feature previously, retrieve the URL again at any time:
aws iam get-outbound-web-identity-federation-infoYou can also find it in the IAM console under Access management → Account settings → Outbound identity federation.
2. Grant the Agent’s IAM role permission to mint tokens. Attach a policy allowing sts:GetWebIdentityToken to the role your Agents run as. Restrict the audience to your Virtual Cluster ID so the role can only mint tokens for WarpStream:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "MintWarpStreamWorkloadIdentityToken", "Effect": "Allow", "Action": "sts:GetWebIdentityToken", "Resource": "*", "Condition": { "ForAllValues:StringEquals": { "sts:IdentityTokenAudience": "vci_XXXXXXXXXX" }, "NumericLessThanEquals": { "sts:DurationSeconds": "3600" } } } ]}To let one role authenticate to several WarpStream clusters, list each Virtual Cluster ID as an allowed audience:
"ForAllValues:StringEquals": { "sts:IdentityTokenAudience": ["vci_YYYYYYYYYY", "vci_ZZZZZZZZZZ"]}No extra IAM permissions are required — any workload can fetch its own identity token from the GCP metadata server.
Just make sure your Agents run as the service account you intend to authorize, and note that service account’s email (for example warp-agent@my-project.iam.gserviceaccount.com). You’ll use it in the binding’s claim rule in Step 2.
- On GKE, associate the Agent’s Kubernetes service account with the Google service account using Workload Identity Federation for GKE.
- On Compute Engine, this is the VM’s attached service account.
Step 2 — Create the federation binding
Section titled “Step 2 — Create the federation binding”A binding tells the control plane which OIDC issuer and claims to accept for a given Virtual Cluster. Create it with Terraform (recommended) or the API.
Terraform
Section titled “Terraform”Use the warpstream_workload_identity_federation resource (provider v2.7.10+):
resource "warpstream_workload_identity_federation" "aws_agents" { virtual_cluster_id = "vci_XXXXXXXXXX" name = "aws-agents" issuer_url = "https://<uuid>.tokens.sts.global.api.aws" read_only = false max_credential_ttl_seconds = 3600
claim_match_rules = [ { claim_path = "sub" # Replace with the ARN of the AWS IAM role your Agents are deployed with. expected_value = "arn:aws:iam::123456789012:role/warp-agent" }, ]}resource "warpstream_workload_identity_federation" "gcp_agents" { virtual_cluster_id = "vci_XXXXXXXXXX" name = "gcp-agents" issuer_url = "https://accounts.google.com" read_only = false max_credential_ttl_seconds = 3600
claim_match_rules = [ { claim_path = "email" # Replace with the email of the GCP service account your Agents are deployed with. expected_value = "warp-agent@my-project.iam.gserviceaccount.com" }, ]}Send a POST to create_workload_identity_federation with your Application Key in the warpstream-api-key header:
curl https://api.warpstream.com/api/v1/create_workload_identity_federation \ -H 'warpstream-api-key: XXXXXXXXXX' \ -H 'Content-Type: application/json' \ -d '{ "virtual_cluster_id": "vci_XXXXXXXXXX", "name": "aws-agents", "issuer_url": "https://<uuid>.tokens.sts.global.api.aws", "read_only": false, "max_credential_ttl_seconds": 3600, "claim_match_rules": [ { "claim_path": "sub", "expected_value": "arn:aws:iam::123456789012:role/warp-agent" } ] }'curl https://api.warpstream.com/api/v1/create_workload_identity_federation \ -H 'warpstream-api-key: XXXXXXXXXX' \ -H 'Content-Type: application/json' \ -d '{ "virtual_cluster_id": "vci_XXXXXXXXXX", "name": "gcp-agents", "issuer_url": "https://accounts.google.com", "read_only": false, "max_credential_ttl_seconds": 3600, "claim_match_rules": [ { "claim_path": "email", "expected_value": "warp-agent@my-project.iam.gserviceaccount.com" } ] }'List the bindings on a cluster:
curl https://api.warpstream.com/api/v1/list_workload_identity_federations \ -H 'warpstream-api-key: XXXXXXXXXX' \ -H 'Content-Type: application/json' \ -d '{"virtual_cluster_id": "vci_XXXXXXXXXX"}'Delete a binding by its wif_... ID (from the list response):
curl https://api.warpstream.com/api/v1/delete_workload_identity_federation \ -H 'warpstream-api-key: XXXXXXXXXX' \ -H 'Content-Type: application/json' \ -d '{"virtual_cluster_id": "vci_XXXXXXXXXX", "id": "wif_XXXXXXXXXX"}'Step 3 — Configure the Agent
Section titled “Step 3 — Configure the Agent”Set the token source on the Agent and remove the static Agent Key — the two are mutually exclusive.
WARPSTREAM_AGENT_WORKLOAD_IDENTITY_TOKEN_SOURCE=awsWARPSTREAM_AGENT_WORKLOAD_IDENTITY_TOKEN_SOURCE=gcpThe equivalent command-line flag is -workloadIdentityTokenSource aws (or gcp). Do not also set WARPSTREAM_AGENT_KEY, WARPSTREAM_AGENT_KEY_PATH, or WARPSTREAM_API_KEY; the Agent will refuse to start if a static key is combined with a workload identity token source.
On startup the Agent exchanges a token per region and begins refreshing it automatically. If authentication fails, the Agent logs the exchange failure; the most common causes are a missing IAM permission (AWS), the wrong role/service-account identity in the claim rule, or the account’s issuer URL not matching the binding.
Reference
Section titled “Reference”Binding fields
Section titled “Binding fields”| Field | Required | Description |
|---|---|---|
virtual_cluster_id |
yes | The Virtual Cluster (vci_...) the binding grants access to. |
name |
yes | Human-readable name, unique within the cluster (3–128 characters). |
issuer_url |
yes | HTTPS URL of the OIDC issuer whose tokens this binding accepts (your AWS account issuer, or https://accounts.google.com). |
claim_match_rules |
yes | One or more rules; all must match. See below. |
read_only |
no | If true, the minted credential is read-only. Defaults to false. |
max_credential_ttl_seconds |
no | Maximum lifetime of a minted credential, between 60 (1 minute) and 86400 (24 hours). Defaults to 3600. |
audience |
— | Read-only. Always the Virtual Cluster ID; derived by the control plane and not configurable. This is the audience the Agent’s OIDC token must request. |
Bindings are immutable — to change a binding, delete it and create a new one.
Claim matching
Section titled “Claim matching”Each rule is a claim_path / expected_value pair:
claim_pathis a dot-separated path into the token’s claims (e.g.sub,email, or a nestedcontext.namespace). If a single path segment itself contains a literal dot, wrap that segment in double quotes, e.g."kubernetes.io".namespace.expected_valueis matched case-sensitively. A single trailing*acts as a prefix wildcard (arn:aws:iam::123456789012:role/warp-*); a*anywhere else is treated literally.
All rules in a binding are ANDed together, and at least one rule is always required — a token is never accepted on a valid signature and audience alone.
Common claims
Section titled “Common claims”| Cloud | issuer_url |
Claim to match | Example value |
|---|---|---|---|
| AWS | https://<uuid>.tokens.sts.global.api.aws |
sub |
arn:aws:iam::123456789012:role/warp-agent |
| GCP | https://accounts.google.com |
email |
warp-agent@my-project.iam.gserviceaccount.com |
For the full list of claims available in an AWS token, see Understanding token claims.