> ## 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 Login via Password File

> Define local xorlab users in a static password file, with password and account recommendations.

To get an overview over all available login mechanisms, have a look at [Authentication](/latest/authentication-overview).

When using local users, we recommend to:

* Use secure passwords or passphrases. Make them unique, random, and long; preferably create them in a password generator of your favorite password manager.
* Don't share accounts.
* Enable 2FA.

## Quickstart

1. In the [Expert Editor](/latest/expert-editor), open `auth.yml` in `auth/auth/`. Make sure the following configuration is present. Normally it is pre-configured. Rename `examplePassword` to a more meaningful name.

   ```yaml auth.yml theme={null}
   enabledAuthBackends:
     - examplePassword

   usernamePasswordAuthBackends:
     examplePassword:
   ```

2. Open `passwordFile.yml` in the same folder and add the local users. Below you find the available attributes that you can configure. We recommend to always require 2FA via `totpRequired`.

```yaml passwordFile.yml theme={null}
  users:
  - username: admin
      tenant: customerA
      displayName: The Admin
      passwordHash: "<ADD PWD HASH HERE>"
      emails: ["email1@example.com", "email2@example.com"]
      totpRequired: true
      roles:
      - xcc_admin
  - username: user1
      tenant: customerA
      passwordHash: "{bcrypt}$2y$10$.4If2RFwcvHRrxlR98m9ju/mCRYCHLAYULByGXvJY.jBuK2/bckZu"
      totpRequired: true
      roles:
      - xcc_analyst
```

3. Click **Publish**. The users become available within about one minute.

The following `users` attributes are available:

| Attribute        | Value                                                                                                          |
| :--------------- | :------------------------------------------------------------------------------------------------------------- |
| `username`       | Unique user name                                                                                               |
| `tenant`         | The `tenant` attribute should reference `name`, defined in `guarded_tenants.yml`                               |
| `displayName`    | More descriptive user name                                                                                     |
| `passwordHash`   | Hash value of a password (see [Password hash generator](#password-hash-generator) below)                       |
| `emails`         | List of emails associated with the user                                                                        |
| `roles`          | Role in AG assigned to the user                                                                                |
| `totpRequired`   | Optional flag. If set to `true`, the user must complete TOTP onboarding at the next login                      |
| `totpSeedBase32` | Base32-encoded TOTP seed that will be set automatically be xorlab after the user completes the TOTP onboarding |

## 2FA/MFA onboarding

Password file users can be forced to set up TOTP during their next login by adding `totpRequired: true` to the user entry in `passwordFile.yml`.

```yaml passwordFile.yml {5} theme={null}
users:
  - username: adminMfa
    # password: test
    passwordHash: "{bcrypt}$2a$10$HVcQJ4zCw1B0AKPz2Mx8FO4HjtbP46FZNaVJDsosYrMeZXTHTs5ti"
    totpRequired: true
    roles:
      - xcc_admin
      - xcc_insights
      - xcc_monitor
```

Afterward, click **Publish**. The authentication configuration becomes active within about one minute, and the user will then be forced into a TOTP onboarding flow during the next login.

<img src="https://mintcdn.com/xorlab/O_O2TUa6eRBR54aI/latest/assets/2fa-screen.png?fit=max&auto=format&n=O_O2TUa6eRBR54aI&q=85&s=489b6c2f5f20baa70f2aad92f779bd08" alt="2FA Login" width="1084" height="939" data-path="latest/assets/2fa-screen.png" />

If the onboarding is successful, the following changes will be automatically made by xorlab:

* `totpSeedBase32` is stored on the user object
* `totpRequired` is removed again (in this way, a new TOTP onboarding can be triggered by setting it to true again)

After onboarding, the user must provide a valid TOTP code when logging in.

<Accordion title="`totpSeedBase32`">
  By default, xorlab generates the seed automatically and updates the `passwordFile.yml`. However, if necessary, you can manually set the seed yourself. One can be created with `openssl rand 20 | base32`.
</Accordion>

## Password hash generator

1. Run the `docker exec -it auth_auth create_hash` command on the **XCC** terminal to generate a password hash from the password you enter and re-type when prompted. You should get the output similar to the one below:
   ```shell theme={null}
   $ docker exec -it auth_auth create_hash
   ActiveGuard password hash generator
   Password to hash: 1234
   Hashed password:
   {bcrypt}$2a$10$YOmSE8jp9fSBlVP3P3KEh.UnezedRVSnBZL7x5xWQvYfiBF0z49Uy
   ```
2. Copy the generated hash, open Expert Editor and paste it into `auth/auth/passwordFile.yml` as a value for the `passwordHash` key of a particular user.
3. Once you finish adding password hashes for all users, click **Publish**. After about one minute, the changes are hot-reloaded and active.

In case you don't have access to the XCC terminal, run `htpasswd -nBC 10 ignore | sed 's/ignore:/{bcrypt}/'` on a Linux terminal to generate a password hash as alternative to step 1 above.

## Enable Logging

With this authorization method, it's good to know whether there were any unsuccessful login attempts. You can use the logging system for that:

1. Follow the instructions for logging [audit trail events](/latest/logging-events#audit-trail-events) to create a log for the `audit.access.denied` event.

2. Your `auth/auth/logback-audit.xml` config file should look like the one below:

   ```xml theme={null}
   <?xml version="1.0" encoding="UTF-8"?>
   <included>
    <appender name="syslogAppender" class="com.xorlab.sgappliance.shared.logback.SyslogAppender">
      <syslogHost>syslog.example.com</syslogHost>
      <port>514</port>
      <protocol>UDP</protocol>
      <facility>LOCAL0</facility>
      <encoder>
      <pattern>%jsonMsg%n</pattern>
      </encoder>
    </appender>

    <!-- Log all unsuccessful login attempts -->
    <logger name="audit.access.denied">
      <appender-ref ref="syslogAppender"/>
    </logger>
   </included>
   ```

If you want to log all login attempts, both unsuccessful and successful, just change the `logger name` value to `"audit.access"`.

## Multi-Tenancy

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

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