Aller au contenu
apim.one

The guide

Access

Subscription, IP filtering, spike arrest and quota, OAuth2, OIDC, mTLS and token exchange: who is calling, with what proof, and how far.

OAuth2 is an authorisation delegation framework: an application obtains limited access to a resource on someone's behalf, without handling their password. OpenID Connect adds identification on top: knowing who the user is. The distinction carries direct consequences for design.

The access token is there to call the API, it is meant for the API, and the client has no business reading it. The identity token describes the authenticated user, it is meant for the client application, never for the API. An API that accepts an identity token as authorisation has a design fault, and it shows up by reading the token's audience.

Who proves what

Three questions arise on every call, and confusing them is the original error behind most designs. Authentication establishes who is calling. Authorisation establishes what that caller is allowed to do. And a third, often forgotten: on whose behalf, when an application calls in the name of a user.

An API key answers only the first, and only partly: it proves the caller holds the key, not who they are. It designates no end user and does not expire. It is a traffic identifier, insufficient as soon as there is data to protect.

What it does bring lies elsewhere, and it is the central mechanism of an API platform. The key, or the OAuth client, belongs to a declared application, and that application has subscribed to products. The platform therefore knows, before even looking at the token, which APIs this caller is allowed to call and at what volume. A call to an API with no subscription is refused without the service being consulted, and the quota counter is charged to the subscription, not to the IP address.

That is what separates an API platform from a proxy with a list of keys. The test goes to whoever runs the platform: when a partner asks for access to one more API, is it a subscription form they fill in, or a ticket that ends in a line of configuration written by hand? The second answer points to a catalogue that will never be up to date.

The access token answers all three. In its most common form it is a signed token, a JWT: a readable object carrying the issuer, the audience, an expiry date and the granted scopes, with a cryptographic signature to check it was not forged. Verifying it therefore requires no network call, and it is that property which drives everything that follows.

Which flow for which case

CaseFlowNote
Service to service, no userClient credentialsThe most common in the enterprise
Web application with a back endAuthorization code + PKCEThe secret stays server side
Mobile or single page applicationAuthorization code + PKCENo embedded secret
Device with no browserDevice authorizationTerminal, television set, printer
A service acting in the name of a userToken exchangeDetail below

Two flows are to be set aside, and RFC 9700 does not put them on the same footing. The password flow, where the application handles the user's credentials, must not be used, without reservation. The implicit flow is discouraged: the token comes back in the fragment of the redirect URL, never sent to the server but exposed to browser history and to the injection of a token into the authorisation response. Both survive mainly in copied configurations.

Token exchange

A user calls API A, which has to call API B to serve them. There are three answers.

Forwarding the user's token hands B a token whose audience designates A, with all the user's scopes. If B is compromised, that token can be used elsewhere.

Calling B with a service token makes the user disappear: audit and authorisation decisions can no longer rely on them.

Token exchange, standardised by RFC 8693, answers properly. A obtains from the identity provider a token meant for B, with reduced scopes, which preserves the original identity.

Where to validate the token

Client

Access token

Gateway

Signature, expiry, audience, issuer

Service

Business authorisation, revalidation

The gateway validates the shape of the token and rejects early, the service revalidates and applies the business authorisation, which the gateway cannot know.

Validating at the gateway alone leaves the backend defenceless the day a call bypasses it, and one eventually does. Validating at the service alone multiplies implementations, and therefore mistakes: audience left unchecked, algorithm accepted without constraint, keys never rotated.

The robust answer uses both, with distinct roles: authentication and scopes at the gateway, which rejects early and protects capacity, business authorisation in the service, the only place that knows who is allowed to see which record. A gateway that takes business authorisation decisions has picked up logic that does not belong to it, see the gateway.

Token lifetime, and revocation

This is the heaviest design decision on the page, and the least debated. It settles three things at once: the latency of every call, the coupling to the identity provider, and the real delay before an access can be cut off.

Two forms exist. The signed token is verified locally, with no network call, so with no added latency and no dependency on the IdP on the call path. It stays valid until it expires, whatever happens: nothing can cancel it.

The opaque token is a reference with no content, which the validator has to submit to the IdP through introspection, standardised by RFC 7662. Every call becomes dependent on the availability of the IdP, but revocation is immediate.

Signed tokenOpaque token
VerificationLocalIntrospection call
Added latencyNoneThe IdP's, on every call not cached
IdP outageTraffic carries onTraffic stops
RevocationAt expiryImmediate

The compromise that holds in most cases pairs a short-lived signed token, a few minutes, with a long-lived refresh token held by the client. The first is never revoked, it expires. The second is revocable, and since it is only used at spaced intervals, querying it puts no weight on the call path.

