# Active Directory and LDAP sign-in

> People sign in on the Proxus sign-in page with their Active Directory or LDAP user name and password; their directory groups give their Proxus roles.

Source: https://proxus.io/docs/administer/active-directory

At the end of this guide, people sign in on the Proxus sign-in page with their Active Directory user name and
password, and their AD groups decide their Proxus roles. Proxus talks to your domain controllers directly; nothing
else is installed. The same works for OpenLDAP, FreeIPA and other LDAP directories.

Proxus never stores directory passwords. At every sign-in it asks the directory whether the password is right, so a
changed, expired or disabled AD account takes effect at the next sign-in.

For single sign-on across applications, or Windows sign-in without typing a password, use
[Active Directory through Keycloak](https://proxus.io/docs/administer/active-directory-keycloak) instead.

## Before you start

- A **read-only service account** in Active Directory, for example `svc-proxus-ldap`, with a password that does not
  expire. Proxus uses it to find people and their groups.
- **LDAPS** on your domain controllers (port 636), and your company's root CA certificate as a `.pem` file. Windows
  Server 2025 refuses plain LDAP sign-ins by default; use LDAPS everywhere.
- AD groups for Proxus, for example `proxus-admins`, `proxus-operators` and `proxus-viewers`, with people in them.
  Groups inside these groups count too.
- The hub must reach the domain controllers on port 636.

## Step 1: Give Proxus the CA certificate

Copy your company's root CA certificate into the hub's config folder, for example as `company-root-ca.pem`. In a
container, that is `/app/config/company-root-ca.pem` (the `config` volume).

You can skip this step if the domain controllers' certificates come from a CA the hub's operating system already
trusts.

## Step 2: Turn on directory sign-in

1. Open `Proxus-config.toml` in the config folder, find `[Authentication.Ldap]` and fill it in:

      ```toml
   [Authentication.Ldap]
   Enabled = true
   Servers = ["ldaps://dc1.plant.local:636", "ldaps://dc2.plant.local:636"]
   TrustedCaFile = "/app/config/company-root-ca.pem"
   BindDn = "CN=svc-proxus-ldap,OU=Service Accounts,DC=plant,DC=local"
   UserBaseDn = "OU=Users,DC=plant,DC=local"
   GroupBaseDn = "OU=Groups,DC=plant,DC=local"

   [Authentication.Ldap.RoleMap]
   proxus-admins = ["Administrators"]
   proxus-operators = ["Operator"]
   proxus-viewers = ["Viewer"]
   ```
   
   Proxus tries the servers in order, so a second domain controller keeps sign-in working when the first is down.
2. Give the hub the service account's password as an environment variable, not in the file. With Docker Compose, add
   it to the `environment` of the `proxus-ui` service:

   ```yaml
   environment:
     Authentication__Ldap__BindPassword: ${PROXUS_LDAP_BIND_PASSWORD}
   ```

   and put `PROXUS_LDAP_BIND_PASSWORD=...` in the `.env` file next to `docker-compose.yml`.
3. Restart the hub.

The defaults fit Active Directory: people are found by their `sAMAccountName`, which becomes their Proxus user name,
and nested groups are followed. Every key is described in
[Configuration keys](https://proxus.io/docs/reference/configuration#authenticationldap).

## Step 3: Check the roles

At every sign-in, Proxus gives the roles that `RoleMap` maps the person's groups to, and takes away mapped roles
whose group the person left. Roles that `RoleMap` does not name are left as an administrator set them in Proxus.

The first time a person signs in, Proxus creates their user with the **Default** role besides the mapped ones. Change
this with `DefaultRoles`, or set `CreateUsers = false` to let in only people an administrator has linked.

## Step 4: Test it

1. Open Proxus in a private browser window.
2. Sign in with the user name and password of an AD account that is in `proxus-admins`.
3. In Proxus, open **Security > Users**: the person is listed with **Administrators**.
4. Take the person out of the group in AD and sign in again: the role is gone.

## Existing Proxus users

A Proxus user who already has the same user name as an AD account keeps signing in with their Proxus password. To
move such users to Active Directory, set `LinkExistingUsers = true` and restart the hub: from their next sign-in, they
use their AD password and their Proxus password stops working.

Administrators never move. They keep their Proxus password, so there is always a way in.

## Keep a way in

Keep at least one Proxus administrator who signs in with a Proxus password (the **Admin** user, with
[two-step verification](https://proxus.io/docs/administer/two-step-verification)). When no domain controller can be reached, that
account still works; people who sign in with the directory see a message that the directory cannot be reached.

## How it is protected

- Passwords go only to the domain controllers, over LDAPS or StartTLS. With a plain `ldap://` address and no
  `StartTls`, the hub writes a warning at start.
- A wrong password counts as a failed sign-in, so [account lockout](https://proxus.io/docs/administer/users-and-roles) applies, as it
  does in Active Directory.
- An empty password is always refused. What people type cannot change the directory search.
- Directory users can turn on [two-step verification](https://proxus.io/docs/administer/two-step-verification). They change their
  password in Active Directory; Proxus does not show **Change My Password** to them.
- An administrator can switch a directory user off in Proxus (**Active** off); the AD account is not changed.

## OpenLDAP and other directories

Change the filters to your directory's object classes, for example for OpenLDAP:

```toml
[Authentication.Ldap]
UserFilter = "(&(objectClass=inetOrgPerson)(uid={0}))"
UserNameAttribute = "uid"
GroupFilter = "(&(objectClass=groupOfNames)(member={0}))"
```

`{0}` is the typed user name in `UserFilter` and the person's DN in `GroupFilter`.

## When something does not work

The hub writes the reason of every refused directory sign-in to its log (category **Authentication**).

| What you see | Why | What to do |
| --- | --- | --- |
| "The company directory cannot be reached right now" | No server answered, the certificate is not trusted, or the service account was refused. | Check that the hub reaches port 636, that `TrustedCaFile` is the root CA of the servers' certificates, and the service account's DN and password. The log names the cause. |
| "User name or password is incorrect" for a right password | The person is not under `UserBaseDn`, or `UserFilter` does not find them. | Check the person's place in AD and the filter. |
| "Your directory account is right, but it may not open Proxus" | A Proxus user with that name exists and is not linked, it is switched off, or `CreateUsers` is off. | See [Existing Proxus users](#existing-proxus-users), or switch the user on. |
| Sign-in works but the person has no Proxus role | Their groups are not under `GroupBaseDn`, or are named differently. | Compare the group names with the `RoleMap` lines. |
| A warning at start that a server is not encrypted | A plain `ldap://` address without `StartTls`. | Use `ldaps://`, or set `StartTls = true`. |

## What's next

- [Active Directory through Keycloak](https://proxus.io/docs/administer/active-directory-keycloak): single sign-on and Windows sign-in
- [Users and roles](https://proxus.io/docs/administer/users-and-roles)
- [Two-step verification](https://proxus.io/docs/administer/two-step-verification)
