Tokens and claims

Look up each token a project issues, its lifetime, signing algorithm and claims, and how to validate one.

A project issues several kinds of token. Each is signed with one of the project's keys, published at https://acme.authfi.io/.well-known/jwks.json.

Token types

A claim is a named value inside a token. A JWT is a signed token whose claims any holder can read and any service can verify.

TokenIssued toSigned withHeader typLifetime
ID tokenAn application, after a person signs inRS256JWT15 minutes by default
Access tokenAn application or a serviceRS256at+jwt15 minutes by default
Refresh tokenAn application, after a person signs inNot a JWT30 days by default, used once
Agent access tokenAn AI agent, after it signs inEdDSAat+jwt15 minutes by default
Transaction tokenAn agent, for one actionEdDSAtxn_token+jwt60 seconds
Client assertionMade by the agent itself, to sign inThe agent's own keyJWTAt most 5 minutes, used once

The ID token has the same lifetime as the access token.

ID token

Tells an application who signed in. It is returned by the token endpoint when the scope includes openid. See Add sign-in to an app.

{
  "iss": "https://acme.authfi.io",
  "sub": "[email protected]",
  "aud": "<your client ID>",
  "email": "[email protected]",
  "email_verified": true,
  "name": "Ada Lovelace",
  "groups": ["engineering"],
  "roles": ["developer"],
  "auth_time": 1760000000,
  "iat": 1760000000,
  "exp": 1760000900
}
ClaimDescription
issThe project's issuer
subThe person's identifier in this project
audThe client ID the token was issued to
exp, iatWhen it expires, and when it was issued
auth_timeWhen the person last signed in
nonceThe nonce your application sent, unchanged
emailThe person's email
email_verifiedWhether the email is verified
nameThe person's name
groupsThe groups assigned to the application, or shared with it, that the person is in
rolesThe roles the person holds

The ID token carries email, email_verified, name, groups and roles whatever scopes you request. Scopes decide what userinfo returns. See Scopes.

groups lists only the groups assigned to the application or shared with it, not every group the person belongs to. See Application types.

Access token

Lets an application or a service call an API. It follows the JWT access token profile (RFC 9068). See Sessions and Service to service.

ClaimDescription
issThe project's issuer
subThe person, or for a service its own client ID
audA list. For a person, the client ID it was issued to. For a service, the API named in resource.
client_idThe application the token was issued to
scopeThe scopes granted, space-separated. For a service, the scopes it asked for, unchanged.
roles, permissions, groupsWhat the person holds
sidThe session the token came from
amr, acrHow the person signed in. See acr and amr values.
auth_timeWhen the person last signed in
jtiA unique identifier for this token
iat, expWhen it was issued, and when it expires

sid, amr and acr describe a person's sign-in. A service's token has none of them, because nobody signed in.

An access token carries no name or email. Read those from the ID token or from userinfo.

acr and amr values

acr is the sign-in strength reached. An application asks for one with acr_values at the authorization endpoint. Several values, separated by spaces, mean any of these, or stronger. See Sessions.

acrThe person
urn:authfi:acr:1faSigned in
urn:authfi:acr:mfaCompleted multi-factor authentication (MFA)
urn:authfi:acr:passkeySigned in with a passkey
urn:authfi:acr:passkey_mfaSigned in with a passkey and completed MFA

amr is the list of methods the person used.

amr valueMethod
pwdA password
otpA one-time code
mfaMore than one method
hwkA key held in hardware, such as a passkey
userThe passkey verified the person (a PIN or biometric)
fedAnother identity provider

Custom claims

A claim that a webhook action returns is added to the token under custom. See Actions at sign-in.

{ "sub": "[email protected]", "custom": { "plan": "enterprise", "cost_center": "R-204" } }

Refresh token

Gets new tokens without another sign-in, at the token endpoint. It is not a JWT. See Refresh tokens.

PropertyValue
Lifetime30 days by default
UseOnce. Every use returns a new refresh token.
Issued toEvery application that holds a secret. An application without one, when the project allows it, which is the default.
ReusePresenting a used refresh token revokes every refresh token from the same sign-in and returns invalid_grant
RevokeAt the revocation endpoint

Agent access token

