Skip to content

The talk on 2026-06-30 was not about replacing OAuth or OpenID Connect.

That is an important starting point, because identity protocol discussions can quickly turn into acronym collecting. PAR, JAR, DPoP, mTLS, FAPI, RAR, JARM, token exchange, federation. All useful in the right place. None of them changes the basic reality that most modern applications still need a well-run OAuth and OIDC foundation.

What has changed is the secure deployment baseline. Browser applications are heavier. APIs call other APIs. Non-human actors do more work. Tokens move through logs, proxies, support workflows, local tools, telemetry, and browser runtimes. In that environment, “the caller has a token” is no longer a strong enough mental model.

The rule I used in the conference session was deliberately simple:

Keep tokens where they can be defended, and bind them when they must travel.

The rest of the landscape follows from that rule.

flowchart TD
    Rule["2026 rule: defend or bind tokens"]
    Rule --> Baseline["Secure baseline"]
    Rule --> Boundary["Browser boundary"]
    Rule --> Proof["Sender constraint"]
    Rule --> Actors["API-to-API access"]
    Rule --> Assurance["High assurance"]

    Baseline --> B1["Code flow + PKCE"]
    Boundary --> C1["BFF when risk justifies it"]
    Proof --> D1["DPoP or mTLS"]
    Actors --> E1["Audience and token exchange"]
    Assurance --> F1["PAR, JAR, JARM, RAR, FAPI"]

    classDef principle fill:#eef6ff,stroke:#2563eb,color:#10233f
    classDef domain fill:#f6f8fb,stroke:#64748b,color:#172033
    classDef action fill:#ffffff,stroke:#94a3b8,color:#172033
    class Rule principle
    class Baseline,Boundary,Proof,Actors,Assurance domain
    class B1,C1,D1,E1,F1 action

The baseline moved

The baseline is not exotic. That is the point.

For new designs, authorization code with PKCE should be the ordinary default. The implicit grant and password grant belong in migration discussions, not in new architecture diagrams. Redirect URI matching should be exact. Clients that interact with more than one issuer need to protect themselves against mix-up attacks, including validating the iss value defined by RFC 9207. Refresh tokens need replay protection, usually through rotation or sender constraint.

That summary comes from standards guidance, not from a ProAuth-specific opinion. RFC 9700, the OAuth 2.0 Security Best Current Practice, is the anchor. The OAuth 2.1 document is still an IETF draft, so it should be cited as work in progress, but it is useful because it consolidates many of the same modern expectations into a cleaner framework.

In the demo, the first flow showed the baseline rather than a novelty feature: OIDC code flow with PKCE, issuer information on the callback, audience validation at the API, and refresh-token behavior that makes replay visible. That is where most teams should start. If the ordinary flow is weak, advanced profiles only hide the weakness behind a more impressive diagram.

Browser apps are a boundary decision

PKCE protects authorization-code redemption. It does not make browser token storage safe.

That distinction matters because many SPA designs still stop the review too early. Once an access token or refresh token is reachable by browser JavaScript, the token boundary includes everything that can run in that origin: application code, dependencies, third-party scripts, compromised packages, extensions, and XSS payloads. Short lifetimes and careful storage help, but they do not change the fact that the browser has become the OAuth token holder.

The IETF browser-based apps draft is still a draft, not a final RFC. Its architecture framing is still valuable. It distinguishes browser-only clients, token-mediating backends, and a full Backend-for-Frontend pattern. The full BFF changes the boundary: the browser gets an application session, while OAuth tokens stay server-side and are injected into API calls by the backend.

The conference demo made that visible by showing two similar browser experiences. In the direct-token SPA, the browser could see usable tokens. In the BFF version, the browser could call the application, but it did not receive an access token it could replay elsewhere.

That does not make a BFF free. It brings session storage, proxy routes, CSRF protection, logout behavior, latency, and operational ownership. It also does not make XSS harmless. A compromised browser origin can still trigger user actions while the session is active. The gain is narrower and important: OAuth tokens stop being browser assets.

The ProAuth documentation includes a Backend-for-Frontend package for this pattern. Read that as implementation support for a boundary decision, not as a reason to skip the architecture review.

Sender constraint changes replay

Bearer tokens have a blunt property: possession is enough. RFC 6750 is explicit about that security model.

Sender-constrained tokens add another fact. The caller must present the token and prove possession of the key or certificate to which the token is bound. If a token appears in a log or copied command line, the stolen string is incomplete evidence.

There are two main patterns from the talk:

PatternGood fitMain tradeoff
DPoPApplication-layer proof where client certificates are difficult to operateThe client runtime and DPoP key still need protection
mTLS certificate bindingControlled server-to-server environments with certificate operations already in placeCertificate lifecycle, ingress behavior, and trust boundaries become part of the design

