# How-To Guides

# Creating a Realm in Keycloak

A <span class="s2">**realm**</span> in Keycloak is the top-level container for managing users, roles, groups, identity providers, and applications. It provides complete logical isolation, making it ideal for multi-tenant systems or staging/production splits. This guide explains different ways to create a realm via the Admin Console, REST API, and Docker CLI while covering permissions, best practices, and troubleshooting.

## **Creating a Realm via Keycloak Admin Console**

The Admin Console is the most straightforward way to create and manage realms using a web-based UI.

#### **Access the Admin Console**

Log in to your Keycloak Admin Console:

```
http://<your-keycloak-domain>/admin/
```

Use the <span class="s1">**admin**</span> account created during setup or one with realm management privileges.

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/q4uimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/q4uimage.png)

#### **Create a New Realm**

1. Click the realm dropdown in the top-left corner (default is <span class="s1">master</span>).
2. <span class="s1">Click </span>**Create Realm**<span class="s1">.</span>
3. Enter the following details:
    
    
    - <span class="s1">**Realm Name**</span><span class="s2">: A unique name like </span>customer-portal<span class="s2"> or </span>internal-tools<span class="s2">.</span>
    - <span class="s1">**Display Name**</span>: Optional friendly name shown on login screens.
4. Click <span class="s1">**Create**</span>.

#### **Configure Realm Settings**

Once created, you can adjust behavior by navigating to

- <span class="s1">**Realm Settings &gt; Login**</span>: Enable email verification, OTP, remember-me, etc.
- <span class="s1">**Realm Settings &gt; Themes**</span>: Set custom themes for login and account pages

## **Creating a Realm via Keycloak REST API**

For automation and CI/CD pipelines, use the Admin REST API.

#### **Get Access Token**

Use the master realm or a privileged realm with an admin user.

```bash
curl -X POST "https://<keycloak-domain>/realms/master/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin" \
  -d "password=admin-password" \
  -d "grant_type=password" \
  -d "client_id=admin-cli"
```

Save the <span class="s1">access\_token</span> from the response.

#### **Create the Realm**

```bash
curl -X POST "https://<keycloak-domain>/admin/realms" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{
    "realm": "newrealm",
    "enabled": true,
    "displayName": "New Realm"
  }'
```

This creates a new realm called <span class="s1">newrealm</span> with default settings.

## **Creating a Realm via Docker CLI** 

If Keycloak is running inside a Docker container:

#### **Access the Container**

```
docker exec -it keycloak bash
```

#### **Create Realm Using Import File**

1. Create a JSON realm file (e.g., <span class="s1">myrealm.json</span>):

```yaml
{
  "realm": "myrealm",
  "enabled": true
}
```

2. Run Keycloak with the import flag:

```
kc.sh import --file /opt/keycloak/data/import/myrealm.json
```

Or via Docker:

```
docker run -v $PWD:/opt/keycloak/data/import \
  quay.io/keycloak/keycloak:latest \
  import --file /opt/keycloak/data/import/myrealm.json
```

#### **Required Permissions for Realm Creation**

- Users must have <span class="s1">manage-realm</span> or <span class="s1">admin</span> roles in the master realm.
- If using the REST API, token must be obtained using <span class="s1">admin-cli</span>.

To grant permissions:

```
# From master realm
Users > admin > Role Mappings > Realm Roles > Assign 'admin'
```

## **Best Practices for Creating Realms**

- **Use Descriptive Realm Names:** Avoid generic names like <span class="s2">test</span> or <span class="s2">default</span>. Use environment- or tenant-specific names like <span class="s2">dev-project-x</span>, <span class="s2">production-client123</span>.
- **Enable Login Hardening Features:** <span class="s3">Under </span>**Realm Settings &gt; Login**<span class="s3">:</span>
    - Enable email verification
    - Disable user registration (unless required)
    - Enable OTP for 2FA
- **Use Theme Branding:** Upload and assign a custom login theme under <span class="s4">**Themes**</span> to reflect client or environment branding.
- **Automate via REST or Terraform:** For CI/CD deployments, automate realm provisioning using REST API or tools like Terraform (<span class="s2">mrparkers/keycloak</span> provider).

## **Common Issues and Troubleshooting**

<table border="1" id="bkmrk-issue-possible-cause" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Issue**

</th><th style="border-color: rgb(0, 0, 0);">**Possible Cause**

</th><th style="border-color: rgb(0, 0, 0);">**Solution**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);"><span class="s1">403 Forbidden</span> when creating via API

</td><td style="border-color: rgb(0, 0, 0);">Access token lacks permission

</td><td style="border-color: rgb(0, 0, 0);">Ensure token is generated from a user with <span class="s1">admin</span> role in <span class="s1">master</span> realm

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Realm already exists

</td><td style="border-color: rgb(0, 0, 0);">Attempting to recreate an existing realm

</td><td style="border-color: rgb(0, 0, 0);">Use a different realm name or delete existing one before re-creating

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Realm not listed in dropdown

</td><td style="border-color: rgb(0, 0, 0);">Misconfiguration or missing role

</td><td style="border-color: rgb(0, 0, 0);">Refresh UI or check admin user’s permissions

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Docker import doesn’t create realm

</td><td style="border-color: rgb(0, 0, 0);">File format error or wrong path

</td><td style="border-color: rgb(0, 0, 0);">Ensure JSON is valid and mounted correctly in <span class="s1">/opt/keycloak/data/import</span>

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Login page shows default theme

