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

# SAML App

Register SAML Service Providers with the Orchestrator's built-in SAML Provider. The Orchestrator handles SAML assertion generation, attribute mapping, and protocol translation -- allowing you to federate enterprise applications that depend on SAML while connecting to modern or legacy upstream identity providers.

<Note>
  **Console vs. YAML:** In the Maverics Console, a SAML app's authentication,
  authorization, attribute mappings, and the Identity Fabric components it relies on
  are configured directly on the application's settings page. In YAML, these elements
  are configured within each app's configuration block (for example under
  `apps[].authentication`, `apps[].authorization`, and `apps[].claimsMapping`).
</Note>

## Overview

SAML apps represent Service Providers registered with the Orchestrator's [SAML Provider](/reference/modes/saml-provider) mode. When a Service Provider sends a SAML authentication request, the Orchestrator authenticates the user against a configured identity provider, generates a SAML assertion with the mapped attributes, and returns it to the SP's Assertion Consumer Service URL. This requires `samlProvider` to be configured in the deployment.

## How It Works

The SAML Provider authentication flow follows these steps:

1. **SP-initiated request** -- A user accesses a SAML service provider. The SP generates a SAML AuthnRequest and redirects the user to the Orchestrator's SSO endpoint.
2. **Upstream authentication** -- The Orchestrator routes the user to the configured upstream identity provider for authentication. The upstream IdP can use any protocol (OIDC, SAML, LDAP) -- the Orchestrator handles protocol translation.
3. **Attribute enrichment** -- After authentication, the Orchestrator loads additional attributes from configured attribute providers and merges them with the authenticated identity.
4. **Assertion generation** -- The Orchestrator generates a signed SAML assertion containing the NameID and mapped claims from the authenticated identity and enriched attributes.
5. **SP receives assertion** -- The SAML response (containing the signed assertion) is POSTed to the SP's assertion consumer service URL. The SP validates the signature and establishes a session.
6. **IdP-initiated flow (optional)** -- Users can also start from the Orchestrator's IdP-initiated login URL, which generates an assertion and sends it directly to the SP without an AuthnRequest.

## Use Cases

* **SAML federation for enterprise apps** -- register Service Providers like Salesforce, ServiceNow, and Workday so the Orchestrator acts as their SAML Identity Provider
* **Protocol translation (OIDC-to-SAML)** -- authenticate users with an OIDC provider upstream while issuing SAML assertions downstream to applications that only support SAML
* **IdP migration for SAML-dependent apps** -- migrate applications from a legacy SAML IdP to a modern identity provider without reconfiguring each Service Provider
* **Attribute mapping and enrichment** -- map and transform attributes from upstream identity providers into the SAML assertion format each Service Provider expects

## Key Concepts

### Protocol Translation

The Orchestrator can translate between protocols -- an upstream OIDC identity provider can feed a downstream SAML service provider, or vice versa. The service provider only sees SAML; the identity provider only sees OIDC. This makes IdP migration possible without changing SP configurations.

### Assertion Signing

By default, both the SAML assertion and the SAML response are signed using the provider's signing material. Individual apps can override signing behavior (e.g., disable assertion signing for SPs that don't verify it) or use per-app signing keys.

### NameID and Claims

The NameID identifies the authenticated subject in the SAML assertion. By default, the `<NameID>` element includes `NameQualifier` and `SPNameQualifier` attributes. Some service providers do not expect these qualifiers -- use `disableNameQualifier` and `disableSPNameQualifier` to omit them when needed. Claims mapping uses the same `connector.attribute` format as OIDC, translating connector attributes into SAML assertion attributes.

### Request Verification

When service providers sign their AuthnRequest messages, the Orchestrator verifies the signature using the SP's certificate. This can be skipped for SPs that don't sign requests.

### Resources and Dependencies

A SAML app declares the Identity Fabric components and service extensions it uses as its **resources**. Identity providers, attribute providers, and service extensions must be added to the app's resources before they can be referenced anywhere else in its configuration -- the authentication source, authorization rules, NameID source, attribute claim sources, and the Build Claims and Build RelayState service extensions all select from the app's declared resources. This guarantees every reference points at a component the app actually uses.

## Setup

