> ## Documentation Index
> Fetch the complete documentation index at: https://www.truefoundry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OIDC with a Custom Identity Provider

> Configure OpenID Connect single sign-on between TrueFoundry and any standards-compliant OIDC Identity Provider.

This guide explains how to wire up TrueFoundry SSO against any Identity Provider (IdP) that speaks OpenID Connect — useful when there isn't a dedicated guide for your IdP yet. If your IdP is Microsoft Entra ID, Okta, Google, or another provider that already has a TrueFoundry guide, prefer that guide instead.

After you finish, members of your IdP can sign in to TrueFoundry through a customisable **Login with SSO** button.

## Prerequisites

* A TrueFoundry tenant with **Admin** access to **Settings → Security & Access → SSO**.
* Administrator access to your Identity Provider, with permission to register applications / clients.
* An IdP that implements **OpenID Connect** with the **Authorization Code** grant.
* Network access from TrueFoundry to your IdP's discovery document (`/.well-known/openid-configuration`) is strongly recommended — it lets TrueFoundry auto-discover the OIDC endpoints. If discovery isn't reachable you can still configure the endpoints manually (see [Step 4](#step-4-fallback-manual-endpoint-configuration)).

<Tip>
  Keep the IdP admin console and TrueFoundry's **Settings → Security & Access → SSO** page open in side-by-side tabs. You'll copy the Client ID, Client Secret, and Issuer URL from one into the other.
</Tip>

## Configuration overview

<Steps>
  <Step title="Register a client application in your IdP">
    Create a web application / OIDC client and configure the TrueFoundry callback URL.
  </Step>

  <Step title="Configure claims">
    Make sure the ID token carries `email` and a stable unique identifier such as `sub`.
  </Step>

  <Step title="Configure TrueFoundry">
    Enter the Client ID, Client Secret, and Issuer URL in TrueFoundry's SSO settings.
  </Step>

  <Step title="(Fallback) Manual endpoint configuration">
    Required only if your IdP does not expose a standard discovery document.
  </Step>

  <Step title="Assign users and test sign-in">
    Grant users access in your IdP and verify the end-to-end flow.
  </Step>
</Steps>

## Step 1 — Register a client application in your IdP

The exact wording varies by IdP, but every OIDC-compliant Identity Provider asks for the same set of inputs.

<Steps>
  <Step title="Create a new OIDC client">
    In your IdP admin console, create a new application (sometimes labelled **OIDC client**, **App registration**, **Relying Party**, or **Web app**). Choose **Web** as the application type.
  </Step>

  <Step title="Set the redirect / callback URL">
    Add the TrueFoundry callback URL as the only allowed redirect URI:

    ```
    https://login.truefoundry.com/oauth2/callback
    ```

    <Warning>
      The URL must match exactly — no trailing slash, no extra path segments. A mismatch produces a `redirect_uri_mismatch` error during sign-in.
    </Warning>
  </Step>

  <Step title="Enable the Authorization Code grant">
    Confirm that your IdP allows the **Authorization Code** grant type for this client. TrueFoundry does not use the implicit or password grants.
  </Step>

  <Step title="Capture the client credentials">
    After saving, your IdP will display:

    * **Client ID** (sometimes called *Application ID*)
    * **Client Secret** (sometimes called *Application secret* or *Key*)
    * **Issuer URL** — usually of the form `https://<idp-host>/...` and used to build the discovery URL `<issuer>/.well-known/openid-configuration`.

    Copy all three. Treat the Client Secret as sensitive — store it in your password manager and never commit it to source control.
  </Step>
</Steps>

## Step 2 — (Optional) Configure claims

TrueFoundry needs at least two claims in the ID token: the user's email and a stable unique identifier. Most IdPs include these by default — this step is only needed if yours doesn't.

<Steps>
  <Step title="Confirm the ID token claims">
    Make sure the ID token (or the response from the UserInfo endpoint) carries the following claims:

    | Claim         | Purpose                                  | Required?   |
    | ------------- | ---------------------------------------- | ----------- |
    | `sub`         | A stable, unique identifier for the user | Required    |
    | `email`       | The user's primary email address         | Required    |
    | `given_name`  | The user's first name                    | Recommended |
    | `family_name` | The user's last name                     | Recommended |

    <Tip>
      If your IdP doesn't emit a `sub` claim by default, map any stable unique attribute (for example the user's directory ID) to `sub`. Avoid mapping mutable values like email to `sub` because users may change them over time.
    </Tip>
  </Step>

  <Step title="Decide on scopes">
    TrueFoundry requests `openid email` by default. Add `profile` if you want first/last name. You'll enter the final scope list in [Step 3](#step-3-configure-truefoundry).
  </Step>
</Steps>

## Step 3 — Configure TrueFoundry

<Steps>
  <Step title="Open SSO settings">
    In TrueFoundry, go to **Settings → Security & Access → SSO**.

    Click the **+** icon labeled **Add New SSO Config**.

    <Frame caption="SSO page in TrueFoundry — click the + icon to add a new SSO configuration">
      <img src="https://mintcdn.com/truefoundry/OlEFjoHwZJ0edSjd/images/sso/entra/saml-truefoundry-add-sso-config.png?fit=max&auto=format&n=OlEFjoHwZJ0edSjd&q=85&s=f768205b84d9f33ce04a8b8576ab0070" alt="TrueFoundry SSO settings page with the Add New SSO Config plus button highlighted" width="1024" height="263" data-path="images/sso/entra/saml-truefoundry-add-sso-config.png" />
    </Frame>
  </Step>

  <Step title="Fill in the SSO form">
    * **Enabled**: turn this on.
    * **Name**: a lowercase alphanumeric label — for example, `companyoidc`.
    * **SSO Provider**: choose **Custom**.
    * **Authentication Configuration**: select **OIDC**.
    * **Client ID**: the Client ID from Step 1.
    * **Client Secret**: the Client Secret from Step 1.
    * **Discover endpoints**: leave this **on** so TrueFoundry pulls the OIDC endpoints from the discovery document.
    * **Issuer URL**: the issuer string from your IdP — for example `https://idp.example.com/realms/main`. TrueFoundry will fetch `https://idp.example.com/realms/main/.well-known/openid-configuration` to discover the rest of the endpoints.
    * **Scopes** *(optional)*: leave blank to use the default `openid email`. Add `profile` or any other scopes your IdP requires to emit the claims you configured in Step 2.
  </Step>

  <Step title="Save">
    Click **Save**. TrueFoundry validates the discovery document and stores the credentials. If validation fails, see [Step 4](#step-4-fallback-manual-endpoint-configuration) or the [troubleshooting](#troubleshooting) section.
  </Step>
</Steps>

## Step 4 — (Fallback) Manual endpoint configuration

Most modern IdPs expose `/.well-known/openid-configuration` at the issuer URL. Skip this step if discovery worked in Step 3.

Use manual configuration when:

* Your IdP does not publish a discovery document at the standard path.
* The discovery document is reachable from a browser but not from TrueFoundry's network (for example, the IdP is on a private network).
* The discovery document returns non-standard or invalid JSON.

<Steps>
  <Step title="Locate the four OIDC endpoints">
    From your IdP's documentation, collect:

    | Field                      | What it is                                                                                      |
    | -------------------------- | ----------------------------------------------------------------------------------------------- |
    | **Authorization Endpoint** | Where TrueFoundry sends the user to authenticate (the `authorization_endpoint` from discovery). |
    | **Token Endpoint**         | Where TrueFoundry exchanges the authorization code for tokens (`token_endpoint`).               |
    | **UserInfo Endpoint**      | Where TrueFoundry fetches profile claims using the access token (`userinfo_endpoint`).          |
    | **JWKS Endpoint**          | Where TrueFoundry fetches the public keys used to verify ID token signatures (`jwks_uri`).      |
  </Step>

  <Step title="Turn off discovery and paste the endpoints">
    In TrueFoundry's SSO form, toggle **Discover endpoints** off. Paste each endpoint into the corresponding field, then click **Save**.

    <Note>
      The Issuer URL is still required even in manual mode — TrueFoundry uses it as the expected `iss` value when validating ID tokens.
    </Note>
  </Step>
</Steps>

## Step 5 — Assign users and test sign-in

<Steps>
  <Step title="Assign users in your IdP">
    Depending on your IdP, you'll either grant users access by assigning them to the application directly, by adding them to a group that's assigned to the application, or by making the application available to all users in the tenant. Follow your IdP's documentation.

    <Warning>
      Users who haven't been assigned to the application will see an "access denied" or "user not assigned" error when they try to sign in.
    </Warning>
  </Step>

  <Step title="Test sign-in">
    1. Open a private/incognito window and visit your TrueFoundry login page.
    2. Click **Login with SSO** (or whichever button label you chose under **Show advanced fields → Button Text**).
    3. Authenticate as an assigned user.

    If the sign-in succeeds you'll land in the TrueFoundry dashboard. The user is created automatically if [JIT provisioning](/docs/platform/user-management#user-provisioning) is on; otherwise the user must already exist in TrueFoundry or be invited.
  </Step>
</Steps>

## Optional customizations

The fields below live under **Show advanced fields** on the SSO form and apply to both OIDC and SAML.

| Field                | What it does                                                                                                           | Default          |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------- |
| **Button Text**      | Label shown on the SSO login button.                                                                                   | `Login with SSO` |
| **Button Image URL** | Icon shown next to the button label.                                                                                   | None             |
| **Email Claim**      | OIDC claim that carries the user's email. Override if your IdP uses a non-standard name (for example `mail` or `upn`). | `email`          |
| **Unique ID Claim**  | OIDC claim used as the stable user identifier. Override if your IdP doesn't emit `sub`.                                | `sub`            |

<Tip>
  If you want to brand the login button per environment, set the **Button Text** and **Button Image URL** to match your company brand.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="'Failed to discover OIDC endpoints' or 'discovery document not found'">
    TrueFoundry could not load `<issuer>/.well-known/openid-configuration`. Verify the URL in a browser. If the document is unreachable or returns non-JSON content, follow [Step 4](#step-4-fallback-manual-endpoint-configuration) to enter the four endpoints manually.
  </Accordion>

  <Accordion title="'invalid_client' or 'invalid client secret'">
    Either the wrong secret was pasted, the secret was rotated/expired in your IdP, or only an identifier (not the secret value) was copied. Generate a fresh client secret in your IdP, copy the value immediately, and update TrueFoundry.
  </Accordion>

  <Accordion title="Sign-in works but the user's email is empty">
    The ID token is missing the `email` claim.

    * Make sure the `email` claim is included in the ID token in your IdP.
    * Add `email profile` to **Scopes** on the TrueFoundry SSO form.
    * If your IdP uses a non-standard claim name (for example `mail` or `upn`), expand **Show advanced fields** and set **Email Claim** to that name.
  </Accordion>

  <Accordion title="'redirect_uri_mismatch' during sign-in">
    The redirect URI registered in your IdP doesn't match the one TrueFoundry sends. The IdP must have `https://login.truefoundry.com/oauth2/callback` listed exactly — no trailing slash, no extra query parameters, and the scheme must be `https`.
  </Accordion>

  <Accordion title="'Issuer mismatch' or 'iss claim does not match expected value'">
    The `iss` value inside the ID token doesn't equal the **Issuer URL** you entered in TrueFoundry. Some IdPs return an issuer with or without a trailing slash, or with a different host than the one used for discovery. Check the `iss` claim in a returned token (use [jwt.io](https://jwt.io)) and update the **Issuer URL** to match it exactly.
  </Accordion>

  <Accordion title="'Token validation failed: token used too early' or clock-skew errors">
    The TrueFoundry Auth Server validates the `iat`/`nbf`/`exp` timestamps on the ID token. If your IdP host clock drifts, NTP can fall behind by enough seconds to break validation. Sync the IdP host's clock with an authoritative time source.
  </Accordion>

  <Accordion title="HTTP vs HTTPS issuer">
    TrueFoundry requires `https://` for the Issuer URL and all four endpoints. If your IdP is only reachable on `http://`, terminate TLS in front of it (for example, with a reverse proxy) and use the HTTPS URL. Self-signed certificates must be issued by a CA trusted by TrueFoundry's Auth Server.
  </Accordion>
</AccordionGroup>

## Optional next steps

* **Use SAML instead** — see [SAML with a Custom Identity Provider](/docs/platform/sso/custom-saml).
* **Automate user provisioning** — see [Manage Users](/docs/platform/user-management#user-provisioning) for SCIM, JIT, and Invite-only options.
