Overview
Multi-Resource Refresh Tokens (MRRT) allow using a single refresh token to obtain access tokens for multiple audiences, simplifying token management in applications that interact with multiple backend services.Read more about Multi-Resource Refresh Tokens in the Auth0 documentation.
Basic Configuration
Configure a default audience in your Auth0 client initialization:lib/auth0.ts
The
offline_access scope is required to receive a refresh token that can be used with MRRT.Configuring Scopes Per Audience
When working with multiple APIs, you can define different default scopes for each audience by passing an object instead of a string:lib/auth0.ts
How Scope Configuration Works
- Each key in the
scopeobject is anaudienceidentifier - The corresponding value is the scope string for that audience
- When calling
getAccessToken({ audience: "..." }), the SDK automatically uses the configured scopes for that audience - When additional scopes are passed in the method call, they are merged with the default scopes for that audience
When using scope as an object without an entry for the default audience, the SDK defaults to
DEFAULT_SCOPE (only for the default audience used during authentication).Usage Examples
App Router - Route Handlers
app/api/data/route.ts
Pages Router - API Routes
pages/api/data.ts
Pages Router - getServerSideProps
pages/dashboard.tsx
Middleware
middleware.ts
The syntax for calling
getAccessToken() varies depending on the context:- App Router (Server Components, Route Handlers, Server Actions):
getAccessToken(options) - Pages Router (API Routes, getServerSideProps):
getAccessToken(req, res, options) - Middleware:
getAccessToken(req, res, options)
Token Management Best Practices
Configure Broad Default Scopes
Define comprehensive scopes in yourAuth0Client constructor for common use cases. This minimizes the need to request additional scopes dynamically, reducing the number of tokens stored:
lib/auth0.ts
Minimize Dynamic Scope Requests
Avoid passingscope when calling getAccessToken() unless absolutely necessary. Each audience + scope combination results in a token to store in the session, increasing session size:
Consider Stateful Session Storage
If your application requires strict least privilege with many dynamic scope requests, use stateful session storage instead of cookie-based sessions to avoid size limitations:lib/auth0.ts
Token Storage and Session Size
Each unique combination ofaudience and scope results in a separate access token stored in the session:
Error Handling
Handle MRRT-specific errors appropriately:app/api/data/route.ts
Refresh Token Rotation
Common Issues and Solutions
Token Returns Default Audience Instead of Requested
Problem: Requesting a token for a specific audience returns a token for the default audience. Solution: Verify that the audience is included in your Application’s Refresh Token Policies in the Auth0 Dashboard.Session Cookie Size Exceeded
Problem: Browser rejects cookies due to size limits. Solution:- Reduce the number of audiences/scope combinations
- Use stateful session storage
- Configure broader default scopes to minimize dynamic requests
Missing offline_access Scope
Problem: Cannot obtain refresh token for MRRT.
Solution: Add offline_access to your authorization parameters:
Race Conditions with Token Refresh
Problem: Multiple concurrent requests cause refresh token rotation issues. Solution: Configure an overlap period in Auth0 Dashboard or handle requests sequentially when possible.Best Practices Summary
- Configure MRRT Policies in Auth0 Dashboard with all required audiences
- Use broad default scopes to minimize token storage
- Include
offline_accessscope for refresh tokens - Monitor session size and use stateful storage if needed
- Handle token errors gracefully with appropriate fallbacks
- Test audience configuration during development
- Document your audiences and their required scopes