</td><td style="border-color: rgb(0, 0, 0);">Custom theme not set

</td><td style="border-color: rgb(0, 0, 0);">Go to <span class="s1">**Realm Settings &gt; Themes**</span> and set your theme manually

</td></tr></tbody></table>

# Adding and Managing Users in Keycloak

Users in Keycloak represent the individuals or system accounts that authenticate and interact with your applications. This guide explains multiple methods to create and manage users via the Admin Console, REST API, and Docker CLI while covering required roles, best practices, and common issues.

## **Creating Users via Keycloak Admin Console**

The Admin Console is the most user-friendly method to manage users and assign roles.

#### **Access the Admin Console**

Log in to your Keycloak Admin Console:

```
http://<your-keycloak-domain>/admin/
```

Choose the realm where you want to manage users.

#### **Add a New User**

1. <span class="s1">Go to </span>**Users &gt; Add User**
2. Fill in the following:
    
    
    - <span class="s1">**Username**</span> (required)
    - <span class="s1">**Email**</span>, <span class="s1">**First Name**</span>, <span class="s1">**Last Name**</span> (optional but recommended)
    - Set <span class="s1">**Email Verified**</span> if applicable
3. Click <span class="s1">**Create**</span>

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/Sdmimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/Sdmimage.png)

#### **Set Credentials**

After creating the user:

1. Go to the <span class="s1">**Credentials**</span> tab
2. Set a password
3. Toggle <span class="s1">**Temporary**</span> to <span class="s2">OFF</span> if you don’t want the user to reset on first login
4. <span class="s1">Click </span>**Set Password**

## **Creating Users via Keycloak REST API**

This method is suitable for CI/CD pipelines or automated scripts.

#### **Get Access Token**

```bash
curl -X POST "https://<keycloak-domain>/realms/master/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin" \
  -d "password=admin-password" \
  -d "grant_type=password" \
  -d "client_id=admin-cli"
```

Copy the <span class="s1">access\_token</span> from the response.

#### **Create User**

```bash
curl -X POST "https://<keycloak-domain>/admin/realms/<realm>/users" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <access_token>" \
  -d '{
    "username": "johndoe",
    "email": "johndoe@example.com",
    "enabled": true,
    "emailVerified": true,
    "firstName": "John",
    "lastName": "Doe"
  }'
```

#### **Set Password**

```bash
curl -X PUT "https://<keycloak-domain>/admin/realms/<realm>/users/<user-id>/reset-password" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "password",
    "value": "StrongPassword123!",
    "temporary": false
  }'
```

To get <span class="s1">&lt;user-id&gt;</span>, call:

```bash
curl -H "Authorization: Bearer <access_token>" \
  https://<keycloak-domain>/admin/realms/<realm>/users?username=johndoe
```

## **Creating Users via Docker CLI** 

#### **Step into the Container**

```bash
docker exec -it keycloak bash
```

#### **Use Admin CLI Script**

```bash
/opt/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080 \
  --realm master --user admin --password admin

/opt/keycloak/bin/kcadm.sh create users -r <realm> -s username=jane -s enabled=true
```

#### **Set Password**

```
/opt/keycloak/bin/kcadm.sh set-password -r <realm> --username jane --new-password "SecurePass!123"
```

### **Required Permissions for User Management**

- Requires <span class="s1">manage-users</span> role in the realm.
- Admin token used via CLI or REST must be scoped with user management privileges.

To assign permission via Admin Console:

```bash
Users > admin > Role Mappings > Realm Roles > Assign 'manage-users'
```

## **Best Practices for Managing Users**

**Use Verified Emails**

Ensure <span class="s2">emailVerified</span> is set to true for pre-created users to skip email confirmation.

**Avoid Temporary Passwords for API Imports**

If scripting user creation, set <span class="s2">temporary: false</span> to avoid forcing password reset on first login.

**Group Users by Role or Department**

Organize users into <span class="s3">**groups**</span> (e.g., devs, sales, ops) for easier role management and policy application.

**Monitor Login History**

Enable event logging to track user login activity under <span class="s3">**Events &gt; Settings**</span>.

**Enforce Strong Passwords**

Go to <span class="s3">**Authentication &gt; Password Policy**</span> and configure rules like minimum length, digits, special chars, etc.

## **Common Issues and Troubleshooting**

<table border="1" id="bkmrk-issue-possible-cause" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Issue**

</th><th style="border-color: rgb(0, 0, 0);">**Possible Cause**

</th><th style="border-color: rgb(0, 0, 0);">**Solution**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);">409 Conflict: User exists

</td><td style="border-color: rgb(0, 0, 0);">Username already taken

</td><td style="border-color: rgb(0, 0, 0);">Use a unique username or search existing users

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">403 Forbidden<span class="s1"> on API</span>

</td><td style="border-color: rgb(0, 0, 0);">Missing permission or token scope

</td><td style="border-color: rgb(0, 0, 0);">Ensure admin has <span class="s1">manage-users</span> in the correct realm

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">User not able to log in

</td><td style="border-color: rgb(0, 0, 0);">Password not set or user is disabled

</td><td style="border-color: rgb(0, 0, 0);">Check status under the user’s profile and verify credentials

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Password reset fails

</td><td style="border-color: rgb(0, 0, 0);">Temporary password not set correctly

