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

> ## Agent Instructions
> Pages under /latest/ document the current release. Paths that begin with a version number, for example /10.0/, are frozen snapshots of superseded releases kept for reference only — never present their instructions as current. If the reader's version is unknown, answer from /latest/ and say which version the answer describes.
> xorlab is deployed on-premises, hybrid, or as a cloud service, and integrates with either Microsoft 365 or on-premises mail infrastructure. Configuration steps often differ between these. State which deployment and integration mode an instruction applies to instead of presenting one as universal.
> Distinguish inline mode from monitoring mode when describing anything that acts on email. Monitoring mode observes a copy and cannot block or quarantine; inline mode routes mail through xorlab and can.
> Write the product name as lowercase 'xorlab'. Use the documented component names: xorlab Control Center (XCC), xorlab MTA, xorlab Sandbox (DANA), xorlab Natural Language Understanding (NLU). After the first mention, use the short forms XCC, MTA, Sandbox, and NLU. Do not use DANA as a standalone name for the Sandbox, but keep it where it is a literal string in configuration keys, container names, and hostnames.
> Do not invent configuration keys, rule parameters, list names, log properties, or API fields. If a value is not present in this documentation, say that it is not documented rather than guessing.

# Enable SAML Login

> Set up a generic SAML integration for single sign-on. For Entra ID, use the dedicated Entra ID guide instead.

<Warning>
  **SAML with M365 Entra ID**

  If you use Entra ID, please instead follow [SAML with Entra ID](/latest/m365-saml-entra-authentication).
</Warning>

In order to get a working SAML authentication setup, you have to configure three elements:

1. Identity provider (on the customer side)
2. Authentication backend in xorlab
3. [Certificate in a trust store](/latest/authentication-certificates)

Because multiple SAML identity providers can be active simultaneously in xorlab, they have to be distinguished by their names in the xorlab configuration. Here, this name will be referred to as `saml2BackendName`.

## Identity provider configuration

On the identity provider side, you have to set up a new application for xorlab with the following properties:

* SSO URL: `https://<xorlabDomain>/auth/saml2/sso/<saml2BackendName>`
* Audience URI (SP Entity ID): `https://<xorlabDomain>/auth/saml2/service-provider-metadata/<saml2BackendName>`
* The SAML response needs to be signed
* The SAML assertion needs to be signed

<Note>
  **Authentication request signing is now supported**

  If your IdP requires authentication request signing, this optional feature is supported in xorlab. For more information, please refer to [Authentication request signing](/latest/authentication-saml-request-signing).
</Note>

In addition, the SAML assertion must have attributes to transport the:

* username (required; a list of one element)
* roles (required; a list of many elements)
* display name (optional; a list of one element)
* emails (optional; a list of many elements)
* `nameID` claim (required)

Mapping these assertion attributes to xorlab user attributes can be specified in the configuration.

<Note>
  Before you start configuring this backend in xorlab, please read the [Authentication](/latest/authentication-overview) article, if you haven’t already.
</Note>

## xorlab configuration

The configuration on the xorlab side is in the `auth.yml` file under the `saml2AuthBackends:` section. It is important that you use the same name for the SAML backend within xorlab as it is named on the identity provider side.

Also, the identity provider needs to provide the metadata for the application configuration either via an URL or in a file.

### Basic configuration

All basic settings are configured under the `idp:` subsection of the SAML backend section—in the example below we used `mySamlProvider` as the backend name:

```yaml auth.yml theme={null}
saml2AuthBackends:
  mySamlProvider:
    idp:
      metadataFile: example-saml-provider-metadata.xml
      # metadataUrl: https://example-idp.com/metadata
```

If the IdP (Relying Party) metadata is stored in a file, specify its location and name as a value for the `metadataFile` attribute. Otherwise, point to this metadata available over a HTTP(S) endpoint by providing its URL address as a value for the `metadataUrl` attribute. Note that only one metadata location can be specified so, in the above example, the `metadataUrl` key is commented out and xorlab will use the metadata file.

### Attribute mapping

In the next step, you have to map (assign) attributes from the SAML assertion to the user model in xorlab. The mapping is described using [Spring expression language](https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html) and is configured under the `attributeMapping:` subsection.

You can use these methods:

* `attr('<name>')`: retrieve the attribute with the `'<name>'` name from attributes in the source authorization system.
* `replace(<string or list of strings>, '<pattern>', 'replace')`: replace every occurrence of `'<pattern>'` with `'replace'` in an input string or a list of input strings.
* `azureAdEmails()`: read all email addresses from the Azure Active Directory `proxyAddresses` attribute.

Literal values have to be quoted, e.g., `key: 'literal value'`.

