Skip to main content

Authentication

The advanced setup uses Keycloak as the identity provider. DIAL Chat authenticates users via OIDC, and DIAL Core validates JWT tokens against Keycloak's JWKS endpoint.

Keycloak​

From docker-compose-base.yml:

keycloak:
image: keycloak/keycloak:26.7
user: root
command: ["start-dev", "--import-realm", "--http-port=${KC_PORT}"]
environment:
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD}
KC_HOSTNAME: http://${COMMON_HOST}:${KC_PORT}
KC_HOSTNAME_STRICT: true
KC_HTTP_ENABLED: true
QUARKUS_HTTP_LIMITS_MAX_HEADER_SIZE: 64k
KC_INITIALIZE_EMPTY: 'true'
KC_CACHE: local
KC_HEALTH_ENABLED: 'true'
ports:
- "${KC_PORT}:${KC_PORT}"
- "${DIAL_CHAT_HOST_PORT}:${DIAL_CHAT_HOST_PORT}"
- "${DIAL_ADMIN_FRONTEND_HOST_PORT}:3000"
volumes:
- ./keycloak/data:/opt/keycloak/data
- ./keycloak/import/realm-config.json:/opt/keycloak/data/import/realm-config.json
restart: always
healthcheck:
test: ["CMD-SHELL", "bash -c 'exec 3<>/dev/tcp/127.0.0.1/${KC_PORT}'"]
interval: 5s
timeout: 5s
retries: 30
start_period: 20s

Environment variables​

VariableDescription
KC_BOOTSTRAP_ADMIN_USERNAMEInitial admin username. Hardcoded to admin.
KC_BOOTSTRAP_ADMIN_PASSWORDInitial admin password. Injected from .env via ${KC_ADMIN_PASSWORD}.
KC_HOSTNAMEPublic URL of the Keycloak server, built from ${COMMON_HOST} so browser redirects and container-internal calls agree.
KC_HOSTNAME_STRICTWhen true, Keycloak issues URLs using KC_HOSTNAME only.
KC_HTTP_ENABLEDEnable plain HTTP. Required when running behind a reverse proxy or in development.
QUARKUS_HTTP_LIMITS_MAX_HEADER_SIZEMaximum HTTP header size. Set to 64k to accommodate large JWT tokens.
KC_INITIALIZE_EMPTYInitialize an empty database on first startup.
KC_CACHECache mode. local for a single-node development instance.
KC_HEALTH_ENABLEDExpose health endpoints, used by the healthcheck that gates Chat and Admin startup.
warning

The start-dev command runs Keycloak in development mode. For production deployments, use start with a properly configured database and TLS.

Realm import​

Keycloak imports the realm configuration at startup from ./keycloak/import/realm-config.json. This file defines the dial realm, clients, roles, and default users. See realm-config.json for the realm file structure.

Volumes​

MountPurpose
./keycloak/dataKeycloak data directory (embedded H2 database in dev mode)
./keycloak/import/realm-config.jsonRealm configuration for automatic import

Chat (authenticated)​

In the advanced setup, Chat uses Keycloak OIDC instead of API key authentication:

chat:
image: epam/ai-dial-chat:1.0.15
platform: linux/amd64
environment:
PORT: ${DIAL_CHAT_HOST_PORT}
API_PREFIX: "api"
AUTH_SESSION_SECRET: "${AUTH_SESSION_SECRET}"
AUTH_CALLBACK_BASE_URL: "http://${COMMON_HOST}:${DIAL_CHAT_HOST_PORT}"
AUTH_POST_LOGOUT_REDIRECT_URI: "http://${COMMON_HOST}:${DIAL_CHAT_HOST_PORT}"
AUTH_KEYCLOAK_CLIENT_ID: "dial-chat"
AUTH_KEYCLOAK_SECRET: "${AUTH_KEYCLOAK_SECRET}"
AUTH_KEYCLOAK_HOST: "http://${COMMON_HOST}:${KC_PORT}/realms/dial"
AUTH_KEYCLOAK_DIAL_ROLES_FIELD: "resource_access.dial-chat.roles"
AUTH_COOKIE_SECURE: "false"
DIAL_CORE_URL: "http://core:8080"
THEMES_CONFIG_URL: "http://themes:8080"
ENABLED_UI_FEATURES: "code-apps,schema-apps,custom-apps,chat-settings,..."
LIVE_CHAT_INTERACTION_ENABLED: "true"
RESPONSES_API_ENABLED: "true"
network_mode: "service:keycloak"
depends_on:
themes:
condition: service_started
core:
condition: service_started
keycloak:
condition: service_healthy
restart: always

Chat no longer publishes its own port — it shares Keycloak's network namespace (see the note above), and PORT tells Chat to listen on ${DIAL_CHAT_HOST_PORT} directly so the published mapping lines up. AUTH_COOKIE_SECURE: "false" is required because this stack serves plain HTTP.

Environment variables​

VariableDescription
AUTH_KEYCLOAK_CLIENT_IDKeycloak client ID for DIAL Chat. Must match the client configured in realm-config.json.
AUTH_KEYCLOAK_DIAL_ROLES_FIELDPath to the roles claim in the Keycloak token. Uses resource_access.dial-chat.roles for client-scoped roles.
AUTH_KEYCLOAK_HOSTKeycloak realm URL for OIDC discovery.
AUTH_KEYCLOAK_SECRETKeycloak client secret. Injected from .env.
AUTH_SESSION_SECRETSession encryption key. Injected from .env. Replaces NEXTAUTH_SECRET.
AUTH_CALLBACK_BASE_URLPublic base URL used to build the OIDC callback. Replaces NEXTAUTH_URL.
AUTH_POST_LOGOUT_REDIRECT_URIWhere Keycloak sends the browser after sign-out.
AUTH_COOKIE_SECUREWhen false, session cookies are sent over plain HTTP. Required for this local stack.
PORTPort Chat listens on. Set to ${DIAL_CHAT_HOST_PORT} because Chat shares Keycloak's network namespace.
API_PREFIXPath prefix for the Chat API routes.
DIAL_CORE_URLDIAL Core internal URL. Replaces DIAL_API_HOST.
THEMES_CONFIG_URLThemes service internal URL. Replaces THEMES_CONFIG_HOST.
ENABLED_UI_FEATURESComma-separated list of enabled Chat UI features. Replaces ENABLED_FEATURES.
LIVE_CHAT_INTERACTION_ENABLEDEnable live chat interaction.
RESPONSES_API_ENABLEDEnable the Responses API.

Comparison with quick start Chat​

AspectQuick StartAdvanced
AuthenticationDIAL_API_KEY (static key)Keycloak OIDC (AUTH_KEYCLOAK_*)
Session encryptionHardcoded "secret"${AUTH_SESSION_SECRET} from .env
DependenciesCore, ThemesCore, Themes, Keycloak (gated on its healthcheck)
NetworkingOwn port mapping 3000Shares Keycloak's namespace; Keycloak publishes ${DIAL_CHAT_HOST_PORT}

See DIAL Chat configuration for all Chat environment variables.

Further reading​