Hence the figure that has to be stated: the real delay before a consumer can be cut off is the lifetime of the access token. A platform that issues eight hour tokens cannot promise to cut a partner off in less than eight hours, whatever the console says. If the contractual or regulatory commitment is shorter, either the lifetime has to come down, or a revocation list consulted at the gateway has to be added for urgent cases only.

The usual setting, to be confirmed against exposure: five to fifteen minutes for an access token, a few hours to a few days for the refresh. Shortening further simply moves the load onto the IdP, which then becomes the component to size.

The points to watch

The audience. A token issued for API A must not be accepted by API B. Checking aud fits in one line of configuration. Its absence remains the most widespread fault.

The algorithm. Accepting the algorithm declared in the token header is a documented vulnerability. The list of permitted algorithms is set on the validation side.

Key rotation. The JWKS cache has to refresh itself, failing which the platform rejects every token at the identity provider's next rotation.

Clock skew. A few seconds of drift between issuer and validator are enough to reject valid tokens. The tolerance is set small. Set wide, it becomes a vulnerability.

Token size. A token loaded with roles can exceed the header size allowed by an intermediate component. The failure only hits users with many roles, which makes it slow to diagnose.

Scope granularity. A single scope across the whole platform protects nothing, hundreds of scopes are no longer granted correctly by anyone. The useful grain is the resource and the operation.

mTLS

OAuth2 identifies the calling application, mutual TLS identifies the channel. The two combine, and mTLS remains the mechanism expected by default on highly sensitive partner flows, particularly in banking and insurance.

Its two difficulties have nothing to do with cryptography. Certificate lifecycle first, which demands an inventory, expiry alerts and a renewal notice period written into the contract. Termination next: if a load balancer terminates TLS before the gateway, the client identity has to be passed on to the gateway through a trustworthy channel.

A partner certificate expiring is a common incident, and its peculiarity is being entirely predictable: the date is known at issuance.

Filtering and limits

Before any question of identity, two defences sit at the gateway and cost almost nothing. They are also the ones most often forgotten in configurations carried over from one project to the next.

IP address filtering. Restricting the origin of traffic to a known list. On a partner flow, on an administration API, on a back office, it is the measure that takes the least work for the most effect. It never replaces authentication, because an address can be spoofed and a partner changes infrastructure without warning, but it cuts the surface down before the first token is read. The trade-off is an inventory to keep, and an expiry to watch like a certificate's.

Rate limits, which are two distinct mechanisms. Confusion between the two is common and is paid for in incidents.

Spike arrestQuota
WindowThe second, the minuteThe day, the month
What it protectsBackend capacityThe commercial contract
Attached toThe route, the instanceThe subscription
On breachSmoothing or immediate rejectionRefusal until the next period
Who sets itOperationsThe product

Spike arrest absorbs a burst. A client sending a thousand calls in one second when the backend holds a hundred is stopped before it has brought the service down, and the rest of the consumers do not notice. The quota, for its part, says a subscription is entitled to a million calls a month, which has nothing to do with capacity and everything to do with what was sold.

A platform that has only the quota lets bursts through. A platform that has only spike arrest cannot bill, nor tell two consumers apart. Both are put in place, and the refusal returns a 429 with a header saying when to retry, failing which the client retries immediately and aggravates the very thing the limit was meant to avoid.

What the gateway protects, and what it does not

The OWASP API Security Top 10 lists the risks specific to APIs. The useful way to read it is to sort what is handled at the gateway from what is not.

RiskHandled at the gateway?
Object level authorisation, reaching someone else's recordNo, only the service knows the right
Broken authenticationYes, largely
Property level authorisation, modifying a forbidden fieldPartly, through schema filtering
Unrestricted consumptionYes
Function level authorisation, calling an administration operationPartly, through routing
Unrestricted access to sensitive business flowsNo, a matter for the service
Server side request forgeryPartly, through validation of incoming URLs
Security misconfigurationYes
Improper inventory, forgotten APIs or old versions still liveYes, if the inventory is kept
Unsafe consumption of third party APIsPartly

Authorisation faults, the most exploited of the lot, are handled in the code and checked in test. Buying a platform changes nothing there.

The gateway does cover volume and configuration risks well. Four defences are switched on from the start: spike arrest and quota as described above, inbound schema validation with unknown properties refused, size and depth limits on bodies, and error messages that reveal neither the technical stack nor an internal query.

The GraphQL case

A single route, a body that describes an arbitrary query: per call rate limiting loses its meaning when one call can cost a thousand times more than another. And while POST is the mandatory verb, the specification allows GET for reads, which is enough to slip traffic past a protection placed on POST alone.

The specific protections therefore have to be put in place explicitly: maximum depth, cost analysis, introspection disabled in production, persisted queries for known clients. A gateway that advertises GraphQL support often does no more than route it. The list above makes a good pre-sales questionnaire.

Updated August 2026.