</td><td style="border-color: rgb(0, 0, 0);">Use <span class="s1">"temporary": false</span> if you want permanent password via API

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Email not received for verification

</td><td style="border-color: rgb(0, 0, 0);">SMTP not configured

</td><td style="border-color: rgb(0, 0, 0);">Go to <span class="s1">**Realm Settings &gt; Email**</span> and add SMTP server details

</td></tr></tbody></table>

# Creating and Configuring Clients in Keycloak

A <span class="s2">**client**</span> in Keycloak represents an application or service that uses Keycloak to authenticate users. Clients can be web apps, REST APIs, mobile apps, or even CLI tools. This guide explains how to create and configure clients through the Admin Console, REST API, and CLI (Docker), and also includes roles, best practices, and common troubleshooting steps.

## **Creating Clients via Keycloak Admin Console**

This is the simplest way to register and configure a client visually.

#### **Access the Admin Console**

Log in to:

```
http://<your-keycloak-domain>/admin/
```

Choose the realm where the client should be added.

#### **Add a New Client**

1. <span class="s1">Go to </span>**Clients &gt; Create**
2. Fill in the fields:
    
    
    - <span class="s1">**Client ID**</span>: A unique name, e.g., <span class="s2">frontend-app</span> or <span class="s2">api-service</span>
    - <span class="s1">**Client Type**</span>: Choose between <span class="s2">OpenID Connect</span> (default) or <span class="s2">SAML</span>
    - <span class="s1">**Root URL**</span>: The application base URL (e.g., <span class="s2">http://localhost:3000</span>)
3. Click <span class="s1">**Next**</span>, then <span class="s1">**Save**</span>[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/gqaimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/gqaimage.png)

#### **Configure Client Settings**

- Go to the <span class="s1">**Settings**</span> tab for the client:
    
    
    - <span class="s1">**Access Type**</span><span class="s2">: Choose </span>public<span class="s2">, </span>confidential<span class="s2">, or </span>bearer-only
    - <span class="s1">**Valid Redirect URIs**</span>: Add allowed redirect URLs (e.g., <span class="s2">http://localhost:3000/\*</span>)
    - <span class="s1">**Web Origins**</span>: Add <span class="s2">\*</span> or specific origins allowed to call this client
    - <span class="s1">**Standard Flow Enabled**</span>: Enable for browser-based login
    - <span class="s1">**Direct Access Grants**</span>: Enable if using password grant from API
- Save the changes

## **Creating Clients via Keycloak REST API**

#### **Get Access Token**

```bash
curl -X POST "https://<keycloak-domain>/realms/master/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin" \
  -d "password=admin-password" \
  -d "grant_type=password" \
  -d "client_id=admin-cli"
```

<span class="s1">Save the </span>access\_token<span class="s1">.</span>

#### **Create a Client**

```bash
curl -X POST "https://<keycloak-domain>/admin/realms/<realm>/clients" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "my-app",
    "enabled": true,
    "publicClient": false,
    "redirectUris": ["http://localhost:3000/*"],
    "webOrigins": ["http://localhost:3000"],
    "protocol": "openid-connect"
  }'
```

This creates a confidential client named <span class="s1">my-app</span>.

## **Creating Clients via Docker CLI** 

#### **Step into the Container**

```
docker exec -it keycloak bash
```

#### **Authenticate and Create Client**

```bash
/opt/keycloak/bin/kcadm.sh config credentials \
  --server http://localhost:8080 \
  --realm master --user admin --password admin

/opt/keycloak/bin/kcadm.sh create clients -r <realm> \
  -s clientId=my-cli-client \
  -s enabled=true \
  -s publicClient=false \
  -s redirectUris='["http://localhost:3000/*"]' \
  -s webOrigins='["http://localhost:3000"]'
```

#### **Required Permissions for Client Management**

- Requires <span class="s1">manage-clients</span> or <span class="s1">admin</span> role in the realm
- Token used via REST or CLI must be scoped to allow client creation

To grant roles via Admin Console:

```
Users > admin > Role Mappings > Realm Roles > Assign 'manage-clients'
```

## **Best Practices for Client Configuration**

- **Use Confidential Clients for Backends:** Set <span class="s2">publicClient = false</span> and use <span class="s2">client\_secret</span> for server-to-server communication.
- **Use Public Clients for SPAs:** Frontend apps using redirect flows should be marked as <span class="s2">publicClient = true</span>.
- **Set Narrow Redirect URIs:** Avoid using wildcards like <span class="s2">\*</span> unless absolutely necessary. Use precise URIs for better security.
- **Limit Token Lifespans:** Go to <span class="s3">**Realm Settings &gt; Tokens**</span> and configure access and refresh token lifetimes.
- **Rotate Client Secrets Regularly:** Manually rotate secrets or use automation for higher security compliance.
- **Use Roles and Mappers for RBAC:** Assign client roles and use <span class="s3">**protocol mappers**</span> to inject them into access tokens for authorization checks.

## **Common Issues and Troubleshooting**

<table border="1" id="bkmrk-issue-possible-cause" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Issue**

</th><th style="border-color: rgb(0, 0, 0);">**Possible Cause**

</th><th style="border-color: rgb(0, 0, 0);">**Solution**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);">Invalid redirect URI

</td><td style="border-color: rgb(0, 0, 0);">Redirect URI doesn’t match registered value

</td><td style="border-color: rgb(0, 0, 0);">Ensure exact match in <span class="s1">**Valid Redirect URIs**</span>

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Client not visible after creation

</td><td style="border-color: rgb(0, 0, 0);">UI or API delay

</td><td style="border-color: rgb(0, 0, 0);">Refresh or re-login to see updated clients

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Access token doesn’t include roles

</td><td style="border-color: rgb(0, 0, 0);">Missing mappers

</td><td style="border-color: rgb(0, 0, 0);">Add protocol mapper for <span class="s1">client roles</span> under <span class="s2">**Client &gt; Mappers**</span>

</td></tr><tr><td style="border-color: rgb(0, 0, 0);"><span class="s1">403 Forbidden</span> when using client credentials

</td><td style="border-color: rgb(0, 0, 0);">Client type is public or secret is wrong

</td><td style="border-color: rgb(0, 0, 0);">Verify <span class="s1">publicClient=false</span> and check the client secret

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Invalid client credentials<span class="s1"> error</span>

</td><td style="border-color: rgb(0, 0, 0);">Wrong client ID or secret

</td><td style="border-color: rgb(0, 0, 0);">Verify spelling and match values from Admin Console

</td></tr></tbody></table>

# Setting Up Roles and Permissions in Keycloak

Roles and permissions in Keycloak define what users and applications are allowed to do. Roles can be assigned to users, groups, or clients, and are embedded into access tokens to enforce authorization. This guide explains how to define and manage roles via the Admin Console, REST API, and CLI, with best practices and common issues.

## **Creating Roles via Keycloak Admin Console**

This is the easiest way to create and manage roles visually.

#### **Access the Admin Console**

Log in to:

```
http://<your-keycloak-domain>/admin/
```

Choose the appropriate realm.

#### **Create Realm Roles**

1. <span class="s1">Go to </span>**Roles &gt; Add Role**
2. Enter:
    
    
    - <span class="s1">**Role Name**</span><span class="s2">: e.g., </span>admin<span class="s2">, </span>viewer<span class="s2">, </span>editor
    - <span class="s1">**Description**</span>: Optional but recommended
3. Click <span class="s1">**Save**</span>

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/dvYimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/dvYimage.png)

