> ## 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.

# Add SSO to Web Apps

By the end of this guide, you will have a Maverics Orchestrator deployed as an identity-aware reverse proxy -- authenticating users through your identity provider and injecting identity headers into requests to your backend application, with no application code changes required.

## What Is HTTP Proxy Mode?

HTTP Proxy authentication places the Maverics Orchestrator between your users and your backend application as a reverse proxy. The Orchestrator intercepts every request, checks whether the user is authenticated, redirects unauthenticated users to your identity provider, and then injects identity information as HTTP headers into the upstream request. Your backend application reads these headers to identify the user -- no changes to the application code or configuration are required.

This pattern is especially useful for legacy applications, COTS (commercial off-the-shelf) products, and any application that supports header-based authentication (e.g., SiteMinder-style `SM_USER` headers, `REMOTE_USER`, or custom identity headers).

## 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 that supports OIDC, such as [Microsoft Entra ID](/reference/orchestrator/identity-fabric/azure-ad), [Okta](/reference/orchestrator/identity-fabric/okta), or [Auth0](/reference/orchestrator/identity-fabric/auth0). See the full list of [Identity Fabric](/reference/orchestrator/identity-fabric).
* **A target web application** -- A web application accessible via HTTP/HTTPS that you want to protect with modern authentication. The application should accept identity information via HTTP headers.

## Configure HTTP Proxy Mode

