Authentication

Overview

Core Exchange uses the OpenID Connect protocol (OIDC) to authenticate your customers. OIDC is an extension of OAuth2. Plaid will use the OIDC flow to get authorization from the end user. This authorization allows Plaid to access your Core Exchange API on their behalf. In order to successfully allow your users to complete the authorization flow, you must:

Create an OIDC-compliant server

You can generate an OIDC-compliant server in any of the following ways:

  • Using your existing OAuth identity provider. (For example, Okta, Auth0, Ping Identity, Azure Active Directory, AWS Cognito)
    • If you don't yet have an identity provider, Plaid recommends our partner, Okta. Okta is an industry-leading, independent provider with expertise onboarding data partners to OAuth integrations. Contact us for help getting started with Okta.
  • Building a server with an OIDC-certified open source or commercial implementation
  • Building a server from scratch (not recommended)

Issue Plaid a client ID and client secret

In order to allow Plaid to authenticate its request for an access token, you will need to issue a client ID and client secret. You may create the client ID and client secret using your preferred method, but we provide some guidance here. Once you have created a client ID and client secret, provide them to your Plaid contact.

Authorization flow overview

Once you have an OIDC-compliant server and have issued Plaid a client ID and client secret, the authorization flow occurs as follows:

  1. Plaid redirects the end user to your authorization_endpoint
  2. The user completes all authentication steps and you generate an authorization code
  3. Plaid uses the authorization code to request an access token
  4. Plaid uses the access token to:

(This described authentication flow conforms to commonly implemented patterns for the OIDC spec. Plaid welcomes partner feedback.)

OIDC-compliant server

Basic server requirements

ConfigurationNotes
Server domain
  • Communicate the fully qualified domain name of your OIDC server to Plaid.
  • Your organization can choose the domain, but it will likely be different from the subdomain hosting your API server. For example, you may choose:
    • A subdomain of your primary domain: auth.firstplatypusbank.com
    • An entirely different domain: firstplatypusbank.okta.com
  • This server must support HTTPS.
Well-known configuration endpoint
  • Plaid will retrieve the rest of your server configuration from the well-known path: /.well-known/openid-configuration.
    • For example: https://auth.firstplatypusbank.com/.well-known/openid-configuration
  • See the next section for the information Plaid expects to receive.

Well-known configuration

The /.well-known/openid-configuration endpoint of the OIDC server is a public endpoint that accepts HTTP GET requests without authentication. It returns a JSON object containing the minimum following values:

PropertyDescription
authorization_endpointThe endpoint hosting the user authentication page.
token_endpointThe endpoint Plaid calls to exchange the authorization code for an access token.
userinfo_endpointThe endpoint Plaid calls to retrieve the user identifier.
token_endpoint_auth_methods_supportedThe supported authentication methods Plaid can use to request an access token from the token_endpoint.

