Skip to main content
Custom OIDC lets you add your own OpenID Connect (OIDC) identity provider — an enterprise SSO, your existing auth system, or any standards-compliant IdP — as a login method in Para. Users sign in with your provider and get a Para embedded wallet, just like any other social login. In this flow Para is the OIDC client (relying party) and your provider is the identity provider. You configure it once on your partner record — from the Developer Portal or the Para CLI — and it works everywhere your app authenticates: the Para Modal renders it automatically, and your own custom UI can trigger it like any OAuth method.
Custom OIDC is for end users signing in through Para with your IdP. If your backend already authenticates users and you only need server-side wallets, see Bring Your Own Auth instead — a different pattern.

How it works

  1. A user selects your provider on the Para login screen.
  2. Para redirects them to your IdP to sign in.
  3. Your IdP redirects back to Para’s callback with an authorization code.
  4. Para exchanges the code, verifies the identity, and creates or loads the user’s Para wallet.
You give Para a client ID and client secret from your IdP; Para gives you a redirect URI to register with your IdP. That’s the whole handshake.

Before you start

  • An OpenID Connect provider that supports OIDC Discovery (it serves a /.well-known/openid-configuration document).
  • Admin access to register a new client with that provider.
  • A Para project and API key — create one if you haven’t.
  • For production API keys, an organization on the Scale or Enterprise plan. Custom OIDC is available on every plan in the beta environment, so you can build and test before upgrading.
One provider or several? This page sets up a single OIDC provider, which works on all current Para SDK versions. You can also register multiple OIDC providers as named connections — see Multiple OIDC providers below for how, and for the SDK version that requires.

1. Register Para with your provider

In your identity provider, register a new OIDC client (sometimes called an “application” or “relying party”) and note its Client ID and Client secret. Add both of Para’s redirect URIs to the client’s list of allowed redirect URIs. Sign-ins may use either one until all of your users are on the current Para SDK login flow:
Para uses the same redirect URIs for every project in an environment — your project context is carried in the OAuth state parameter. The exact URIs are also shown when you configure Custom OIDC in the next step.

2. Configure Custom OIDC in Para

Set up the default provider with the Para CLI. After that you can edit it in the Developer Portal, where you can also add more OIDC providers as named connections.
Configure the same settings with the Para CLI:
Review the saved configuration at any time with show:
--oauth-methods sets the full OAuth list, so include any other providers you want enabled alongside CUSTOM_OIDC.

3. Use it in your app

Once Custom OIDC is enabled, no extra SDK code is required to make it appear.

With the Para Modal

The Para Modal renders a Custom OIDC button automatically, labeled with your sign-in label. Users tap it, sign in with your provider, and land back in your app with a Para wallet.

With your own UI

If you build your own login UI, trigger Custom OIDC like any other OAuth provider — pass "CUSTOM_OIDC" as the method:
See Build a Custom UI for the full OAuth flow. To label your own button consistently, read the configured value from para.config.authConfig?.oidcConfig?.buttonLabel. A provider added as a named connection signs in differently; see Sign in with a connection.
Custom OIDC is a CUSTOM_OIDC OAuth method on the web and in React Native. In a React Native app, follow the social login guide and pass CUSTOM_OIDC as the method. The Swift and Flutter SDKs don’t support Custom OIDC.

Multiple OIDC providers

Beyond the single provider above, you can register several OIDC providers side by side — for example, one SSO per enterprise customer. Each one is a named connection with its own handle, credentials, and sign-in button.
SDK version requirement. Your first (default) OIDC provider renders on all current SDK versions. Additional OIDC connections only render in Para Modal / React SDK version 3.20.0 and later — apps on older versions show just the default provider’s button.
Add a connection from the Authentication screen with Add custom provider, choosing the OpenID Connect provider (the same fields as above, plus a Handle: a short lowercase slug like acme-sso), or with the CLI:
A connection uses only the current-flow redirect URI, https://api.getpara.com/internal/v1/auth/oauth/custom_oidc/callback in production (copy it from the connection dialog). If you move an existing single-provider setup to connections, keep the /auth/custom_oidc/callback URI registered with your IdP too: apps on older SDK versions continue to use it.

Sign in with a connection

The Para Modal renders each enabled connection as its own button. In your own UI: Sign users in through a connection with authenticateWithCustomOAuth (or the useAuthenticateWithCustomOAuth hook), not authenticateWithOAuth. Pass:
  • provider: "CUSTOM_OIDC" for an OpenID Connect connection, "CUSTOM_OAUTH" for an OAuth 2.0 connection.
  • providerConfigHandle: the connection’s handle, such as acme-sso or spotify.
The call resolves once the user is signed in and their wallets are ready. It requires Para SDK 3.20.0 or later.
Call it directly from the button’s click handler. With onOAuthPopup, the SDK opens a popup right away, while the click still allows one, and sends it to the sign-in page itself. The callback only hands you the window. Without it, the SDK sends the current page to the sign-in page instead.
To render one button per connection, read the enabled connections from para.config.authConfig.oauthConnections. Each entry has a handle, a provider, a label and logoUrl for the button, and an oidc flag. Pass "CUSTOM_OIDC" when oidc is true. An entry whose provider is a built-in name such as GOOGLE is your own credentials for that provider, so keep signing in with authenticateWithOAuth. Any other entry is a custom OAuth 2.0 connection, so pass "CUSTOM_OAUTH". The Swift and Flutter SDKs don’t support custom connections.

Token endpoint authentication methods

Token endpoint authentication controls how Para authenticates to your provider’s token endpoint when it exchanges the authorization code: Choose the method your provider expects for the client you registered. client_secret_post and client_secret_basic require a client secret; none requires none.

Security

  • Your client secret is write-only. Para stores it with KMS envelope encryption and never returns it. The CLI prompts for it without echoing, and it’s never written to .pararc.
  • The issuer must be https with no query string — this keeps credentials out of the stored issuer and any logs. A path is fine (https://idp.yourcompany.com/tenant-123).
  • Para validates your provider’s discovery document over the network when it connects; private and internal addresses are rejected.

Troubleshooting

The redirect URIs registered with your provider must exactly match Para’s callbacks for the environment you’re using. Register both the /auth/custom_oidc/callback and the /internal/v1/auth/oauth/custom_oidc/callback URI for https://api.getpara.com (production) or https://api.beta.getpara.com (beta); a sign-in fails on whichever one is missing. Re-copy them from the Custom OIDC configuration.
Your token endpoint authentication method must match what your provider expects. If your client is confidential, use client_secret_post or client_secret_basic and make sure a secret is set. If it’s a public client, use none.
The issuer must be https with no query string, fragment, or credentials — just https://host/path. Para fetches your discovery document from {issuer}/.well-known/openid-configuration.
Para couldn’t load your discovery document. Confirm the issuer is publicly reachable over HTTPS and serves a valid /.well-known/openid-configuration.

Custom OIDC vs Bring Your Own Auth

Both let you use your own identity system, but they’re different integrations:

Next steps