#### **Create Client Roles**

1. <span class="s1">Go to </span>**Clients &gt; \[client-name\] &gt; Roles &gt; Create Role**
2. Fill in the <span class="s1">**Role Name**</span> and optional <span class="s1">**Description**</span>
3. Save the role

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/cQIimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/cQIimage.png)

#### **Assign Roles to Users**

1. <span class="s1">Go to </span>**Users &gt; \[username\] &gt; Role Mappings**
2. In <span class="s1">**Available Roles**</span>, choose from:
    
    
    - Realm roles (top-left dropdown)
    - Client roles (select client under “Client Roles”)
3. <span class="s1">Click </span>**Add selected**

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/j8timage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/j8timage.png)

## **Creating Roles via Keycloak REST API**

#### **Get Access Token**

```bash
curl -X POST "https://<keycloak-domain>/realms/master/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin" \
  -d "password=admin-password" \
  -d "grant_type=password" \
  -d "client_id=admin-cli"
```

<span class="s1">Save the </span>access\_token<span class="s1">.</span>

#### **Create Realm Role**

```bash
curl -X POST "https://<keycloak-domain>/admin/realms/<realm>/roles" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "viewer",
    "description": "Read-only access"
  }'
```

#### **Create Client Role**

```bash
curl -X POST "https://<keycloak-domain>/admin/realms/<realm>/clients/<client-id>/roles" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "api-user",
    "description": "API access for clients"
  }'
```

To get the client ID:

```bash
curl -H "Authorization: Bearer <access_token>" \
  "https://<keycloak-domain>/admin/realms/<realm>/clients"
```

## **Creating Roles via Docker CLI** 

**Access the Container**

```
docker exec -it keycloak bash
```

**Create Roles via CLI**

```bash
/opt/keycloak/bin/kcadm.sh config credentials \
  --server http://localhost:8080 --realm master \
  --user admin --password admin

/opt/keycloak/bin/kcadm.sh create roles -r <realm> \
  -s name=auditor -s description="Can view reports"
```

To create client roles:

```bash
/opt/keycloak/bin/kcadm.sh create clients/<client-id>/roles -r <realm> \
  -s name=external-api -s description="Role for external apps"
```

## **Required Permissions for Managing Roles**

To manage roles, users need:

- <span class="s1">manage-realm</span> role for realm roles
- <span class="s1">manage-clients</span> role for client-specific roles

To assign via Admin Console:

```
Users > [admin-user] > Role Mappings > Realm Roles > Add 'manage-realm' or 'manage-clients'
```

## **Best Practices for Roles and Permissions**

- **Use Fine-Grained Role Names:** <span class="s2">Use names like </span>invoice\_viewer<span class="s2">, </span>invoice\_editor<span class="s2">, or </span>admin\_dashboard<span class="s2"> for clarity.</span>
- **Use Groups to Assign Roles in Bulk:** Create groups such as <span class="s3">managers</span>, <span class="s3">sales</span>, or <span class="s3">auditors</span>, then assign roles to groups.
- **Map Roles to Access Tokens:** Use <span class="s4">**Client &gt; Mappers**</span> to include role names in the <span class="s3">access\_token</span> or <span class="s3">id\_token</span>.
- **Prefer Client Roles for Application Permissions:** Client roles are scoped to individual apps and help separate responsibilities.
- **Use Composite Roles Sparingly:** Composite roles combine multiple roles into one but may add complexity if overused.