A sample configuration for attribute mapping which simply retrieves attributes from the auth system (Entra ID in this case) would look like this:

```yaml auth.yml theme={null}
    attributeMapping:
      displayName: attr('http://schemas.microsoft.com/identity/claims/displayname')
      emails: attr('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name')
      roles: attr('http://schemas.microsoft.com/ws/2008/06/identity/claims/role')
```

Available attributes are explained in the table below:

| Attribute     | Description                                                                                                                                                                                                                                                                                                                                                           |
| :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `userName`    | An attribute mapping for the username. The result of this mapping will be put into the `subject` attribute of the token issued to the consuming services<br />**Note:** The default is to use the assertion subject as a username. If you want to change this behavior, then specify a mapping for the username. However, in most setups, this should not be the case |
| `displayName` | An attribute mapping for the display name of the user. It is optional and could be used by consuming services in places where a more descriptive name of the user is appreciated                                                                                                                                                                                      |
| `emails`      | Mapping for the list of emails associated with the user. Consuming services might use this list to associate the user with a certain pool of email messages                                                                                                                                                                                                           |
| `roles`       | Mapping for the list of roles assigned to the user. This mapping can only be set for authentication backends which do not do their own authorization                                                                                                                                                                                                                  |
| `tenant`      | **Only required for multi-tenancy deployments**: Make sure the value of the `tenant` attribute correspond to the `name` defined in the `guarded_tenants.yml`.                                                                                                                                                                                                         |

### Role mapping

The last step is to configure role mapping. You must map all roles served by the SAML identity provider to the corresponding xorlab roles under the `roleMapping:` subsection. Roles that are not mapped are ignored by default. Multiple xorlab roles can be mapped to the same identity provider role, e.g., `xcc_login` → `company1-group1`, `xcc_admin` → `company1-group1`.

If the SAML identity provider already serves roles compatible with xorlab (see [*Built-in Roles*](/latest/built-in-user-roles)), you can also specify a “pass-through” role-mapping mode using `roleMappingMode: PASS_THROUGH`.

<Note>
  Please be aware that in the pass-through role-mapping mode, all roles served by the SAML identity provider are added to the xorlab authorization context. If this context is becoming too large, i.e., too many irrelevant roles are added, then it might lead to errors and users being unable to access XCC. Therefore, it is advisable to only map the roles that are relevant to xorlab.
</Note>

A sample role mapping configuration is shown below:

```yaml auth.yml theme={null}
    roleMapping:
      xcc_admin:
      - xcc_admin
      xcc_monitor:
      - xcc_monitor
      xcc_insights:
      - xcc_insights
      xcc_quarantine_user:
      - xcc_quarantine_user
```

A sample role mapping configuration using the pass-through mode:

```yaml auth.yml theme={null}
    roleMappingMode: PASS_THROUGH
    roleMapping:
      # You can still define a role mapping in pass-through mode
      xcc_monitor: [ xcc_admin ]
```

### Activate the configuration

After updating `auth/auth/auth.yml`, click **Publish**. The authentication configuration becomes active within about one minute.

### Multi-Tenancy

The setup on this page applies unchanged in a multi-tenant deployment. Two things are added on top: a `tenant` entry in the [Attribute mapping](#attribute-mapping) that matches the tenant `name` in `guarded_tenants.yml`, and a [tenant-restricted user role](/latest/built-in-user-roles) in the [Role mapping](#role-mapping).

<Card title="Enable Tenant Login" icon="building" horizontal href="/latest/multi-tenancy-authentication#saml-login">
  Complete per-tenant SAML example, and the other login options available to tenants.
</Card>

### Example configuration

The final configuration for a SAML backend—Azure in this example—should look like this:

```yaml auth.yml theme={null}
tokenSigningKey: "xyz"

enabledAuthBackends:
  - azureSaml

saml2AuthBackends:
  azureSaml:
    idp:
      metadataUrl: https://login.microsoftonline.com/<tenant_id>/federationmetadata/2007-06/federationmetadata.xml?appid=<app_id>
    attributeMapping:
      displayName: attr('http://schemas.microsoft.com/identity/claims/displayname')
      emails: attr('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name')
      roles: attr('http://schemas.microsoft.com/ws/2008/06/identity/claims/role')
    roleMapping:
      xcc_admin:
      - xcc_admin
      xcc_monitor:
      - xcc_monitor
      xcc_insights:
      - xcc_insights
      xcc_quarantine_user:
      - xcc_quarantine_user
```

<Note>
  **Shared mailboxes and aliases**

  The configuration from the above example will not support shared mailboxes or aliases obtained with the `proxyAddresses` attribute.
</Note>
