FAPI 2.0 Security Profile
ProAuth supports opt-in FAPI 2.0 Security Profile enforcement for tenants and client applications. FAPI mode is intended for high-value API access where authorization requests, client authentication, and access tokens must be strongly protected.
FAPI mode is disabled by default. Existing tenants and client applications continue to use the non-FAPI behavior unless you explicitly enable the profile.
Effective Policy
The effective security profile is resolved in this order:
- Tenant option
RequireFapi2SecurityProfile = trueforces FAPI 2.0 for every client in the tenant. - Otherwise, client application
SecurityProfiledecides. - If client application
SecurityProfileisnull, ProAuth uses tenant optionDefaultClientSecurityProfile.
Use None for normal OIDC/OAuth behavior and Fapi2Security for FAPI 2.0 enforcement. Migrated existing clients are set to explicit None to preserve compatibility.
Tenant Options
Configure tenant options through the v2 Management API.
| Option | Values | Default | Behavior |
|---|---|---|---|
DefaultClientSecurityProfile | None, Fapi2Security | None | Applied when a client application's SecurityProfile is null. |
RequireFapi2SecurityProfile | true, false | false | Forces all clients in the tenant into FAPI mode. |
RequireFapi2SignedAuthorizationRequests | true, false | false | Requires signed request objects at PAR for clients whose effective profile is FAPI 2.0. |
AllowFapi2ClientCredentials | true, false | false | Allows the machine grant for FAPI clients that also have client-credentials login enabled. |
DefaultOAuthResource | Absolute resource URI | Empty | Selects an audience for OAuth authorization or client-credentials requests that omit resource and do not request openid. Client resource restrictions still apply. |
Client Application Setting
Set SecurityProfile on the v2 client application resource:
{
"name": "payments-api-client",
"securityProfile": "Fapi2Security"
}In the AdminApp, select the profile under Client App → Security. Configure the required authentication method and sender constraints under Credentials. These are separate settings: selecting FAPI does not provision keys, certificates or client proof generation.
Required Client Configuration
A FAPI client must use:
- Authorization code flow only:
response_type=code. - PAR for every authorization request.
- PKCE with
code_challenge_method=S256. - A confidential client application.
- Client authentication with
private_key_jwt,tls_client_auth, orself_signed_tls_client_auth. - Sender-constrained access tokens through DPoP or certificate binding.
For DPoP-bound FAPI clients, set dpopBoundAccessTokens = true and send a valid DPoP proof at the token endpoint. For mTLS-bound FAPI clients, use tls_client_auth or self_signed_tls_client_auth; certificate-bound access tokens are enabled by default for those methods. Non-mTLS clients can also set requireCertificateBoundAccessTokens = true when a client certificate is presented at the token endpoint.
Authorization Requests
In FAPI mode, clients first send the complete authorization request to the PAR endpoint. The browser-facing authorization request must then contain only:
client_idrequest_uri
The pushed request itself must include a registered redirect_uri, response_type=code, and S256 PKCE parameters.
ProAuth uses the stored PAR values as authoritative, including through login and consent. Extra browser parameters cannot override them. A request URI can be visited again before authorization completes; acceptance or rejection consumes it, and later reuse fails.
Signed Authorization Requests
Enable tenant option RequireFapi2SignedAuthorizationRequests to require the signed-request portion of FAPI 2.0 Message Signing for effective FAPI clients. Provision an active client key set with usage RequestObjectSigning; client-authentication key registration alone does not enable request-object verification. Use PS256 or ES256, with the optional client RequestObjectSigningAlg restricting that choice further.
Send all authorization parameters inside the signed request JWT at PAR, including client_id, response_type, redirect_uri, scope and PKCE values. The JWT issuer must be the client identifier and its audience must contain the authorization server issuer. Include nbf no more than 60 minutes in the past and exp no more than 60 minutes after nbf; validation allows 60 seconds of clock skew. The oauth-authz-req+jwt type is supported. Unsigned outer authorization values, including state and nonce, cannot supplement or override the signed request. PAR client authentication remains separate.
The option defaults to false, preserving unsigned FAPI Security Profile requests. It applies only to clients with effective FAPI enforcement. With tenant-wide FAPI enforcement and signed-request policy enabled, discovery publishes require_signed_request_object: true and the FAPI signing algorithms. This setting covers signed authorization requests; it does not enable JARM.
When a DPoP proof is supplied at PAR, ProAuth validates it against the resolved signed dpop_jkt, if present, and binds the authorization code to that proof's key. Token redemption must use the same key. This proof binding is retained even when the signed request omits dpop_jkt.
Token Requests
By default, FAPI mode accepts authorization_code and refresh_token grants. Enable tenant option AllowFapi2ClientCredentials and client setting allowClientCredentialLogin to additionally allow client_credentials. Machine clients still require asymmetric authentication and sender-constrained access tokens. They do not use PAR, PKCE or an interactive user session. Authorization-code redemption requires the original authorization code to have been issued with S256 PKCE and the token request to include code_verifier.
private_key_jwt client assertions for FAPI clients must use the issuer URL as a single string audience, not an array, and must be signed with PS256 or ES256. The permitted clock skew is 60 seconds. Discovery publishes supported client assertion algorithms separately from the OP's token-signing algorithms.
If client_id is omitted from the token request, ProAuth uses the assertion subject to locate the client registration, then validates the signature and all required assertion claims. PKCE proves possession of the authorization code verifier; it does not replace confidential-client authentication.
OAuth API Access
For API authorization without identity claims, request your API scopes without openid. Protect the API using resource-server validation: validate issuer, audience, expiry, required scopes and DPoP or certificate binding. UserInfo is an OIDC endpoint and is not a substitute for your API.
Clients can select an audience with the RFC 8707 resource parameter. For clients that omit it, configure DefaultOAuthResource on the tenant and allow that URI in each applicable client's resource list. It must be an absolute URI without credentials or a fragment. This optional default does not override an explicit resource, affect openid requests, or change the audiences stored in authorization codes and refresh tokens. Existing tenants keep their previous behavior until configured.
OAuth authorization-server metadata is available at /.well-known/oauth-authorization-server and /.well-known/oauth-authorization-server/{tenantKey}. The tenant-specific metadata uses the same issuer policy as OIDC discovery.
UserInfo Requests
FAPI access tokens must be presented in the Authorization header (Bearer for certificate-bound tokens, DPoP for DPoP-bound tokens). ProAuth rejects query-string access tokens for FAPI clients, even when a matching client certificate is supplied. Normal OIDC clients retain their existing token-presentation behavior.
Refresh Tokens
Non-FAPI clients keep ProAuth's default rolling refresh-token policy. Each successful refresh-token grant returns a new refresh token, revokes the used refresh token, and treats reuse of an old refresh token as a replay signal that revokes the token family for that user and client.
FAPI clients use stable sender-constrained refresh tokens. A successful FAPI refresh-token grant returns new access and ID tokens but does not return a replacement refresh_token. The client continues to use the original refresh token until it expires or is explicitly revoked.
FAPI refresh-token grants still require the configured FAPI client authentication and sender constraint:
- DPoP-bound clients must send a valid
DPoPproof with each refresh request. - mTLS clients must present the configured client certificate with each refresh request.
If a FAPI refresh request fails before token issuance, for example because the DPoP proof is missing, the refresh token is not consumed. A later compliant refresh request can still use the same refresh token. Explicit revocation, user deactivation, or expiry still makes the refresh token invalid.
Lifetimes
FAPI mode caps PAR handles to less than 600 seconds and authorization codes to at most 60 seconds. Non-FAPI clients keep the configured tenant lifetimes.
Discovery
Discovery stays broad unless tenant option RequireFapi2SecurityProfile is true. When the tenant requires FAPI, discovery advertises only FAPI-compatible response types, grant types, and client authentication methods, and sets require_pushed_authorization_requests to true.
Error Behavior
FAPI-specific failures use the standard OAuth/OIDC error response model. Examples include invalid_request for missing PAR or missing S256 PKCE, unsupported_response_type for implicit or hybrid response types, and invalid_client or unauthorized_client for unsupported client authentication.