## **Common Issues and Troubleshooting**

<table border="1" id="bkmrk-issue-possible-cause" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Issue**

</th><th style="border-color: rgb(0, 0, 0);">**Possible Cause**

</th><th style="border-color: rgb(0, 0, 0);">**Solution**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);">Role doesn’t appear in token

</td><td style="border-color: rgb(0, 0, 0);">Missing protocol mapper

</td><td style="border-color: rgb(0, 0, 0);">Add a role mapper in <span class="s1">**Client &gt; Mappers**</span>

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">User not authorized despite role assignment

</td><td style="border-color: rgb(0, 0, 0);">Role not assigned to the correct client/realm

</td><td style="border-color: rgb(0, 0, 0);">Verify if the role is client-scoped or realm-wide

</td></tr><tr><td style="border-color: rgb(0, 0, 0);"><span class="s1">403 Forbidden</span> despite valid login

</td><td style="border-color: rgb(0, 0, 0);">Role not embedded in access token

</td><td style="border-color: rgb(0, 0, 0);">Ensure token includes required roles via protocol mappers

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">REST API: <span class="s1">409 Conflict</span> when creating role

</td><td style="border-color: rgb(0, 0, 0);">Role with same name already exists

</td><td style="border-color: rgb(0, 0, 0);">Use a unique name or update existing role

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Cannot assign role to user

</td><td style="border-color: rgb(0, 0, 0);">User lacks <span class="s1">manage-users</span> privilege

</td><td style="border-color: rgb(0, 0, 0);">Ensure admin has role assignment rights

</td></tr></tbody></table>

# Enabling Identity Federation in Keycloak

<span class="s2">**Identity federation**</span> allows you to delegate authentication to external identity providers (IdPs) like Google, GitHub, Facebook, or enterprise systems such as LDAP and Active Directory. This guide explains how to integrate identity providers using the Keycloak Admin Console, REST API, and Docker CLI (kcadm.sh). It includes configuration examples, permission requirements, best practices, and common issues.

## **Adding Identity Providers via Keycloak Admin Console**

This method supports most popular providers like Google, GitHub, Facebook, and SAML/LDAP.

#### **Access the Admin Console**

Log in to your Keycloak Admin Console:

```
http://<your-keycloak-domain>/admin/
```

Select the realm where you want to add the identity provider.

#### **Add an Identity Provider (OIDC-based)**

1. <span class="s1">Go to </span>**Identity Providers &gt; Add Provider**
2. <span class="s1">Choose an option like </span>Google<span class="s1">, </span>GitHub<span class="s1">, or </span>OpenID Connect v1.0
3. Fill in the following:
    
    
    - <span class="s1">**Alias**</span>: A unique name like <span class="s2">google</span> or <span class="s2">github</span>
    - <span class="s1">**Client ID**</span>: From the external IdP
    - <span class="s1">**Client Secret**</span>: From the external IdP
    - <span class="s1">**Authorization URL**</span>, <span class="s1">**Token URL**</span>, <span class="s1">**User Info URL**</span>: Auto-filled for well-known providers
4. Set <span class="s1">**Sync Mode**</span> (e.g., <span class="s2">IMPORT</span>, <span class="s2">FORCE</span>, or <span class="s2">LEGACY</span>)
5. Enable <span class="s1">**Store Tokens**</span> if you want offline access
6. Click <span class="s1">**Save**</span>

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/ujPimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/ujPimage.png)

#### **Test the Identity Provider**

1. Go to the realm login page
2. You’ll now see a <span class="s1">**“Login with Google”**</span> or equivalent option

## **Adding LDAP or Active Directory** 

1. <span class="s1">Go to </span>**User Federation &gt; Add Provider → LDAP**
2. Fill in connection details:

<table id="bkmrk-field-example-connec"><thead><tr><th>**Field**

</th><th>**Example**

</th></tr></thead><tbody><tr><td>Connection URL

</td><td>ldap://ldap.mycompany.com

</td></tr><tr><td>Users DN

</td><td>ou=users,dc=mycompany,dc=com

</td></tr><tr><td>Bind DN

</td><td>cn=admin,dc=mycompany,dc=com

</td></tr><tr><td>Bind Credential

</td><td>Your LDAP password

</td></tr><tr><td>Vendor

</td><td>Active Directory<span class="s1">, </span>Other<span class="s1">, etc.</span>

</td></tr></tbody></table>

2. <span class="s1">Choose </span><span class="s2">**Edit Mode**</span><span class="s1">: </span>READ\_ONLY<span class="s1">, </span>WRITABLE<span class="s1">, or </span>UNSYNCED
3. Enable <span class="s1">**Periodic Sync**</span> if needed
4. Save and test the connection

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/agpimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/agpimage.png)

## **Adding Identity Providers via REST API**

#### **Get Access Token**

```
curl -X POST "https://<keycloak-domain>/realms/master/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin" \
  -d "password=admin-password" \
  -d "grant_type=password" \
  -d "client_id=admin-cli"
```

<span class="s1">Save the </span>access\_token<span class="s1">.</span>

#### **Add OIDC Identity Provider**

