Skip to main content

User Management

Create user accounts, assign roles, and manage access through Keycloak, the system's OIDC identity provider.

Checklist

  • Access the Keycloak admin console
  • Create the first admin user in the "zol" realm
  • Assign the admin realm role
  • Verify login through the frontend
  • Verify admin access to the management dashboard

Keycloak Admin Console

The Keycloak admin console is available on the server at port 8080 (localhost only). Access it via SSH tunnel:

# Open an SSH tunnel from your local machine
ssh -L 8080:127.0.0.1:8080 deploy@YOUR_SERVER_IP

# Then open in your browser:
# http://localhost:8080/admin

Login with the Keycloak admin credentials defined in .env.prod:

VariableDefault
KEYCLOAK_ADMINadmin
KEYCLOAK_ADMIN_PASSWORDSet in .env.prod
warning

The Keycloak admin account is a system-level account for managing the identity provider itself. It is separate from application-level admin users who manage crawls, diagnostics, and settings within the ZOL RAG application.

Realm Configuration

The system uses the "zol" realm, which is automatically imported on first startup from the realm export file at scripts/keycloak/zol-realm.json. The realm defines:

SettingValue
Realm namezol
Frontend clientzol-rag-frontend (public, PKCE)
Backend clientzol-rag-backend (confidential)
Token endpoint/realms/zol/protocol/openid-connect/token

Create a User

  1. Open the Keycloak admin console and select the "zol" realm (top-left dropdown).
  2. Navigate to Users in the left sidebar.
  3. Click Create new user.
  4. Fill in the required fields:
    • Username: e.g., admin@zol.be
    • Email: e.g., admin@zol.be
    • First name and Last name
    • Email verified: toggle ON
  5. Click Create.
  6. Go to the Credentials tab and click Set password.
    • Enter the password, confirm it.
    • Set Temporary to OFF (unless you want the user to change password on first login).

Assign the Admin Role

  1. Navigate to the user's detail page.
  2. Go to the Role mapping tab.
  3. Click Assign role.
  4. Filter by realm roles and select admin.
  5. Click Assign.

The application checks for the admin realm role in the JWT token's realm_access.roles claim. Users without this role have standard user permissions.

Roles

RolePermissions
userSearch queries, view results (default for all authenticated users)
adminAll of user + crawl management, diagnostics, user management, settings
info

All authenticated users automatically receive the user role. Only the admin role needs to be explicitly assigned.

Verify Login

Via Frontend

Navigate to the application URL (e.g., https://test.medchat.health). The frontend uses @react-keycloak/web with the KeycloakProvider and will redirect to the Keycloak login page automatically for protected routes.

Via API (Token Acquisition)

# Obtain an access token from Keycloak
TOKEN=$(curl -s -X POST \
"https://YOUR_DOMAIN/realms/zol/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=zol-rag-frontend" \
-d "username=admin@zol.be" \
-d "password=YOUR_PASSWORD" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

# Verify token works — check current user info
curl -s https://YOUR_DOMAIN/api/v1/auth/me \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool

A successful response includes the user's email, name, and roles (including admin if assigned).

JWT Token Lifecycle

ParameterDefaultDescription
Access token lifespan5 minutesShort-lived, used for API requests
Refresh token lifespan30 minutesUsed to obtain new access tokens
SSO session idle30 minutesIdle timeout for the SSO session
SSO session max10 hoursMaximum duration of an SSO session

The frontend automatically handles token refresh via the Keycloak JavaScript adapter. The backend validates tokens using python-jose by verifying the signature against Keycloak's JWKS endpoint (/realms/zol/protocol/openid-connect/certs).

Password Reset

Password resets are managed entirely through Keycloak:

  1. Admin-initiated: In the Keycloak admin console, navigate to the user, go to Credentials, and click Reset password.
  2. Self-service (if configured): Enable the "Forgot password" flow in the realm's Login settings. This requires SMTP configuration in Keycloak for sending reset emails.
# To configure SMTP for self-service password reset:
# Keycloak Admin Console → Realm Settings → Email → Configure SMTP server

Creating Additional Users

Additional users can be created through:

  1. Keycloak admin console — follow the same steps as above.
  2. Keycloak REST API — for programmatic user creation:
# Get an admin token
ADMIN_TOKEN=$(curl -s -X POST \
"http://localhost:8080/realms/master/protocol/openid-connect/token" \
-d "grant_type=password" \
-d "client_id=admin-cli" \
-d "username=admin" \
-d "password=YOUR_KEYCLOAK_ADMIN_PASSWORD" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

# Create a new user
curl -s -X POST \
"http://localhost:8080/admin/realms/zol/users" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "user@zol.be",
"email": "user@zol.be",
"firstName": "New",
"lastName": "User",
"enabled": true,
"emailVerified": true,
"credentials": [{
"type": "password",
"value": "THEIR_PASSWORD",
"temporary": false
}]
}'

Public Endpoints

The following endpoints bypass authentication entirely and do not require a Keycloak token:

  • Feedback submission — allows anonymous user feedback
  • WebSocket query endpoint — public chat interface for hospital visitors
  • Health check (GET /health) — infrastructure monitoring

Security Notes

  • Authentication uses Keycloak OIDC with JWT Bearer tokens
  • Access tokens are validated against Keycloak's JWKS endpoint (public key verification)
  • The backend uses get_current_user and require_admin FastAPI dependencies for route protection
  • Failed login attempts are rate-limited by Keycloak's brute force detection (configurable in realm settings)
  • All tokens are signed with RS256 (asymmetric keys managed by Keycloak)
  • The Keycloak admin console is bound to 127.0.0.1 only — accessible via SSH tunnel

Architectural Evolution

Prior to March 2026, the system used a legacy cookie-based authentication system with bcrypt password hashing. This was replaced by Keycloak OIDC to meet GDPR Article 25 requirements and provide enterprise-grade identity management. The migration to Keycloak also enables future integration with hospital-internal identity providers (e.g., Active Directory federation) without application code changes.

Next: Monitoring →