(If omitted, Plaid will use basic authentication by default.)
response_types_supportedAn array of supported response types. Plaid expects this to include code.
scopes_supportedAn array that must include at minimum openid and offline_access:
  • openid: Allows Plaid to access the user identifier from the ID token. Plaid uses the user identifier to uniquely identify users across different application connections. This allows Plaid to:
    • Optimize traffic
    • List all active connections for a given user in my.plaid.com

    (If your organization can't provide this, Plaid will query /customers/current instead.)
  • offline_access: Grants Plaid a refresh token to refresh user data in the background. This is required for several important use cases, including:
    • Plaid partners performing balance checks before ACH transfers
    • Transaction data subscriptions

    (See Offline Access in the OIDC specification for more information.)

Example

Plaid's request:

curl GET 'https://auth.firstplatypusbank.com/.well-known/openid-configuration'

Your response:

{
"authorization_endpoint": "https://auth.firstplatypusbank.com/oauth2/v1/authorize",
"token_endpoint": "https://auth.firstplatypusbank.com/oauth2/v1/token",
"userinfo_endpoint": "https://auth.firstplatypusbank.com/oauth2/v1/userinfo",
"token_endpoint_auth_methods_supported": ["client_secret_basic"],
"response_types_supported": ["code"],
"scopes_supported": ["openid", "offline_access"]
}

Client ID and client secret

In order to register an application for your server, you will need to create a client ID and client secret. These will be shared with Plaid so that the Plaid can identify itself. Below, you will find best practices and code samples to help you create a client ID and client secret.

Client ID

A client ID is a public identifier that you assign to Plaid. While it is not secret, we recommend choosing a client ID that is not easy to guess.

Note: The client ID must be between 8 and 256 characters long.

How to create a client ID

One way to create a client ID is to use a random 32-character hex string. See the code samples below:

Bash
openssl rand -hex 16
JavaScript
import crypto from "crypto";
const randomString = crypto.randomBytes(16).toString("hex");
console.log(randomString)
Python
import secrets
secrets.token_hex(16)

Client secret

The client secret is essentially a password that you assign to Plaid. In order to keep it secure, please follow these best practices:

  • Generate the client secret in a way that makes it impossible to guess or backwards-generate. (For example, do not use a UUID as many common libraries take into account the timestamp or MAC address of the generating server.)
  • Never store the client secret in plain text—always keep it encrypted or hashed.
  • Make the client secret visually different from the client ID. (This reduces the risk of a user copy/paste error when handling the client ID and client secret.)

Note: The client secret must be between 8 and 256 characters long.

How to generate a client secret

One way to securely generate a client secret is to follow the steps below:

  1. Create a 256-bit value using a cryptographically secure pseudo random number generator (CSPRNG)
  2. Convert the value from step 1 to a hexadecimal representation

See the code samples below:

Bash
openssl rand -hex 32
JavaScript
import crypto from "crypto";
const randomString = crypto.randomBytes(32).toString("hex");
console.log(randomString)
Python
import secrets
secrets.token_hex(32)

Authorization flow

1. Plaid redirects the end user

When your user first initiates the process of linking their account, Plaid redirects their browser to the authorization_endpoint specified in your well-known configuration. Plaid's redirect includes these query parameters:

Query parameterValueDescription
response_typecodeThe type of response Plaid expects.
redirect_urihttps://cdn.plaid.com/link/v2/stable/oauth.htmlWhere Plaid expects your organization to redirect back to once the user completed all authentication steps.
scopeAt a minimum openid and offline_accessThe set of scopes Plaid requests access to.
client_idA client IDThe client ID you issued to Plaid.
stateAn opaque stringPlaid generates this. Your organization will return the same string when redirecting to the redirect_uri.

Example

Plaid's redirect:

https://auth.firstplatypus.com/oauth2/v1/authorize?response_type=code&redirect_uri=https%3A%2F%2Fcdn.plaid.com%2Flink%2Fv2%2Fstable%2Foauth.html&scope=openid%20offline_access&client_id=c5a5245b062bf8420d11ab4361b28a15&state=eyJvYXV0aF9zdGF0ZV

This page will be requested directly by the user's device. Your authorization endpoint must support TLS and be publicly accessible. Control of user authentication has now been handed off to you. A typical authentication flow will include a username and password submission form and a 2FA step. For partners with native mobile applications, Plaid strongly recommends enabling support for App2App and using biometric authentication to improve the user's authentication experience.

2. You give Plaid an authorization code

After the user completes all required authentication steps, your organization generates a temporary authorization code and redirects the user's browser back to the redirect_uri. The following query parameters must be included with the request:

Query parameterDescription
codeThe temporary authorization code. Plaid exchanges this for an access token in the next step.
stateThe state parameter from the previous step. Plaid verifies that the two values match.

Example

Your response:

https://cdn.plaid.com/link/v2/stable/oauth.html?code=1284918391&state=eyJvYXV0aF9zdGF0ZV

Note: If a user does not complete all the required steps (for example, if they choose to cancel rather than authorize) you should handle it as an error. See the user cancellation section for more information.

3. Plaid requests an access token

Plaid sends a request to your token_endpoint. Unlike the two previous steps, the request to token_endpoint is a backend-to-backend call and must be authenticated. The authentication credentials consist of the client ID and client secret you issued to Plaid. The authentication method will be one of the authentication methods specified in your well-known configuration.

For example, if the authentication method is set to client_secret_basic, Plaid will include a basic authentication header in its request.

Plaid will also send the authorization code (code) in the body of the request and expects to receive an access_token, id_token, and refresh_token in your response.

Body parameters

Body parameterValueComment
grant_typeauthorization_codeThe type of grant Plaid is exchanging for an access token. (In this case, an authorization code.)
redirect_urihttps://cdn.plaid.com/link/v2/stable/oauth.htmlWhere Plaid expects your organization to redirect back to once the user completed all authentication steps.
codeThe code you sent to Plaid in the previous stepThe temporary authorization code Plaid is exchanging for the access token.

Example

Plaid's request (using basic authentication):

curl --request POST 'https://auth.firstplatypusbank.com/oauth2/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header "Authorization: Basic YzVhNTI0NWIwNjJiZjg0MjBkMTFhYjQzNjFiMjhhMTU6clZYWU9vUVM0ckhVRzc5bl80OGFs"
--data-raw '{
"grant_type": "authorization_code",
"code": "1284918391",
"redirect_url": "https://cdn.plaid.com/link/v2/stable/oauth.html"
}'