<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., `HTTP Proxy Auth`).
        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="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 running in HTTP Proxy mode, 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 (the 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. This example uses Microsoft Entra ID, but any OIDC-compatible IdP works the same way.

        ```yaml maverics.yaml theme={null}
        connectors:
          - name: azure
            type: azure
            oidcWellKnownURL: https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration
            oauthClientID: your-client-id
            oauthClientSecret: <vault.azure_client_secret>
            scopes: openid profile email
        ```

        Replace `{tenant-id}` with your Microsoft Entra ID tenant ID. The `oauthClientSecret` uses the `<vault.azure_client_secret>` 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 (HTTP Proxy) determines how your *application* receives identity (via headers). The connector determines what protocol your *IdP* speaks. These are independent -- you can connect a SAML-only or LDAP-only IdP and the Orchestrator will translate identity attributes into HTTP headers for your application. See the [Identity Fabric overview](/reference/orchestrator/identity-fabric) for all connector types.
    </Note>
  </Step>

  <Step title="Define a proxy application">
    Next, create a proxy application entry that tells the Orchestrator which hostname to listen on and where to forward requests.

    <Tabs>
      <Tab title="Console UI">
        1. Navigate to **Applications** in the sidebar and click **Create**.
        2. Select **Proxy-based**.
        3. Fill in the application form:

        | Field          | Required | Description                                                                                    |
        | -------------- | -------- | ---------------------------------------------------------------------------------------------- |
        | Name           | Yes      | A friendly name for your application (e.g., `my-legacy-app`).                                  |
        | Upstream URL   | Yes      | The backend URL the Orchestrator forwards requests to (e.g., `https://backend.internal:8080`). |
        | Route Patterns | Yes      | Hostname/path patterns the Orchestrator intercepts (e.g., `myapp.example.com`).                |

        Advanced fields such as TLS profile and **Preserve Host** (which forwards the original `Host` header to the upstream) are available but not required for basic setup.

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

      <Tab title="Configuration">
        Define a proxy application in the `apps` section. The `upstream` URL is where the Orchestrator forwards authenticated requests. The `routePatterns` define which hostnames and paths the Orchestrator intercepts.

        ```yaml maverics.yaml theme={null}
        apps:
          - name: my-legacy-app
            type: proxy
            upstream: https://backend.internal:8080
            routePatterns:
              - "myapp.example.com"
        ```

        The `upstream` must be reachable from the Orchestrator's network. The `routePatterns` entry tells the Orchestrator to intercept all HTTP requests for `myapp.example.com` and proxy them to `https://backend.internal:8080`.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Add authentication policy">
    Now bind the identity connector to the proxy application by adding an authentication policy. The policy defines which paths require authentication and which IdP handles it.

    <Tabs>
      <Tab title="Console UI">
        In the Console, authentication policies are configured on the proxy application itself, within its access control policies.

        1. Open your proxy application. In the **Resources** card, click **Edit**, click **Add Resource**, select the connector you created in Step 2, and click **Save**. A connector must be added as a resource before it can be used as an authentication source.
        2. Find the **Access Control** card and click **Edit**, then click **Policy** to add an access control policy and set its **Location** to the path you want to protect (e.g., `/`).
        3. From the **Select an authentication source** dropdown, select your identity provider -- the connector you added.
        4. For **Authorization method**, choose **Allow all access** to permit any authenticated user (you can add rules later).
        5. Click **Save**.

        <Note>
          In the Console, an application's authentication, headers, and policies are configured together on the application. In YAML, these are separate sections within the application configuration block.
        </Note>
      </Tab>

      <Tab title="Configuration">
        Add a `policies` section to your proxy application. The `location` defines the URL path to protect, `authentication.idps` references the connector name from Step 2, and `authorization.allowAll` permits all authenticated users.

        ```yaml maverics.yaml theme={null}
        apps:
          - name: my-legacy-app
            type: proxy
            upstream: https://backend.internal:8080
            routePatterns:
              - "myapp.example.com"
            policies:
              - location: "/"
                authentication:
                  idps: ["azure"]
                authorization:
                  allowAll: true
        ```

        The `idps` array references the connector `name` from Step 2 (`azure`). Setting `location: "/"` protects all paths under the root. Setting `allowAll: true` authorizes every authenticated user -- you can add fine-grained authorization rules later.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configure header injection">
    This is where the Orchestrator translates identity into something your application understands. Add headers to inject user attributes from the identity provider into HTTP requests sent to your backend.

    <Tabs>
      <Tab title="Console UI">
        Header injection is configured within the proxy application's access control policy.

        1. Open the application you configured in the previous step, find the **Access Control** card, and click **Edit**.
        2. In your policy, find the **Headers** section.
        3. Add header mappings:

        | Field             | Description                                                                      |
        | ----------------- | -------------------------------------------------------------------------------- |
        | Header Name       | The HTTP header name sent to the upstream (e.g., `SM_USER`, `REMOTE_USER`).      |
        | Identity Source   | Select the identity provider connector to pull the attribute from.               |
        | Attribute Mapping | The attribute from the IdP to use as the header value (e.g., `email`, `groups`). |

        4. Click **Header** to add additional rows for each header your application expects.
        5. Click **Save**.
      </Tab>

      <Tab title="Configuration">
        Add a `headers` section to your proxy application. Each entry specifies a header name and a value using the `{{ connector.attribute }}` template syntax.

        ```yaml maverics.yaml theme={null}
        apps:
          - name: my-legacy-app
            type: proxy
            upstream: https://backend.internal:8080
            routePatterns:
              - "myapp.example.com"
            headers:
              - name: SM_USER
                value: "{{ azure.email }}"
              - name: X-Remote-Groups
                value: "{{ azure.groups }}"
            policies:
              - location: "/"
                authentication:
                  idps: ["azure"]
                authorization:
                  allowAll: true
        ```

        The template syntax `{{ azure.email }}` pulls the `email` claim from the `azure` connector. The prefix before the dot must match the connector `name` from Step 2. Common header patterns include:

        | Header Name       | Purpose                          | Example Value                    |
        | ----------------- | -------------------------------- | -------------------------------- |
        | `SM_USER`         | SiteMinder-style user identifier | `{{ azure.email }}`              |
        | `REMOTE_USER`     | Standard remote user header      | `{{ azure.preferred_username }}` |
        | `X-Remote-User`   | Custom user identifier           | `{{ azure.email }}`              |
        | `X-Remote-Groups` | Group memberships                | `{{ azure.groups }}`             |
        | `X-Remote-Name`   | Display name                     | `{{ azure.name }}`               |
      </Tab>
    </Tabs>
  </Step>

  <Step title="Publish your configuration">
    After configuring your deployment, identity connector, application, and headers 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 HTTP Proxy auth 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 the flow">
    With the identity provider connected, proxy application defined, authentication policy applied, and headers configured, you are ready to test the complete authentication 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 walk through the authentication flow:

    1. **Visit the proxy URL** -- Open `https://myapp.example.com` in a browser. You should be redirected to your identity provider's login page.
    2. **Authenticate** -- Log in with valid credentials at the IdP.
    3. **Verify redirect** -- After authentication, you should land on your backend application with full access.
    4. **Verify headers** -- Check that your backend application receives the injected identity headers. If your application has a debug or profile page that displays HTTP headers, verify `SM_USER` and `X-Remote-Groups` contain the expected values.
    5. **Check logs** -- Review the Orchestrator logs for authentication events confirming the flow completed successfully.

    <Check>
      **Success!** Your Maverics Orchestrator is acting as an identity-aware reverse
      proxy -- authenticating users through your identity provider and injecting
      identity headers into requests to your backend application. Users experience
      seamless authentication without any changes to your application code.
    </Check>
  </Step>
