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

# Setting up Keycloak

> Configure sign-in, groups, administrator roles and user synchronization for VARIOS AI with Keycloak

VARIOS AI signs users in via OpenID Connect. This page describes how to set up a realm and a client in Keycloak, how to connect users from LDAP or Active Directory or create them as local Keycloak users, and which values go into the `.env`.

<Info>
  This guide describes a proven configuration (best practice). Adapt the steps to your environment as needed. Whichever approach you choose, the service account roles, the `.env` values and the group structure must meet the requirements described on this page.
</Info>

## Prerequisites

* Keycloak is installed and running. For installation instructions, see the [Keycloak getting started guides](https://www.keycloak.org/guides#getting-started).
* You can sign in to the Keycloak admin console and are allowed to create and configure a realm and a client.
* VARIOS AI can reach Keycloak at its domain via HTTPS, by default on TCP port 443. The domain name must resolve from the VARIOS AI runtime environment; if Keycloak uses a different HTTPS port, that port must be reachable.
* You know the domain of your VARIOS AI installation. To connect LDAP or Active Directory, you also need the connection and search details agreed with the person responsible for the directory.

In all steps, replace `<PROJECT_DOMAIN>` with the domain of your VARIOS AI installation (e.g. `varios.example.com`), `<KEYCLOAK_HOST>` with the domain of your Keycloak instance (e.g. `keycloak.example.com`) and `<REALM>` with the name of the realm.

## Create the realm

<Steps>
  <Step title="Create a realm">
    In the admin console, open the realm selector and choose **Create realm**. Enter a unique name under **Realm name**, e.g. `varios-ai`, and click **Create**. The realm name is part of all URLs you later enter in the `.env`.
  </Step>

  <Step title="Configure login settings">
    Optional: Under **Realm settings → General**, set a **Display name** if the sign-in page should show your organization's name or "VARIOS AI" instead of "Keycloak".

    Under **Realm settings → Login**, enable **Remember me**. Enable **Email as username** if users should sign in with their email address instead of their username.
  </Step>

  <Step title="Increase the token lifetime">
    Under **Realm settings → Tokens**, set **Access Token Lifespan** to `8 Hours` and click **Save**.
  </Step>
</Steps>

## Create the client

<Steps>
  <Step title="Create a client">
    Open **Clients → Create client**. Choose `OpenID Connect` as **Client type** and enter a **Client ID**, for example `variosai`. The client ID goes into `OIDC_CLIENT_ID`; it is not the same as the realm name.
  </Step>

  <Step title="Enable capabilities">
    Under **Capability config**, enable **Client authentication** and **Service accounts roles**.
  </Step>

  <Step title="Enter the URLs">
    Under **Login settings**, enter the address of your VARIOS AI installation, not the Keycloak address:

    | Field                               | Value                        |
    | ----------------------------------- | ---------------------------- |
    | **Root URL**                        | `https://<PROJECT_DOMAIN>`   |
    | **Home URL**                        | `https://<PROJECT_DOMAIN>`   |
    | **Valid redirect URIs**             | `https://<PROJECT_DOMAIN>/*` |
    | **Valid post logout redirect URIs** | `https://<PROJECT_DOMAIN>/*` |
    | **Web origins**                     | `https://<PROJECT_DOMAIN>`   |

    Click **Save**.

    <Info>
      **Web origins** expects an origin without a path, so do not add `/*` at the end.
    </Info>
  </Step>

  <Step title="Copy the client secret">
    Open the **Credentials** tab of the client and copy the **Client Secret**. Enter it as `OIDC_CLIENT_SECRET`.
  </Step>

  <Step title="Assign service account roles">
    Open the **Service accounts roles** tab of the client and click **Assign role**. Switch the filter to **Filter by clients** and assign the following roles of the `realm-management` client:

    * `view-users`
    * `view-groups`
    * `query-users`
    * `query-groups`

    <Info>
      VARIOS AI uses the service account to read users, groups and group memberships from the realm. Without these roles, user synchronization fails.
    </Info>
  </Step>
</Steps>

## Connect users

Users can be taken over from an existing directory or created directly in Keycloak.

<Tabs>
  <Tab title="LDAP or Active Directory">
    Keycloak reads users and groups from your directory and makes them available to VARIOS AI. All directory values depend on your schema.

    Before the first import, clarify the following with the person responsible for the directory: connection address and certificate or CA, bind account, base DNs for users and groups, search scope, user and group filters if needed, and the attributes actually used for usernames, unique identifiers and group memberships. Agree on which users and groups are intended for VARIOS AI. Non-standard directory schemas may require expert support.

    <Steps>
      <Step title="Add an LDAP provider">
        Open **User federation** and add an **LDAP** provider. Enter a **UI display name** and choose the **Vendor**, e.g. `Active Directory`. Enter the **Connection URL** of your directory, a read-only identity as **Bind DN** (bind DN or UPN) and its password under **Bind credentials**. Check the details with **Test connection** and **Test authentication**.

        <Warning>
          Only use an encrypted connection: `ldaps://`, or `ldap://` with **Enable StartTLS** turned on. With StartTLS, turn off **Connection pooling**. The hostname in the connection URL must match the directory server's certificate. If the certificate is signed by an internal CA, Keycloak must trust that CA. If certificate errors occur, check the hostname, certificate chain and truststore before you continue.
        </Warning>
      </Step>

      <Step title="Define the search">
        Under **LDAP searching and updating**, define which users are imported:

        | Field                                                                    | Value                                                             |
        | ------------------------------------------------------------------------ | ----------------------------------------------------------------- |
        | **Edit mode**                                                            | `READ_ONLY`, Keycloak does not write back to the directory        |
        | **Users DN**                                                             | Container or OU that holds the users; a group is not allowed here |
        | **Username LDAP attribute**                                              | e.g. `sAMAccountName` or `cn`                                     |
        | **RDN LDAP attribute**, **UUID LDAP attribute**, **User object classes** | according to your directory schema                                |
        | **User LDAP filter**                                                     | optional, limits the import to the agreed users                   |
        | **Search scope**                                                         | `Subtree` if users are located in sub-OUs                         |

        <Warning>
          **Users DN** is a search container, not an AD group. If the base is too broad and no suitable **User LDAP filter** is set, more users than intended are imported into Keycloak and subsequently into VARIOS AI. Check the scope with regard to permissions and license planning before you run **Sync all users**, and take the **Search scope** into account.
        </Warning>
      </Step>

      <Step title="Set up synchronization">
        Under **Synchronization settings**, enable **Periodic changed users sync**, set the interval to match the required freshness, e.g. `86400` seconds for a daily synchronization, and save. Then run the first import via **Action → Sync all users**. Under **Users**, check the number and identity of the imported users and adjust the base DN or filter if users are missing or too many were imported.

        <Note>
          This synchronization only runs from LDAP to Keycloak. The transfer from Keycloak to VARIOS AI is a separate process, see [Synchronize users and groups](#synchronize-users-and-groups).
        </Note>
      </Step>

      <Step title="Add a group mapper">
        The group mapper imports the groups from your directory that VARIOS AI needs for assignments and roles, see [Groups in VARIOS AI](#groups-in-varios-ai). Open the **Mappers** tab of the LDAP provider and add a mapper of type `group-ldap-mapper`:

        | Field                                    | Value                                                                          |
        | ---------------------------------------- | ------------------------------------------------------------------------------ |
        | **LDAP Groups DN**                       | Container or OU that holds the groups                                          |
        | **LDAP filter**                          | optional, limits the import to the groups intended for VARIOS AI               |
        | **Group name LDAP attribute**            | usually `cn`                                                                   |
        | **Membership LDAP attribute**            | e.g. `member`, `memberOf` or `memberUid`                                       |
        | **Membership attribute type**            | `DN` or `UID`                                                                  |
        | **Member-Of LDAP attribute**             | usually `memberOf`                                                             |
        | **Preserve group inheritance**           | turn off so that all groups are created at the top level                       |
        | **Drop non-existing groups during sync** | turn on so that groups deleted in the directory are also removed from Keycloak |

        Save the mapper and run the group import via **Action → Sync LDAP groups to Keycloak**. Under **Groups**, check that only the intended groups with the expected members exist. If no groups appear after **Sync all users**, trigger the group import from the mapper separately.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Local users">
    Local Keycloak users are suitable for tests and small environments without a directory service.

    <Steps>
      <Step title="Create groups">
        Under **Groups → Create group**, create the groups you use in VARIOS AI to assign assistants, AI models and connectors, as well as the groups for the administrator roles, see [Groups in VARIOS AI](#groups-in-varios-ai).
      </Step>

      <Step title="Create users">
        Open **Users → Add user** and enter **Username**, **Email**, **First name** and **Last name**. Add the user to the appropriate groups via **Join groups** and click **Create**.
      </Step>

      <Step title="Set an initial password">
        Open the **Credentials** tab of the user, click **Set password** and leave **Temporary** enabled. The user has to change the password at the first sign-in.
      </Step>
    </Steps>
  </Tab>
</Tabs>

<Warning>
  VARIOS AI only imports users whose **Email**, **First name** and **Last name** are filled in. Users without these details are skipped during synchronization.
</Warning>

## Groups in VARIOS AI

VARIOS AI imports the groups from Keycloak together with their members. VARIOS AI uses the groups for two purposes:

* **Access to resources:** Under [Groups](/en/monthly/admin/groups), you assign assistants, AI models and connectors to groups and set budgets.
* **Administrator roles:** Members of specific groups receive the administrator roles in VARIOS AI.

Only create the groups in Keycloak, or import the groups from your directory, that you need to control access in VARIOS AI, for example departments or project teams.

<Note>
  VARIOS AI only imports top-level groups and only direct memberships. Subgroups and memberships inherited through them are not taken into account.
</Note>

### Map administrator roles

In the `.env`, enter the name of the corresponding group for each role:

| Role                     | Variable                      | Example           |
| ------------------------ | ----------------------------- | ----------------- |
| Administrator            | `ADMIN_GROUP_NAME`            | `Admin`           |
| Super administrator      | `SUPERADMIN_GROUP_NAME`       | `SuperAdmin`      |
| Compliance administrator | `COMPLIANCE_ADMIN_GROUP_NAME` | `ComplianceAdmin` |

The group name must match exactly, including upper and lower case. Each variable takes exactly one group name. Existing groups from your directory do not have to be renamed; enter their names in the variables.

## Values for the .env

```bash theme={null}
OIDC_PROVIDER=keycloak
OIDC_AUTHORITY=https://<KEYCLOAK_HOST>/realms/<REALM>
OIDC_CONFIGURATION_URL=https://<KEYCLOAK_HOST>/realms/<REALM>/.well-known/openid-configuration
OIDC_CLIENT_ID=<Client ID>
OIDC_CLIENT_SECRET=<Client Secret>
OIDC_LOGOUT_URL=
OIDC_SCOPE=openid profile offline_access
OIDC_USER_IDENTIFIER=preferred_username
OIDC_ROLES_CLAIM=roles
SCIM_DIRECTION=pull
SCIM_MANDANT=<REALM>
SCIM_TOKEN=
SCIM_TENANT_ID=
SCIM_OBJECT_ID=
KEYCLOAK_REALM_BASE_URL=https://<KEYCLOAK_HOST>/realms/<REALM>
KEYCLOAK_ADMIN_REALM_BASE_URL=https://<KEYCLOAK_HOST>/admin/realms/<REALM>
ADMIN_GROUP_NAME=Admin
SUPERADMIN_GROUP_NAME=SuperAdmin
COMPLIANCE_ADMIN_GROUP_NAME=ComplianceAdmin
```

Use the realm name for `SCIM_MANDANT`. `OIDC_LOGOUT_URL`, `SCIM_TOKEN`, `SCIM_TENANT_ID` and `SCIM_OBJECT_ID` are not needed for Keycloak and stay empty. Do not remove these variables from the `.env` entirely, otherwise Docker Compose prints warnings at startup.

## Synchronize users and groups

VARIOS AI reads users, groups and group memberships from Keycloak using the client's service account. This synchronization is independent of the synchronization between LDAP and Keycloak. You set the interval under **Admin Menu → Settings → General** in the **User Sync Pull Interval (minutes)** field; the default is five minutes. Users and groups deleted in Keycloak are also removed from VARIOS AI.

Administrator roles are applied at sign-in based on the synchronized group memberships. If a user is added to an administrator group, they receive the role after the next synchronization and a new sign-in.

To start the synchronization immediately, click **Synchronize now** under **Admin Menu → Settings → General**. Alternatively, run the following on the server:

```bash theme={null}
docker compose exec -u www-data php /data/flow usersync:sync --force
```

Without `--force`, the synchronization is skipped if the last run was within the configured interval.

## Verification

* A user from the realm can sign in to VARIOS AI.
* A user from the group set in `SUPERADMIN_GROUP_NAME` sees the Administration menu.
* The synchronized entries appear under Administration → Users and Groups.
* A user sees the assistants, models and connectors assigned to their groups.
* With an LDAP connection, the number and identity of the synchronized users and groups match the agreed selection.
* A changed group membership reaches Keycloak, then VARIOS AI, and takes effect after a new sign-in.
* A test user removed from the directory or from Keycloak is also removed from VARIOS AI.

If sign-in fails, first check the **Valid redirect URIs** and the client secret. If users are missing, check **Email**, **First name** and **Last name** as well as the service account roles. If administrator rights are missing, check the exact spelling of the group names in the `.env`.
