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

# Single Logout (SLO)

By the end of this guide, you will have Single Logout configured on your Maverics Orchestrator -- enabling users to log out of all identity providers they authenticated with and terminate their Maverics session in a single action.

## What Is Single Logout?

When a user authenticates through the Maverics Orchestrator, they may authenticate with multiple Identity Fabric connectors during a single session. The Orchestrator's session tracks which identity providers the user has authenticated with.

Without Single Logout, ending a session with one identity provider leaves the others active. The Maverics session and other IdP sessions remain, which means the user is still effectively logged in and can access applications without re-authenticating.

Single Logout solves this by propagating the logout signal across all authenticated identity providers via **front-channel logout**. When a user visits the SLO endpoint, the Orchestrator:

1. Checks the session for each Identity Fabric connector the user authenticated with
2. For each authenticated connector, calls that connector's logout method, which redirects the user to the IdP for front-channel logout
3. Each IdP logout redirects back to the SLO handler, allowing the Orchestrator to iterate through remaining authenticated connectors
4. After all IdP logouts complete, terminates the Maverics session (preventing session replay attacks)
5. Runs the `postLogoutSE` Service Extension if configured
6. Redirects the user to the `postLogout.redirectURL`, or displays a default "You have been logged out." message if no redirect URL is configured

<Note>
  Single Logout is separate from any protocol-level logout endpoints you may configure on an Orchestrator running as a SAML or OIDC provider. Provider endpoints (such as `singleLogoutService` for SAML or `endSession` for OIDC) handle protocol-specific logout requests from individual service providers or relying parties. The global SLO handler, by contrast, handles the user-facing logout flow across all authenticated Identity Fabric connectors.
</Note>

## 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).
* **At least one configured application** -- An OIDC, SAML, or proxy application registered with the Orchestrator. See the [SSO with OIDC](/guides/authentication/sso-with-oidc), [Federate SAML Apps](/guides/authentication/saml-federation), or [Add SSO to Web Apps](/guides/authentication/http-proxy-auth) guides.
* **An identity provider connector** -- A configured upstream IdP. See the [Identity Fabric reference](/reference/orchestrator/identity-fabric) for supported connectors.

## Configure Single Logout

<Steps>
  <Step title="Configure the SLO block">
    Add the `singleLogout` block at the top level of your Orchestrator configuration. This defines the post-logout redirect destination and optional Service Extension hook.

    <Tabs>
      <Tab title="Console UI">
        Single Logout can be configured in the Maverics Console within a Deployment.

        1. Open the **Maverics Console** and navigate to the Deployment you want to configure.
        2. Scroll to the **Single Logout** section.
        3. Click **Edit** to open the SLO settings.
        4. Set the **Logout URL** -- this is the URL that will be registered on the Orchestrator deployment and called by user interaction on an app to initiate the SLO process (e.g., `https://auth.example.com/single-logout`).
        5. Under **Post Logout**, set the **Redirect URL** to where users should be sent after logout completes (e.g., `https://enterprise.com/index.html`).
        6. Optionally, configure a **Post Logout Service Extension** by specifying the function name and file path for custom post-logout logic.
        7. Click **Save** to apply the changes.
      </Tab>

      <Tab title="Configuration">
        Add the `singleLogout` block to your `maverics.yaml` file. This block is a **top-level key** -- it is not nested under `session` or any application.

        ```yaml maverics.yaml theme={null}
        singleLogout:
          logoutURL: https://auth.example.com/single-logout
          postLogout:
            redirectURL: https://enterprise.com/index.html
        ```

        | Key                                    | Type   | Required | Description                                                                                                                                                                                |
        | -------------------------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
        | `singleLogout.logoutURL`               | string | No       | The URL registered on the Orchestrator deployment that is called by user interaction on an app to initiate the SLO process.                                                                |
        | `singleLogout.postLogout.redirectURL`  | string | No       | Where to redirect the user after logout completes (e.g., a landing page or login screen). If not set, the Orchestrator displays a default "You have been logged out." page.                |
        | `singleLogout.postLogout.postLogoutSE` | object | No       | A [Service Extension](/reference/orchestrator/service-extensions) hook that runs after the logout flow completes but before the redirect. Use for audit logging, cleanup, or custom logic. |
      </Tab>
    </Tabs>
  </Step>

  <Step title="Ensure Identity Fabric connectors support logout">
    Single Logout works by iterating through the Identity Fabric connectors that the user has authenticated with during their session. Each connector's logout method is called via front-channel redirect, so the connectors must support logout.

    Verify that your Identity Fabric connectors are configured correctly. The Orchestrator automatically tracks which connectors the user authenticated with via the session -- no additional per-connector SLO configuration is required beyond the standard connector setup.

    <Note>
      If an Identity Fabric connector points to another Orchestrator deployment running as a SAML or OIDC provider, that provider deployment's logout endpoints must be configured for the front-channel logout to propagate correctly. For example, if you have an auth provider deployment and a separate proxy app deployment, and the proxy app's Identity Fabric connector points to the auth provider, ensure the auth provider has its SAML `singleLogoutService` or OIDC `endSession` endpoint configured. See the [SAML Provider](/reference/modes/saml-provider) and [OIDC Provider](/reference/modes/oidc-provider) references for details.
    </Note>

    See the [Identity Fabric reference](/reference/orchestrator/identity-fabric) for supported connectors and their logout capabilities.
  </Step>

  <Step title="Verify the SLO flow">
    With Single Logout configured, test the end-to-end flow:

    1. **Authenticate** -- Log in to one of your applications through the Orchestrator. If possible, authenticate with multiple Identity Fabric connectors to test the full front-channel logout loop.
    2. **Trigger SLO** -- Navigate to the Orchestrator's Single Logout endpoint.
    3. **Observe front-channel logout** -- The Orchestrator redirects through each authenticated IdP's logout endpoint in sequence. Each IdP redirects back to the SLO handler so the next IdP can be logged out.
    4. **Verify redirect** -- After all IdP logouts complete, you should be redirected to the `postLogout.redirectURL` (or see a default "You have been logged out." page if no redirect URL is configured).
    5. **Confirm session termination** -- Try accessing your applications. You should be prompted to re-authenticate, confirming that the Maverics session and all IdP sessions were cleared.

    <Tip>
      Enable debug-level [logging](/reference/orchestrator/telemetry/logging) to trace the SLO flow. The Orchestrator logs each IdP logout as it iterates through authenticated connectors, making it easy to verify that all IdPs are being logged out in sequence.
    </Tip>
  </Step>
