Front API access token
The account endpoints of the front API (/fapi/v1/me…, /fapi/v1/verifications… and /fapi/v1/organizations…) accept two kinds of authentication:
- the user's
__Host-idp_sessioncookie, on the environment's sign-in host (the hosted account pages use this); - a front API access token, for a first-party application that runs on another origin (a single-page app or a native app).
Getting the token
Ask the token endpoint for the front API as the resource (RFC 8707), in an authorization code exchange or a refresh:
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
DPoP: <proof>
grant_type=refresh_token&refresh_token=<refresh token>&client_id=app_01j9...&resource=https%3A%2F%2Facme.keenauth.app%2Ffapi
The value is the environment's issuer followed by /fapi. The request is accepted only when:
- the application is an active first-party application (otherwise
invalid_target); - the request carries a DPoP proof (otherwise
invalid_dpop_proof); - the grant belongs to a sign-in session, and on a refresh the refresh token is DPoP-bound (otherwise
invalid_target).
Only the access token changes. Its audience is <issuer>/fapi, it carries only the OpenID scopes of the grant (openid, profile, email, phone, offline_access), it lives as long as a userinfo token, and it is bound to the proof's key. The grant itself, its refresh token and its scopes stay as they are; a refresh rotates the refresh token as usual.
Calling the account endpoints
Send the token with the DPoP scheme and a new proof for each request (RFC 9449):
GET /fapi/v1/me/sessions
Idp-Client: <SDK identifier>
Authorization: DPoP <access token>
DPoP: <proof with htm, htu, iat, jti, ath>
htuishttps://<sign-in host>plus the path, without the query.athis the base64url SHA-256 of the access token.- No cookie is read. The request acts on the session the token was issued for; if that session ended, the token stops working.
- A browser request from another origin must come from one of the application's allowed web origins. Cross-origin requests never carry credentials.
- A sensitive change still needs a recent sign-in. The
401 step_up_requiredanswer then carriesWWW-Authenticate: DPoP error="insufficient_user_authentication", …, max_age=300.
Errors
| Status | Code | When |
|---|---|---|
| 400 | malformed_request |
More than one Authorization header, or one that is not DPoP <token>. |
| 401 | unauthenticated |
The token is invalid, expired or revoked, has another audience, is not DPoP-bound, or its session or application is no longer active. |
| 401 | invalid_dpop_proof |
The proof is invalid or was signed with another key. |
| 401 | use_dpop_nonce |
Send a new proof with the nonce from the DPoP-Nonce header. |
| 403 | origin_not_allowed |
The page origin is not one of the application's allowed web origins. |
Each 401 carries a WWW-Authenticate: DPoP … challenge.