Response parameters

Your organization validates that the client_id, client_secret, code and redirect_uri parameters from Plaid's request all match the expected values. Your response to this request contains everything that Plaid needs to later access your Core Exchange API:

PropertyDescription
access_tokenAn opaque string (likely a JWT structured according to the Oauth2 specification). Plaid will present this string as a bearer token to all requests made to your Core Exchange API. This encodes the identity of the user and the scope of access granted.
expires_inThe lifetime of the access token, in seconds. Typically 15 minutes (900 seconds). Plaid checks for expiration before using an access token. If the access token is expired, Plaid will use the refresh token to request a new access token. If your organization expires the token before the stated expiration date, Plaid expects to receive a 401 response with an error code of "602 not authorized".
id_tokenAn OIDC ID token. Plaid only reads the sub field from this token.
In a deployment with multiple financial institutions, the sub field must be unique to each financial institution. (It doesn't need to be unique to the user across all financial institutions.)
refresh_tokenAn opaque string (likely a JWT) that can be used to request a new access token. Plaid will use this to fetch data periodically long after the original access token expires. See the refresh flow section for more information.
Plaid doesn't recommend setting an inactivity timeout for the refresh token because it's not a good indicator of whether a user is active with a Plaid partner. For example, some Plaid partners can trigger Plaid to call the Core Exchange endpoint /accounts/{accountID} infrequently for large transactions.

Example

Your response:

{
"access_token": "agstynmdygjdghabrgraeh...",
"expires_in": 900,
"id_token": "snsyjrhvjdtvyjvsgcegaethstj...",
"refresh_token": "dhcsrtjsrgayvkdisfdgntshstu..."
}

After it receives this response, Plaid has everything it needs to access your Core Exchange API.

Error handling

How to handle errors that occur during the authorization flow.

Incorrect redirect URI

If the request fails due to an incorrect, missing, invalid, or mismatched redirect_uri, notify Plaid of the error and do not redirect the user to the redirect_uri. We recommend displaying an error page to notify the user that an error has occurred.

User cancellation

If the user cancels the request or if the request fails for any other reason other than an incorrect URI, include the following required query parameters with the request. (Please see the OAuth spec for a complete list of possible parameters.)


Query parameterDescription
errorThe reason for the error. See the Errors table below for a list of possible errors.
stateThe opaque string Plaid passed as the state parameter in the authorization_endpoint redirect step.
Errors

See the table below for a full list of possible errors, as defined in the OAuth spec.


ParameterDescription
invalid_requestThe request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
unauthorized_clientThe client is not authorized to request an authorization code using this method.
access_deniedThe resource owner or authorization server denied the request.
unsupported_response_typeThe authorization server does not support obtaining an authorization code using this method.
invalid_scopeThe requested scope is invalid, unknown, or malformed.
server_errorThe authorization server encountered an unexpected condition that prevented it from fulfilling the request. (This error code is needed because a 500 Internal Server Error HTTP status code cannot be returned to the client via an HTTP redirect.)
temporarily_unavailableThe authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. (This error code is needed because a 503 Service Unavailable HTTP status code can't be returned to the client via an HTTP redirect.)
Example

Your response:

https://cdn.plaid.com/link/v2/stable/oauth.html?error=access_denied&state=eyJvYXV0aF9zdGF0ZV

Refresh flow

For some use cases, Plaid needs to periodically fetch fresh data on behalf of the user. To get a new access token, Plaid makes another request to your token_endpoint with a different set of parameters.

Body parameters

Body parameterValueDescription
grant_typerefresh_tokenSpecifies that Plaid is requesting a new access token to replace the expired access token.
refresh_tokenExample: dhcsrtjsrgayvkdisfdgntshstu...The refresh token you issued to Plaid.

Note: Plaid recommends setting the expiration at 13 months. This allows you to avoid running into expiration issues during time-sensitive intervals (for example, on tax day).

Example

Plaid's request (using basic authentication):

curl --request POST 'https://auth.firstplatypusbank.com/oauth2/v1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header "Authorization: Basic YzVhNTI0NWIwNjJiZjg0MjBkMTFhYjQzNjFiMjhhMTU6clZYWU9vUVM0ckhVRzc5bl80OGFs"
--data-raw '{
"grant_type": "refresh_token",
"refresh_token": "dhcsrtjsrgayvkdisfdgntshstu..."
}'

Your response:

{
"access_token": "lngarogglkcangasgabba...",
"expires_in": 900,
"id_token": "snsyjrhvjdtvyjvsgcegaethstj..."
}

See the previous section for descriptions of these response parameters.

Error handling

See the table below for a full list of possible errors that may occur during the refresh flow. (Note: These errors do not appear in the OAuth spec.)


ParameterDescription
invalid_requestThe request is missing required parameter.
invalid_clientClient authentication failed.
invalid_grantThe provided authorization grant or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client (rely on error description from FIs to further break this out).
unauthorized_clientThe authenticated client is not authorized to use this authorization grant type.
unsupported_grant_typeThe authorization grant type is not supported by the authorization server.
invalid_scopeThe requested scope is invalid, unknown, or malformed.

App2app

App2app is a mechanism that allows mobile apps performing OAuth2 or OpenID Connect based authentication to offer a much simpler, faster flow if the user already has an app provided by the authorization server owner installed on their mobile device.

Follow the steps below to implement App2app with your Core Exchange API:

1. Set up app deep link URLs

Set up claimed HTTPS URLs so that the OAuth redirect launches the app (if installed) instead of the mobile web page. Ensure fallback to web if the app is not installed or is not available. (For example, if the user is on a desktop.)

See the resources below for instructions on how to set up deep link URLs:

2. Set up in-app flow to issue OAuth authorization code

  • Native experience (Recommended): Build a fully in-app flow whereby the users completes the authentication flow and the authorization code is issued from within the app, before redirecting back to Plaid.
  • Semi-native experience (Alternative): If a fully native experience cannot be resourced we can discuss alternative options, but there will be UX trade-offs.

3. Provide the authorization endpoint redirect URLs to Plaid

Plaid recommends that the data partner provides Plaid with two redirect URLs:

  • An App2app flow redirect URL
  • A regular web-based flow redirect URL

This allows Plaid to control the user path and isolate any issues that may arise. (For example, if a specific developer ("app") incorrectly implements the App2app flow.)