</Steps>

## Dynamic Session Expiration with SLO

You can combine Single Logout with [Service Extensions](/reference/orchestrator/service-extensions) to dynamically expire sessions and redirect users to the SLO endpoint. This is useful for enforcing role-based session policies -- for example, giving contractors shorter sessions than full-time employees.

Configure dynamic session expiration using the `evalMaxLifetimeSE` and `evalIdleTimeoutSE` hooks in the `session.lifetime` block:

```yaml maverics.yaml theme={null}
session:
  lifetime:
    evalMaxLifetimeSE:
      funcName: EvalMaxLifetime
      file: /etc/maverics/extensions/session.go
    evalIdleTimeoutSE:
      funcName: EvalIdleTimeout
      file: /etc/maverics/extensions/session.go
  store:
    type: local
    local:
      capacity: 50000

singleLogout:
  logoutURL: https://idp.enterprise.com/single-logout
  postLogout:
    redirectURL: https://enterprise.com/index.html
```

The Service Extension evaluates session lifetime on each request. When the session exceeds the allowed duration, the SE redirects the user to the SLO endpoint, triggering a full logout across all applications:

```go session.go theme={null}
package main

import (
	"net/http"
	"time"

	"github.com/strata-io/service-extension/orchestrator"
)

const sloEndpoint = "https://auth.example.com/single-logout"

func EvalMaxLifetime(
	api orchestrator.Orchestrator,
	rw http.ResponseWriter,
	req *http.Request,
	createdAt time.Time,
) bool {
	maxLifetime := 12 * time.Hour

	employeeType, err := api.Session().GetString("idp.employeeType")
	if err == nil && employeeType == "contractor" {
		maxLifetime = 1 * time.Hour
	}

	if time.Now().After(createdAt.Add(maxLifetime)) {
		api.Logger().Info("se", "session expired, redirecting to SLO")
		http.Redirect(rw, req, sloEndpoint, http.StatusFound)
		return false
	}

	return false
}
```

<Note>
  The `sloEndpoint` constant in the Go code should point to the Orchestrator's Single Logout endpoint. See [Local Sessions -- Dynamic Session Expiration](/reference/orchestrator/sessions/local#dynamic-session-expiration) for the complete example including idle timeout evaluation.
</Note>

## Post-Logout Service Extension

The `postLogoutSE` hook runs custom logic after the SLO flow completes -- after all Identity Fabric connector logouts and the Maverics session termination, but before the user is redirected to `postLogout.redirectURL`. Common use cases include audit logging, analytics, and cleanup of external resources.

```yaml maverics.yaml theme={null}
singleLogout:
  logoutURL: https://idp.enterprise.com/single-logout
  postLogout:
    redirectURL: https://enterprise.com/index.html
    postLogoutSE:
      funcName: PostLogout
      file: /etc/maverics/extensions/postLogout.go
```

```go logout.go theme={null}
package main

import (
	"net/http"

	"github.com/strata-io/service-extension/orchestrator"
)

func PostLogout(
	api orchestrator.Orchestrator,
	rw http.ResponseWriter,
	req *http.Request,
) {
	api.Logger().Info("se", "user completed single logout",
		"remoteAddr", req.RemoteAddr,
	)
}
```

