Client authentication and grant security migration
This upgrade separates client authentication, PKCE and DPoP. Plan a coordinated deployment: drain all old ProAuth instances before upgrading the database and starting the new version. Mixed-version operation is unsupported for this security transition.
Prepare clients
| Deployment | Client registration | Authorization code |
|---|---|---|
| Browser or native public application | IsPublic=true, authentication method none | S256 PKCE required |
| Server application | IsPublic=false, registered Basic, POST, JWT or mTLS authentication | Client authentication required; S256 PKCE recommended |
| FAPI application | Confidential, private_key_jwt or mTLS, FAPI profile | S256 PKCE and sender constraint required |
Public applications must omit client secrets and assertions. A supplied invalid credential fails the request even when PKCE or DPoP succeeds. Client credentials, introspection and token exchange require confidential callers. Public device authorization and public PAR remain supported.
When authentication metadata is absent, the documented default is none for public clients and client_secret_basic for confidential clients. The database migration records these defaults explicitly. Existing explicit registrations are preserved; clients whose type contradicts their authentication method are disabled. Repair their method through the v2 management API before enabling them. Public/confidential classification is immutable after creation: moving between types requires a new client identity and retirement of the previous client's grants.
Clients using POST secrets without explicit metadata must register client_secret_post. Check both token and PAR requests: for example, an ASP.NET Core OpenID Connect application using its built-in POST-secret behavior needs this explicit registration. PKCE and DPoP never replace confidential-client authentication.
Authorization and redirects
AllowedResponseTypes defaults to code. It is a semicolon-separated list of response-type combinations; for example code;code id_token. Implicit and hybrid capabilities remain available through explicit registration. Prefer code with S256 for new applications. A challenged code requires its original verifier; an unsolicited verifier, malformed verifier, or plain challenge is rejected.
Configure AllowedResponseTypes and IsNativeApplication through management API v2. Updates through the legacy v1 API preserve both settings.
Redirect URIs match exactly, including escaping, case, path and trailing slash. Tenant placeholders resolve to the current tenant's exact values. Native HTTP loopback port variation requires IsNativeApplication=true and an IP literal such as http://127.0.0.1/callback; IsPublic alone does not enable it. Set this v2 field for existing native clients before resuming traffic. The built-in CLI initializer sets it automatically.
Invitation emails now start a correlated browser transaction. Completion uses the authenticated ProAuth browser session and response_type=none, without issuing unused authorization codes. Resend outstanding invitation emails after upgrading.
Tokens and deployment
The additive SQL Server and PostgreSQL migrations revoke existing authorization codes and refresh tokens. Users must authorize again. The state-store token backend changes its token/index namespace, invalidating all previous stored tokens; old entries expire under their existing TTLs. Self-contained access tokens accepted by external resources can remain valid until expiry unless those resources check revocation.
Back up the database and review the client inventory before deployment. Read-only SQL inventories are supplied under Database/Scripts/client-authentication-security-preflight.sqlserver.sql and Database/Scripts/client-authentication-security-preflight.postgresql.sql; they never select secret values. Inventory absent/contradictory authentication metadata, POST authentication, implicit/hybrid response types, native redirects, nonexact redirect matches and public applications sending secrets. Re-register affected response types and native status explicitly through management API v2. Do not distribute secrets to public applications.
Authorization code and rotating refresh redemption are serialized by shared storage. A failed state-store issuance can consume the grant without producing a response; restart authorization after invalid_grant. FAPI reusable refresh tokens remain reusable after successful issuance. Do not retry a token request concurrently.
DPoP and token exchange
Registered DPoP requirements now apply to code, refresh, client credentials, device code and token exchange. Bound refresh tokens continue to require the original proof key even after configuration changes. Resource servers must validate DPoP proof, method, URI, token hash and replay independently.
A confidential broker may receive a DPoP-bound token-exchange result. Sender-constrained subject tokens are rejected until a supported possession/delegation contract exists. External subject JWTs must pass signature, exact issuer, permitted audience and lifetime validation; the external federation validator permits the supported RSA, RSA-PSS and ECDSA signature algorithms. A broker must explicitly allow the local client representing the federated identity in AllowedTokenExchangeClientApps (or exchange its own registered federation).
See OAuth Security BCP, PKCE, DPoP and native application redirects.
Schema migration order
For SQL Server and PostgreSQL, apply the AdminApp migrations through OptionDisplayGroups first, then TrustedContextClaimDisclosure, then ClientAuthenticationSecurity. The migration runner uses this order automatically. Existing AdminApp migration history remains valid; do not recreate the initial v3 schema.