Persona Authentications sits inside your sign-in flow as an identity provider, using OpenID Connect (OIDC) to talk to whatever sends users to it. This article covers the OIDC concepts the rest of the Authentications articles assume: the roles in the protocol, the tokens it issues, and how a Persona authentication template and inquiry line up with those concepts. For the setup steps themselves, see How to configure Persona Authentications with OpenID Connect.
The two roles in OIDC
OIDC is an identity layer on top of OAuth 2.0. It defines two parties:
- The relying party (RP), the application that wants to know who a user is. This is your identity provider (IdP) or your own application, depending on how you have wired up your sign-in flow.
- The OpenID provider (OP), the service that authenticates the user and issues tokens vouching for their identity.
Persona Authentications is the OpenID provider. Your IdP (or your application, if it talks to Persona directly) is the relying party.
The authorization code flow
Persona implements the OIDC authorization code flow, which moves through three endpoints:
| Endpoint | Purpose |
|---|---|
/authorize | Starts the flow. The relying party sends the user’s browser here. |
/token | Exchanges a one-time authorization code for tokens, over a direct backend request. |
/userinfo | Returns account-backed claims for the authenticated user, filtered by scope. |
At a protocol level, the flow looks like this:
- The relying party redirects the user’s browser to Persona’s
/authorizeendpoint with aclient_id,redirect_uri, and the requestedscope. - Persona authenticates the user, in our case by running them through a verification inquiry, then redirects back to the relying party’s
redirect_uriwith a one-time authorizationcode. - The relying party exchanges that
codeat/tokenfor anid_tokenand anaccess_token. - The relying party can optionally call
/userinfowith theaccess_tokento fetch additional claims.
id_token vs. access_token
| Token | What it’s for |
|---|---|
id_token | A signed JWT asserting who the user is. Read its claims directly; it’s meant for the relying party, not for calling an API. |
access_token | An opaque or signed credential the relying party presents to /userinfo to fetch more claims about the user. |
How Persona fills claims from Account fields
Scopes (like openid) and claims requests determine what shows up in each token. This section covers the claims that end up in the id_token when you request them.
Persona builds these claims from the Account tied to the authentication, not from the inquiry. If your flow defers account creation, the authentication can’t resolve an Account; see Deferring account creation for Persona Authentications.
Which Account fields map to which claims
The table lists the claims Persona sends by default, the scope that requests them, and the Account field each one comes from.
| Claim | Scope | Account field it comes from |
|---|---|---|
sub | always present | Defaults to the Account token. Can be mapped to another Account identifier instead, such as reference ID. |
name | profile | The Account’s full name, assembled and normalized from the name field’s first, middle, and last parts. |
given_name | profile | name.first |
family_name | profile | name.last |
middle_name | profile | name.middle |
nickname | profile | nickname |
preferred_username | profile | Generally the login_hint sent by the relying party. Can be mapped to another Account identifier instead. |
picture | profile | A Persona-hosted file URL for the Account’s selfie photo, when one is present. |
birthdate | profile | birthdate, formatted as YYYY-MM-DD. |
updated_at | profile | When the Account was last updated, as a Unix timestamp. |
email | email | email_address. Omitted when the Account has no email address. |
email_verified | email | email_verified, defaulting to false. Omitted entirely when the Account has no email address. |
phone_number | phone_number | phone_number. Omitted when the Account has no phone number. |
phone_number_verified | phone_number | phone_number_verified, defaulting to false. Omitted when the Account has no phone number. |
address | address | The Account’s address subfields as a nested OIDC address object: formatted, street_address (street lines joined by a newline), locality from city, region from subdivision, postal_code, and country. Omitted when every subfield is blank. |
verified_claims | identity_assurance | Built from the verified claims the relying party requested, returned in the id_token only. See Using Verified Claims for Persona Authentications. |
A claim whose Account field is blank is omitted from the token. Persona never returns a claim as null or as an empty string.
Requesting claims
Claims can be requested in either the id_token or from the /userinfo endpoint with the OIDC claims request parameter, which names the individual claims you want.
They can also be requested with the scopes parameter, which is a shorthand for requesting groups of related claims:
| Scope | Claims it requests |
|---|---|
openid | No claims. The ID token itself, which is required for an OIDC request. |
profile | name, family_name, given_name, middle_name, nickname, preferred_username, picture, birthdate, updated_at |
email | email, email_verified |
phone_number | phone_number, phone_number_verified |
address | address |
identity_assurance | verified_claims |
offline_access | No claims. Requests a refresh token in addition to the id_token and access_token. |
tefca | TEFCA-specific claims for TEFCA integrations; see TEFCA Individual Access Services (IAS). |
Requesting a scope doesn’t request all its claims. To keep the id_token compact, only email, email_verified, name, given_name, family_name, preferred_username, picture, and verified_claims are returned in the id_token when you request their scope. The /userinfo endpoint returns every supported claim except verified_claims, which the OIDC spec restricts to the id_token.
Custom claims
Authentication template operators can define custom claims that put additional Account data into the tokens. A custom claim has a name, a value drawn from an Account field, and can be limited to particular scopes and to the id_token, the /userinfo endpoint, or both. Custom claims supplement the standard claims, and they never override one: if a custom claim shares a name with a standard claim, the standard value wins.
Discovery documents and supported scopes
Persona publishes discovery documents at https://authenticate.withpersona.com/authenticate/oidc/.well-known/openid-configuration (production) and https://authenticate.withpersona.com/authenticate/oidc-sandbox/.well-known/openid-configuration (sandbox), and the matching issuer and token endpoints in How to configure Persona Authentications with OpenID Connect. Discovery is published per server, not per authentication template, so claims_supported lists the union of every claim Persona can emit: a claim that appears there is not a promise that your template will emit it. What you receive for a given sign-in depends on the scopes and claims request, and on the Account’s field values.
The scopes Persona supports today are openid, profile, email, phone_number, address, identity_assurance, offline_access, and tefca. The tefca scope covers TEFCA integration; see TEFCA Individual Access Services (IAS).
How Persona’s objects map onto OIDC
The protocol concepts above map onto three Persona objects:
- Authentication template is the OIDC client configuration: redirect URIs, scopes, the client authentication method, and any claim mappings. Every authentication template is bound to one inquiry template, which is what actually verifies the user.
- Authentication is a single run of that flow, one sign-in attempt by one user. It’s the object that ties together the inquiry Persona ran and the tokens Persona issued.
- Account is where verified identity data ends up. When an authentication uses verified claims, the ground-truth values you send land on the account tied to the authentication, not on the inquiry itself.
What happens during a sign-in
- A user attempts to sign in to your application.
- Your IdP redirects them to Persona’s
/authorizeendpoint (optionally after a pushed authorization request to the IdP’s backend). - Persona finds or creates the account tied to the sign-in attempt, then runs the user through the inquiry bound to the authentication template.
- Once the inquiry completes, Persona redirects back to your IdP with an authorization code.
- Your IdP exchanges the code for tokens and lets the user into your application.
Debugging a failed authentication
When an authentication fails, the error redirect includes a link back to that authentication in the Persona Dashboard, and the error message carries the authentication, inquiry, and account tokens. To get the same data programmatically instead of reading it off a redirect, subscribe to the authentication.failed webhook event.
Where to go from here
- How to configure Persona Authentications with OpenID Connect walks through setting up an authentication template end to end.
- Using Pushed Authorization Requests (PAR) for Persona Authentications covers sending identity data to Persona over a backend call instead of the browser.
- Using Verified Claims for Persona Authentications covers asking Persona to verify claims you already believe are true, including Okta’s custom IDV integration.
- Deferring account creation for Persona Authentications covers starting an authentication before Persona can identify which account it belongs to.