```
curl -X POST "https://<keycloak-domain>/admin/realms/<realm>/identity-provider/instances" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "google",
    "providerId": "google",
    "enabled": true,
    "trustEmail": true,
    "storeToken": false,
    "addReadTokenRoleOnCreate": false,
    "firstBrokerLoginFlowAlias": "first broker login",
    "config": {
      "clientId": "GOOGLE_CLIENT_ID",
      "clientSecret": "GOOGLE_CLIENT_SECRET"
    }
  }'
```

## **Adding Identity Providers via Docker CLI** 

**Access the Container**

```
docker exec -it keycloak bash
```

**Add Provider**

```
/opt/keycloak/bin/kcadm.sh config credentials \
  --server http://localhost:8080 \
  --realm master --user admin --password admin

/opt/keycloak/bin/kcadm.sh create identity-provider/instances -r <realm> \
  -s alias=github -s providerId=github \
  -s enabled=true \
  -s config.clientId=GITHUB_CLIENT_ID \
  -s config.clientSecret=GITHUB_CLIENT_SECRET
```

## **Required Permissions for Identity Federation**

- Requires <span class="s1">manage-identity-providers</span> or <span class="s1">admin</span> role in the target realm
- REST tokens must come from a user with these privileges

To assign via Admin Console:

```
Users > [admin-user] > Role Mappings > Realm Roles > Add 'manage-identity-providers'
```

## **Best Practices for Identity Federation**

- **Use Standard Broker Flows:** Leverage <span class="s2">**First Broker Login**</span> flow to prompt for email verification or account linking.
- **Map External Claims to Roles:** Use <span class="s2">**Identity Provider Mappers**</span> to assign roles or sync attributes (like <span class="s3">email</span>, <span class="s3">groups</span>, <span class="s3">org</span>) automatically.
- **Avoid Using Public Client IDs in Backend:** Always use confidential clients when configuring from the backend or REST API.
- **Enable Logging During Setup:** Use Keycloak’s <span class="s2">**Events &gt; Settings**</span> to track login attempts and errors for debugging.
- **Test With Separate Test Realm First:** Validate your configuration in a dev/test realm before enabling in production.

## **Common Issues and Troubleshooting**

<table border="1" id="bkmrk-issue-possible-cause" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Issue**

</th><th style="border-color: rgb(0, 0, 0);">**Possible Cause**

</th><th style="border-color: rgb(0, 0, 0);">**Solution**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);">Login button not showing on login page

</td><td style="border-color: rgb(0, 0, 0);">Provider not enabled

</td><td style="border-color: rgb(0, 0, 0);">Ensure <span class="s1">enabled=true</span> and <span class="s1">alias</span> is correct

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Invalid client\_id<span class="s1"> error</span>

</td><td style="border-color: rgb(0, 0, 0);">Client ID mismatch

</td><td style="border-color: rgb(0, 0, 0);">Verify credentials from the IdP provider dashboard

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">User not found after login

</td><td style="border-color: rgb(0, 0, 0);">No email or username claim returned

</td><td style="border-color: rgb(0, 0, 0);">Check mappers and ensure <span class="s1">email</span> or <span class="s1">preferred\_username</span> is mapped

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">LDAP users not visible in UI

</td><td style="border-color: rgb(0, 0, 0);">Wrong base DN or invalid bind credentials

</td><td style="border-color: rgb(0, 0, 0);">Test connection under <span class="s1">**User Federation**</span> settings

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">403 Forbidden<span class="s1"> on REST call</span>

</td><td style="border-color: rgb(0, 0, 0);">Missing role or token scope

</td><td style="border-color: rgb(0, 0, 0);"><span class="s1">Ensure token has </span>manage-identity-providers

</td></tr></tbody></table>

# Enabling Two-Factor Authentication (2FA) in Keycloak

Two-Factor Authentication (2FA) adds an extra layer of security to user logins by requiring something the user knows (password) and something they have (typically an OTP via a mobile app). This guide explains how to enable and enforce OTP-based 2FA for all or specific users in Keycloak, using the Admin Console, authentication flows, and best practices.

## **Enabling 2FA via the Admin Console**

#### **Log in to the Admin Console**

Navigate to:

```
http://<your-keycloak-domain>/admin/
```

Choose the realm where you want to enable 2FA.

#### **Enable OTP in Authentication Flow**

1. <span class="s1">Go to </span>**Authentication &gt; Flows**
2. Select the <span class="s1">**Browser**</span> flow (or copy it if you want a custom flow)
3. Locate the <span class="s1">**Browser**</span> execution list:
    
    
    - Ensure that <span class="s1">**OTP Form**</span> is listed and set to <span class="s1">**REQUIRED**</span>
    - If it’s not listed:
        
        
        - <span class="s1">Click </span>**Add Execution**
        - Choose <span class="s1">**OTP Form**</span>, then set its requirement to <span class="s1">**REQUIRED**</span>
4. Click <span class="s1">**Save**</span>

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/NfCimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/NfCimage.png)

#### **Configure OTP Policy**

Go to <span class="s2">**Realm Settings &gt; OTP**</span> and configure:

- <span class="s1">**OTP Type**</span>: <span class="s2">TOTP</span> (time-based, most common)
- <span class="s1">**Period**</span>: 30 seconds (default)
- **Digits**<span class="s1">: 6</span>
- **Algorithm**<span class="s1">: SHA1</span>
- **Look Ahead Window**<span class="s1">: 1 or 2</span>

Click <span class="s2">**Save**</span>

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/e6Ximage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/e6Ximage.png)