</Steps>

## Adding Authorization Rules

Once authentication is working, you can add path-specific authorization to restrict access based on user attributes like group membership.

```yaml theme={null}
policies:
  - location: "/admin"
    authentication:
      idps: ["azure"]
    authorization:
      rules:
        - and:
            - contains: ["{{ azure.groups }}", "app-admins"]
  - location: "/"
    authentication:
      idps: ["azure"]
    authorization:
      allowAll: true
```

In this example, the `/admin` path requires the user to be a member of the `app-admins` group, while all other paths are accessible to any authenticated user. Policies are evaluated in order -- more specific paths should be listed first.

For the full set of authorization operators and rule composition, see the [Security and Policies guide](/guides/security/policies) and the [Authorization reference](/reference/orchestrator/authorization).

## Troubleshooting

<AccordionGroup>
  <Accordion title="Users see a 502 or connection error after login">
    This usually means the Orchestrator authenticated the user successfully but
    cannot reach the upstream application. Verify that the `upstream` URL is correct
    and that the backend is running and accessible from the Orchestrator's network.
    Check for firewall rules, DNS resolution, or TLS certificate issues between the
    Orchestrator and the backend.
  </Accordion>

  <Accordion title="Backend application does not receive identity headers">
    Verify that the `headers` section is defined at the application level (not inside
    a policy). Check that the connector name in the template syntax matches the
    `name` field of your connector exactly (e.g., `{{ azure.email }}` requires a
    connector named `azure`). Review the Orchestrator logs for template evaluation
    errors.
  </Accordion>

  <Accordion title="Users are not redirected to the identity provider">
    Ensure the `policies` section has a `location` that matches the request path.
    If `location` is set to a specific path like `/app`, requests to `/` will not
    trigger authentication. Use `location: "/"` to protect all paths. Also verify
    that `routePatterns` matches the hostname the user is accessing.
  </Accordion>
</AccordionGroup>

## Related Pages

<CardGroup cols={2}>
  <Card title="HTTP Proxy Reference" icon="server" href="/reference/modes/http-proxy">
    Complete configuration reference for HTTP Proxy mode -- route patterns, upstreams, headers, and policies
  </Card>

  <Card title="Authorization Reference" icon="shield-check" href="/reference/orchestrator/authorization">
    Authorization rules, operators, and policy composition for fine-grained access control
  </Card>

  <Card title="Identity Fabric" icon="plug" href="/reference/orchestrator/identity-fabric">
    All supported identity providers and connector configuration
  </Card>

  <Card title="Sessions" icon="user-clock" href="/reference/orchestrator/sessions">
    Session storage options and cookie configuration for proxy authentication
  </Card>
</CardGroup>
