---
title: "Keycloak"
url: "https://docs.yugabyte.com/stable/integrations/keycloak/"
---

# Keycloak

Use Keycloak with YSQL API

[Keycloak](https://www.keycloak.org/ "Keycloak") is an open source identity and access management tool that adds authentication to applications and secure services with minimum effort.

Using YugabyteDB as the database for Keycloak provides high availability, horizontal scalability, and global data distribution, making it ideal for large-scale, mission-critical identity systems.

## Prerequisites

Before you start using Keycloak, ensure that you have the following:

- OpenJDK 21.
- The latest version of [Keycloak](https://www.keycloak.org/downloads "Keycloak").
- A YugabyteDB cluster. Refer to [YugabyteDB Quick start guide](/stable/quick-start/macos/ "YugabyteDB Quick start guide") to install and start a local cluster.

## Configure and start Keycloak

To configure Keycloak, do the following:

1. In YugabyteDB, create a database called `keycloak` on your cluster.
   
   ```sh
   CREATE DATABASE keycloak;
   ```
2. Add the following configurations in the `keycloak/conf/keycloak.conf` file.
   
   ```sh
   # The database vendor.
   db=postgres
   
   # The username of the database user.
   db-username=yugabyte
   
   # The password of the database user.
   db-password=yugabyte
   
   # The full database JDBC URL. If not provided, a default URL is set based on the selected database vendor.
   db-url=jdbc:postgresql://localhost:5433/keycloak
   ```
3. Start Keycloak in the foreground using the following command:
   
   ```sh
   $ ./bin/kc.sh start-dev
   ```
   
   This may take some time. The server is ready when you see the following logs:
   
   ```output
   2025-06-18 12:43:11,631 INFO  [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) Starting     Infinispan embedded cache manager
   2025-06-18 12:43:11,691 INFO  [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) JGroups     JDBC_PING discovery enabled.
   2025-06-18 12:43:11,810 INFO  [org.infinispan.CONTAINER] (main) Virtual threads support enabled
   2025-06-18 12:43:13,127 INFO  [org.infinispan.CONTAINER] (main) ISPN000556: Starting user marshaller 'org.infinispan.commons.marshall.ImmutableProtoStreamMarshaller'
   2025-06-18 12:43:13,393 INFO  [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: node_759642, Site name: null
   2025-06-18 12:43:13,705 INFO  [org.keycloak.services] (main) KC-SERVICES0050: Initializing master realm
   2025-06-18 12:43:16,361 INFO  [io.quarkus] (main) Keycloak 26.2.5 on JVM (powered by Quarkus 3.20.1) started in 182.882s. Listening on: http://0.0.0.0:8080
   2025-06-18 12:43:16,362 INFO  [io.quarkus] (main) Profile dev activated.
   2025-06-18 12:43:16,362 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-postgresql,     keycloak, narayana-jta, opentelemetry, reactive-routes, rest, rest-jackson, smallrye-context-propagation, vertx]
   ```
   
   The Keycloak server should be available at `localhost:8080`.

## Verify the integration using ysqlsh

1. Run [ysqlsh](/stable/api/ysqlsh/ "ysqlsh") to connect to your database using the YSQL API as follows:
   
   ```sh
   $ ./bin/ysqlsh
   ```
2. Connect to the `keycloak` database to verify it works as follows:
   
   ```sql
   yugabyte=# \c keycloak
   ```
   
   ```output
   You are now connected to database "keycloak" as user "yugabyte".
   ```
   
   ```sql
   keycloak=# \dt
   ```
   
   ```output
                        List of relations
    Schema |             Name              | Type  |  Owner
   --------+-------------------------------+-------+----------
    public | admin_event_entity            | table | yugabyte
    public | associated_policy             | table | yugabyte
    public | authentication_execution      | table | yugabyte
    public | authentication_flow           | table | yugabyte
    public | authenticator_config          | table | yugabyte
    public | authenticator_config_entry    | table | yugabyte
    public | broker_link                   | table | yugabyte
    public | client                        | table | yugabyte
    public | client_attributes             | table | yugabyte
    public | client_auth_flow_bindings     | table | yugabyte
    public | client_initial_access         | table | yugabyte
    public | client_node_registrations     | table | yugabyte
    public | client_scope                  | table | yugabyte
    public | client_scope_attributes       | table | yugabyte
    public | client_scope_client           | table | yugabyte
    public | client_scope_role_mapping     | table | yugabyte
    public | component                     | table | yugabyte
    public | component_config              | table | yugabyte
    public | composite_role                | table | yugabyte
    public | credential                    | table | yugabyte
    public | databasechangelog             | table | yugabyte
    public | databasechangeloglock         | table | yugabyte
    public | default_client_scope          | table | yugabyte
    public | event_entity                  | table | yugabyte
    public | fed_user_attribute            | table | yugabyte
    public | fed_user_consent              | table | yugabyte
    public | fed_user_consent_cl_scope     | table | yugabyte
    public | fed_user_credential           | table | yugabyte
    public | fed_user_group_membership     | table | yugabyte
    public | fed_user_required_action      | table | yugabyte
    public | fed_user_role_mapping         | table | yugabyte
    public | federated_identity            | table | yugabyte
    public | federated_user                | table | yugabyte
    public | group_attribute               | table | yugabyte
    public | group_role_mapping            | table | yugabyte
    public | identity_provider             | table | yugabyte
    public | identity_provider_config      | table | yugabyte
    public | identity_provider_mapper      | table | yugabyte
    public | idp_mapper_config             | table | yugabyte
    public | jgroups_ping                  | table | yugabyte
    public | keycloak_group                | table | yugabyte
    public | keycloak_role                 | table | yugabyte
    public | migration_model               | table | yugabyte
    public | offline_client_session        | table | yugabyte
    public | offline_user_session          | table | yugabyte
    public | org                           | table | yugabyte
    public | org_domain                    | table | yugabyte
    public | policy_config                 | table | yugabyte
    public | protocol_mapper               | table | yugabyte
    public | protocol_mapper_config        | table | yugabyte
    public | realm                         | table | yugabyte
    public | realm_attribute               | table | yugabyte
    public | realm_default_groups          | table | yugabyte
    public | realm_enabled_event_types     | table | yugabyte
    public | realm_events_listeners        | table | yugabyte
    public | realm_localizations           | table | yugabyte
    public | realm_required_credential     | table | yugabyte
    public | realm_smtp_config             | table | yugabyte
    public | realm_supported_locales       | table | yugabyte
    public | redirect_uris                 | table | yugabyte
    public | required_action_config        | table | yugabyte
    public | required_action_provider      | table | yugabyte
    public | resource_attribute            | table | yugabyte
    public | resource_policy               | table | yugabyte
    public | resource_scope                | table | yugabyte
    public | resource_server               | table | yugabyte
    public | resource_server_perm_ticket   | table | yugabyte
    public | resource_server_policy        | table | yugabyte
    public | resource_server_resource      | table | yugabyte
    public | resource_server_scope         | table | yugabyte
    public | resource_uris                 | table | yugabyte
    public | revoked_token                 | table | yugabyte
    public | role_attribute                | table | yugabyte
    public | scope_mapping                 | table | yugabyte
    public | scope_policy                  | table | yugabyte
    public | server_config                 | table | yugabyte
    public | user_attribute                | table | yugabyte
    public | user_consent                  | table | yugabyte
    public | user_consent_client_scope     | table | yugabyte
    public | user_entity                   | table | yugabyte
    public | user_federation_config        | table | yugabyte
    public | user_federation_mapper        | table | yugabyte
    public | user_federation_mapper_config | table | yugabyte
    public | user_federation_provider      | table | yugabyte
    public | user_group_membership         | table | yugabyte
    public | user_required_action          | table | yugabyte
    public | user_role_mapping             | table | yugabyte
    public | web_origins                   | table | yugabyte
   ```

## Test Keycloak

1. Navigate to `localhost:8080` to access the dashboard to create a user.
   
   ![Keycloak Create User](/images/develop/ecosystem-integrations/keycloak/keycloak-create-user.png "Keycloak Create User")
2. Provide a username and password, and click **Create user**.
   
   Keycloak creates the user.
   
   ![Keycloak Open Admin Console](/images/develop/ecosystem-integrations/keycloak/keycloak-open-admin-console.png "Keycloak Open Admin Console")
   
   You can also verify the user creation on your database as follows:
   
   ```sql
   yugabyte=# \c keycloak
   ```
   
   ```output
   You are now connected to database "keycloak" as user "yugabyte".
   ```
   
   ```sql
   keycloak=# SELECT id,username FROM user_entity;
   ```
   
   ```output
                     id                  |   username
   --------------------------------------+---------------
    5fa4b561-66e1-49ab-9a85-bbb4d6088f15 | keycloak_user
   (1 row)
   ```
3. Click **Open Administration Console**.
4. On the sign in page, enter the username and password you just created, and click **Sign in**.
   
   ![Keycloak Sign In](/images/develop/ecosystem-integrations/keycloak/keycloak-sign-in.png "Keycloak Sign In")
   
   You are now signed in to the Keycloak dashboard.
   
   ![Keycloak Dashboard](/images/develop/ecosystem-integrations/keycloak/keycloak-welcome-page.png "Keycloak Dashboard")
