--- description: How Keycloak provides sign-in on a self-managed deployment, how the operator bootstrap creates the first organization and Administrator, and how to set up email, add members and lock people out. --- # Identity and first sign-in !!! info "Availability" - **Deployment:** Self-managed deployments that use Keycloak as the identity backend (`IDENTITY_BACKEND=keycloak`). The Compose bundle and the Air-gapped Helm example use Keycloak. Air-gapped deployments can't use Auth0, so they use Keycloak. On a self-managed deployment, Keycloak handles sign-in, the member directory and invitations for Actian AI Analyst. This page covers the operator's side, including where Keycloak behaves differently from Actian SaaS. Once the first Administrator signs in, they manage members and settings in **Settings**, as on Actian SaaS. See [Members](../settings/members.md) and [Security](../settings/security.md). ## Where Keycloak runs | Option | How it works | |---|---| | **Compose bundle** | Keycloak 26.5 is part of the stack. Its data lives in the bundled Postgres, in a `keycloak` database next to the product database. The Caddy proxy sends `/auth/realms`, `/auth/resources`, `/auth/admin` and `/auth/js` to Keycloak. | | **Helm chart, chart-managed** | Set `keycloak.enabled: true` (the chart default is `false`). The chart runs Keycloak from the bundle's image and needs an empty `keycloak` database on your Postgres. Your ingress must route the same four `/auth` paths to the Keycloak Service. See [Install on Kubernetes with Helm](install-kubernetes-helm.md). | | **Helm chart, your own Keycloak** | Leave `keycloak.enabled: false`. Import the realm template from the Release bundle into your Keycloak with `KC_SPA_ORIGIN`, `KC_API_AUDIENCE` and `KEYCLOAK_ADMIN_CLIENT_SECRET` set, and install the `ai-analyst` login theme. | AI Analyst needs Keycloak 26.5 or later, with the Organizations feature turned on for the realm. If Organizations is off, the server stops with an error that names the realm. Turn it on under **Realm settings** → **General** → **Organizations**, or set `"organizationsEnabled": true` in the realm import. ### The shipped realm The realm template that ships in the Release bundle creates: - A realm named `aianalyst`. - Two clients: `ai-analyst-spa`, which the web app signs in with, and `ai-analyst-admin`, a service account that AI Analyst uses to manage the directory. - Organizations turned on, with email addresses used as usernames. - The `ai-analyst` login theme, with English, French, Dutch, Portuguese and Japanese sign-in pages (`en`, `fr`, `nl`, `pt`, `ja`; English by default). - Self-registration turned off. AI Analyst turns registration on, with email verification, only while an organization has [Sign-up domains](#let-colleagues-sign-up-with-sign-up-domains) and the realm has email set up. Keycloak imports the realm only when it doesn't exist yet. Changes you make in the Keycloak admin console survive restarts and upgrades, but realm-template changes in a later release aren't applied to your existing realm. See [Upgrade and backup](upgrade-and-backup.md). ## Operator bootstrap: the first organization A self-managed deployment has no Actian staff console to create organizations. Instead, when the server starts, it runs an *operator bootstrap* from these settings: | Setting | Required | What it does | |---|---|---| | `BOOTSTRAP_ORG_NAME` | Yes, to run the bootstrap | The name of the organization to create. If it's empty, the bootstrap doesn't run. | | `BOOTSTRAP_ADMIN_EMAIL` | Yes, when `BOOTSTRAP_ORG_NAME` is set | The email address of the organization's first Administrator. | | `BOOTSTRAP_ADMIN_PASSWORD` | No | A temporary password for the Administrator's first sign-in. | | `BOOTSTRAP_SIGNUP_DOMAINS` | No | Comma-separated email domains the organization starts with as Sign-up domains, for example `acme.com,acme.de`. | With the Compose bundle, set them in `.env`; the stack doesn't start without `BOOTSTRAP_ORG_NAME` and `BOOTSTRAP_ADMIN_EMAIL`. With the Helm chart, put them in the server Secret (`ai-analyst-secrets`). On the first boot, the bootstrap: 1. Creates the organization as a Keycloak Organization, and creates its Environment in AI Analyst. 2. Creates the Administrator's Keycloak user, unless a user with that email already exists, and adds them to the organization. 3. Reserves the **Administrator** preset for that email. It's applied the first time the Administrator opens AI Analyst. 4. Adds any `BOOTSTRAP_SIGNUP_DOMAINS`. 5. Records an `operator.bootstrap` entry in the organization's audit log. On later boots, the server finds that audit entry and changes nothing. From then on, manage the organization, its members and its Sign-up domains in **Settings**. !!! warning "Bootstrap settings apply only once" - Changing `BOOTSTRAP_ADMIN_EMAIL`, `BOOTSTRAP_ADMIN_PASSWORD` or `BOOTSTRAP_SIGNUP_DOMAINS` after the first boot has no effect. - Don't change `BOOTSTRAP_ORG_NAME` after the first boot. The server finds the bootstrap organization by a name derived from this value. A different value can make the server create and bootstrap a second organization. If the bootstrap can't run, the server stops with one of these errors: | Error | Fix | |---|---| | `BOOTSTRAP_ORG_NAME is set without BOOTSTRAP_ADMIN_EMAIL: …` | Set `BOOTSTRAP_ADMIN_EMAIL`. | | `BOOTSTRAP_ORG_NAME is set, but Operator bootstrap needs IDENTITY_BACKEND=keycloak. …` | Set `IDENTITY_BACKEND=keycloak`, or unset `BOOTSTRAP_ORG_NAME`. | A refused Sign-up domain in `BOOTSTRAP_SIGNUP_DOMAINS` also stops that boot, with a message that names the domain. You can't create more organizations from inside AI Analyst on a Keycloak deployment. ## Sign in as the first Administrator The bootstrap Administrator doesn't need email set up to sign in. 1. Open `https:///` (Compose) or your `FRONTEND_ORIGIN` (Helm). Visitors go straight to the Keycloak sign-in page. 2. Enter the `BOOTSTRAP_ADMIN_EMAIL` address. 3. On the next page, enter the temporary `BOOTSTRAP_ADMIN_PASSWORD`. The sample `.env` ships a placeholder value for it, so replace the placeholder with your own before the first start. 4. Choose a new password when Keycloak asks for one, then enter your first and last name. You arrive in AI Analyst as the organization's Administrator. The temporary password only matters for this first sign-in. Restarts never reset it. Sign in promptly after the first start, so the temporary password is replaced. !!! note "When the temporary password doesn't apply" - **No `BOOTSTRAP_ADMIN_PASSWORD`**: the Administrator's user exists without a password. Set one in the Keycloak admin console: realm **aianalyst** → **Users** → the Administrator → **Credentials** → **Set password**, with **Temporary** on. - **The user already existed**: if a Keycloak user with that email existed before the first boot (for example, created by hand), the bootstrap reuses it unchanged and doesn't apply the temporary password. Sign in with that user's existing password. ## Keycloak admin console The Keycloak admin console is at `https:///auth/admin/`. You use it to set up email, set or reset passwords, and disable users. Sign in as Keycloak's own administrator (in Keycloak's `master` realm). This account is separate from the AI Analyst Administrator: === "Compose bundle" The username is `KEYCLOAK_ADMIN_USERNAME` (default `admin`) and the password is `KEYCLOAK_ADMIN_PASSWORD`, both from `.env`. === "Helm chart" With the chart-managed Keycloak, the username and password are `KC_BOOTSTRAP_ADMIN_USERNAME` and `KC_BOOTSTRAP_ADMIN_PASSWORD` in the Keycloak Secret, the one named in `keycloak.existingSecret` (`ai-analyst-keycloak` in the example values). Your ingress must route `/auth/admin` to Keycloak. !!! warning "Restrict the admin console" The Compose bundle's proxy doesn't restrict `/auth/admin`. Anyone who can reach your public host can reach the sign-in page of the admin console. Restrict that path at your proxy or ingress, for example to your administrators' network, and keep the Keycloak administrator password safe. Members of your organization never need the admin console. ## Set up email in Keycloak Keycloak, not AI Analyst, sends invitation emails and the verification emails for Sign-up domains. Until the `aianalyst` realm has an SMTP server: - Invitations fail, so you can't invite members from **Settings** → **Administration** → **Members**. - You can't add Sign-up domains, and Sign-up domains from `BOOTSTRAP_SIGNUP_DOMAINS` don't open registration. To set up email: 1. Open the Keycloak admin console and select the realm **aianalyst**. 2. Go to **Realm settings** → **Email**. 3. In **From**, enter a bare email address, such as `analyst@example.com`. Put the sender name in the display-name field next to it. 4. Enter your SMTP relay's host, port, encryption and credentials, and save. 5. If you listed domains in `BOOTSTRAP_SIGNUP_DOMAINS`, restart the server so it opens registration (Compose: `docker compose restart server`). !!! warning "Use a bare address in From" Keycloak 26.5 fails to send any email when the **From** field includes a display name. Keep the name in the separate display-name field. **Keycloak must be able to reach the relay.** In the Compose bundle, Keycloak sits on a network with no route off the host. Either run the relay as a container on the stack's network, or start the stack with the `compose.customer-network.yml` override so Keycloak can reach your network. See [Install with Docker Compose](install-docker-compose.md). !!! note "Two separate email settings" The realm's SMTP settings cover invitations and sign-up verification only. The product's own email, such as Scheduled Insights and notifications, uses the server's `EMAIL_TRANSPORT` and `SMTP_*` settings. Setting `SMTP_*` doesn't make invitations work. See the [Configuration reference](configuration-reference.md). ## Add colleagues There are two ways to bring people into the organization. Both need email set up in Keycloak. ### Invite people A member with the **Manage members and access** capability invites people from **Settings** → **Administration** → **Members** → **Invite by email**, and chooses their Capabilities. Keycloak sends the invitation through your SMTP relay. If invitations don't arrive, see [Troubleshooting](#troubleshooting). See also [Members](../settings/members.md). ### Let colleagues sign up with Sign-up domains Instead of inviting everyone, a member with the **Manage organization** capability can list your company's email domains in **Settings** → **Administration** → **Security** → **Sign-up domains**. This section appears only on Keycloak deployments. While at least one domain is listed: - The Keycloak sign-in page offers registration and requires email verification. - Anyone who registers and verifies an address on a listed domain joins the organization with its Default preset, or with the Capabilities of an invitation already waiting for them. - Nobody can join while all Seats are taken. Open invitations count toward Seats. Some domains are refused, for example public email providers such as Gmail or Outlook, disposable email domains, shared hosting domains, and domains another organization on the deployment already uses. You also can't add Sign-up domains while **Require SSO** is on, and you must remove every Sign-up domain before you turn **Require SSO** on. AI Analyst manages the realm's registration setting itself. It checks the setting when the server starts and after every Sign-up domain change, so if you turn registration on or off by hand in the Keycloak admin console, AI Analyst changes it back. ## Remove or lock out a member Removing a member in **Settings** → **Administration** → **Members** removes them from the organization in Keycloak and clears their Capabilities. It doesn't delete their Keycloak user, so in some cases they can still sign in: - **Sign-up domains**: if their email is on one of the organization's Sign-up domains, they rejoin at **No access** the next time they sign in. - **Enterprise SSO members**: people who joined through the organization's single sign-on can't be removed in AI Analyst. The app shows: *This member signs in through your organization's single sign-on, so they can't be removed here. Set them to No access, or remove them at your identity provider.* To lock someone out completely, disable their user in the Keycloak admin console: realm **aianalyst** → **Users** → the user → turn off **Enabled**. ## Reset a member's password AI Analyst can't send password-reset emails on a Keycloak deployment, and the **Password** section doesn't appear on members' personal **Security** page. To reset a member's password, set a temporary one in the Keycloak admin console: realm **aianalyst** → **Users** → the member → **Credentials** → **Reset password** (or **Set password** if the member has none), with **Temporary** on. Keycloak asks the member to choose a new password at their next sign-in. ## Enterprise SSO on Keycloak A member with the **Manage organization** capability can connect the organization's own identity provider (SAML or OIDC) in **Settings** → **Administration** → **Security** → **Enterprise SSO** → **Set up SSO**. On Keycloak, AI Analyst creates the connection as an identity provider in the `aianalyst` realm, linked to the organization, and Keycloak brokers those sign-ins. - **Service provider URLs**: the **ACS URL** and **Entity ID** (SAML) or **Redirect URI** (OIDC) that the setup shows are on your public host, under `/auth/realms/aianalyst/broker/`. Copy them from the setup rather than building them by hand. Your identity provider must be able to send users' browsers to these URLs. - **No test login**: Keycloak has no SSO test login. Instead, the first sign-in by any member through the organization's identity provider, after its details last changed, verifies the connection. The setup tells you to sign out, then sign in once through your identity provider. - **Automatic membership is always on**: the first time someone signs in through the identity provider, they become a member. - **Require SSO is enforced by AI Analyst**: once **Require SSO** is on, AI Analyst refuses sessions that didn't come through the organization's identity provider. Those people see **Sign in with single sign-on** and are asked to sign out and sign in again through the identity provider. ## What's different from Actian SaaS | Feature | On a Keycloak deployment | |---|---| | Sign-in page | Visitors go straight to Keycloak's sign-in page. The in-app email-first sign-in page isn't used. | | SCIM provisioning | Not available. The setting is hidden. | | SSO email domains (with DNS proof) | Not available. The setting is hidden. | | SSO test login | Not available. A real sign-in through the identity provider verifies the connection. | | Sign-up domains | Available only on Keycloak deployments. | | Automatic membership for SSO sign-ins | Always on. | | **Require SSO** | Enforced by AI Analyst rather than the identity provider. | | **Require MFA** | Not supported. The toggle still appears on the **Security** page, but saving a change to it fails. | | Multi-factor authentication | Authenticator apps only, set up during Keycloak sign-in. Setting up an authenticator app, email codes or recovery codes from AI Analyst isn't supported. | | Removing an MFA method | Removing a method, or turning MFA off, on the personal **Security** page means the member's next sign-in asks them to set up an authenticator app again. | | Sign-in sessions | The personal **Security** page shows each session's IP address and last-used time, but not the device or browser. | | Password reset | Not available from AI Analyst. Reset passwords in the Keycloak admin console. | | New organizations | Can't be created from inside AI Analyst. The operator bootstrap creates the first one. | ## Sign-in page language and theme The `ai-analyst` login theme provides AI Analyst's sign-in pages in English, French, Dutch, Portuguese and Japanese. A realm imported before the Release bundle shipped this theme keeps Keycloak's own sign-in pages, because the realm import never runs again. To switch it by hand: 1. In the Keycloak admin console, select realm **aianalyst** → **Realm settings** → **Themes**. 2. Set **Login theme** to `ai-analyst`. 3. Under **Localization**, turn on internationalization and add `en`, `fr`, `nl`, `pt` and `ja`. ## Troubleshooting **Every request from the web app fails with 401 (Compose bundle).** The server can't verify Keycloak's tokens. Check that `PUBLIC_HOST` isn't `localhost`. If you use your own TLS certificate that chains to a private CA, put that CA in `./certs/ca.crt` and set `SERVER_EXTRA_CA_CERTS=/etc/ai-analyst/certs/ca.crt`. The server fetches Keycloak's signing keys through the proxy and must trust its certificate. By default it trusts the proxy's internal CA. On Helm, see [Install on Kubernetes with Helm](install-kubernetes-helm.md) for trusting a private CA. **The server won't start and the log mentions `BOOTSTRAP_ORG_NAME`.** See the bootstrap errors in [Operator bootstrap](#operator-bootstrap-the-first-organization). **The server won't start and the log says the realm doesn't have Organizations enabled.** Turn on Organizations for the `aianalyst` realm. See [Where Keycloak runs](#where-keycloak-runs). **Invitations fail or never arrive.** Check that the realm has email set up, that **From** holds a bare address, and that Keycloak can reach the relay. Ask the invitee to check their spam folder. **Adding a Sign-up domain shows "Set up email in Keycloak first."** Set up the realm's email, then try again. See [Set up email in Keycloak](#set-up-email-in-keycloak). **Adding a Sign-up domain shows "Saved, but Keycloak registration hasn't been updated yet."** AI Analyst saved the domain but couldn't update Keycloak's registration setting. It catches up on the next Sign-up domain change or server restart. **A removed member can still sign in.** See [Remove or lock out a member](#remove-or-lock-out-a-member). Disable their user in Keycloak to keep them out. **The sign-in page shows Keycloak's default look.** Your realm predates the `ai-analyst` login theme. See [Sign-in page language and theme](#sign-in-page-language-and-theme).