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

# SSO using OIDC

> Configure any standard OpenID Connect provider as your identity provider for Bifrost Enterprise.

This guide applies to any identity provider that implements the OpenID Connect (OIDC) standard - including PingIdentity, ForgeRock, OneLogin, JumpCloud, CyberArk Identity, and others not covered by a dedicated Bifrost guide.

## Prerequisites

* An OIDC-capable identity provider with admin access
* Bifrost Enterprise deployed and accessible
* Your Bifrost callback URL: `https://<your-bifrost-domain>/login`
* The ability to create a **confidential** (client secret) OAuth 2.0 application in your IdP
* Bifrost [roles](../rbac) created for the roles you plan to map

***

## Step 1: Create an OIDC application in your IdP

**1. Register a new application**

In your identity provider's admin console, create a new application. Look for options like **Create App Integration**, **Add Application**, **New Application**, or **Register Client**.

Choose a type that matches the **Authorization Code** flow with a server-side callback - typically **Web Application** or **Regular Web Application** with a **Confidential** client. Avoid **SPA** or **Native** types.

**2. Configure redirect URIs**

Set the following URIs in your IdP:

| Field | Value |
| - | - |
| **Redirect / Callback URI** | `https://<your-bifrost-domain>/login` |
| **Discovery callback URI** | `https://<your-bifrost-domain>/workspace/scim/oauth-discover-callback` |
| **Logout / Sign-out URI** | `https://<your-bifrost-domain>` (optional) |

Save the application.

***

## Step 2: Configure token claims

**1. Ensure the required scopes are requested**

Your application must request the following OAuth scopes:

* `openid` - required for OIDC
* `profile` - provides `name`, `given_name`, `family_name`
* `email` - provides the user's email address
* `offline_access` - provides a refresh token for session maintenance (if supported)

**2. Include group or role claims**

For role and team mapping to work, your IdP must include group memberships or role values in the ID token.

| Provider type | How to add group/role claims |
| - | - |
| **Okta / Auth0** | Add a groups claim in the app settings or via an Action |
| **Keycloak / Zitadel** | Enable project/realm role claims in token settings |
| **LDAP-backed IdPs** | Map LDAP group attributes to OIDC claims |
| **Generic OIDC** | Use your provider's claim mapping or transformation rules |

Any claim present in the ID token is available for mapping in Bifrost.

***

## Step 3: Copy your credentials

**1. Note the Issuer URL, Client ID, and Client Secret**

From your application settings, copy:

| Value | Where to find |
| - | - |
| **Issuer URL** | Also called OIDC Issuer or Authorization Server URL. Must match the `iss` claim in the JWT. |
| **Client ID** | Application ID or Client ID |
| **Client Secret** | Application secret (confidential clients only) |

The issuer URL typically looks like `https://auth.company.com` or `https://auth.company.com/realms/my-realm`. Bifrost uses it to discover endpoints via `<issuer>/.well-known/openid-configuration`.

***

## Step 4: Assign users

**1. Grant users access to the application**

In your IdP, assign the users or groups that should be able to log in to Bifrost:

* **Explicit assignment** - add users directly to the application
* **Group-based access** - assign a group; all members get access
* **Policy-based** - configure an access policy

Only users explicitly granted access can authenticate via Bifrost.

***

## Step 5: Configure Bifrost

**1. Open User Provisioning and choose Generic OIDC**

In your Bifrost dashboard, go to **Governance** → **User Provisioning**.

Select **Generic OIDC Provider** and click **Next**.