## **Enforcing 2FA for Specific Users**

2FA is optional by default. To make it required for a specific user:

1. <span class="s1">Go to </span>**Users &gt; \[username\]**
2. Open the <span class="s1">**Credentials**</span> tab
3. <span class="s1">Click </span>**Set Up Required Action**
4. Choose <span class="s1">**Configure OTP**</span> from the dropdown
5. Click <span class="s1">**Save**</span>

The user will be prompted to set up 2FA on their next login.

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/VIvimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/VIvimage.png)

## **Enforcing 2FA for All Users**

To enforce 2FA globally:

1. <span class="s1">Go to </span>**Authentication &gt; Bindings**
2. Set <span class="s1">**Browser Flow**</span> to a flow where <span class="s1">**OTP Form**</span> is <span class="s2">REQUIRED</span>
3. All users will be required to configure 2FA on their next login if not already done

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/ssQimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/ssQimage.png)

## **Enabling 2FA via REST API**

**Get Admin Access Token**

```bash
curl -X POST "https://<keycloak-domain>/realms/master/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin" \
  -d "password=admin-password" \
  -d "grant_type=password" \
  -d "client_id=admin-cli"
```

**Assign “Configure OTP” Required Action to a User**

```bash
curl -X PUT "https://<keycloak-domain>/admin/realms/<realm>/users/<user-id>" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"requiredActions": ["CONFIGURE_TOTP"]}'
```

To get the user ID:

```bash
curl -H "Authorization: Bearer <access_token>" \
  https://<keycloak-domain>/admin/realms/<realm>/users?username=<username>
```

## **Enabling 2FA via Docker CLI** 

**Authenticate and Set OTP Action**

```bash
docker exec -it keycloak bash

/opt/keycloak/bin/kcadm.sh config credentials \
  --server http://localhost:8080 \
  --realm master --user admin --password admin

/opt/keycloak/bin/kcadm.sh update users/<user-id> -r <realm> \
  -s 'requiredActions=["CONFIGURE_TOTP"]'
```

## **Required Permissions for 2FA Management**

- Requires <span class="s1">manage-users</span> role
- REST API calls must use a token with <span class="s1">manage-users</span> permission in the realm

To assign via Admin Console:

```
Users > [admin-user] > Role Mappings > Realm Roles > Add 'manage-users'
```

## **Best Practices for 2FA**

- **Use Time-Based OTP (TOTP):** TOTP is compatible with standard apps like Google Authenticator, Authy, or FreeOTP.
- **Customize OTP Setup Page:** Modify the <span class="s2">otp.ftl</span> page inside your theme to reflect your brand and offer setup instructions.
- **Inform Users Before Enforcing:** Enable OTP as a required action with communication ahead of rollout to avoid login issues.
- **Use Conditional 2FA Flows:** Use <span class="s3">**conditional executions**</span> (e.g., only require OTP from outside a trusted network/IP range).
- **Back Up OTP Configuration:** Encourage users to back up their OTP seed or enable recovery codes for critical accounts.

## **Common Issues and Troubleshooting**

<table border="1" id="bkmrk-issue-possible-cause" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Issue**

</th><th style="border-color: rgb(0, 0, 0);">**Possible Cause**

</th><th style="border-color: rgb(0, 0, 0);">**Solution**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);">Users not prompted for 2FA

</td><td style="border-color: rgb(0, 0, 0);">OTP Form not set to REQUIRED in flow

</td><td style="border-color: rgb(0, 0, 0);">Set requirement to <span class="s1">REQUIRED</span> in the Browser flow

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">OTP setup skips

</td><td style="border-color: rgb(0, 0, 0);"><span class="s1">Configure OTP</span> not added as required action

</td><td style="border-color: rgb(0, 0, 0);">Manually assign it to users or enforce via default flow

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">“Invalid TOTP” error on login

</td><td style="border-color: rgb(0, 0, 0);">Wrong time sync or wrong app

</td><td style="border-color: rgb(0, 0, 0);">Ensure mobile device clock is correct and app supports TOTP

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">OTP works once then fails

</td><td style="border-color: rgb(0, 0, 0);">Look-ahead window too small

</td><td style="border-color: rgb(0, 0, 0);">Increase look-ahead window under Realm Settings &gt; OTP

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">No OTP page shown after password

</td><td style="border-color: rgb(0, 0, 0);">Flow misconfigured

</td><td style="border-color: rgb(0, 0, 0);">Review order and requirement levels of all executions in the flow

</td></tr></tbody></table>

# Resetting User Passwords in KeycloakNew Page

Password resets are a critical part of account lifecycle management. Keycloak provides multiple secure methods for resetting a user’s password manually through the Admin Console, programmatically via REST API, or via user self-service workflows using email links. This guide walks through all these approaches, including configuration steps, best practices, and common issues.

## **Resetting Password via Admin Console**

This is the most direct method for administrators to reset passwords.

#### **Access the Admin Console**

Log in to:

```
http://<your-keycloak-domain>/admin/
```

Select the desired realm.

#### **Reset a User’s Password**

1. <span class="s1">Go to </span>**Users &gt; \[username\] &gt; Credentials**
2. <span class="s1">Under </span>**Set Password**<span class="s1">:</span>
    
    
    - Enter a new password
    - Confirm it
    - <span class="s1">Toggle </span>**Temporary**<span class="s1">:</span>
        
        
        - <span class="s1">**ON**</span> = user will be forced to change it on next login
        - <span class="s1">**OFF**</span> = permanent change
