MCP Auth is here
Drop-in OAuth for your MCP Servers
Learn more
API Authentication
Jun 19, 2025

Resource Indicators (RFC 8707) for OAuth 2.0: A developer's guide

If you’re building apps that interact with multiple APIs using OAuth 2.0, you’ve probably wondered:

How does the authorization server know which resource server the client wants to access?

That’s where RFC 8707 comes in. It's a simple but powerful addition to OAuth 2.0 that lets clients explicitly tell the authorization server which specific resource they want to access.

This might sound minor, but it solves key security and usability challenges in modern multi-API environments.

The Problem: ambiguous token destinations

In classic OAuth 2.0, when a client requests an access token, the authorization server doesn't know where that token will be used. Consider this scenario:

  • Your company has multiple APIs: Photos API, Videos API, and Documents API
  • All three are protected by the same authorization server
  • A mobile app requests an access token

The question: Which API is this token for? All of them? Just one?

Without knowing the intended destination, the authorization server faces several problems:

  • Security risks: Access tokens might be valid for multiple resources, leading to unintended access
  • Poor optimization: Without knowing the destination, the token might include the wrong scopes or be misconfigured
  • Weak audience restrictions: Hard to prevent token theft and replay attacks. The authorization server doesn't know what audience (aud) to set in the token

In short: The client knows where it’s going, but the authorization server doesn’t.

The solution: resource parameter

RFC 8707 introduces a new resource parameter that clients include in OAuth requests:

resource=https://api.photos.example.com

This tells the authorization server: "I want a token specifically for the Photos API."

Practical example

Say a client wants to access the Photos API

POST /token Host: authorization-server.example.com Content-Type: application/x-www-form-urlencoded grant_type=client_credentials& client_id=client123& client_secret=secret& resource=https%3A%2F%2Fapi.photos.example.com

Result

The authorization server issues a token that:

  • Only works at https://api.photos.example.com
  • Has "aud": "https://api.photos.example.com" in the JWT
  • Prevents use of other APIs. Even if the token is leaked, it won’t work elsewhere

Guidelines for developers

1. Use specific base URIs

Guideline: Use the most specific URI for the complete API or set of resources you intend to access. Examples:

  • https://api.example.com/: For exclusive application on that host
  • https://api.example.com/app/: For one of many apps on that host
  • https://apps.example.com/scim/: For SCIM API with multiple endpoints like /Users, /Groups, /Schemas

2. Single resource preferred

Guideline: Prefer requesting a single resource per token.

Why: Multiple audiences create security risks: if the Photos API gets your token, it could potentially use it to access the Videos API too.

3. Tenant-specific access

In multi-tenant systems, tokens should not be valid across tenants. You can scope them by embedding tenant IDs in the resource URI:

For multi-tenant systems:

  • Avoid: https://api.example.com/app
  • Use: https://api.example.com/tenant123/app

Why it matters

Real-world implementation example

Here's how this looks in a typical authorization code flow:

Step 1: Authorization request

GET /authorize?response_type=code &client_id=myapp &scope=read:photos &resource=https://api.photos.example.com &redirect_uri=https://myapp.com/callback

Step 2: Token exchange

POST /token grant_type=authorization_code &code=abc123 &resource=https://api.photos.example.com

Step 3: Receive audience restricted token

{ "access_token": "eyJ...", "token_type": "Bearer", "scope": "read:photos", "aud": "https://api.photos.example.com" }

The token's aud claim will be https://api.photos.example.com, making it useless anywhere else.

Where to use the resource parameter

Error handling

If the authorization server doesn’t recognize or support the requested resource, it may return: Error: invalid_target

Response:

{ "error": "invalid_target", "error_description": "The requested resource is not valid or supported" }

Make sure your client handles this gracefully.

TL;DR

Final thought

Think of RFC 8707 as adding a “destination address” to OAuth tokens. It’s a small addition, but it makes a big difference when you're dealing with complex, multi-API ecosystems and want your tokens to be precise, secure, and reliable.

If your authorization server supports it, start using the resource parameter today.

No items found.
On this page
Share this article
Secure your APIs with OAuth

Acquire enterprise customers with zero upfront cost