See [Service Extensions](/reference/orchestrator/service-extensions) for the full list of available hooks.

## Local Development

When developing and testing SLO locally, keep these considerations in mind:

* **TLS requirements** -- Session cookies default to `Secure` (HTTPS only). For local HTTP testing, set `session.cookie.disableSecure: true` in your Orchestrator configuration. Do not use this setting in production.
* **Cookie domain** -- If your local applications run on different ports of `localhost`, set `session.cookie.domain` to `localhost` so the session cookie is shared across ports.
* **IdP logout** -- Some IdPs may not support logout redirects to `localhost`. During local development, you can test the Maverics session termination without full IdP front-channel logout propagation.

Example local development configuration:

```yaml maverics.yaml theme={null}
http:
  address: 0.0.0.0:8443
  tls: server

tls:
  server:
    certFile: /etc/maverics/certs/localhost.pem
    keyFile: /etc/maverics/certs/localhost-key.pem

session:
  cookie:
    domain: localhost
    disableSecure: false
  store:
    type: local
    local:
      capacity: 1000

singleLogout:
  logoutURL: https://localhost:8443/single-logout
  postLogout:
    redirectURL: https://localhost:8443/
```

<Tip>
  Use tools like [mkcert](https://github.com/FiloSottile/mkcert) to generate locally-trusted TLS certificates. This avoids browser security warnings and keeps your local environment closer to production by keeping the `Secure` cookie flag enabled.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="User is re-authenticated after SLO">
    **Symptoms:** After triggering Single Logout, the user is immediately logged back in when accessing an application.

    **Causes:**

    * An Identity Fabric connector's logout did not fully clear the IdP session. The upstream IdP recognizes the user's existing session and silently re-authenticates without prompting for credentials.
    * The connector does not support logout, so the SLO flow skipped it.

    **Resolution:**

    1. Verify that your Identity Fabric connectors support logout and are configured correctly. See the [Identity Fabric reference](/reference/orchestrator/identity-fabric) for connector-specific logout support.
    2. Enable debug-level logging to confirm the Orchestrator is iterating through all authenticated connectors during the SLO flow.
    3. Verify that each IdP's logout endpoint redirects back to the Orchestrator so the front-channel logout loop can continue to the next connector.
  </Accordion>

  <Accordion title="SLO endpoint returns 404">
    **Symptoms:** Navigating to the Single Logout endpoint returns a 404 error.

    **Causes:**

    * The `singleLogout` block is missing from the Orchestrator configuration.
    * The Orchestrator has not been restarted after adding the `singleLogout` block.

    **Resolution:**

    1. Verify that the `singleLogout` block exists at the top level of your configuration (not nested under `session` or any app).
    2. Restart the Orchestrator after making configuration changes.
  </Accordion>

  <Accordion title="Front-channel logout loop does not complete">
    **Symptoms:** The SLO flow starts but gets stuck or only logs out of one IdP.

    **Causes:**

    * An IdP's logout endpoint does not redirect back to the Orchestrator's SLO handler.
    * A network or TLS issue prevents the redirect from reaching the Orchestrator.

    **Resolution:**

    1. Check that each IdP is configured to redirect back to the Orchestrator after logout. The SLO handler relies on these redirects to iterate through all authenticated connectors.
    2. Enable debug-level logging to see which connector the flow stopped at.
    3. Verify TLS and network connectivity between the Orchestrator and each IdP.
  </Accordion>

  <Accordion title="Post-logout redirect does not work">
    **Symptoms:** After SLO completes, the user sees "You have been logged out." instead of being redirected.

    **Causes:**

    * The `postLogout.redirectURL` is not set. The Orchestrator defaults to displaying a plain text message when no redirect URL is configured.
    * A `postLogoutSE` is configured and writes its own response, overriding the redirect behavior.

    **Resolution:**

    1. Set `singleLogout.postLogout.redirectURL` to a valid URL.
    2. If using a `postLogoutSE`, ensure the SE does not write its own HTTP response or redirect -- doing so overrides the default redirect behavior.
  </Accordion>
</AccordionGroup>

## What's Next

<CardGroup cols={2}>
  <Card title="Logout Reference" icon="book-open" href="/reference/orchestrator/sessions/logout">
    Complete reference for all logout types including Single Logout configuration
  </Card>

  <Card title="Local Sessions" icon="microchip" href="/reference/orchestrator/sessions/local">
    Session store configuration, dynamic session expiration, and session management
  </Card>

  <Card title="Service Extensions" icon="code" href="/reference/orchestrator/service-extensions">
    Custom Go hooks including postLogoutSE for post-logout logic
  </Card>

  <Card title="Sessions Overview" icon="id-badge" href="/reference/orchestrator/sessions">
    Session types, lifecycle, and production deployment guidance
  </Card>
</CardGroup>