![Bifrost Choose Provider screen with Generic OIDC Provider selected](https://mintcdn.com/bifrost/SXZ0FKfb8GppuoXc/media/user-provisioning/generic-oidc/bifrost-provider-selection.png?fit=max\&auto=format\&n=SXZ0FKfb8GppuoXc\&q=85\&s=a8cb4a31700b06f69d5688ba053c14ee)

**2. If your IdP is on a private network, add a trusted network**

Skip this step if your IdP is reachable on the public internet.

A self-hosted IdP on `10.x`, `172.16-31.x`, or `192.168.x` is blocked by that guard until you explicitly trust its range, and discovery fails with an error like:

```
Invalid issuer URL: access to IP 10.20.4.11 is not allowed
Invalid issuer URL: host idp.internal.company.com resolves to a disallowed address 10.20.4.11
```

On the **Provider Configuration** screen, click **Trusted Networks** → **Add network**, then enter:

| Field | Value |
| - | - |
| **IP or CIDR** | The range your IdP resolves to - e.g. `10.20.0.0/16`. A bare IP such as `192.168.1.50` is treated as a single host (`/32`, or `/128` for IPv6). |
| **Description** | Optional label, e.g. `On-prem Keycloak` |

Add the range **before** clicking **Discover endpoints** - the allowlist is read at discovery time.

![Bifrost Generic OIDC Provider Configuration screen with a Trusted Networks button above the Issuer URL field](https://mintcdn.com/bifrost/cK_CsstX8kfrVcBE/media/user-provisioning/generic-oidc/bifrost-trusted-networks.png?fit=max\&auto=format\&n=cK_CsstX8kfrVcBE\&q=85\&s=3bb5d7aad4e57c85ab3a0b6345e08911)

To remove a range later, reopen the same **Trusted Networks** sheet and delete the row.

You can also declare the allowlist in `config.json` instead of the dashboard:

```json theme={null}
{
  "scim_config": {
    "enabled": true,
    "provider": "generic",
    "trusted_networks": [{ "cidr": "10.20.0.0/16", "description": "On-prem Keycloak" }],
    "config": { "...": "provider fields" }
  }
}
```

Or, on Helm:

```yaml theme={null}
bifrost:
  scim:
    enabled: true
    provider: "generic"
    trustedNetworks:
      - cidr: "10.20.0.0/16"
        description: "On-prem Keycloak"
```

Declaring the key makes the file own the whole list: it replaces whatever is stored, and an explicit `[]` clears ranges added from the dashboard. Omit the key entirely to leave dashboard-managed ranges alone.

**3. Fill in the provider configuration**

Enter the credentials you copied in Step 3:

| Field | Value |
| - | - |
| **Issuer URL** | Your IdP's OIDC issuer URL (no trailing slash) |
| **Client ID** | Application Client ID |
| **Client Secret** | Application Client Secret |
| **Audience** | Optional - the expected `aud` claim. Defaults to Client ID. |

Click **Discover endpoints** to auto-fill the authorize, token, and userinfo endpoints from your issuer's discovery document. Then click **Verify & Next**.

![Bifrost Provider Configuration form showing Issuer URL, discovered endpoints, Client ID, Client Secret, and optional Audience fields](https://mintcdn.com/bifrost/SXZ0FKfb8GppuoXc/media/user-provisioning/generic-oidc/bifrost-provider-config.png?fit=max\&auto=format\&n=SXZ0FKfb8GppuoXc\&q=85\&s=2734f4e7522ba3fe5d6bba1250f44835)

**4. Discover claims**

On the Attribute Mapping screen, click **Discover Claims** to fetch live claims from your IdP.

Bifrost opens a sign-in popup - no session is created. Once you authenticate, it returns the exact claims your IdP is sending in the JWT. Use this to confirm which attributes - groups, roles, department, or custom claims - are present before building your mappings.

![Bifrost Discover Claims screen listing all claims returned by the generic OIDC provider](https://mintcdn.com/bifrost/SXZ0FKfb8GppuoXc/media/user-provisioning/generic-oidc/bifrost-discover-claims.png?fit=max\&auto=format\&n=SXZ0FKfb8GppuoXc\&q=85\&s=81b945ffbaf7f318e142a8b008cee4e4)

> [!NOTE]
>
> If **Discover Claims** fails, confirm your IdP is configured to allow the `openid`, `profile`, and `email` scopes and that the discovery callback URI is registered.

**5. Set up attribute mappings**

Use the sections below the claim list to map IdP claim values to Bifrost roles, teams, and business units.

**Attribute-to-Role Mappings**

Map a claim value to a Bifrost role. All matching rules are evaluated. If several rules match, Bifrost picks one using your chosen resolution strategy:

* **The role with the most permissions** (default)
* **The first matching role, by list order** (drag rows to set priority)

If no rule matches, login is denied.

**Attribute-to-Team Mappings**

Map a claim value to a Bifrost team. All matching rules apply.

* Use a specific value (e.g. `engineering`) to map that exact claim value to a named team
* Use `*` to sync the claim value directly as the team name
* Use `${*}` to extract part of the string - e.g. `/${*}` matches `/Engineering` and creates team **Engineering**

**Attribute-to-Business Unit Mappings**

Same wildcard support as team mappings. When a rule matches, the resolved business unit is assigned to the user, and all matching rules apply, so a user can belong to several business units at once.

![Bifrost Attribute Mapping screen showing role and team mapping rules configured for the generic OIDC provider](https://mintcdn.com/bifrost/SXZ0FKfb8GppuoXc/media/user-provisioning/generic-oidc/bifrost-attribute-setup.png?fit=max\&auto=format\&n=SXZ0FKfb8GppuoXc\&q=85\&s=1e935badc0c73bef883d5472682c7858)

> [!NOTE]
>
> Setting a value to `*` maps the claim value directly as the entity name. Value comparisons are case-insensitive.

Click **Next** when done.

**6. Review and enable**

Review your full configuration - connection details, attribute mappings, and SCIM status - then click **Save & Enable**.

![Bifrost Review and Enable screen showing Generic OIDC Provider connection details and configured attribute mappings](https://mintcdn.com/bifrost/SXZ0FKfb8GppuoXc/media/user-provisioning/generic-oidc/bifrost-review-enable.png?fit=max\&auto=format\&n=SXZ0FKfb8GppuoXc\&q=85\&s=bed2e10fbd2f4ab89d5b8711d1ddfedb)

> [!WARNING]
>
> Restart your Bifrost server after enabling for the changes to take effect.

***

## How background sync works

Bifrost refreshes each OIDC session when it expires (sessions last at least 30 minutes). If a session cannot be refreshed, Bifrost checks with your IdP whether the user is still active; if the IdP reports the user as inactive, Bifrost decommissions that user locally.

For providers that support it, see [SCIM with Generic OIDC](./scim) to enable real-time user and group provisioning.

***

## Troubleshooting

**User is not redirected to the IdP** - verify the provider is enabled in Bifrost and the server was restarted after saving. Confirm the Issuer URL has no trailing slash and is reachable from your Bifrost server.

**Discover endpoints or Discover Claims fails with "access to IP ... is not allowed" or "resolves to a disallowed address"** - your IdP is on a private network. Add its IP or CIDR range under **Trusted Networks** on the Provider Configuration screen (see Step 5), then retry. If the error names `localhost` or `metadata.google.internal`, those hosts can never be trusted - use the IdP's real private address or internal DNS name.

**Discover endpoints fails with "URL scheme must be https"** - the guard on discovery requires TLS even for internal issuers. Terminate HTTPS in front of your IdP with a certificate your Bifrost host trusts.

**JWKS validation fails** - Bifrost fetches `<issuer>/.well-known/openid-configuration` to discover the JWKS endpoint. Ensure this URL is reachable from your Bifrost host.

**Audience mismatch** - set the **Audience** field in Bifrost to match the `aud` claim in the JWT. Leave blank to default to the Client ID.

**Claims are present in Discover Claims but role mapping is not working** - confirm the claim name matches exactly what the IdP sends (case-sensitive, including namespacing). Dotted paths (e.g. `realm_access.roles`) are supported.

**Login fails after successful IdP authentication** - check that the redirect URI in your IdP exactly matches `https://<your-bifrost-domain>/login`. Trailing slashes and path differences are not allowed.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.