Every feature unlocked. No hidden fees.
Start Free
$0
/ month
3 FREE SSO/SCIM connections
Built-in multi-tenancy and organizations
SAML, OIDC based SSO
SCIM provisioning for users, groups
Unlimited users
Unlimited social logins
API Authentication

Resource Indicators (RFC 8707) for OAuth 2.0: A developer's guide

Ravi Madabhushi

If you’re building apps that interact with multiple APIs using OAuth 2.0, you’ve probably wondered:

How does the authorization server know which resource server the client wants to access?

That’s where RFC 8707 comes in. It's a simple but powerful addition to OAuth 2.0 that lets clients explicitly tell the authorization server which specific resource they want to access.

This might sound minor, but it solves key security and usability challenges in modern multi-API environments.

The Problem: ambiguous token destinations

In classic OAuth 2.0, when a client requests an access token, the authorization server doesn't know where that token will be used. Consider this scenario:

  • Your company has multiple APIs: Photos API, Videos API, and Documents API
  • All three are protected by the same authorization server
  • A mobile app requests an access token

The question: Which API is this token for? All of them? Just one?

Without knowing the intended destination, the authorization server faces several problems:

  • Security risks: Access tokens might be valid for multiple resources, leading to unintended access
  • Poor optimization: Without knowing the destination, the token might include the wrong scopes or be misconfigured
  • Weak audience restrictions: Hard to prevent token theft and replay attacks. The authorization server doesn't know what audience (aud) to set in the token

In short: The client knows where it’s going, but the authorization server doesn’t.

The solution: resource parameter

RFC 8707 introduces a new resource parameter that clients include in OAuth requests:

resource=https://api.photos.example.com

This tells the authorization server: "I want a token specifically for the Photos API."

Practical example

Say a client wants to access the Photos API

POST /token Host: authorization-server.example.com Content-Type: application/x-www-form-urlencoded grant_type=client_credentials& client_id=client123& client_secret=secret& resource=https%3A%2F%2Fapi.photos.example.com

Result

The authorization server issues a token that:

  • Only works at https://api.photos.example.com
  • Has "aud": "https://api.photos.example.com" in the JWT
  • Prevents use of other APIs. Even if the token is leaked, it won’t work elsewhere

Guidelines for developers

1. Use specific base URIs

Guideline: Use the most specific URI for the complete API or set of resources you intend to access. Examples:

  • https://api.example.com/: For exclusive application on that host
  • https://api.example.com/app/: For one of many apps on that host
  • https://apps.example.com/scim/: For SCIM API with multiple endpoints like /Users, /Groups, /Schemas

2. Single resource preferred

Guideline: Prefer requesting a single resource per token.

Why: Multiple audiences create security risks: if the Photos API gets your token, it could potentially use it to access the Videos API too.

3. Tenant-specific access

In multi-tenant systems, tokens should not be valid across tenants. You can scope them by embedding tenant IDs in the resource URI:

For multi-tenant systems:

  • Avoid: https://api.example.com/app
  • Use: https://api.example.com/tenant123/app

Why it matters

Real-world implementation example

Here's how this looks in a typical authorization code flow:

Step 1: Authorization request

GET /authorize?response_type=code &client_id=myapp &scope=read:photos &resource=https://api.photos.example.com &redirect_uri=https://myapp.com/callback

Step 2: Token exchange

POST /token grant_type=authorization_code &code=abc123 &resource=https://api.photos.example.com

Step 3: Receive audience restricted token

{ "access_token": "eyJ...", "token_type": "Bearer", "scope": "read:photos", "aud": "https://api.photos.example.com" }

The token's aud claim will be https://api.photos.example.com, making it useless anywhere else.

Where to use the resource parameter

Error handling

If the authorization server doesn’t recognize or support the requested resource, it may return: Error: invalid_target

Response:

{ "error": "invalid_target", "error_description": "The requested resource is not valid or supported" }

Make sure your client handles this gracefully.

TL;DR

Final thought

Think of RFC 8707 as adding a “destination address” to OAuth tokens. It’s a small addition, but it makes a big difference when you're dealing with complex, multi-API ecosystems and want your tokens to be precise, secure, and reliable.

If your authorization server supports it, start using the resource parameter today.

No items found.
Ship Enterprise Auth in days