Discovering a protected resource
The printer knows the photo API because its developers told it about the API. They configured the address https://api.photos.example, the issuer https://auth.photos.example whose tokens it accepts, the scope photos.read, and the fact that tokens go in the Authorization header. Authorization server metadata reduced the authorization server's settings to one trusted issuer, but the link between the API and that issuer is still something a person typed.
Now the printer's developers want to go further. They want people to print from photo libraries the printer has never been set up for: any service that offers the same kind of photo API. You would type the address of your library's API, and the printer would work out the rest. That only works if an API can describe itself.
An API that describes itself
Protected resource metadata, published as RFC 9728, does for APIs what authorization server metadata does for authorization servers. OAuth calls an API that accepts access tokens a protected resource, and the specification lets each one publish a JSON document saying which authorization servers it accepts tokens from, which scopes it uses, and how it wants tokens presented.
An API is named by its resource identifier: an HTTPS URL with no fragment, and normally no query either. The photo API's identifier is https://api.photos.example, the same value the photo service puts in the aud claim of tokens issued for it.
To see what discovery can provide, follow it with an API whose answers we already know. Suppose the only thing the printer has been given is the photo API's address, and everything else has to come from the API.
Building the metadata address
All domains, tokens, and values in these examples are fictional. Like the authorization server's document, the API's lives at a well-known address built from its identifier, here with the name oauth-protected-resource:
GET /.well-known/oauth-protected-resource HTTP/1.1
Host: api.photos.example
The response is a JSON object that begins with the resource identifier and names the photo service's authorization server. It is shortened here:
HTTP/1.1 200 OK
Content-Type: application/json
{
"resource": "https://api.photos.example",
"authorization_servers": ["https://auth.photos.example"],
...
}
The insertion rule from authorization server metadata applies when the identifier has a path. If the photo service published a second version of its API with the identifier https://api.photos.example/v2, that API's document would be at https://api.photos.example/.well-known/oauth-protected-resource/v2.
Each protected resource publishes its own document at an address derived from its own identifier, even when one server hosts several APIs. The specification relies on that: because a document's address is fixed by the identifier it describes, a document can speak only for the resource whose address it sits under.
Asking the API directly
A client does not always know an API's identifier. Sometimes all it has is an address to call, such as the one you typed. RFC 9728 lets the API point the way when a client calls that address without a token. The printer requests https://api.photos.example exactly as you typed it:
GET / HTTP/1.1
Host: api.photos.example
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://api.photos.example/.well-known/oauth-protected-resource"
The request line shows / because that is how HTTP sends an address with no path. As Using access tokens described, a request that carries no token earns a 401 with a WWW-Authenticate challenge and no error code. The resource_metadata parameter adds the address of the API's metadata document. The printer fetches that document and continues from there.
The parameter is not limited to plain bearer tokens. An API that requires DPoP can include it in a DPoP challenge like those in Validating proofs at the server, and it can sit in the same challenge as other parameters, such as the max_age value a step-up challenge uses.
An API can also send the parameter later, to a client that already uses it, as a signal that its metadata may have changed. The client should then fetch the document again and validate it before using any new values. That lets an API move to a different authorization server without coordinating with every client in advance.
Whichever way the printer arrives at the document, what it does next is the same: it follows the document to the authorization server it names, as Locating its authorization servers describes. Trust and metadata validation then looks at what the printer must check before believing any of it, starting with whether the document matches the address it called.