Beta

Create a tenant

A new tenant starts with its own users, OAuth settings, audit history and logs. You are its first Tenant Admin.

BTL Admin

Validating metadata and issuer identity

The metadata document tells the printer where to send authorization codes, refresh tokens, and its client credentials. Anyone who could substitute a document of their own would receive all of them. Before the printer uses a single endpoint, it has to establish two things: that the document came from the authorization server it meant to ask, and that the document claims to describe that server and no other.

The issuer must match

The printer built the metadata address from an issuer it trusts. The issuer member in the document it receives must be identical to that issuer. If it is not, RFC 8414 says the client must not use any of the document's contents: not the endpoints that look right, not the keys, nothing.

All domains in these examples are fictional. To see what this check stops, recall the printer's second photo service, Pixel Vault, and suppose its authorization server has been compromised, as in Authorization server mix-up. The attacker controls auth.pixelvault.example and can publish any document there, including this one:

GET /.well-known/oauth-authorization-server HTTP/1.1
Host: auth.pixelvault.example

HTTP/1.1 200 OK
Content-Type: application/json

{
  "issuer": "https://auth.photos.example",
  "authorization_endpoint": "https://auth.pixelvault.example/authorize",
  "token_endpoint": "https://auth.pixelvault.example/token",
  ...
}

The document borrows the photo service's issuer and keeps Pixel Vault's own endpoints. If the printer accepted it, every connection to Pixel Vault would record https://auth.photos.example as its expected issuer. Pixel Vault's server could then send your browser on to the photo service, as it did in the mix-up lesson. The honest response that came back would carry the photo service's issuer, pass the printer's iss check, and its code would go to Pixel Vault's token endpoint. That is the mix-up attack again, carried out through configuration, and it is the gap Mix-up attacks and failure cases left for metadata validation to close.

Two checks prevent it, and each covers a different question:

  1. The printer fetches the document only from the address built from the issuer it trusts, over HTTPS, and checks that the server's certificate is valid for that host, as Validating a certificate described. That settles where the document came from.
  2. The issuer in the document is identical to the issuer the printer started from. That settles which authorization server the document claims to describe. A document fetched for https://auth.pixelvault.example must say https://auth.pixelvault.example, so it cannot speak for anyone else.

The second check matters on shared hosts too. The document at https://auth.photos.example/.well-known/oauth-authorization-server/business must name https://auth.photos.example/business. If it named https://auth.photos.example instead, the printer would reject it, because a document published for one issuer is never taken as describing another, even on the same host.

An exact comparison

The issuer check uses the same rule as the iss check in Checking the response issuer: the two strings must be identical, character for character, with no normalization. Metadata is where that string enters the printer's configuration, so the printer stores the issuer exactly as it was configured and compares the document's issuer with that stored value, never with a tidied version of either. If an operator types https://auth.photos.example/ with a trailing slash, the honest document fails the check, and the fix is to correct the configured value, not to relax the comparison. Once accepted, the same string is what the printer expects in every iss response parameter and in the iss claim of the photo service's tokens.

The issuer must use HTTPS, and so should every endpoint in the document. OAuth requires TLS at the endpoints that carry credentials, so a document listing an http:// token endpoint is a reason to stop. The key set address must use HTTPS as well.

A client library might load and check metadata like this:

async function loadMetadata(issuer: string) {
  const url = new URL(issuer);
  if (url.protocol !== 'https:' || url.search || url.hash) {
    throw new Error('An issuer must be an https URL with no query or fragment');
  }

  // Insert the well-known name between the host and any path.
  const path = url.pathname.replace(/\/$/, '');
  const address = `${url.origin}/.well-known/oauth-authorization-server${path}`;

  // The HTTPS client checks the server certificate. Never turn that off.
  const response = await fetch(address);
  if (response.status !== 200) throw new Error('Metadata is unavailable');
  const metadata = await response.json();

  // Compare with the configured issuer exactly, with no normalization.
  if (metadata.issuer !== issuer) {
    throw new Error('Issuer mismatch: do not use any part of this document');
  }
  return metadata;
}

Where the issuer comes from

These checks prove that a document speaks for an issuer. They cannot tell the printer whether that issuer is the right one to use for your photos. That decision comes first, and it comes from configuration the printer's operators control, or from a deliberate trust decision that has checks of its own.

It never comes from a value that arrived in a message someone else could influence:

  • the iss parameter on an authorization response, which is only ever compared, as Checking the response issuer explained, and never looked up;
  • an issuer or metadata address mentioned in an error response, a redirect, or a parameter added to the callback;
  • an address supplied by the very party that would benefit from the printer using it.

A client that fetched metadata for whatever issuer a response named, and then sent the code to that document's token endpoint, would be carrying out the mix-up attack on the attacker's behalf. The issuer check would pass, because the attacker's document would honestly name the attacker's issuer. Validation answers whether a document matches an issuer. Trusted configuration answers whether that issuer belongs in the exchange at all.

Keeping metadata fresh

RFC 8414 does not say how long a client may keep a metadata document. Clients cache it, using ordinary HTTP caching headers where the server sends them, and fetch it again on a schedule so that new endpoints and capabilities reach them. The key set is a separate document with its own rhythm: a verifier fetches it again when it meets a key identifier it does not have, as Token formats and validation described.

Every refreshed copy is validated exactly like the first. It still has to name the issuer the printer started from, so a refreshed document that names a different one is rejected, not adopted. If a refresh fails, the client can keep using its last validated copy while it retries. It should not fall back to guesses or to a copy it could not validate.

Some changes deserve attention even when the document validates. If the photo service's document stopped advertising S256 or iss support, a careful client would keep its own expectations and alert its operators, rather than quietly turning off checks it relies on. The per-server records from Checking the response issuer work the same way: the client's own configuration says which servers send iss, and a document that stops advertising support does not quietly remove that expectation.

RFC 8414 also defines signed_metadata, a JWT inside the document in which a named party vouches for the values; a client that supports it gives the signed values precedence over the plain ones, and a client that does not may ignore it.

All of this assumes the printer already knows which issuer to start from. When a client meets an API it was never configured for, the API itself can name its authorization servers, which is where Protected resource metadata begins.

Try it in the Lab

PUT IT INTO PRACTICE

Check your understanding

Try these questions before moving on. If an answer isn't right, use the feedback and try again.

0 of 2 answered correctly

Enable JavaScript to answer these questions and save progress in this browser.

QUESTION 1 OF 2The printer fetches metadata for the issuer https://auth.pixelvault.example, and the document says "issuer": "https://auth.photos.example". What should it do?

QUESTION 2 OF 2The printer is configured with the issuer https://auth.photos.example/business. The document it fetches from https://auth.photos.example/.well-known/oauth-authorization-server/business says "issuer": "https://auth.photos.example". What should it do?

We value your privacy

We use cookies and similar technologies to enhance your browsing experience, and analytics to understand our traffic. By clicking "Allow All", you consent to optional analytics. Cookie Policy

Learn identity