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

# Protect Your First Application

This guide picks up where the Quick Start left off. You already have a running Orchestrator with SSO protecting a basic route. Now you will add session management, identity header injection, and production-ready configuration.

## Prerequisites

* **Completed the [Quick Start guide](/guides/getting-started/quick-start)** -- You should have a running Orchestrator with an identity provider connected and a working application route protected by SSO.
* **A configured identity provider connector** -- Your Orchestrator should already be connected to an identity provider (Microsoft Entra ID, Okta, or another supported IdP) from the Quick Start.

## Configure Your Application

You should already have a working application route from the Quick Start guide. The steps below add session management and header injection to that existing configuration.

<Steps>
  <Step title="Set up session management">
    Session management controls how the Orchestrator tracks authenticated users between requests. Without session management, users would need to re-authenticate on every page load -- which is not a practical experience.

    The Orchestrator creates a session after a user successfully authenticates. This session stores the user's identity information (who they are, what claims they have) so that subsequent requests can be authorized without a full round-trip to the identity provider. Sessions can be stored in-memory for development or configured with [cookie-based sticky sessions](/reference/orchestrator/sessions/local) for production multi-node deployments (the load balancer uses the `maverics_session` cookie for affinity).

    <Tabs>
      <Tab title="Console UI">
        Session management is configured in the Deployment settings, not on an individual application.

        1. Navigate to **Deployments** in the sidebar and select your deployment.

        2. Under **Orchestrator Settings**, find the **Session and Cookie** section.

        3. Click **Edit Session and Cookie** to open the settings dialog.

        4. Configure session lifetime settings:

           | Field                | Default          | Description                                                                                                                    |
           | -------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------ |
           | Max Lifetime Seconds | 86400 (24 hours) | The maximum number of seconds that can elapse post-authentication before a session's authentication state becomes invalidated. |
           | Idle Timeout         | 0 (disabled)     | The number of seconds a session may remain idle before timing out. Set to `0` to disable idle timeout.                         |
           | Cache Size           | 50,000           | Limits the number of sessions maintained in memory.                                                                            |

        5. Optionally configure the **Cookie** settings:

           | Field                           | Description                                                                                          |
           | ------------------------------- | ---------------------------------------------------------------------------------------------------- |
           | Domain                          | Specifies the hosts to which the session cookie will be sent (e.g., `example.com`).                  |
           | Name                            | The name of your Maverics session cookie.                                                            |
           | Disable HttpOnly Attribute      | If enabled, the session cookie can be accessed via client-side scripts. Leave disabled for security. |
           | Disable Secure Cookie Attribute | If enabled, the cookie can be sent over unencrypted HTTP. Leave disabled for security.               |

        6. Click **Save**.

        <Note>
          The dialog also offers optional **Service Extension** dropdowns for evaluating session maximum lifetime and idle timeout programmatically. See the [Sessions reference](/reference/orchestrator/sessions) for details.
        </Note>
      </Tab>

      <Tab title="Configuration">
        ```yaml theme={null}
        session:
          cookie:
            name: "maverics_session"
            domain: "example.com"
          lifetime:
            maxTimeout: "12h"
            idleTimeout: "30m"
          store:
            type: "local"
            local:
              capacity: 50000
        ```

        The `cookie.domain` scopes the session cookie to your domain. The `lifetime` settings control how long sessions remain valid. The `store.type: "local"` uses in-memory storage suitable for development -- for production, consider a `cluster` store type. See the [Sessions Reference](/reference/orchestrator/sessions) for all session configuration options.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configure header injection">
    Header injection (also called identity propagation) is how the Orchestrator passes user identity information to your upstream application. After the Orchestrator authenticates a user, it adds HTTP headers to the proxied request -- telling your application who the user is without your application needing to handle authentication directly.

    Common headers include the user's email address, display name, group memberships, and any custom claims from the identity provider. Your upstream application reads these headers to identify the user and make authorization decisions.

    For example, the Orchestrator might inject:

    * `X-Forwarded-User` -- The authenticated user's unique identifier
    * `X-Forwarded-Email` -- The user's email address from the identity provider
    * `X-Forwarded-Groups` -- A comma-separated list of the user's group memberships

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

        1. Open your application's settings.

        2. In the **Resources** card, click **Edit**, click **Add Resource**, and add your identity provider connector. A connector must be added as a resource before it can be used as an authentication source.

        3. Find the **Access Control** card and click **Edit**, then click **Policy** to add a policy (or edit an existing one) in the **Edit Access Control** drawer.

        4. Set the **Location** for the route you want to protect (e.g., `/`).

        5. From the **Select an authentication source** dropdown, select the identity provider connector that will authenticate users for this location.

        6. For **Authorization method**, choose **Allow all access**.

        7. Under **Headers**, add the identity headers your application needs:

           | Header Name          | Identity Source    | Attribute Mapping |
           | -------------------- | ------------------ | ----------------- |
           | `X-Forwarded-User`   | Your IdP connector | `sub`             |
           | `X-Forwarded-Email`  | Your IdP connector | `email`           |
           | `X-Forwarded-Groups` | Your IdP connector | `groups`          |

           Click **Header** to add each additional header.

        8. Click **Save**.

        <Tip>
          You can also use the **Global Request Headers & Service Extensions** card on the application to add headers to all locations without repeating them in each access control policy.
        </Tip>
      </Tab>

      <Tab title="Configuration">
        Add the `headers` array to your existing app entry from the Quick Start:

        ```yaml theme={null}
        # Add to your existing app entry from Quick Start
        headers:
          - name: "X-Forwarded-User"
            value: "{{ azure.sub }}"
          - name: "X-Forwarded-Email"
            value: "{{ azure.email }}"
          - name: "X-Forwarded-Groups"
            value: "{{ azure.groups }}"
        ```

        Headers are defined as an array of `{name, value}` objects. Values use the `{{ connector.claim }}` template syntax, where the connector name (e.g., `azure`) is the namespace and the claim name (e.g., `email`, `sub`, `groups`) comes from the identity provider.

        Your complete app entry with headers should look like this:

        ```yaml theme={null}
        apps:
          - name: my-application
            type: proxy
            upstream: "https://internal-app.example.com"
            routePatterns:
              - "app.example.com"
            headers:
              - name: "X-Forwarded-User"
                value: "{{ azure.sub }}"
              - name: "X-Forwarded-Email"
                value: "{{ azure.email }}"
              - name: "X-Forwarded-Groups"
                value: "{{ azure.groups }}"
            policies:
              - location: "/"
                authentication:
                  idps: ["azure"]
                authorization:
                  allowAll: true
        ```
      </Tab>
    </Tabs>

    <Warning>
      Make sure your upstream application only trusts these headers when they come
      from the Orchestrator. If users can reach your application directly (bypassing
      the Orchestrator), they could forge these headers. Configure your application
      to only accept traffic from the Orchestrator's IP address or network, or use
      [mTLS](/guides/security/tls) between the Orchestrator and your upstream so
      both sides verify each other's identity cryptographically.
    </Warning>
  </Step>

  <Step title="Test the complete flow">
    With session management and header injection configured, restart the Orchestrator to pick up your updated configuration.

    Now open your application's public URL in a browser and walk through the complete 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. **Verify session persistence** -- Close and reopen your browser, then revisit the application URL. Your session should persist without requiring re-authentication (within the configured timeout)
    5. **Check headers** -- If your application has a debug or profile page, verify that the injected identity headers (`X-Forwarded-User`, `X-Forwarded-Email`, `X-Forwarded-Groups`) are present and contain the correct values

    <Check>
      **Success!** Your application is fully protected by the Maverics Orchestrator.
      Users authenticate through your identity provider, sessions are managed
      automatically, and your application receives user identity through HTTP
      headers -- all without modifying your application code.
    </Check>
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="User authenticates but sees a 403 Forbidden error">
    A 403 error after successful authentication usually means an authorization
    policy is blocking the user. Check whether you have configured any access
    policies that restrict which users can access the application. Also verify
    that the user's claims from the identity provider include the required
    attributes (such as group membership) that your policies expect.
  </Accordion>

  <Accordion title="Headers are not reaching the upstream application">
    Verify that header injection is configured for the correct application entry.
    If your upstream application is behind a load balancer or reverse proxy, that
    intermediate layer may be stripping non-standard headers. Check each hop in
    the request path. You can use a tool like `curl -v` to inspect the headers
    the Orchestrator sends to your upstream.
  </Accordion>

  <Accordion title="Session expires too quickly or not at all">
    Session behavior is controlled by the session store configuration. Check the
    session timeout value -- it may be set too low for your use case. If sessions
    are not expiring, verify that the session store is correctly configured and
    that the Orchestrator is reading from the same store it writes to (important
    in multi-instance deployments). See the
    [Sessions reference](/reference/orchestrator/sessions) for all
    timeout and expiration options.
  </Accordion>
</AccordionGroup>

## What's Next

<CardGroup cols={2}>
  <Card title="Authentication Guides" icon="key" href="/guides/authentication/overview">
    Explore SSO with OIDC, SAML federation, and identity provider migration
  </Card>

  <Card title="Deploy to Production" icon="server" href="/guides/operations/deploy">
    Learn how to deploy the Orchestrator for production workloads with high availability
  </Card>
</CardGroup>
