> For the complete documentation index, see [llms.txt](https://docs.catalyx.solutions/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.catalyx.solutions/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/keycloak-realm-setup.md).

# Keycloak Realm Setup

Create the realm, clients, and login user the platform needs before you install — with the commands to do it by hand.

Before you run [Platform Installation](/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/platform-installation.md), a Keycloak realm has to exist with three clients and a login user already in it. The operator only *provisions into* an existing realm (see [Managed Keycloak](/catalyx-blockchain-manager/canton-network/version-2.0/validator-management/identity-provider-configuration/managed-keycloak.md)) — it never creates the realm itself, so this is a one-time manual step.

## One realm, shared by the platform and every validator

Everything below goes into one realm. That's the same realm you point the operator at with `operator.keycloak.realm` in [Platform Installation](/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/platform-installation.md), and the same realm [Managed Keycloak](/catalyx-blockchain-manager/canton-network/version-2.0/validator-management/identity-provider-configuration/managed-keycloak.md) later provisions per-validator clients into. There's no separate "platform realm" and "validator realm" — one realm serves both.

## Placeholders used below

<table><thead><tr><th width="200">Placeholder</th><th width="260">Example</th><th>Is</th></tr></thead><tbody><tr><td><code>$REALM</code></td><td><code>validator-intellecteu-devnet</code></td><td>The realm you create — becomes <code>operator.keycloak.realm</code>.</td></tr><tr><td><code>$BASE_HOSTNAME</code></td><td><code>validators.example.com</code></td><td>Should match <code>operatorRuntime.baseHostname</code> — used in the UI client's redirect URI.</td></tr><tr><td><code>$UI_USERNAME</code> / <code>$UI_EMAIL</code></td><td><code>catalyx-ui-admin</code> / <code>catalyx-ui-admin@example.com</code></td><td>The browser login user you create for <code>catalyx-canton-ui</code>.</td></tr></tbody></table>

{% hint style="danger" %}
Pick your own values — don't reuse the examples above, and don't leave any password as a placeholder like `admin` in anything beyond a local minikube run.
{% endhint %}

## What to create

<table><thead><tr><th width="220">Object</th><th width="110">Realm</th><th>Configuration</th></tr></thead><tbody><tr><td>Realm</td><td>—</td><td><code>$REALM</code>, enabled, display name "CatalyX Canton Validator" (or your own).</td></tr><tr><td>Client — <code>catalyx-operator-admin</code></td><td><code>$REALM</code></td><td>Confidential, service accounts enabled, standard flow <strong>disabled</strong> (service account only — never used for browser login). Its secret is what you store as <code>admin-client-secret</code> in the <code>catalyx-operator-keycloak</code> secret in <a href="/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/platform-installation.md">Platform Installation</a>, and is referenced by <code>operator.keycloak.adminClientId</code>.</td></tr><tr><td>Client — <code>catalyx-api</code></td><td><code>$REALM</code></td><td>Confidential, service accounts enabled, standard flow enabled, direct access grants <strong>disabled</strong>, <code>redirectUris: ["/*"]</code>, <code>webOrigins: ["/*"]</code>. Its secret is what you store as <code>client-secret</code> in the <code>catalyx-api-credentials</code> secret.</td></tr><tr><td>Client — <code>catalyx-canton-ui</code></td><td><code>$REALM</code></td><td>Public, standard flow enabled (browser OIDC with PKCE), direct access grants disabled, redirect URI <code>https://$BASE_HOSTNAME/*</code>, web origin <code>https://$BASE_HOSTNAME</code>. Matches <code>ui.oidc.clientId</code> (default <code>catalyx-canton-ui</code>).</td></tr><tr><td>User — <code>$UI_USERNAME</code></td><td><code>$REALM</code></td><td>Enabled, email verified, password set. Used to sign in to the CatalyX UI in a browser via <code>catalyx-canton-ui</code>. Carries no realm roles — it's a plain login, not an admin account.</td></tr></tbody></table>

## Permission to grant

There is one role assignment to make: the `catalyx-operator-admin` service account (`service-account-catalyx-operator-admin`) gets the **`realm-admin`** client role of **`$REALM`**'s own **`realm-management`** client — not `master`'s. That scopes the operator to administering just `$REALM`, and is what lets its client-credentials login create and update the per-validator clients, scopes, and users described in [Managed Keycloak](/catalyx-blockchain-manager/canton-network/version-2.0/validator-management/identity-provider-configuration/managed-keycloak.md).

## Commands

Everything below can equally be done by hand in the Keycloak Admin Console (**Realm settings → Create realm**, **Clients → Create client**, **Users → Add user**, and the role assignment under a user's **Role mapping** tab).

Run these with `kcadm.sh` against your Keycloak — from a shell with `kcadm.sh` on the path (for example `kubectl exec` into the Keycloak pod), or adapt them to the [Admin REST API](https://www.keycloak.org/docs-api/latest/rest-api/index.html) if you're not using the CLI.

{% stepper %}
{% step %}
**Authenticate**

```bash
kcadm.sh config credentials \
  --server "$KEYCLOAK_URL" \
  --realm master \
  --user admin \
  --password <admin-password>
```

{% endstep %}

{% step %}
**Create the realm**

```bash
kcadm.sh create realms \
  -s realm="$REALM" \
  -s enabled=true \
  -s displayName="CatalyX Canton Validator"
```

{% endstep %}

{% step %}
**Create `catalyx-operator-admin` in `$REALM` and grant it `realm-admin`**

```bash
kcadm.sh create clients -r "$REALM" \
  -s clientId=catalyx-operator-admin \
  -s enabled=true \
  -s publicClient=false \
  -s serviceAccountsEnabled=true \
  -s standardFlowEnabled=false

kcadm.sh add-roles -r "$REALM" \
  --uusername service-account-catalyx-operator-admin \
  --cclientid realm-management \
  --rolename realm-admin
```

{% endstep %}

{% step %}
**Create `catalyx-api` in `$REALM`**

```bash
kcadm.sh create clients -r "$REALM" \
  -s clientId=catalyx-api \
  -s enabled=true \
  -s publicClient=false \
  -s serviceAccountsEnabled=true \
  -s standardFlowEnabled=true \
  -s directAccessGrantsEnabled=false \
  -s 'redirectUris=["/*"]' \
  -s 'webOrigins=["/*"]'
```

{% endstep %}

{% step %}
**Create `catalyx-canton-ui` in `$REALM`**

```bash
kcadm.sh create clients -r "$REALM" \
  -s clientId=catalyx-canton-ui \
  -s enabled=true \
  -s publicClient=true \
  -s serviceAccountsEnabled=false \
  -s standardFlowEnabled=true \
  -s directAccessGrantsEnabled=false \
  -s "redirectUris=[\"https://$BASE_HOSTNAME/*\"]" \
  -s "webOrigins=[\"https://$BASE_HOSTNAME\"]"
```

{% endstep %}

{% step %}
**Create the UI login user**

```bash
kcadm.sh create users -r "$REALM" \
  -s username="$UI_USERNAME" \
  -s email="$UI_EMAIL" \
  -s enabled=true \
  -s emailVerified=true

kcadm.sh set-password -r "$REALM" \
  --username "$UI_USERNAME" \
  --new-password <choose-a-password>
```

{% endstep %}

{% step %}
**Retrieve the `catalyx-operator-admin` secret**

```bash
CLIENT_ID=$(kcadm.sh get clients -r "$REALM" \
  -q clientId=catalyx-operator-admin --fields id --format csv --noquotes)
kcadm.sh get "clients/$CLIENT_ID/client-secret" -r "$REALM"
```

Store the printed `value` as `admin-client-secret` in the `catalyx-operator-keycloak` secret — see step 2 of [Platform Installation](/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/platform-installation.md).
{% endstep %}

{% step %}
**Retrieve the `catalyx-api` secret**

```bash
CLIENT_ID=$(kcadm.sh get clients -r "$REALM" \
  -q clientId=catalyx-api --fields id --format csv --noquotes)
kcadm.sh get "clients/$CLIENT_ID/client-secret" -r "$REALM"
```

Store the printed `value` as `client-secret` in the `catalyx-api-credentials` secret — also step 2 of [Platform Installation](/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/platform-installation.md).
{% endstep %}
{% endstepper %}

***

## Next step

With the realm, its three clients, and the UI login user in place, continue to [Platform Installation](/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/platform-installation.md) to create the Kubernetes secrets from the two client secrets above and install the Helm chart.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.catalyx.solutions/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/keycloak-realm-setup.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
