Authentication
DIAL Chat signs users in through OpenID Connect. The BFF runs the login flow with your identity provider, keeps the session in an encrypted HttpOnly cookie, and refreshes tokens on the server, so the browser never holds an access token. These environment variables configure the session and each identity provider. This reference is for platform engineers who connect Chat to an identity provider; DIAL Core needs the same provider in its identity provider settings.
Session
| Variable | Default | Description |
|---|---|---|
AUTH_SESSION_SECRET | — | Required. The 32-byte key that encrypts the session cookie, as 64 hexadecimal characters. |
AUTH_CALLBACK_BASE_URL | — | Required. The public base URL of the BFF, used for the OIDC redirect URIs. |
AUTH_POST_LOGOUT_REDIRECT_URI | AUTH_CALLBACK_BASE_URL | Where the browser lands after logout, for every provider. |
AUTH_SESSION_MAX_AGE_SECONDS | 2592000 (30 days) | The rolling session lifetime, from 1 to 2147483647. Each successful token refresh resets it. A known refresh-token expiry, or the access-token expiry when there is no refresh token, can shorten it. |
AUTH_COOKIE_SECURE | true | Set false only for local HTTP testing. It then drops the __Host- prefix from cookie names, and turns off HSTS and the CSP upgrade-insecure-requests directive. |
AUTH_SESSION_COOKIE_NAME | __Host-chat.sess | The session cookie name. |
AUTH_TRANSACTION_COOKIE_NAME | __Host-chat.tx | The login transaction cookie name. |
AUTH_LEGACY_COOKIE_NAMES | — | Cookie names left on the same origin by a previous deployment, comma-separated. Chat expires them on any request that still carries them. Remove the value once no client carries them. |
Changing AUTH_SESSION_MAX_AGE_SECONDS affects new logins and renewals; cookies already issued keep their deadline. An expired session can return the user through the identity provider's own SSO session without a password prompt.
Register Chat in your identity provider
Each provider's client configuration needs two URLs:
| Registered in the identity provider as | Value |
|---|---|
| Redirect URI | <AUTH_CALLBACK_BASE_URL>/api/v1/auth/callback/<provider id>, for example https://chat.example.com/api/v1/auth/callback/keycloak |
| Post-logout redirect URI | AUTH_POST_LOGOUT_REDIRECT_URI, or AUTH_CALLBACK_BASE_URL when unset |
Identity providers
Each provider has its own variables, named AUTH_<PROVIDER>_<FIELD>:
- A provider is registered only when its
CLIENT_IDvariable is set. Unconfigured providers are skipped. - When
CLIENT_IDis set but another required variable is missing, Chat fails to start and names the variable. - Each provider type can be configured once. Its ID, used in
/api/v1/auth/login/<id>, is fixed. - A
HOSTvariable takes a bare host, optionally with a path, such askeycloak.example.com/realms/dial(https://is assumed), or a fullhttp://orhttps://URL. - Chat discovers the provider from its host, then validates tokens against the canonical
issuerthe provider returns.
Every provider except Google also takes AUTH_<PROVIDER>_NAME (the label on the login page), AUTH_<PROVIDER>_SCOPE, AUTH_<PROVIDER>_ADMIN_ROLE_NAMES, and AUTH_<PROVIDER>_DIAL_ROLES_FIELD. Google takes NAME and SCOPE only.
Auth0
ID auth0.
| Variable | Required | Default |
|---|---|---|
AUTH_AUTH0_CLIENT_ID | Yes | — |
AUTH_AUTH0_SECRET | Yes | — |
AUTH_AUTH0_HOST | Yes | — |
AUTH_AUTH0_AUDIENCE | No | — |
AUTH_AUTH0_SCOPE | No | openid email profile offline_access |
Azure AD
ID azure-ad, for Microsoft Entra ID.
| Variable | Required | Default |
|---|---|---|
AUTH_AZURE_AD_CLIENT_ID | Yes | — |
AUTH_AZURE_AD_SECRET | Yes | — |
AUTH_AZURE_AD_TENANT_ID | Yes | — |
AUTH_AZURE_AD_SCOPE | No | openid profile user.Read email offline_access |
Azure AD B2C
ID azure-b2c.
| Variable | Required | Default |
|---|---|---|
AUTH_AZURE_B2C_CLIENT_ID | Yes | — |
AUTH_AZURE_B2C_CLIENT_SECRET | Yes | — |
AUTH_AZURE_B2C_ISSUER | See below | — |
AUTH_AZURE_B2C_TENANT_ID | See below | — |
AUTH_AZURE_B2C_USER_FLOW | See below | — |
AUTH_AZURE_B2C_SCOPE | No | openid profile email offline_access |
Set either AUTH_AZURE_B2C_ISSUER, or both AUTH_AZURE_B2C_TENANT_ID and AUTH_AZURE_B2C_USER_FLOW. Without an issuer, Chat derives it as https://<TENANT_ID>.b2clogin.com/<TENANT_ID>.onmicrosoft.com/<USER_FLOW>/v2.0.
Cognito
ID cognito.
| Variable | Required | Default |
|---|---|---|
AUTH_COGNITO_CLIENT_ID | Yes | — |
AUTH_COGNITO_SECRET | Yes | — |
AUTH_COGNITO_HOST | Yes | — for example cognito-idp.<region>.amazonaws.com/<userPoolId> |
AUTH_COGNITO_SCOPE | No | openid email profile |
GitLab
ID gitlab.
| Variable | Required | Default |
|---|---|---|
AUTH_GITLAB_CLIENT_ID | Yes | — |
AUTH_GITLAB_SECRET | Yes | — |
AUTH_GITLAB_HOST | Yes | — |
AUTH_GITLAB_SCOPE | No | read_user |
Google
ID google. The issuer is always https://accounts.google.com, so there is no host variable. Google has no admin-role or roles-claim override; it uses ADMIN_ROLE_NAMES and DIAL_ROLES_FIELD.
| Variable | Required | Default |
|---|---|---|
AUTH_GOOGLE_CLIENT_ID | Yes | — |
AUTH_GOOGLE_SECRET | Yes | — |
AUTH_GOOGLE_SCOPE | No | openid email profile offline_access |
Keycloak
ID keycloak.
| Variable | Required | Default |
|---|---|---|
AUTH_KEYCLOAK_CLIENT_ID | Yes | — |
AUTH_KEYCLOAK_SECRET | Yes | — |
AUTH_KEYCLOAK_HOST | Yes | — including the realm path, for example keycloak.example.com/realms/dial |
AUTH_KEYCLOAK_SCOPE | No | openid email profile offline_access |
Okta
ID okta.
| Variable | Required | Default |
|---|---|---|
AUTH_OKTA_CLIENT_ID | Yes | — |
AUTH_OKTA_CLIENT_SECRET | Yes | — |
AUTH_OKTA_ISSUER | Yes | — the full issuer URL, for example https://dev-123.okta.com/oauth2/default |
AUTH_OKTA_SCOPE | No | openid email profile |
PingID
ID ping-id.
| Variable | Required | Default |
|---|---|---|
AUTH_PING_ID_CLIENT_ID | Yes | — |
AUTH_PING_ID_SECRET | Yes | — |
AUTH_PING_ID_HOST | Yes | — |
AUTH_PING_ID_SCOPE | No | offline_access |
"Required" applies only when you configure that provider.
Roles and administrators
| Variable | Default | Description |
|---|---|---|
DIAL_ROLES_FIELD | dial_roles | The dot-separated path to the roles claim in the ID or access token, for providers that set no AUTH_<PROVIDER>_DIAL_ROLES_FIELD. |
ADMIN_ROLE_NAMES | admin | Comma-separated role names that make a user an administrator in Chat, for providers that set no AUTH_<PROVIDER>_ADMIN_ROLE_NAMES. |
Every role check in Chat — administrators, role-gated features (*_ENABLED_ROLES), and CATALOG_CREATION_ROLES — reads roles from this claim, for cookie and header-token sessions alike. A dotted path is followed into a header token's payload. Array entries are read as strings, and a single string counts as one role.
Header bearer-token authentication
Besides the session cookie, the BFF can accept Authorization: Bearer <token> from programmatic clients, verifying the token against the JWKS of the registered provider that issued it. A valid header token takes precedence over the cookie and is exempt from CSRF checks. It is off by default because it widens who can call the BFF to anyone holding a valid token from a trusted issuer.
| Variable | Default | Description |
|---|---|---|
AUTH_HEADER_TOKEN_ENABLED | false | Turns header-token authentication on. When false, an Authorization header is ignored. |
AUTH_HEADER_TOKEN_ALLOWED_ISSUERS | — | Comma-separated trusted iss values. Required when the feature is on, or Chat fails to start. |
AUTH_HEADER_TOKEN_CLOCK_TOLERANCE_SECONDS | 30 | Clock-skew tolerance when checking exp and nbf, in seconds. |
AUTH_HEADER_TOKEN_JWKS_CACHE_TTL_SECONDS | 600 | How long a provider's JWKS is cached, in seconds. |
AUTH_HEADER_TOKEN_BUCKET_CACHE_TTL_SECONDS | 60 | How long the DIAL Core bucket of a header-authenticated caller is cached, in seconds. |
A verified token must carry a non-empty sub. The BFF does not refresh header tokens, so a token that expires during a long generation fails it.
Toolset sign-in through DIAL Core
Toolset OAuth needs the public Chat callback URL in DIAL Core's toolsets.security.allowedRedirectUris:
{
"toolsets": {
"security": {
"allowedRedirectUris": ["https://chat.example.com/auth/toolset-signin"]
}
}
}
Use the origin users open Chat from; the frontend builds this URI from the browser location, so it can differ from AUTH_CALLBACK_BASE_URL. Keep the entries of other clients, such as DIAL Admin, and restart DIAL Core after the change.
Private certificate authority
At startup, the BFF discovers every configured provider over HTTPS. If a provider's certificate comes from a private CA, mount a PEM bundle with the root and any intermediate certificates, and point NODE_EXTRA_CA_CERTS at it:
services:
chat:
environment:
NODE_EXTRA_CA_CERTS: /certificates/company-ca.pem
volumes:
- ./company-ca.pem:/certificates/company-ca.pem:ro
The file must exist when the process starts. Do not set NODE_TLS_REJECT_UNAUTHORIZED=0; it turns off certificate checks for every HTTPS connection.
Further reading
- Identity providers in DIAL Core — the matching settings on the Core side
- SSO and identity providers — setup guides for each provider
- Features and UI — role-gated features and Catalog creation rules
- Toolsets security — OAuth sign-in, keys, and encryption for Toolsets