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

Resource server responsibilities

The photo API validates every token it receives and decides every request, as the Tokens and resource servers lessons described. That code is written once. The facts it depends on keep moving: the authorization server rotates its keys, the API gains a staging copy, server clocks drift, and the photo service decides its scopes need redesigning.

An API that accepts tokens stays correct only while those facts stay correct, and its team needs to notice quickly when one of them does not.

Trusting the right issuer

All domains and identifiers in these examples are fictional. The photo service runs its API in two environments, each with its own authorization server:

SettingProduction APIStaging API
Trusted issuerhttps://auth.photos.examplehttps://auth.staging.photos.example
Expected audiencehttps://api.photos.examplehttps://api.staging.photos.example
Accepted algorithmES256ES256
Clock leeway30 seconds30 seconds

Each API trusts exactly one issuer, and that value comes from its deployment configuration, never from anything inside a token. The production API does not also accept staging tokens for convenience during testing. Staging authorization servers tend to have test accounts with known passwords, relaxed policies, and more people with administrative access. A production API that accepted their tokens would give all of those people a way into real photo libraries.

The key set address is not configured separately. The API reads jwks_uri from its trusted issuer's metadata, so the issuer and its keys cannot drift out of step. A deployment check that sends a correctly signed staging token to the production API, and expects a rejection, catches a mixed-up configuration before customers or attackers do.

Keys, clocks, and caches

Token formats and validation explained how the API selects a key by kid and fetches the key set again when it meets one it does not know. Operating that mechanism means making sure it can work when it is needed. The API's network rules must allow it to reach the key set address. Nobody should paste a single public key into its configuration as a shortcut, because that copy will not change when the photo service starts signing with photos-2027-01. Rejections for an unknown kid deserve their own alert: a few may be forgeries, but a wave of them just after a rotation means the API is not seeing the new key.

Lifetime checks depend on the API's own clock. Token formats and validation also described the small tolerance that absorbs clock differences. The photo API allows thirty seconds, and each of its servers keeps time with a network time service so that the tolerance rarely matters. A server whose clock drifts further than that starts rejecting fresh tokens as expired, or accepting expired ones, and only that server does so, which makes the fault look random. Monitoring each server's clock offset turns it into an ordinary alert.

Several things are cached: the metadata document, the key set, and, where the API introspects, recent introspection results. Each cache needs a maximum age and a decision about what happens when it cannot refresh. For the key set, the sensible choice is to keep using the cached keys and raise an alert. For introspection results, Token introspection set a stricter rule: a cached answer is never stretched past its normal lifetime, and a token that cannot be checked is refused.

Changing scopes without breaking clients

Years ago, the photo service offered a single scope called photos that allowed reading, uploading, and deleting. It now offers photos.read, albums.create, and photos.delete, and wants the old scope gone. Some clients still request it, and refresh tokens issued under it are still producing access tokens.

A change like this runs in stages:

  1. Add. The new scopes go live. The API accepts them, and for now it still treats photos as satisfying any of them.
  2. Measure. The API and the authorization server count which clients still request or present photos, by client_id.
  3. Stop new grants. New registrations cannot request the old scope, and the developers of existing clients are asked to switch.
  4. Announce a date. Each remaining client's developers hear when the old scope stops working and what their users will see.
  5. Remove. After the date, the API no longer accepts photos, and grants that still carry it need the person's approval again.

The order matters because tokens outlive deployments. An access token issued at 08:59 with photos in its scope is still presented at 09:05, and a refresh token issued last year can keep producing tokens with the old scope until its grant changes. The API keeps accepting both until the measurements show the old scope has stopped arriving or the announced date has passed.

The API also describes itself. If it publishes protected resource metadata at https://api.photos.example/.well-known/oauth-protected-resource, as the Protected resource metadata lessons described, its scopes_supported list changes in the same release as the scopes. Generating that document from the same configuration the API enforces keeps the description and the behavior from drifting apart.

Watching rejections and outages

Every rejection the API returns is a small piece of evidence, and counted by reason and by client they become useful. Expired tokens from one client suggest it is not replacing tokens before they expire. insufficient_scope from another suggests it never asked for the access it now uses. Tokens with the wrong audience may mean a client is sending tokens meant for another API, or that someone is replaying tokens taken from elsewhere. The decision records described in Enforcing access at an API already hold the reason and the client. Counting them, and alerting when a count jumps, is what turns those records into monitoring.

The API also needs a plan for the hours when the authorization server is unavailable. Local JWT validation keeps working with cached keys, while anything that depends on introspection fails closed, as Token introspection explained. The plan decides in advance which routes are which, sets short timeouts so a slow authorization server does not tie up every request the API is handling, and spaces out retries so that thousands of introspection calls do not arrive together the moment the authorization server recovers.

None of this appears in a request trace on an ordinary day. It is what keeps the trace looking ordinary on the day the photo service rotates its signing key.

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 production photo API receives a correctly signed token whose iss is the staging authorization server. What should it do?

QUESTION 2 OF 2The photo service is retiring its catch-all photos scope. Why does the API keep accepting it for a while after the new scopes go live?

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