Guides and Tutorials

Bring Your Own Auth

Bring Your Own Auth lets you keep your existing login system, homegrown or from another vendor, and still have Descope issue the tokens. Users sign in with the system they use today, and a Descope Flow turns that sign-in into a Descope session and JWT.

Note

If you would rather move your users off your existing auth system, the migration guides cover that path.

Why Bring Your Own Auth?

Many teams already have a login system that protects their product UIs and APIs. Then a new need appears that Descope solves well, such as an MCP server, an Inbound App for third-party integrations, or agent login. Moving every user to a new identity system first is a large project, and a second login stack for the new surface is worse.

Bring Your Own Auth avoids both. Your system stays the source of truth for who a user is. Descope handles everything after the sign-in: consent, scopes, custom claims, and token issuance.

You don't need to run any other login on Descope for this to work. You can use Descope only for MCP auth or agent access, next to the customer identity system you already have. The same idea applies to second factors, where Homegrown Auth with MFA keeps your login and adds Descope MFA on top.

Where Your Login Plugs In

Every Bring Your Own Auth option runs inside a Descope Flow, and the Flow decides how the user proves who they are. The Flow is the only place you need to change. The Flow hands authentication to your system and gets an identity back. You can do this instead of Descope's native authentication methods or next to them.

After that, the Flow continues as usual and ends with the End action, which issues the Descope session and JWT. The surrounding protocol doesn't change. MCP servers and Inbound Apps run the Flow as an OAuth user consent flow. In that case, Descope returns an authorization code, and the client exchanges the code for an access token.

Choosing an Approach

How the Flow reaches your system depends on what your system supports. You have four options:

Your systemApproachWho shows the login
Supports OIDC or SAMLFederate it as an IdPYour IdP
Has its own login page, no OIDC or SAMLExternal AuthenticationYour login page
Exposes an API that checks credentialsCollect credentials in the FlowA Descope Flow screen
Already gave the user a session tokenReuse the existing sessionNobody, if the session is valid

If your system speaks OIDC or SAML, federation is the recommended path, because it uses standard protocols and needs no custom code. For a homegrown system, External Authentication is usually the best fit, because users keep your login page exactly as it is and your users' credentials never pass through Descope.

Federating an OIDC or SAML IdP

When your login system is an IdP that supports OIDC or SAML, such as Okta, Microsoft Entra ID, or your own OIDC provider, Descope can federate with it directly. You can add it as a custom OAuth provider for all users, or as a tenant-level SSO connection when each customer brings their own IdP.

At runtime, the Flow redirects the user to your IdP, the user signs in there, and the IdP returns to Descope with the user's identity. The Flow then continues with any consent or claims steps and ends with the End action.

Your appor OAuth clientDescope Flowsign-in + consentYour IdPOIDC or SAML1. start the Flow2. redirect to your IdP3. user signs in4. OIDC or SAML response5. consent, custom claimsEnd action: session + JWT6. tokens (or auth code)

Select any step to see what happens.

Handing Off to Your Login Page

Your system may have a login page but no OIDC or SAML support. In that case, the External Authentication action sends the user to that page and waits for your backend to report who signed in. Your users see the login they already know, and Descope never sees their credentials.

The exchange works as follows:

  1. The Flow runs the External Authentication action, which redirects the user to your login page URL.
  2. Descope adds an external_auth_req_id query parameter to that URL.
  3. The user signs in on your page.
  4. Your backend calls POST __BaseURL__/v1/mgmt/flow/externalauth/complete with the externalAuthReqId and the user's loginId.
  5. Descope returns a redirect URL, and your backend sends the browser there.
  6. The Flow resumes and continues to the End action.

The request body can also carry verification flags and customClaims. It can associate the user with tenants through selectedTenantId and userTenants, and the External Authentication action page lists every field. If the user is already signed in to your system, your backend can call the endpoint right away after it checks that the session is active.

Your appor OAuth clientDescope Flowsign-in + consentYour login pageexisting UXYour backendcalls Descope1. start the Flow2. redirect + external_auth_req_id3. user signs inresult + request ID4. POST externalauth/completeredirectUrl5. redirect browserbrowser follows redirectUrlEnd action: session + JWT6. tokens (or auth code)

Select any step to see what happens.

Collecting Credentials in the Flow

When your system has an API that checks credentials, a Flow screen can collect them and send them to your API. The Generate JWT action then creates or finds the user in Descope from form.email or form.externalId, so set one of them first.

To build the Flow:

  1. Add a Screen where the user enters their credentials.
  2. Send the credentials to your API with a Generic HTTP Connector.
  3. Map the user ID or email from the response into the Flow context.
  4. Add a Generate JWT action to issue the Descope session.
Your appor OAuth clientDescope Flowsign-in + consentYour APIchecks credentials1. start the Flow2. Flow screen collects credentials3. check credentials (HTTP connector)user ID or email4. map to form.email or form.externalIdGenerate JWT: session + JWT5. tokens (or auth code)

Select any step to see what happens.

Reusing an Existing Session

The user may already be signed in to your system with a session token, such as a custom JWT or an opaque token in a cookie. The Flow can check that token and skip the login screen entirely. The steps match the previous option, except that the input is a token instead of credentials.

To build the Flow:

  1. Read the token in the Flow, for example from a cookie when the Flow runs on the same custom domain, or as a dynamic value.
  2. Check the token with a Generic HTTP Connector, for example against GET /userinfo or POST /introspect on your API.
  3. Map the user ID or email from the response into the Flow context.
  4. Add a Generate JWT action to issue the Descope session.
Your appor OAuth clientDescope Flowsign-in + consentYour APIchecks the token1. start the Flow + session token2. check token (HTTP connector)user ID or email3. map to form.email or form.externalIdGenerate JWT: session + JWT4. tokens (or auth code)

Select any step to see what happens.

Next Steps

Once the Flow signs users in with your system, you can use it to protect an MCP server, to let Inbound Apps access your APIs, or to approve personal agents. The External Authentication and Generate JWT action pages list every setting.

Was this helpful?

On this page