Lets an AI agent call a service. It is returned by the agent token endpoint, /apis/regional/v1/ai/auth/token, and follows RFC 9068. An agent has no refresh token: when the access token expires, it signs a new client assertion. See Give an AI agent an identity and Accept agents at your own API.

ClaimDescription
issThe project's issuer
subThe agent, or the person it is acting for
client_idThe agent ID, agt_…. Always the agent.
audWhere the token may be used, from resource in the request
agent_typedelegated or autonomous
owner_user_idThe person who answers for the agent, when it has an owner
approval_group_idThe group that answers for the agent, when it has one
actPresent when the agent acts for a person. act.sub is the agent, as agent:agt_….
capabilitiesThe names of the capabilities the agent was granted
scopeThe same grants, as a space-separated string
roles, groupsThe agent's own roles and groups, when it has any
tenant_idThe project's internal identifier
jtiA unique identifier for this token
iat, expWhen it was issued, and when it expires

capabilities holds names only. AuthFI keeps the limits on each capability and checks them when the agent acts. See Limit what an agent may do.

A token requested with no resource is issued for the project's MCP gateway.

act tells the two cases apart.

Tokensubact.subMeaning
Agent on its ownagt_…AbsentThe agent acts as itself
Agent for a personThe personagent:agt_…The agent acts for that person, who approved it

In a token issued after a person approves through CIBA, scope is what the person approved, and exp is 15 minutes after issue.

Transaction token

Binds an agent to one action and its details. The agent exchanges its access token for one before a sensitive action. See Ask before a sensitive action.

{
  "typ": "txn_token+jwt",
  "sub": "agt_7f3a9c21",
  "txn": "0b7d6a52-…",
  "azd": {
    "action": "transfer:accounts",
    "resource": "account:4821",
    "context": { "amount": 1200, "currency": "USD", "account_type": "business" }
  }
}
ClaimDescription
iss, aud, expAs for the agent access token
typtxn_token+jwt
subThe same agent as the access token
txnThe identifier of this transaction
azd.actionThe action the token is for
azd.resourceWhat the action is done to
azd.contextThe details of the action, fixed when it was issued

Client assertion

Proves an agent's identity at the agent token endpoint. The agent creates and signs it with its own private key. This is private_key_jwt (RFC 7523). See Give an AI agent an identity.

PartValue
Header algEdDSA
Header kidThe key ID registered for the agent
iss and subThe agent ID
audThe token endpoint's full URL
jtiA new random value every time
expAt most 5 minutes after iat

An assertion is accepted once. Build a new one for every request.

Other signed tokens

A project signs these tokens for one purpose each. The page that uses each token lists its claims.

TokenSigned withLifetimeUsed in
Webhook action callRS256exp within 60 secondsActions at sign-in
Cloud role tokenRS256Cloud roles
Revocation eventThe project's keysStop an agent

Checking a token

A service validates a JWT itself, without a call to AuthFI. Most JWT libraries make these checks when you configure them with the issuer, the keys URL, the audience and the algorithm.

  1. Verify the signature with the key whose kid matches the token's header.
  2. Check that iss is the issuer of the project you trust.
  3. Check that aud names this service. Reject a token issued for another service.
  4. Check that exp is in the future.
  5. For a bearer token, check that the header typ is at+jwt. An ID token has typ: JWT and is not a bearer credential.
SettingID tokenAccess tokenAgent access token
Issuerhttps://acme.authfi.iohttps://acme.authfi.iohttps://acme.authfi.io
Keys/.well-known/jwks.json/.well-known/jwks.json/.well-known/jwks.json
AudienceYour client IDThe client ID it was issued to. For a service's token, your API's client ID.Your API's client ID
AlgorithmRS256RS256EdDSA
typJWTat+jwtat+jwt

For a transaction token, also compare azd with the request in front of you, and reject any difference. See Accept agents at your own API.

Keys. Find the key by kid. Cache the key set, and fetch it again when you meet a kid you do not know. See Keys and secrets.

Revocation. A signature check accepts a token until it expires. To learn sooner that an agent was revoked, subscribe to revocation events. An application with a secret can also ask the introspection endpoint.

Sign-in strength. Before a sensitive action, read acr from the token and deny the action if it is weaker than you need.