<Tabs>
  <Tab title="Console UI">
    In the Maverics Console you create a SAML app from a few essentials, then refine the rest of its configuration from the application's settings page.

    <Steps>
      <Step title="Start a new SAML application">
        Go to **Applications** in the sidebar, click **Create**, and select **SAML-based**.
      </Step>

      <Step title="Enter the essentials">
        Provide:

        * **Name** -- the friendly name of your application.
        * **Assertion Consumer Service URL** -- the URL where your service provider receives SAML assertions. You can add more URLs and change the default after creating the app.
        * **Authentication Source** -- the identity service or authentication service extension that authenticates users. Only identity providers and authentication-capable service extensions from your Identity Fabric are selectable.
      </Step>

      <Step title="Save">
        Click **Save**. Maverics creates the app with defaults -- a generated entity ID (`urn:strata:app:<id>`), a signed response and assertion, and an allow-all access policy that uses the authentication source you selected -- and opens the settings page.
      </Step>
    </Steps>

    Once created, the settings page presents the configuration as a set of cards. Click **Edit** on a card to open its drawer.

    **Service Provider Configuration**

    Manage the identifiers and endpoints the SP advertises:

    * **Entity IDs** -- one or more SP entity identifiers. Mark one as the default.
    * **Assertion Consumer Service (ACS) URLs** -- one or more ACS endpoints. Mark one as the default.
    * **Logout Service URL** -- the single logout (SLO) endpoint where the IdP sends logout requests.
    * **Unauthorized Page** -- the URL users are redirected to after a denied authorization.

    **Protocol & Assertion Settings**

    * **Signing Mode** -- choose **Sign both response and assertion**, **Sign assertion only (disable signed response)**, or **Sign response only (disable signed assertion)**.
    * **Request Verification** -- enable **Skip Request Verification** to accept inbound SAML requests without checking their signature, or upload a **Certificate File** (PEM) to verify signed `AuthnRequest` messages.
    * **NameID** -- set the **Name ID Format** URI and, optionally, source the NameID dynamically by selecting a **Dynamic NameID Source** (one of the app's resources) and the **Dynamic NameID Attribute** to read from it. Two optional toggles control the `<NameID>` element in the SAML assertion:
      * **Omit Name Qualifier** -- omit the `NameQualifier` attribute from the `<NameID>` element in the SAML assertion.
      * **Omit SP Name Qualifier** -- omit the `SPNameQualifier` attribute from the `<NameID>` element in the SAML assertion.
    * **IdP-Initiated Login** -- set a **Login URL** to enable IdP-initiated SSO and an optional **Relay State URL** for where the user lands afterward.
    * **Assertion Lifetime** -- the **Duration (seconds)** an assertion is valid. Defaults to 300 seconds (5 minutes).

    **Resources**

    Declare the Identity Fabric components and service extensions this app depends on. Click **Add Resource** and pick an identity provider, attribute provider, or service extension. Attribute providers also require an **Identity Source** and **Username Mapping**; service extensions that expose metadata can have per-app **Metadata Overrides**. Only resources declared here can be referenced by the app's authentication source, authorization rules, NameID source, and attribute mappings.

    **Access Control**

    * **Authentication** -- select the authentication source (an identity provider, continuity strategy, or authentication service extension from the app's resources) that establishes who the user is.
    * **Authorization** -- choose an **Authorization method**: **Allow all access**, **Use rules to define access**, **Use service extension**, or **Use rules + service extension**.
    * **Rules-Based Authorization** -- when using rules, define conditions with an **Identity Source**, **Attribute**, **Condition** (**Equals**, **Contains**, **Does not equal**, **Does not contain**), and **Value**. Combine conditions within a rule, and combine multiple rules, using **AND**/**OR**.

    **Attribute Mappings**

    * **Attributes** -- map each SAML assertion attribute by name to a **Claim Source** (one of the app's resources) and a value. When the source exposes known claims, pick the value from a list; otherwise enter it directly.
    * **Service Extensions** -- optionally select a **Build Claims** service extension to construct assertion attributes and a **Build RelayState** service extension to construct the RelayState value.
  </Tab>

  <Tab title="Configuration">
    SAML apps are defined under the `apps` top-level key with `type: saml`:

    #### Configuration Reference

    **Core Fields**

    | Key                   | Type    | Required | Default | Description                                                                                                                                     |
    | --------------------- | ------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
    | `name`                | string  | Yes      | --      | Unique name for the SAML app.                                                                                                                   |
    | `type`                | string  | Yes      | --      | Must be `saml`.                                                                                                                                 |
    | `entityIDs`           | array   | Yes      | --      | Service provider entity IDs. Each entry has `identifier` (string) and `default` (boolean). At least one entry with `default: true` is required. |
    | `consumerServiceURLs` | array   | Yes      | --      | Assertion Consumer Service URLs. Each entry has `url` (string) and `default` (boolean). At least one entry with `default: true` is required.    |
    | `logoutServiceURL`    | string  | No       | --      | SP logout service URL for single logout.                                                                                                        |
    | `duration`            | integer | No       | `3600`  | Assertion lifetime in seconds.                                                                                                                  |

    **NameID Configuration**

    | Key                             | Type    | Required | Default | Description                                                                                                                                              |
    | ------------------------------- | ------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `nameID.format`                 | string  | No       | --      | SAML NameID format URN (e.g., `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`).                                                                 |
    | `nameID.attrMapping`            | string  | No       | --      | Connector attribute to use as the NameID value (e.g., `upstream-idp.email`). Uses `connector.attribute` format.                                          |
    | `nameID.disableNameQualifier`   | boolean | No       | `false` | When `true`, omits the `NameQualifier` attribute from the `<NameID>` element in the SAML assertion. Per the SAML 2.0 spec, this attribute is optional.   |
    | `nameID.disableSPNameQualifier` | boolean | No       | `false` | When `true`, omits the `SPNameQualifier` attribute from the `<NameID>` element in the SAML assertion. Per the SAML 2.0 spec, this attribute is optional. |

    **Authentication**

    | Key                                | Type   | Required    | Default | Description                                                                                                                      |
    | ---------------------------------- | ------ | ----------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
    | `authentication.idps`              | array  | Conditional | --      | List of identity provider connector names for user authentication. Cannot be combined with `isAuthenticatedSE`/`authenticateSE`. |
    | `authentication.isAuthenticatedSE` | object | Conditional | --      | Service Extension for custom authentication checks. Must be defined together with `authenticateSE`.                              |
    | `authentication.authenticateSE`    | object | Conditional | --      | Service Extension for custom authentication flows. Must be defined together with `isAuthenticatedSE`.                            |

    **Authorization**

    | Key                                    | Type    | Required | Default | Description                                                                                                                                                                                             |
    | -------------------------------------- | ------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `authorization.allowAll`               | boolean | No       | --      | When `true`, all authenticated users are authorized.                                                                                                                                                    |
    | `authorization.rules`                  | array   | No       | --      | Authorization rules using `and`/`or` conditions with `equals`, `notEquals`, `contains`, `notContains` operators. See [Applications](/reference/orchestrator/applications) for the full rules reference. |
    | `authorization.rulesAggregationMethod` | string  | No       | `"and"` | How top-level rules are combined: `"and"` (all must match) or `"or"` (any may match).                                                                                                                   |
    | `authorization.isAuthorizedSE`         | object  | No       | --      | Service Extension for custom authorization logic. Mutually exclusive with `allowAll` and `rules`.                                                                                                       |
    | `authorization.unauthorizedPage`       | string  | No       | --      | Redirect URL for unauthorized users.                                                                                                                                                                    |

    **Claims and Attributes**

    | Key             | Type   | Required | Default | Description                                                                                                                                                                         |
    | --------------- | ------ | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `claimsMapping` | object | No       | --      | Maps SAML assertion attribute names to connector attribute values. Keys are assertion attribute names; values use `connector.attribute` format (e.g., `email: upstream-idp.email`). |
    | `buildClaimsSE` | object | No       | --      | Service Extension for custom SAML assertion claims. When defined, replaces `claimsMapping`.                                                                                         |
    | `attrProviders` | array  | No       | --      | Additional attribute providers for post-authentication attribute loading. Each entry has `connector` (string) and `usernameMapping` (string in `{{ connector.attribute }}` format). |
    | `loadAttrsSE`   | object | No       | --      | Service Extension for custom attribute loading logic.                                                                                                                               |

    **Request Verification**

    | Key                                    | Type    | Required    | Default | Description                                                                                                                      |
    | -------------------------------------- | ------- | ----------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
    | `requestVerification.certificate`      | string  | Conditional | --      | PEM-encoded SP certificate for verifying signed `AuthnRequest` messages. Required when `skipVerification` is `false` or not set. |
    | `requestVerification.skipVerification` | boolean | No          | `false` | When `true`, skip signature verification of incoming `AuthnRequest` messages. Use when the SP does not sign its requests.        |

    **Per-App Signature Override**

    Individual SAML apps can override the provider-level signing configuration. When a per-app `signature` block is defined, it takes precedence over `samlProvider.signature` for that specific app.

    | Key                                | Type    | Required    | Default | Description                                              |
    | ---------------------------------- | ------- | ----------- | ------- | -------------------------------------------------------- |
    | `signature.certificate`            | string  | Conditional | --      | PEM-encoded X.509 certificate for this app's assertions. |
    | `signature.certificateFile`        | string  | Conditional | --      | File path to the certificate.                            |
    | `signature.privateKey`             | string  | Conditional | --      | PEM-encoded private key for this app's signing.          |
    | `signature.privateKeyFile`         | string  | Conditional | --      | File path to the private key.                            |
    | `signature.disableSignedAssertion` | boolean | No          | `false` | Disable assertion signing for this specific app.         |
    | `signature.disableSignedResponse`  | boolean | No          | `false` | Disable response signing for this specific app.          |

    **Deprecated Fields**

    <Note>
      The following fields are deprecated. Migrate to the replacement fields listed below.

      * `audience` -- Use `entityIDs` instead
      * `consumerServiceURL` -- Use `consumerServiceURLs` instead
      * `nameIDFormat` -- Use `nameID.format` instead
    </Note>

    #### Example

    A SAML app registering Salesforce as a Service Provider with attribute mapping, authentication, and IdP-initiated login:

    ```yaml theme={null}
    apps:
      - name: salesforce
        type: saml
        entityIDs:
          - identifier: "https://salesforce.example.com"
            default: true
        consumerServiceURLs:
          - url: "https://salesforce.example.com/saml/acs"
            default: true
        logoutServiceURL: "https://salesforce.example.com/saml/logout"
        duration: 300
        nameID:
          format: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
          attrMapping: "{{ azure.email }}"
          disableNameQualifier: true
          disableSPNameQualifier: true
        requestVerification:
          skipVerification: true
        authentication:
          idps:
            - azure
        claimsMapping:
          email: "azure.preferred_username"
          firstName: "azure.given_name"
          lastName: "azure.family_name"
          groups: "azure.groups"
        idpInitiatedLogin:
          loginURL: "https://auth.example.com/saml/sso/salesforce"
          relayStateURL: "https://salesforce.example.com/"
    ```
  </Tab>
</Tabs>

## Signed and Unsigned Assertions

By default, the SAML Provider signs both the SAML assertion and the SAML response using the signing material configured in `samlProvider.signature`. Some service providers require unsigned assertions or unsigned responses depending on their verification capabilities.

**Controlling signature behavior at the provider level:**

<Tabs>
  <Tab title="Console UI">
    Provider-level signing is configured in the Maverics Console under **Deployment Settings** in the SAML Provider section. The Console UI provides a **Signing Option** dropdown with options for "Response and Assertion" (default), "Response Only", and "Assertion Only".

    To override the default signing flags directly using `disableSignedAssertion` or `disableSignedResponse`, use the Configuration tab.
  </Tab>

  <Tab title="Configuration">
    ```yaml theme={null}
    samlProvider:
      signature:
        certificate: <saml_signing_cert>
        privateKey: <saml_signing_key>
        # Signed assertion + signed response (default)
        disableSignedAssertion: false
        disableSignedResponse: false
    ```
  </Tab>
</Tabs>

**Controlling signature behavior per app:**

Individual apps can override the provider defaults. For example, if the provider signs both but a specific SP needs unsigned assertions:

<Tabs>
  <Tab title="Console UI">
    In the Console, per-app signing is set on the application's **Protocol & Assertion Settings** card. Use the **Signing Mode** dropdown to choose **Sign both response and assertion** (default), **Sign assertion only (disable signed response)**, or **Sign response only (disable signed assertion)**.
  </Tab>

  <Tab title="Configuration">
    ```yaml theme={null}
    apps:
      - name: unsigned-assertion-app
        type: saml
        signature:
          disableSignedAssertion: true
        # ... other fields
    ```
  </Tab>
</Tabs>

**Request verification from the SP side:**

When a service provider signs its `AuthnRequest` messages, the Orchestrator verifies the signature using the SP's certificate. If the SP does not sign requests, set `skipVerification: true`:

<Tabs>
  <Tab title="Console UI">
    In the Console, request verification is set on the application's **Protocol & Assertion Settings** card under **Request Verification**. Upload the SP's **Certificate File** (PEM) to verify signed `AuthnRequest` messages, or enable **Skip Request Verification** if the SP does not sign its requests.
  </Tab>

  <Tab title="Configuration">
    ```yaml theme={null}
    apps:
      # SP that sends signed AuthnRequests
      - name: saml-signed
        type: saml
        requestVerification:
          certificate: <sp_signing_cert>
        # ...

      # SP that does not sign AuthnRequests
      - name: saml-unverified
        type: saml
        requestVerification:
          skipVerification: true
        # ...
    ```
  </Tab>
</Tabs>

## IdP-Initiated Login

IdP-initiated login allows users to start a SAML flow from the identity provider rather than from the service provider. When configured, the Orchestrator exposes a login URL that generates a SAML response and sends it directly to the SP's assertion consumer service.

| Key                                   | Type   | Required | Default | Description                                                                                                    |
| ------------------------------------- | ------ | -------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| `idpInitiatedLogin.loginURL`          | string | Yes      | --      | URL that triggers the IdP-initiated flow. Users or portals navigate to this URL to start the login.            |
| `idpInitiatedLogin.relayStateURL`     | string | No       | --      | URL included as the SAML `RelayState` parameter. The SP redirects the user here after consuming the assertion. |
| `idpInitiatedLogin.buildRelayStateSE` | object | No       | --      | Service Extension for dynamically building the relay state value.                                              |

**Example:**

<Tabs>
  <Tab title="Console UI">
    In the Console, IdP-initiated login is set on the application's **Protocol & Assertion Settings** card under **IdP-Initiated Login**. Enter a **Login URL** to enable the flow (e.g., `https://auth.example.com/saml/sso/portal-app`), and optionally a **Relay State URL** for where the user lands after authentication.
  </Tab>

  <Tab title="Configuration">
    ```yaml theme={null}
    apps:
      - name: portal-app
        type: saml
        idpInitiatedLogin:
          loginURL: https://auth.example.com/saml/sso/portal-app
          relayStateURL: https://portal.example.com/
        # ...
    ```
  </Tab>
</Tabs>

When a user navigates to `https://auth.example.com/saml/sso/portal-app`, the Orchestrator authenticates them (if not already authenticated), builds a SAML assertion, and POSTs it to the app's assertion consumer service URL with the relay state set to `https://portal.example.com/`.

## Assertion Encryption

SAML assertion encryption protects assertion content during transit by encrypting the assertion XML before embedding it in the SAML response. The SP decrypts the assertion using its private key.

| Key                            | Type   | Required | Default | Description                                                                                                                       |
| ------------------------------ | ------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `encryption.keyEncryptMethod`  | string | Yes      | --      | XML encryption method for encrypting the symmetric key (e.g., `http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p`).                 |
| `encryption.dataEncryptMethod` | string | Yes      | --      | XML encryption method for encrypting the assertion data (e.g., `http://www.w3.org/2001/04/xmlenc#aes256-cbc`).                    |
| `encryption.digestMethod`      | string | No       | --      | Digest method for key encryption (e.g., `http://www.w3.org/2001/04/xmlenc#sha256`).                                               |
| `encryption.certificate`       | string | Yes      | --      | PEM-encoded SP certificate (public key) used to encrypt the assertion. The SP holds the corresponding private key for decryption. |

**Example:**

<Tabs>
  <Tab title="Console UI">
    Assertion encryption settings are configured per-app via YAML only. The Console UI does not currently expose encryption fields. See the Configuration tab for the full reference.
  </Tab>

  <Tab title="Configuration">
    ```yaml theme={null}
    apps:
      - name: encrypted-app
        type: saml
        encryption:
          keyEncryptMethod: "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"
          dataEncryptMethod: "http://www.w3.org/2001/04/xmlenc#aes256-cbc"
          digestMethod: "http://www.w3.org/2001/04/xmlenc#sha256"
          certificate: <sp_encryption_cert>
        # ...
    ```
  </Tab>
</Tabs>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Assertion signature validation fails at the SP">
    **Symptoms:** The SP rejects the SAML response with "invalid signature", "signature verification failed", or "unable to validate assertion".

    **Causes:**

    * The signing certificate configured in the Orchestrator (`samlProvider.signature.certificate`) does not match the certificate the SP has on file.
    * The signing certificate has expired.
    * A signing algorithm mismatch between the Orchestrator and the SP's expected algorithm.

    **Resolution:**

    1. Export the `samlProvider.signature.certificate` and provide it to the SP via metadata exchange or manual upload.
    2. Verify the certificate is not expired by checking its `Not After` date.
    3. If using per-app signature overrides, ensure the app-level certificate is the one provided to the SP.
  </Accordion>

  <Accordion title="NameID format mismatch">
    **Symptoms:** The SP accepts the assertion but cannot identify the user, or rejects the assertion with "invalid NameID format" or "unrecognized subject".

    **Causes:**

    * The `nameID.format` does not match what the SP expects (e.g., the SP expects `emailAddress` but the Orchestrator sends `unspecified`).
    * The `nameID.attrMapping` references an attribute that is empty or not returned by the upstream IdP.

    **Resolution:**

    1. Check the SP's metadata or documentation for the required NameID format.
    2. Set `nameID.format` to the matching URN (e.g., `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`).
    3. Verify that `nameID.attrMapping` points to an attribute that is populated for all users (e.g., `upstream-idp.email`).
  </Accordion>

  <Accordion title="Claims/attributes missing from assertion">
    **Symptoms:** The SP receives the assertion but expected attributes (e.g., email, groups, department) are empty or absent.

    **Causes:**

    * The `claimsMapping` references a wrong connector name or an attribute that does not exist on the upstream identity.
    * Attribute providers (`attrProviders`) are not configured, so enrichment attributes are not loaded.
    * The upstream IdP does not return the expected claims in its response.

    **Resolution:**

    1. Verify that connector names in `claimsMapping` match the `connectors[].name` values exactly.
    2. If enrichment is needed, confirm `attrProviders` entries are configured with the correct connector names and `usernameMapping`.
    3. Test the upstream IdP directly to confirm it returns the expected attributes.
  </Accordion>

  <Accordion title="SP-initiated login fails with &#x22;unable to verify request&#x22;">
    **Symptoms:** The login flow fails immediately after the SP redirect, with an error about request verification or signature validation.

    **Causes:**

    * The SP signs its AuthnRequest, but the Orchestrator does not have the SP's signing certificate for verification.
    * The SP's certificate in `requestVerification.certificate` is expired or does not match the key the SP uses.

    **Resolution:**

    1. If the SP signs its AuthnRequests, provide the SP's signing certificate in `requestVerification.certificate`.
    2. If the SP does not sign requests, set `requestVerification.skipVerification: true`.
    3. If the SP recently rotated its signing key, update the certificate in the app configuration.
  </Accordion>

  <Accordion title="IdP-initiated login returns &#x22;unknown service provider&#x22;">
    **Symptoms:** Navigating to the IdP-initiated login URL returns an error about an unknown or unregistered service provider.

    **Causes:**

    * The `idpInitiatedLogin.loginURL` path does not match any configured app.
    * The app's `entityIDs` are missing or do not match what the SP expects.

    **Resolution:**

    1. Verify the login URL matches the configured app name in the URL path (e.g., `/saml/sso/my-app` for an app named `my-app`).
    2. Confirm that `entityIDs` contains at least one entry with `default: true`.
    3. Check that the `consumerServiceURLs` are correctly configured for the target SP.
  </Accordion>

  <Accordion title="Assertion encryption fails">
    **Symptoms:** The SP cannot decrypt the assertion, reporting errors like "unable to decrypt", "decryption failed", or "invalid key".

    **Causes:**

    * The `encryption.certificate` is not the SP's encryption certificate (it might be the signing cert instead).
    * An algorithm mismatch -- `keyEncryptMethod` or `dataEncryptMethod` does not match the SP's supported algorithms.

    **Resolution:**

    1. Verify that `encryption.certificate` is the SP's **public encryption certificate** (not its signing certificate -- these are often different).
    2. Confirm that `keyEncryptMethod` and `dataEncryptMethod` match the algorithms the SP supports (check SP metadata or documentation).
    3. If the SP specifies a `digestMethod`, ensure it is also set in the app configuration.
  </Accordion>
</AccordionGroup>

## Related Pages

<CardGroup cols={2}>
  <Card title="Applications" icon="grid-2" href="/reference/orchestrator/applications">
    Overview of application types, route patterns, and shared configuration
  </Card>

  <Card title="SAML Provider" icon="shield-halved" href="/reference/modes/saml-provider">
    SAML Provider mode configuration for SAML app deployments
  </Card>

  <Card title="Identity Fabric" icon="compass" href="/reference/orchestrator/identity-fabric">
    Configure the identity providers referenced in app policies
  </Card>

  <Card title="Single Logout (SLO)" icon="right-from-bracket" href="/guides/authentication/single-logout">
    Configure Single Logout for SAML applications
  </Card>
</CardGroup>
