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

# SSO with OIDC

By the end of this guide, you will have a running Maverics Orchestrator configured as an OIDC Provider -- authenticating users through your identity provider and issuing tokens to your application.

## Prerequisites

* **A running Maverics Orchestrator** -- If you have not installed the Orchestrator yet, follow the [Quick Start guide](/guides/getting-started/quick-start) or see the [installation reference](/reference/orchestrator/installation).
* **An identity provider account** -- You need credentials for an identity provider such as [Microsoft Entra ID](/reference/orchestrator/identity-fabric/azure-ad), [Okta](/reference/orchestrator/identity-fabric/okta), or [Auth0](/reference/orchestrator/identity-fabric/auth0). While this guide demonstrates an OIDC connector, the Orchestrator supports OIDC, SAML, and LDAP connectors, so your IdP does not need to support OIDC specifically.
* **A target application** -- Any web application that accepts OIDC tokens or that you want to protect with OIDC-based single sign-on.

## Configure SSO

<Steps>
  <Step title="Create an Orchestrator Deployment">
    In the Maverics Console, all configuration lives within a **Deployment** -- a managed Orchestrator instance with its own configuration, storage provider, and signing keys. Before you can create identity connectors and applications, you need a Deployment to hold them.

    <Tabs>
      <Tab title="Console UI">
        1. Log in to the [Maverics Console](https://maverics.strata.io).
        2. Navigate to **Deployments** in the sidebar and click **Create**.
        3. Enter a name for your deployment (e.g., `OIDC SSO`).
        4. Select a deployment provider. The Console supports several options:

           * **Evaluation** -- Strata-managed storage, no infrastructure needed. Best for getting started.
           * **AWS S3**, **Azure Blob Storage**, or **Google Cloud Storage** -- customer-managed cloud storage for production.
           * **GitHub** or **GitLab** -- deploy bundles to a Git repository.
           * **Download Only** -- manual bundle download for air-gapped environments.

           See [Publishing Deployment Configs overview](/reference/console/config-publishing#deployment-providers) for provider setup details.
        5. Click **Create**.

        Your new deployment opens automatically. You can now configure identity connectors and applications within it.
      </Tab>

      <Tab title="Configuration">
        When using direct configuration, no deployment setup is needed -- configuration is defined directly in the `maverics.yaml` file and delivered to the Orchestrator via the `-config` flag or `MAVERICS_CONFIG` environment variable. See [Installation](/reference/orchestrator/installation) for details on configuration delivery options.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configure the OIDC Provider">
    The OIDC Provider must be enabled and configured at the deployment level before creating applications. This sets up the issuer identity, endpoints, and signing keys that all OIDC applications in the deployment share.

    <Tabs>
      <Tab title="Console UI">
        1. Open your deployment and click the **gear icon** in the sidebar to open **Deployment Settings**.
        2. Find the **OIDC Provider** section.
        3. Enter the **Issuer** URL (e.g., `https://your-orchestrator.example.com`). This becomes the `iss` claim in all issued tokens.
        4. Click **Generate** to auto-populate the Well-Known, Authorization, Token, Introspect, Revocation, End Session, UserInfo, and JWKS endpoint URLs from the Issuer.
        5. Under **JSON Web Keys**, click **Edit JSON Web Keys** to configure the signing key pair used for token signing.
        6. Click **Save**.

        <Warning>
          If JSON Web Keys are left blank, the Orchestrator auto-generates a signing key pair at startup. This key pair is **ephemeral** -- a new one is created every time the Orchestrator restarts, which means all previously issued tokens become unverifiable. Only rely on auto-generated keys for local development and testing. For production, always configure explicit signing keys managed by a [secret provider](/guides/security/secrets-management).
        </Warning>

        <Note>
          The OIDC Provider Deployment Settings fields are documented in detail in the [OIDC Provider reference](/reference/modes/oidc-provider#setup). Use the Console UI tab there for field-by-field descriptions.
        </Note>
      </Tab>

      <Tab title="Configuration">
        In YAML, the OIDC Provider is configured via the `oidcProvider` top-level key. This is shown in the next step alongside the application configuration.

        <Warning>
          If the `jwks` array is omitted from `oidcProvider`, the Orchestrator auto-generates a signing key pair at startup. This key pair is **ephemeral** -- it is regenerated on every restart, invalidating all previously issued tokens. For production deployments, always provide explicit keys using [secret provider](/guides/security/secrets-management) references (e.g., `<oidc.signingPublicKey>`).
        </Warning>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Connect your identity provider">
    An identity provider (IdP) is the service that manages your user accounts and handles login -- think Microsoft Entra ID (now Microsoft Entra ID), Okta, or Google Workspace. Connecting the Orchestrator to your IdP tells it where to send users when they need to authenticate.

    The Orchestrator uses [Identity Fabric](/reference/orchestrator/identity-fabric) connectors to communicate with your IdP. This guide demonstrates an OIDC connector, but the connector protocol is independent of the Orchestrator's mode -- even though the Orchestrator is serving OIDC to your application, the IdP connector can use OIDC, SAML, or LDAP. The Orchestrator handles the protocol translation between your IdP and your application.

    You will need your IdP's client ID, client secret, and discovery URL (sometimes called the issuer URL or well-known endpoint). These credentials allow the Orchestrator to establish a trust relationship with your provider.

    <Tabs>
      <Tab title="Console UI">
        1. Navigate to **Identity Fabric** in the sidebar and click **Create**.
        2. Select your identity provider from the list. Choose a provider-specific option (such as **Okta (OIDC)**, **Microsoft Entra ID (OIDC)**, or **Auth0 (OIDC)**) or select **Generic OIDC Configuration** for any OIDC-compliant provider. SAML and LDAP connector options are also available -- this guide demonstrates the OIDC connector path, but any connector type is valid here.
        3. Fill in the connector form:

        | Field                        | Required | Description                                                                                                                       |
        | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- |
        | Name                         | Yes      | A friendly name for your identity provider (e.g., `my-idp`).                                                                      |
        | OIDC Well Known URL          | Yes      | Your IdP's OIDC discovery endpoint (e.g., `https://your-idp.example.com/.well-known/openid-configuration`).                       |
        | OAuth Client ID              | Yes      | The client ID from the application you registered in your IdP for Maverics.                                                       |
        | Client Authentication Method | Yes      | Select **OAuth Client Secret** (default) or **OAuth JWT Client Authentication**.                                                  |
        | OAuth Client Secret          | Yes      | The client secret from your IdP. For production, use a [secret provider](/reference/orchestrator/configuration/secret-providers). |
        | Redirect URLs                | Yes      | The callback URL where your IdP redirects after authentication (e.g., `https://your-orchestrator.example.com/oidc-callback`).     |
        | Scopes                       | No       | Space-separated OIDC scopes (e.g., `openid profile email`).                                                                       |

        The **PKCE** toggle is enabled by default. Disable it only if your IdP does not support Proof Key for Code Exchange.

        4. Click **Save**.
      </Tab>

      <Tab title="Configuration">
        Define an OIDC connector in the `connectors` section of your `maverics.yaml` file. The connector specifies how the Orchestrator communicates with your identity provider.

        ```yaml maverics.yaml theme={null}
        connectors:
          - name: my-idp
            type: oidc
            oidcWellKnownURL: https://your-idp.example.com/.well-known/openid-configuration
            oauthClientID: your-orchestrator-client-id
            oauthClientSecret: <idp.clientSecret>
            oauthLoginRedirect:
              urls:
                - https://your-orchestrator.example.com/oidc-callback
            oauthLogoutRedirect:
              urls:
                - https://your-orchestrator.example.com/logout
            disablePKCE: false
            scopes: openid profile email
        ```

        Replace `your-idp.example.com` with your identity provider's domain. The `oidcWellKnownURL` points to the OIDC discovery endpoint, which provides the Orchestrator with all of the IdP's endpoints and signing keys automatically.

        The `oauthClientSecret` uses the `<idp.clientSecret>` secret reference syntax -- the Orchestrator retrieves this value at runtime from your [secret provider](/reference/orchestrator/configuration/secret-providers) rather than reading a plaintext value from the config file.
      </Tab>
    </Tabs>

    <Tip>
      Not sure which connector to use? The [Identity Fabric overview](/reference/orchestrator/identity-fabric) includes a comparison table mapping each connector to its supported protocols and use cases.
    </Tip>

    <Note>
      **Protocol translation:** This guide shows an OIDC connector, but the Orchestrator can connect to your IdP using any supported protocol -- OIDC, SAML, or LDAP. The Orchestrator's mode (OIDC Provider) determines what protocol your *application* speaks. The connector determines what protocol your *IdP* speaks. These are independent -- you can connect a SAML-only IdP and the Orchestrator will translate to OIDC for your application. See the [Identity Fabric overview](/reference/orchestrator/identity-fabric) for all connector types.
    </Note>
  </Step>

  <Step title="Define your application">
    Next, register your application with the Orchestrator's [OIDC Provider](/reference/modes/oidc-provider). This tells the Orchestrator which application will receive OIDC tokens and how to handle the authentication flow.

    You configure a client ID and secret for your application (separate from the IdP credentials above), the redirect URLs your application accepts after authentication, and which identity connector to use for authenticating users.

    <Tabs>
      <Tab title="Console UI">
        In the Console, you create the OIDC application and connect it to your identity provider in a single flow. The connector you select becomes the application's authentication source.

        1. Navigate to **Applications** in the sidebar and click **Create**.
        2. Select **OIDC-based**.
        3. Fill in the application form:

        | Field         | Required | Description                                                                                                                                          |
        | ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
        | Name          | Yes      | A friendly name for your application (e.g., `my-web-app`).                                                                                           |
        | Client ID     | Yes      | The client identifier your application will use to authenticate with the Orchestrator.                                                               |
        | Client Secret | Yes      | Click **Add Client Secret** and enter a secret. Your application will use this to authenticate token requests.                                       |
        | Redirect URL  | Yes      | Click **Add Redirect URL** and enter the callback URL your application accepts after authentication (e.g., `https://your-app.example.com/callback`). |

        The default grant types (**Authorization Code**, **Refresh Token**, and **Client Credentials**) work for most applications. Under **Access Token Settings**, the token type defaults to **JWT**.

        4. Click **Save**.
        5. On the application settings page, find the **Resources** card and click **Edit**. Click **Add Resource**, select the connector you created in the previous step, and click **Save**. A connector must be added as a resource before it can be selected as an authentication source.
        6. Find the **Access Control** card and click **Edit**.
        7. From the **Select an authentication source** dropdown, select your identity provider. To add more than one source, click **Add identity provider**.
        8. Click **Save**.

        <Tip>
          Store application client secrets using the `<namespace.key>` secret reference syntax rather than plaintext values. See [Secrets Management](/guides/security/secrets-management) for setup instructions.
        </Tip>
      </Tab>

      <Tab title="Configuration">
        Define the OIDC Provider and register your application in the `apps` section. The `authentication.idps` array binds the connector from the previous step to this application.

        ```yaml maverics.yaml theme={null}
        oidcProvider:
          discovery:
            issuer: https://your-orchestrator.example.com
            endpoints:
              wellKnown: https://your-orchestrator.example.com/.well-known/openid-configuration
              jwks: https://your-orchestrator.example.com/oauth2/jwks
              auth: https://your-orchestrator.example.com/oauth2/auth
              token: https://your-orchestrator.example.com/oauth2/token
              userinfo: https://your-orchestrator.example.com/oauth2/userinfo
              introspect: https://your-orchestrator.example.com/oauth2/introspect
          jwks:
            - algorithm: RSA256
              publicKey: <oidc.signingPublicKey>
              privateKey: <oidc.signingPrivateKey>

        apps:
          - name: my-web-app
            type: oidc
            clientID: my-web-app
            credentials:
              secrets:
                - <app.clientSecret>
            redirectURLs:
              - https://your-app.example.com/callback
            authentication:
              idps:
                - my-idp
            accessToken:
              type: jwt
        ```

        The `authentication.idps` array references the connector name from the previous step (`my-idp`). When a user accesses your application, the Orchestrator redirects them to that IdP for authentication.

        The `credentials.secrets` array uses secret references so your application's client secret is never stored in plaintext. The `accessToken.type` can be `jwt` (self-contained tokens) or `opaque` (reference tokens that require introspection).
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configure claim mapping">
    Claims are pieces of identity information about the user -- their email address, display name, group memberships, roles, and any custom attributes your IdP provides. When the Orchestrator acts as an [OIDC Provider](/reference/modes/oidc-provider), it issues tokens to your application that contain these claims.

    Claim mapping lets you control which identity attributes from your IdP end up in the tokens your application receives. You can rename claims (so your app sees `email` instead of `preferred_username`), filter out unnecessary data, or combine claims from multiple sources.

    This is where the Orchestrator's protocol translation becomes powerful -- your IdP might use one claim format, but your application expects another. The Orchestrator handles the translation so neither side needs to change.

    <Tabs>
      <Tab title="Console UI">
        1. Open the application you created in the previous step.
        2. Find the **Claims and OAuth 2.0 Scopes** card and click **Edit**.
        3. Under **Attribute to Standard OIDC Claim Mapping**, add a claim mapping for each attribute your application needs:

        | Field         | Description                                                                                |
        | ------------- | ------------------------------------------------------------------------------------------ |
        | Claim Name    | The claim name that will appear in the issued token (e.g., `email`, `name`, `given_name`). |
        | Claim Source  | Select the identity provider connector to pull the attribute from.                         |
        | Value Mapping | The attribute name from the identity provider (e.g., `preferred_username`, `name`).        |

        4. Click the **Claim** button to add additional rows for each claim you need to map.

        For example, to pass the user's email, name, and family name, add three claim rows:

        * `email` from your IdP's `preferred_username`
        * `name` from your IdP's `name`
        * `family_name` from your IdP's `family_name`

        5. Click **Save**.
      </Tab>

      <Tab title="Configuration">
        Add a `claimsMapping` section to your application definition. Each entry maps a claim name in the issued token (left side) to an attribute from your IdP connector (right side), using the format `connectorName.attributeName`.

        ```yaml maverics.yaml theme={null}
        apps:
          - name: my-web-app
            type: oidc
            clientID: my-web-app
            credentials:
              secrets:
                - <app.clientSecret>
            redirectURLs:
              - https://your-app.example.com/callback
            authentication:
              idps:
                - my-idp
            accessToken:
              type: jwt
            claimsMapping:
              email: my-idp.preferred_username
              name: my-idp.name
              family_name: my-idp.family_name
              given_name: my-idp.given_name
        ```

        The `claimsMapping` keys (`email`, `name`, `family_name`, `given_name`) are the claim names that appear in the tokens your application receives. The values (`my-idp.preferred_username`, `my-idp.name`, etc.) reference attributes from the identity connector. The prefix before the dot must match the connector `name` from the previous step.

        See [OIDC Provider Reference](/reference/modes/oidc-provider) for all available fields, including scopes, token lifetimes, and advanced claim configuration.
      </Tab>
    </Tabs>

    <Tip>
      See the [OIDC Provider reference](/reference/modes/oidc-provider) for the complete list of configurable claims, scopes, and token settings.
    </Tip>
  </Step>

  <Step title="Publish your configuration">
    After configuring your deployment, identity connector, application, and claim mapping in the Console, you need to publish the configuration so the Orchestrator receives it and applies your changes.

    <Tabs>
      <Tab title="Console UI">
        1. At the bottom of the deployment Settings page, click **Publish Preview** in the sticky footer bar.
        2. In the Deployment Manager dialog, review the configuration diff to verify your changes.
        3. Optionally add a revision note describing what changed (e.g., "Initial OIDC SSO setup").
        4. Click **Publish** to deploy the configuration bundle to your storage provider.
        5. The Orchestrator detects the new bundle on its next poll cycle and applies the configuration automatically.

        See [Publishing Deployment Configs overview](/reference/console/config-publishing) for details on the publishing lifecycle, revision history, and bundle verification.
      </Tab>

      <Tab title="Configuration">
        When using direct configuration, configuration is delivered directly to the Orchestrator via the `-config` flag or `MAVERICS_CONFIG` environment variable. No publishing step is needed -- restart the Orchestrator to apply configuration changes.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Verify SSO is working">
    With your identity provider connected, your application defined, and claim mapping configured, you are ready to test the complete SSO flow.

    Start (or restart) the Orchestrator to pick up your configuration and verify it is healthy:

    ```bash theme={null}
    maverics -config /etc/maverics/config.yaml
    curl -s https://localhost:9443/status | jq .
    ```

    A healthy response confirms the Orchestrator is running:

    ```json theme={null}
    {
      "status": "up"
    }
    ```

    Now open your application's public URL in a browser and walk through the SSO flow:

    1. **Visit your application URL** -- You should be redirected to your identity provider's login page
    2. **Authenticate** -- Log in with valid credentials
    3. **Verify redirect** -- After authentication, you should land on your application with full access
    4. **Inspect tokens** -- If your application exposes token details, verify the claims match your mapping configuration

    <Check>
      **Success!** Your Maverics Orchestrator is acting as an OIDC Provider --
      authenticating users through your identity provider and issuing tokens with
      the claims your application expects. Users experience seamless single
      sign-on without your application needing to integrate directly with your IdP.
    </Check>
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Redirect URI mismatch error">
    This is the most common OIDC configuration issue. Your identity provider
    rejects the authentication request because the redirect URI (callback URL)
    the Orchestrator sends does not exactly match what is registered in your IdP.
    Check both sides -- the URI configured in the Orchestrator and the URI
    registered in your IdP's application settings must be character-for-character
    identical, including the protocol (`https://`), domain, port, and path. Trailing
    slashes matter.
  </Accordion>

  <Accordion title="Token validation fails or claims are missing">
    If your application receives a token but cannot validate it, verify that the
    audience (`aud`) claim in the token matches what your application expects.
    The audience is set during claim mapping -- make sure it points to your
    application's client ID or expected identifier. If claims are missing from
    the token, check that the scopes requested during authentication include the
    data you need (for example, `email` scope for email claims, `profile` scope
    for name claims). See the [OIDC Provider reference](/reference/modes/oidc-provider)
    for scope-to-claim mappings.
  </Accordion>

  <Accordion title="Users see a blank page or infinite loading after login">
    This usually indicates the Orchestrator successfully authenticated the user
    but cannot reach the upstream application. Verify that the upstream URL in
    your application route is correct and that the application is running and
    accessible from the Orchestrator's network. Check the Orchestrator logs for
    connection errors or timeouts.
  </Accordion>
</AccordionGroup>

## What's Next

<CardGroup cols={2}>
  <Card title="Federate SAML Apps" icon="shield-halved" href="/guides/authentication/saml-federation">
    Set up SAML 2.0 federation for legacy enterprise applications that do not support OIDC
  </Card>

  <Card title="OIDC Provider Reference" icon="book-open" href="/reference/modes/oidc-provider">
    Explore the complete OIDC Provider configuration -- scopes, claims, token lifetimes, and advanced settings
  </Card>
</CardGroup>
