Introducing RFC 9728: Say hello to standardized OAuth 2.0 resource metadata
OAuth 2.0 just got a major upgrade in how resources describe themselves — find out what RFC 9728 introduces and why it matters.
8 years and 8 months. That’s how long it took for the RFC 9728 to get published.
The first individual draft for what would become RFC 9728 landed in August 2016. It didn’t become an official RFC until April 2025. That’s longer than most startups live!

So, what exactly took nearly a decade to finalize?
Well, RFC 9728 is all about giving OAuth 2.0 resource servers (the APIs behind the scenes) a proper way to describe themselves using metadata. If you've worked with OAuth before, you know that clients and authorization servers have long had ways to advertise their capabilities (thanks to RFCs like 7591 and 8414). But protected resources? They were left out of the party—until now.
Let’s unpack what RFC 9728 finally brings to the table—and why it was worth the wait.
What is RFC 9728?
In short: it’s a new spec that lets resource servers (a.k.a. the APIs behind your apps) describe themselves via metadata, just like authorization servers already can.
Think of it like giving your API an online dating profile: it tells clients and auth servers what it supports, what scopes it likes, and how to talk to it securely.
Before RFC 9728, there was no standard way for clients or auth servers to discover the capabilities of a protected resource. You had to document everything, or hardcode stuff. Now there’s a metadata endpoint for that.
What’s in the metadata?
The metadata is a simple JSON document (optionally signed as a JWT) published at a .well-known
URI, like this:
Here’s what it might contain:
Let’s break those down:
resource
: Required—a URI that uniquely identifies this resource. Think of it as its name tag.authorization_servers
: Optional—lists which auth servers can issue access tokens for this resource.bearer_methods_supported
: Optional—lists the OAuth 2.0 bearer token presentation methods that this protected resource supports.jwks_uri
: Optional—where your resource’s public keys live (used to validate signed requests or tokens).scopes_supported
: Recommended—what scope strings your API accepts. Great for dynamic UIs or clients.
Other optional fields are allowed too, but these are the main ones.
Why did it take so long to publish?
RFC 9728 was a long time coming. First drafted way back in 2016, it didn’t actually get published until April 2025. That’s almost nine years! So what happened?
When RFC 9728 was first proposed, it didn’t get much attention. Its sibling spec, RFC 8414 (for Authorization Server Metadata), was more immediately useful and became widely adopted. But Protected Resource Metadata? People weren’t really asking for it yet, so it just kind of sat there.
Fast forward a few years and the world looked different. Microservices exploded, dynamic integrations became the norm, and AI agents started showing up in real workflows. Suddenly, having a standard way for clients to discover what an API supports — things like token formats or required scopes — made a lot more sense. The use case caught up with the spec.
Finally, like any IETF standard, RFC 9728 went through a lot of review and discussion. Building consensus, incorporating feedback, and making sure it would actually work for everyone takes time. A lot of time, in this case.
Why should devs care?
This spec adds a ton of quality-of-life improvements:
- Easier integrations via metadata discovery: Instead of relying on out-of-band documentation or hardcoded assumptions, clients can now fetch metadata about a protected resource directly from a standardized
.well-known/oauth-protected-resource
endpoint. This includes information like supported token types (e.g., Bearer, DPoP), required scopes, and token introspection URLs. It’s the same concept asopenid-configuration
—but for APIs. - Better security: Metadata can be served over HTTPS and optionally signed as a JWT (
application/oauth-protected-resource-jwt
). This gives clients a way to verify the authenticity and integrity of the metadata they receive. It reduces the risk of misconfigurations (like pointing to the wrong authorization server) and defends against certain classes of spoofing or misrouting attacks. - Dynamic discovery: If you're building a client that talks to many different APIs—think API gateways, API developer tools, or federated service meshes—you no longer need to manually configure every endpoint’s scopes, issuer, or key sources. Clients can dynamically discover what each API expects and configure themselves accordingly. This enables plug-and-play support for new APIs without code changes.
How it works in practice
Let’s say your client app tries to access an API without knowing much about it. Instead of manually configuring everything up front, you can leverage the new .well-known
metadata endpoint defined by RFC 9728 — and sometimes, you don’t even need to know that URL in advance.
Step 1: Hit the API
Your client makes a request to the resource:
Step 2: Get redirected via WWW-Authenticate
If the resource is protected, the server responds with a 401 Unauthorized
and includes a WWW-Authenticate
header like this:
That resource_metadata
value is your shortcut. It tells the client exactly where to go to learn how to interact with the resource.
Step 3: Fetch the metadata
Now your client fetches:
And receives:
Instead of plain JSON, the server can return a signed JWT containing the metadata. Here’s what the client might receive from the .well-known/oauth-protected-resource
endpoint:
This JWT is signed using the authorization server’s private key. The client can:
- Decode and verify it using the
kid
from the JWT header - Fetch the public key from the
jwks_uri
of theissuer
Step 4: Configure on the fly
The client now knows:
- Where to request access tokens (
token_endpoint
) - Which scopes it needs
- What auth methods are supported
- Which issuer to trust
No out-of-band docs, no hardcoded values — it’s all self-discovering.
Best practices
A few things to keep in mind:
- Always use HTTPS: This isn’t just a suggestion — it's a requirement. Metadata endpoints must be served over HTTPS to prevent tampering or man-in-the-middle attacks. Clients should reject any response served over plain HTTP.
- Sign metadata whenever possible: Publishing metadata as a signed JWT (using
application/oauth-protected-resource-jwt
) adds a layer of trust. It allows clients to verify that the metadata came from a legitimate source and hasn’t been altered. Use keys from your authorization server’s JWKS URI, and rotate them responsibly. - Don’t blindly follow redirects: Clients should not automatically follow HTTP redirects when resolving metadata URLs. Redirects can be abused to trigger SSRF (Server-Side Request Forgery) or phishing. If you must support redirects, ensure strict validation of target URLs against a known allowlist.
- Validate all metadata fields: Before acting on any metadata, clients should perform schema and value validation:
- Ensure
issuer
matches expected patterns - Verify the
token_endpoint
uses HTTPS - Check
scopes_supported
for sanity (e.g., no unexpected wildcard scopes)
- Ensure
- Cache intelligently: Metadata is unlikely to change frequently. Clients should cache it (respecting HTTP caching headers or setting their own expiry policy) to reduce load and improve startup time. Refresh periodically, not on every request.
- Fail securely: If metadata discovery fails, fall back gracefully. Don’t skip validation or default to insecure behavior. Surface clear errors to the developer or user, and avoid making assumptions about scopes, issuers, or endpoints.
- Monitor for changes: While the spec doesn't mandate versioning, you should monitor for unexpected changes in metadata fields — especially
issuer
,token_endpoint
, or auth methods. These could indicate a misconfiguration or malicious alteration.
Final thoughts
RFC 9728 might seem like a small addition, but it ties together the OAuth 2.0 ecosystem in a really neat way. Clients, authorization servers, and resource servers can all speak the same discovery language now.
If you’re building APIs that rely on OAuth, consider exposing metadata as per RFC 9728. It’s simple, powerful, and saves everyone time.