3. <span class="s1">Click </span>**Set Password**

The new password takes effect immediately.

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/BPHimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/BPHimage.png)

## **Resetting Password via REST API**

#### **Get Admin Access Token**

```bash
curl -X POST "https://<keycloak-domain>/realms/master/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin" \
  -d "password=admin-password" \
  -d "grant_type=password" \
  -d "client_id=admin-cli"
```

#### **Set New Password for a User**

```bash
curl -X PUT "https://<keycloak-domain>/admin/realms/<realm>/users/<user-id>/reset-password" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "password",
    "value": "SecurePassword123!",
    "temporary": false
  }'
```

<span class="s1">To get </span>&lt;user-id&gt;<span class="s1">:</span>

```bash
curl -H "Authorization: Bearer <access_token>" \
  https://<keycloak-domain>/admin/realms/<realm>/users?username=<username>
```

## **Resetting Password via Docker CLI** 

#### **Inside the Container**

```
docker exec -it keycloak bash
```

#### **Reset User Password**

```bash
/opt/keycloak/bin/kcadm.sh config credentials \
  --server http://localhost:8080 \
  --realm master --user admin --password admin

/opt/keycloak/bin/kcadm.sh set-password -r <realm> \
  --username <username> --new-password "SecurePassword123!" --temporary=false
```

## **Resetting Password via Email (Self-Service)**

#### **Configure SMTP**

1. <span class="s1">Go to </span>**Realm Settings &gt; Email**
2. Enter your SMTP configuration:
    
    
    - Host
    - Port
    - From address
    - Username/password
3. <span class="s1">Click </span>**Test Connection**
4. Click <span class="s1">**Save**</span>

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/zTMimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/zTMimage.png)

#### **Enable “Forgot Password” Option**

1. <span class="s1">Go to </span>**Authentication &gt; Flows &gt; Browser**
2. Ensure <span class="s1">**Reset Credentials**</span> subflow is present
3. <span class="s1">Under </span>**Realm Settings &gt; Login**<span class="s1">, enable:</span>

- - **Forgot Password**
    - **Email as Username**<span class="s1"> (optional)</span>

[![image.png](https://docs.elest.io/uploads/images/gallery/2025-06/scaled-1680-/7rsimage.png)](https://docs.elest.io/uploads/images/gallery/2025-06/7rsimage.png)

#### **Trigger Reset Link (User Side)**

Users can go to the login page, click <span class="s2">**Forgot Password**</span>, and receive a reset link via email.

## **Required Permissions**

- Admin Console: Must have <span class="s1">manage-users</span> role
- REST API: Token must have <span class="s1">manage-users</span> in the target realm

To assign via Admin Console:

```
Users > [admin-user] > Role Mappings > Realm Roles > Add 'manage-users'
```

## **Best Practices for Password Resets**

- **Always Use Temporary Passwords for Manual Resets:** For admin-initiated resets, mark passwords as <span class="s2">temporary</span> to enforce user re-entry.
- **Secure SMTP Configuration:** Always use TLS/SSL for SMTP and avoid using free/public SMTP providers in production.
- **Limit Password Reset Frequency:** <span class="s3">Use brute-force protection under </span>**Realm Settings &gt; Security Defenses &gt; Brute Force Detection**<span class="s3">.</span>
- **Log and Audit Password Resets:** Enable <span class="s4">**Events &gt; Settings**</span> to log password reset events and maintain an audit trail.
- **Inform Users of Security Practices:** Add disclaimers to reset emails and verify request intent using short-lived links.

## **Common Issues and Troubleshooting**

<table border="1" id="bkmrk-issue-possible-cause" style="border-collapse: collapse; border-color: rgb(0, 0, 0);"><thead><tr><th style="border-color: rgb(0, 0, 0);">**Issue**

</th><th style="border-color: rgb(0, 0, 0);">**Possible Cause**

</th><th style="border-color: rgb(0, 0, 0);">**Solution**

</th></tr></thead><tbody><tr><td style="border-color: rgb(0, 0, 0);">Password reset link not received

</td><td style="border-color: rgb(0, 0, 0);">SMTP not configured or invalid

</td><td style="border-color: rgb(0, 0, 0);">Set up SMTP under Realm Settings &gt; Email

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">Reset link expired

</td><td style="border-color: rgb(0, 0, 0);">Time limit exceeded

</td><td style="border-color: rgb(0, 0, 0);">Increase <span class="s1">**Reset Link Lifespan**</span> under Realm Settings &gt; Tokens

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">User not prompted to change password

</td><td style="border-color: rgb(0, 0, 0);">Password not marked as temporary

</td><td style="border-color: rgb(0, 0, 0);">Enable <span class="s1">temporary: true</span> or configure as required action

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">REST API returns <span class="s1">403 Forbidden</span>

</td><td style="border-color: rgb(0, 0, 0);">Missing permissions

</td><td style="border-color: rgb(0, 0, 0);">Ensure admin token has <span class="s1">manage-users</span> role

</td></tr><tr><td style="border-color: rgb(0, 0, 0);">User not found<span class="s1"> error</span>

</td><td style="border-color: rgb(0, 0, 0);">Wrong realm or username

</td><td style="border-color: rgb(0, 0, 0);">Confirm realm and check <span class="s1">Users &gt; View all users</span>

</td></tr></tbody></table>