Skip to main content

Agent Token

When an agent works on its own behalf, with no user involved, it holds an agent token: an access token whose subject is the agent itself, so every call it makes is made as that agent and is traceable to it. (When the agent instead acts for a user, it holds a user token; see Agent Access on Behalf of Users.) The client_credentials grant, enabled by default on a newly registered agent, is the grant an agent uses to obtain a token for itself directly. A token exchange can also produce a token whose subject is the agent; see Agent-to-Agent Delegation.

Choose what the agent token carries

In the Console, on the Tokens tab, under Issued to, select Agent (the token the agent gets acting on its own; it is the default view). There, select the Access Token Attributes to embed and set the Token Validity period. Set the token's default audience on the Advanced tab. Through the API, configure these in the agent's OAuth token settings; see the Agents API Reference.

Get the agent token

curl -X POST https://localhost:8090/oauth2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u '<CLIENT_ID>:<CLIENT_SECRET>' \
-d 'grant_type=client_credentials' \
-d 'resource=https://api.example.com/invoices' \
-d 'scope=invoices:read invoices:write'

resource (RFC 8707) confines the token's audience and scopes to a single resource. Use it whenever the agent reaches more than one API, so a token minted for one resource cannot be replayed against another.

The scopes issued are the intersection of the scopes requested, what the target resource server defines, and what the agent has been granted (see Groups and roles). A requested scope that falls outside that intersection, including openid, is dropped from the issued token rather than rejected. Check the token's scope claim to see what it actually carries.

A request with no scope and no resource is not bound to a resource server: its audience is the agent's configured default audience, or its client ID when no default audience is set.

With private_key_jwt, drop the -u secret and send client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer with a signed client_assertion whose aud is the ThunderID issuer identifier, not the token endpoint URL. See Client Authentication Methods and Client Credentials.

Claims in the agent token

Every agent access token is a signed JWT (typ: at+jwt). A client_credentials token carries:

ClaimValue
subThe agent's resource ID.
issThe ThunderID instance URL.
audThe resolved resource server, or the agent's default audience (its client ID when none is set) for a scopeless request with no resource.
scopeThe scopes authorized through the agent's roles and groups.
client_idThe agent's client ID.
grant_typeclient_credentials.
exp, iat, nbf, jtiStandard JWT lifetime and identity claims.

There is no act claim, because the agent acts as itself and not for anyone else. The attributes and claims selected on the Tokens tab (the agent's schema attributes, its system attributes name and owner, the OU claims ouId, ouName, and ouHandle, and its groups and roles) are added only when selected.

Call a protected API with the agent token

Send the token as a Bearer token. The resource verifies the token's signature with the keys from https://localhost:8090/oauth2/jwks, checks the iss, aud, and exp claims, then authorizes the request against scope. To identify the caller, the resource reads sub (the agent itself) and client_id (the OAuth client that obtained the token); there is no act claim, because the agent acts as itself.

curl https://api.example.com/invoices -H 'Authorization: Bearer <ACCESS_TOKEN>'

Troubleshooting

ErrorLikely cause
invalid_clientWrong client ID or secret; with private_key_jwt, an invalid client assertion (wrong signing key, unknown kid, wrong aud, or expired); or the agent has no OAuth configuration.
unauthorized_clientThe agent is not registered for the requested grant type, or it authenticated with a method other than the one it is registered for.
invalid_requestBoth a client secret and a client assertion were sent. Use only the method the agent is configured for.
invalid_targetThe resource value does not match a registered resource server.
A 403 from the API after the token is acceptedThe token's scope or audience does not satisfy the resource server's policy.

Explore with AI

ThunderID LogoThunderID Logo

Product

DocsAPIsSDKs
© Copyright Linux Foundation Europe.For web site terms of use, trademark policy and other project policies please see https://linuxfoundation.eu/en/policies.