> 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/identity-provider-configuration/managed-keycloak.md).

# Managed Keycloak

With `spec.auth.managedKeycloak: true`, the operator provisions everything the validator's components need inside an existing Keycloak realm, on the validator's first reconcile.

## Configuration

At the platform level, set the operator's Keycloak values at install time — see [Platform Installation](/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/platform-installation.md).

On the validator, the whole `spec.auth` block reduces to four fields:

```yaml
spec:
  auth:
    managedKeycloak: true
    targetAudience: https://canton.network.global
    ledgerApiUserManagementScope: daml_ledger_api
```

`spec.network.partyHint` must also be set — it becomes the wallet user's username.

{% hint style="danger" %}
The realm must already exist, and the operator's admin client must exist **inside that realm** with realm-management permissions. The operator authenticates with the client credentials grant against the realm named in `operator.keycloak.realm`.
{% endhint %}

***

## What gets created

For a validator named `my-validator`, in the realm you configured:

<table><thead><tr><th width="240">Object</th><th width="200">Name</th><th>Notes</th></tr></thead><tbody><tr><td>Public client — CNS UI</td><td><code>my-validator-cns-ui</code></td><td>Redirect URI and web origin derived from <code>operatorRuntime.baseHostname</code>. Gets an audience mapper for <code>targetAudience</code>.</td></tr><tr><td>Public client — Wallet UI</td><td><code>my-validator-wallet-ui</code></td><td>As above.</td></tr><tr><td>Public client — Wallet Gateway</td><td><code>my-validator-wallet-gateway</code></td><td>Created whether or not the Wallet Gateway is enabled. Gets an audience mapper, a hardcoded <code>sub</code> claim mapper, and a 30-minute access token lifespan. The <code>profile</code> and <code>email</code> default scopes are removed.</td></tr><tr><td>Confidential client — backend</td><td><code>my-validator-validator-backend</code></td><td>Service accounts enabled. Its generated secret is written to a Kubernetes Secret.</td></tr><tr><td>Client scope — Ledger API</td><td>the value of <code>ledgerApiUserManagementScope</code></td><td>Created once per realm, with an audience mapper for <code>targetAudience</code>.</td></tr><tr><td>Client scope — per validator</td><td><code>my-validator-ledger-api</code></td><td>Attached as an optional scope to the platform's API client. Carries the audience, the user-management scope claim, and the backend service account's subject.</td></tr><tr><td>User — wallet</td><td>the value of <code>spec.network.partyHint</code></td><td>Enabled, email verified, no password and no roles.</td></tr></tbody></table>

## The generated secret

The operator writes an `Opaque` Kubernetes Secret in the validator's namespace:

|       |                                                              |
| ----- | ------------------------------------------------------------ |
| Name  | `<validator-name>-managed-ledger-api-auth`                   |
| Key   | `client-secret`                                              |
| Value | The generated secret of `<validator-name>-validator-backend` |

{% hint style="warning" %}
This secret has no owner reference, so it is **not** deleted when the validator is deleted. That is deliberate — it lets you recreate a validator without re-provisioning — but it means you must remove it yourself when decommissioning permanently.
{% endhint %}

## Checking the result

Provisioning results are recorded on the validator's status and shown on the console's [Identity](/catalyx-blockchain-manager/canton-network/version-2.0/console-guide-canton/validators/identity-and-endpoints.md) tab.

```bash
kubectl -n catalyx-system get validator my-validator -o jsonpath='{.status.managedAuth}' | jq
```

<table><thead><tr><th width="300">Status field</th><th>Meaning</th></tr></thead><tbody><tr><td><code>provisioned</code></td><td><code>true</code> once provisioning has completed successfully.</td></tr><tr><td><code>walletUiClientId</code>, <code>cnsUiClientId</code>, <code>walletGatewayClientId</code>, <code>ledgerApiClientId</code></td><td>The client IDs that were created.</td></tr><tr><td><code>ledgerApiClientSecretName</code>, <code>ledgerApiClientSecretKey</code></td><td>Where the backend client secret was written.</td></tr><tr><td><code>authUrl</code></td><td>The resolved OIDC issuer URL.</td></tr><tr><td><code>ledgerApiUser</code>, <code>walletUserName</code></td><td>Internal Keycloak user identifiers for the backend service account and the wallet user. These are IDs, not usernames.</td></tr></tbody></table>

{% hint style="info" %}
Once `provisioned` is `true`, the operator stops contacting Keycloak on subsequent reconciles and reads all authentication configuration from `status.managedAuth`.
{% endhint %}

***

## Things to know before you rely on it

**Provisioning is idempotent, but not fully self-correcting.** Clients that already exist have their redirect URIs and web origins overwritten to match the current `operatorRuntime.baseHostname`. **Client scopes are not updated** — a scope created with the wrong `targetAudience` must be corrected by hand in Keycloak.

**Changing the base hostname rewrites redirect URIs.** If you change `operatorRuntime.baseHostname` after validators exist, their public clients are updated on the next provisioning cycle.

**The platform API client is optional but recommended.** If the client named by `operator.keycloak.apiClientId` (default `catalyx-api`) does not exist in the realm, the operator logs a warning and continues — but the console will not be able to perform Ledger API operations for that validator.

**Nothing is cleaned up on delete.** Clients, scopes, and users created for a validator remain in the realm after the validator is deleted.


---

# 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/identity-provider-configuration/managed-keycloak.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.
