Workload identity federation is in beta and off by default. An organization admin turns it on under Settings → Security → Authentication → Token exchange (Beta). The same switch controls member token exchange.
How It Works
- You register an issuer: the system that signs your workload’s tokens, such as
https://token.actions.githubusercontent.com. - You create a federation rule on that issuer: the audience the token must carry, the claims it must have (for example “this repository, this branch”), and the service account it then acts as.
- The workload gets a token from its platform and sends it to
POST /oauth/token. TextQL checks the signature against the issuer’s keys, checks the token’s lifetime, finds the one rule the token matches, and returns an access token for that rule’s service account. - The workload calls TextQL with that access token until it expires, then exchanges a new platform token.
Set It Up
Open Settings → Developers → Workload Identity and click Connect Workload. The wizard walks through four steps:- Issuer. Pick an issuer you already registered, or choose a provider (GitHub Actions, AWS, Google Cloud, Microsoft Entra, Kubernetes or Custom OIDC) to register one.
- Federation rule. Name the rule, confirm the audience, and add claim conditions. Each provider suggests the conditions that identify your workload.
- Target. Pick the service account, the access level, and how long issued tokens last (1 minute to 1 hour).
- Test. Copy the setup snippet for your provider, and optionally paste a real token from your workload to see whether it would be accepted.
organization:write permission to register issuers and manage rules. Members with organization:read can view them.
When you create an API key for a service account and workload identity is available, TextQL first suggests setting up federation instead.
Issuers
An organization can register up to 50 issuers.
Public Issuers
Some issuers sign tokens for anyone who asks. Every GitHub repository can get a token from GitHub Actions, and every Google account can get one from Google. A rule on these issuers must include an exact match on a claim that identifies your own account, or anyone else’s workload could match it.
Prefer numeric IDs such as
repository_owner_id: a name can be claimed by someone else after a rename.
Issuers that belong to one account, such as an AWS account’s STS issuer, a Microsoft Entra tenant or your own Kubernetes cluster, are not public. Their rules still need at least one condition.
Federation Rules
The claims
iss, aud, exp, iat, nbf and jti are checked on every exchange and cannot be conditions.
If more than one rule accepts a token, the exchange is refused until the workload names a rule with federation_rule_id (or TEXTQL_FEDERATION_RULE_ID in the CLI). An organization can have up to 200 rules.
Deleting an issuer deletes its rules. Deleting a service account deletes the rules that target it. Access tokens that were already issued stay valid until they expire, at most one hour later.
Provider Setup
The wizard shows a ready-to-copy snippet for the rule you just created. The examples below show the same setup.GitHub Actions
Registerhttps://token.actions.githubusercontent.com and match repository_owner_id exactly, plus sub for the repository and branch.
TEXTQL_ORG_ID is set.
Google Cloud
Registerhttps://accounts.google.com and match the service account’s email exactly. Google’s identity tokens have no jti claim, so turn off Single-use tokens for this issuer (the wizard does this for you). On GCE, GKE (with Workload Identity), Cloud Run and Cloud Functions, the CLI reads the token from the metadata server:
AWS
Turn on outbound web identity federation under IAM → Account settings and register the token issuer URL it shows. Matchsub on the role ARN.
Turning federation on does not let a role request tokens. Allow sts:GetWebIdentityToken in the workload role’s IAM policy:
Kubernetes
Register the cluster’s service account issuer (kubectl get --raw /.well-known/openid-configuration shows it). If its keys are not reachable from the internet, choose Inline keys and paste the output of kubectl get --raw /openid/v1/jwks. Match sub exactly, as system:serviceaccount:<namespace>:<name>.
Mount a projected token for the rule’s audience and point the CLI at it:
Microsoft Entra
Register your tenant’s v2.0 issuer,https://login.microsoftonline.com/<tenant id>/v2.0, and match sub on the managed identity’s object ID. Entra tokens have no jti claim, so turn off Single-use tokens for this issuer (the wizard does this for you). Write a token for your app registration’s audience to a file and set TEXTQL_FEDERATION_TOKEN_FILE.
Any Other OIDC Issuer
Choose Custom OIDC, register the issuer, and add conditions that only your workloads satisfy.Using the Token
With the CLI
Therefinery CLI uses workload identity when TEXTQL_ORG_ID is set together with a token source:
TEXTQL_API_KEY still takes precedence when set. With a token file, the CLI keeps the access token in its configuration directory until it expires, so later commands in the same job reuse it instead of exchanging the same single-use token again.
Over HTTP
Exchange the token with a standard RFC 8693 request:Authorization: Bearer <token> on API requests. Add scope=api:read to the exchange to ask for read-only access.