In Part One of this series, we worked through three foundational authorization scenarios. In Scenario two, we introduced the third-party partner app: a separate company's application utilizing a DCR registered Client. To secure it, we established an immutable permission ceiling using an Auth0 Client Grant.
The formula was straightforward for the analytics partner, that resolved to read:analytics and nothing more, regardless of what the app requested:

That ceiling is the property we want to keep.
But what happens when that "partner app" is not a human-facing web application, but an autonomous AI agent?
Three Assumptions That Break With Agents

Our standard integration model relied on a predictable world, assuming three things:
- Static Permissions: You pre-registered the application and assigned its Client Grant manually in the Dashboard.
- Predictable Life Cycles: Scopes were static — known at registration time and unchanged at runtime.
- Direct Delegation: The app made direct API calls, acting as a single hop from the client to the resource server.
AI agents shatter all three assumptions.
Pre-registration does not scale when an agentic platform might spin up thousands of ephemeral agent instances, each needing a distinct OAuth client identity. Scopes are discovered dynamically at runtime based on the agent's reasoning. And most importantly, agents are multi-hop by nature: a user talks to a control server, which calls a downstream API, which triggers a data warehouse.
At every hop, the access token needs to carry two critical pieces of context: which user authorized this, and which agent is acting on their behalf. Let's look at how we can rebuild these architectural pillars using modern Auth0 capabilities.
The New Baseline for Third-Party Clients is Strict Mode
Before strict mode, a third-party app could theoretically access an API without a Client Grant if the API's underlying access policy was permissive. Strict mode closes that gap permanently.
When you enable Strict Mode in an API, Auth0 enforces the following: :
- PKCE is mandatory: Strict alignment with OAuth 2.1 best practices.
- Explicit Grants Required: Every third-party client must have an explicit Client Grant to access an API in your tenant
- No Workarounds: The permission ceiling is enforced, ignoring permissive local policies.
Configure it in the Auth0 Dashboard:
Applications → APIs → [Your API] → Settings → Third-party Security Mode → Strict
Or via the Management API:
PATCH /api/v2/resource-servers/{id} { "third_party_security_mode": "strict" }
For agents, this matters precisely because agent registrations happen programmatically and at scale. Without strict mode, a misconfigured Client ID Metadata Documents (CIMD) registration could produce a rogue client. Strict Mode makes that structurally impossible.
Bootstrapping Identity with CIMD
Classic Dynamic Client Registration is powerful but inherently risky without guardrails. CIMD is the constrained, secure alternative.

Instead of an agent sending its desired configuration directly to Auth0, the agent publishes a metadata document at a well-known HTTPS URL. Auth0 fetches, validates, and locks in that document before issuing a client_id.
The Metadata Document (hosted by the agent):
{ "client_name": "Analytics Reporting Agent v1.2", "redirect_uris": ["https://agent.example.com/callback"], "grant_types": ["authorization_code", "refresh_token"], "token_endpoint_auth_method": "private_key_jwt", "scope": "read:analytics" }
Currently Auth0 supports pre-registering Third Party Client using the Management API or the Dashboard. In a future release support for dynamic registered clients through CIMD will follow.
Using the Management API the registration request will be:
POST https://<YOUR_TENANTS_MANAGEMENTAPI_DOMAIN>/api/v2/clients/cimd/register Content-Type: application/json { "external_client_id": "https://<AGENT_URL>/.well-known/client-metadata.json" }
Auth0's response:
{ "client_id": "tpc_8AvZNHu2qSK5KxoSMVAv7c", "mapped_fields": { "external_client_id": "https://<AGENT_URL>/.well-known/client-metadata.json", "name": "Analytics Reporting Agent v1.2", "callbacks": [ "https://agent.example.com/callback" ], "grant_types": [ "authorization_code", "refresh_token" ], "app_type": "native", "token_endpoint_auth_method": "private_key_jwt" } }
Auth0's response returns a client_id. Because this is a third-party client, the API's configured default permissions apply automatically at registration, instantly creating our vital permission ceiling.
The Delegation Chain
CIMD successfully gives the agent a client identity. But when the agent calls a downstream service, the service needs cryptographic proof of the delegation chain. This is where RFC 8693 Token Exchange comes in.
Here is the flow:
- The user authenticates and receives a standard subject token.
- The agent needs to call the downstream API. It presents the user's token, along with its own client credentials, to Auth0’s
/oauth/tokenendpoint.. - Auth0 issues a delegated token that carries both the original user subject (sub) and the acting agent context (act).
The token exchange request:
POST https://YOUR_DOMAIN/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:token-exchange &subject_token=eyJhbG... &subject_token_type=urn:ietf:params:oauth:token-type:access_token &actor_token=eyJhbG... &actor_token_type=urn:ietf:params:oauth:token-type:jwt &audience=https://reporting.example.com/api &scope=read:analytics
The resulting JWT (Decoded Payload):
{ "iss": "https://YOUR_DOMAIN/", "sub": "auth0|user_abc123", "aud": "https://reporting.example.com/api", "scope": "read:analytics", "act": { "sub": "tpc_AgxY8z..." }, "exp": 1748390400 }
Notice the payload. The sub (subject) is still the user. But we now have an act (actor) claim carrying the agent's client ID. Every downstream service receiving this token can now cryptographically verify exactly who is acting, and on whose behalf.
The Agentic Workflow
Let's replay Scenario Two from Part One in the series, but now with our new agentic architecture:.
- Bootstrap (CIMD): The agent publishes its metadata. Auth0 validates it, returns a tpc_ client ID, and automatically applies the
read:analyticspermission ceiling. - Authorize (User Consent): The user interacts with the agent, sees a consent screen, and approves. The agent receives an access token scoped to
read:analytics, bound to the user. - Execute (Token Exchange): The agent needs to pull data from a deep downstream reporting service. It exchanges the user's token via RFC 8693, resulting in a token with an act claim proving its delegation rights.
The authorization formula from Part One has successfully stretched across the multi-hop chain: (User Permissions ∩ App Permissions) ∩ Requested Scopes, strictly enforced at every link.
What Strict Mode Does Not Cover
Client Grants control what an agent type can do (read:analytics). But they do not control which specific records it can access. What if report access should be strictly scoped so the agent can only read reports that this specific user owns?
That requires Fine-Grained Authorization (FGA) — relationship-based access control where the decision depends on the relationship between a user, a resource, and a context. Auth0 FGA handles exactly this, and we will cover it in Part Three.
Put It Into Practice
- Enable strict mode on your API.
- Configure default permissions.
- Publish a CIMD document: Host it at a stable HTTPS URL, then register a Client with your metadata to test agent registration.
- Try Token Exchange and verify the result using jwt.io.
Resources
- Auth0 Guide: First-Party vs. Third-Party Applications — Learn how Auth0 separates operational trust boundaries for partner integrations.
- Auth0 Docs: Dynamic Client Registration — Discover how to configure automatic client onboarding securely.
- Auth0 Docs: On-Behalf-Of Token Exchange — Step-by-step documentation on exchanging subject tokens and minting delegation claims.
- Migrate to Enhanced Security for Third-Party Applications
- Part One: A Guide to Auth0 Authorization with Scopes, Roles, and Client Grants — Review the foundational "permission ceiling" concept that makes this agentic security model possible
If you do not already have an Auth0 account yet, create one for free.