RFC 9449 defines DPoP. A DPoP-bound access token carries a public-key thumbprint, and each protected resource request carries a signed DPoP proof. The resource server has to validate the token, validate the proof signature, check htm, htu, ath, iat, jti, optional nonce behavior, and confirm that the proof key matches the token binding.

RFC 8705 defines OAuth mutual TLS client authentication and certificate-bound access tokens. In that model, the access token can carry certificate confirmation material, and the resource server compares it with the client certificate presented on the API request.

The important sentence is the same for both: resource servers must enforce the binding. Issuing a sender-constrained token and then accepting it as an ordinary bearer token at the API boundary loses the control.

In the ProAuth v3 preview, DPoP token binding, mTLS client authentication, certificate-bound access tokens, and JWT-based client authentication are part of the advanced client-security work. The detailed behavior belongs in the docs for DPoP, mutual TLS client authentication, and JWT client authentication.

Non-human access is not one pattern

“Machine-to-machine” is often too vague to be useful.

A scheduled service acting for itself, an API calling another API on behalf of a user, and a workload participating in a dynamic ecosystem are different actors. They need different token shapes and different validation points.

The review should start with concrete questions:

  • Who is the actor: the client itself, a user through a service, or a service acting in a chain?
  • Which resource is the token meant for?
  • Which API will validate aud, scope, expiry, issuer, and sender constraint?
  • Where should the chain exchange a token instead of forwarding the original one?
  • Which client identity is allowed to request the downstream token?

RFC 8693 defines OAuth 2.0 Token Exchange for cases where a caller needs a token suited to another audience, resource, or scope. RFC 8707 defines resource indicators, which help clients ask for tokens intended for a specific protected resource. RFC 9728 defines protected resource metadata for ecosystems where clients need to discover how a resource expects tokens to be presented.

These standards do not remove policy decisions. They create better places to make them. An API chain should not casually forward a broad upstream token just because the network is internal.

High assurance starts before the token

By the time an access token exists, several security decisions have already happened.

The authorization request may have carried scopes, redirect URI, PKCE material, resource indicators, requested claims, state, nonce, or structured business context. In a traditional redirect, that information travels through the browser front channel. For ordinary flows, that may be acceptable. For higher-value flows, the request itself needs stronger handling.

RFC 9126 defines Pushed Authorization Requests. PAR moves the rich authorization request to a direct back-channel POST and leaves the browser redirect with a short request reference. RFC 9101 defines JWT-Secured Authorization Requests, where request parameters are carried in a signed, and optionally encrypted, request object. JARM applies similar JWT protection to authorization responses. RFC 9396 defines Rich Authorization Requests for cases where flat scopes are not expressive enough.

FAPI 2.0 is the profile that brings many of these controls together. The OpenID FAPI 2.0 Security Profile is final, and it is useful because it turns a set of recommendations into enforceable expectations for high-security API access. It is not a badge to paste onto every client. It is a guardrail for flows where the risk justifies stricter behavior.

In the ProAuth v3 preview, PAR, JAR, DPoP, mTLS client authentication, certificate-bound tokens, JWT client authentication, issuer response support, and FAPI 2.0 profile enforcement are the relevant building blocks from this part of the landscape. The ProAuth PAR and JAR documentation and FAPI 2.0 Security Profile documentation go into the configuration details. The broader v3 scope is tracked in the ProAuth 3.0.0 release notes.

Because this post is dated during the v3 preview window, read those product references as preview-era guidance and confirm exact behavior against the docs and release notes for the build you deploy.

Do not adopt the whole map at once

The fastest way to make this landscape unusable is to treat every acronym as a mandatory project.

Most teams need a sequence:

  1. Inventory clients, grants, redirect URIs, token lifetimes, and browser-held tokens.
  2. Fix the baseline: code flow with PKCE, exact redirects, issuer validation, legacy grant removal, and replay-aware refresh tokens.
  3. Move browser tokens server-side where the application risk justifies a BFF.
  4. Add sender constraints where token replay would hurt.
  5. Narrow API chains with audience validation, resource indicators, and token exchange.
  6. Apply PAR, JAR, JARM, RAR, and FAPI to high-value flows that need stronger request and response assurance.

That order is not a law. It is a way to avoid overwhelming the team.

The conclusion from the talk was intentionally practical: OAuth and OIDC are still the foundation, but the default architecture around them has matured. Protect the basic flow first. Then place the token boundary deliberately. Then bind tokens where replay risk matters. Then use higher-assurance profiles where the business process, ecosystem, or regulation justifies the operational cost.

The standards have moved in that direction. ProAuth v3 preview support is moving in the same direction. The useful work now is deciding which parts of the map belong in your next architecture review.