> 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/create-a-validator.md).

# Create a Validator

A validator is declared as a single `Validator` custom resource. You apply it, and the operator provisions everything else.

{% hint style="info" %}
Validators are created, changed, and deleted through custom resources — not through the console. This keeps validator configuration reviewable and GitOps-friendly. The console is where you *operate* a validator once it exists.
{% endhint %}

## What the operator does

{% stepper %}
{% step %}
**Provisions authentication**

When `spec.auth.managedKeycloak` is `true`, the operator creates the OIDC clients, client scopes, protocol mappers, and wallet user for this validator, then writes the generated backend client secret to a Kubernetes Secret and records the result in `status.managedAuth`.
{% endstep %}

{% step %}
**Provisions databases**

The participant and validator-app databases and schemas are created, plus the PQS and Wallet Gateway databases when those components are enabled.
{% endstep %}

{% step %}
**Creates the component applications**

One child `Application` resource per component: `participant`, `validator`, `wallet-ui`, `cns-ui`, and optionally `pqs` and `wallet-gateway`.
{% endstep %}

{% step %}
**Creates the workloads**

Each `Application` becomes a `Deployment`, a `Service`, and — for externally reachable components — a Traefik `IngressRoute`.
{% endstep %}
{% endstepper %}

The validator reports `Ready` once every component it owns is ready.

***

## Prepare the secrets

Two secrets are needed in the validator's namespace before you apply.

```bash
# Database credentials — must be able to CREATE DATABASE
kubectl create secret generic my-validator-db-credentials \
  --from-literal=username=<db-user> \
  --from-literal=password=<db-password> \
  -n catalyx-system

# One-time onboarding secret from the sponsoring Super Validator
kubectl create secret generic my-validator-onboarding \
  --from-literal=secret=<onboarding-secret> \
  -n catalyx-system
```

{% hint style="danger" %}
The onboarding secret's key **must be `secret`**. The operator reads that exact key name.
{% endhint %}

If you are using an external identity provider rather than managed authentication, you also need a secret holding the backend OIDC client secret — see [External Identity Provider](/catalyx-blockchain-manager/canton-network/version-2.0/installation-instructions-canton/identity-provider-configuration/external-identity-provider.md).

***

## A minimal Validator

This example relies on managed authentication and on operator defaults for every component. It is the shortest useful `Validator`.

{% code title="my-validator.yaml" %}

```yaml
apiVersion: catalyx.manager.canton/v1alpha1
kind: Validator
metadata:
  name: my-validator
  namespace: catalyx-system
spec:
  auth:
    managedKeycloak: true
    targetAudience: https://canton.network.global
    ledgerApiUserManagementScope: daml_ledger_api

  network:
    spliceVersion: "0.6.4"
    partyHint: catalyx-devnet-001
    onboardingSecretName: my-validator-onboarding
    sponsorSvUrl: https://sv.sv-1.dev.global.canton.network.sync.global
    scan:
      address: https://scan.sv-1.dev.global.canton.network.sync.global
      type: bft
      seedUrls:
        - https://scan.sv-1.dev.global.canton.network.sync.global
    synchronizer:
      connectionType: bft
      url: https://sequencer.sv-1.dev.global.canton.network.sync.global

  database:
    host: postgres.default.svc.cluster.local
    participantDb: participant_my_validator
    validatorDb: validator_my_validator
    credentialsSecretRef:
      name: my-validator-db-credentials
```

{% endcode %}

```bash
kubectl apply -f my-validator.yaml
```

{% hint style="warning" %}
**`spec.network.partyHint` is pattern-validated.** It must match `^[a-zA-Z0-9]+-[a-zA-Z0-9]+-[0-9]+$` — that is, two alphanumeric segments and a numeric segment, separated by hyphens. `catalyx-devnet-001` is valid; `myvalidator` and `my_validator_1` are rejected at apply time.
{% endhint %}

{% hint style="info" %}
`spec.network.spliceVersion` sets one version for the participant, validator app, and both UIs. You can still pin any component individually with its own `version` field. Either the component `version` or `spliceVersion` must be set, or the validator is rejected.
{% endhint %}

## Required fields

Only three top-level blocks are mandatory, and the API server rejects the resource at apply time if any is missing:

<table><thead><tr><th width="200">Block</th><th>Mandatory fields inside</th></tr></thead><tbody><tr><td><code>spec.auth</code></td><td>None individually, but the block itself is required.</td></tr><tr><td><code>spec.network</code></td><td><code>partyHint</code></td></tr><tr><td><code>spec.database</code></td><td><code>host</code>, <code>participantDb</code>, <code>validatorDb</code>, <code>credentialsSecretRef.name</code></td></tr></tbody></table>

{% hint style="warning" %}
`spec.network.scan` and `spec.network.synchronizer` are not marked mandatory in the schema, but the validator cannot reconcile without them. Always supply both.
{% endhint %}

For the complete field list, see the [Validator CRD Reference](/catalyx-blockchain-manager/canton-network/version-2.0/validator-crd.md).

***

## Watch it come up

```bash
kubectl -n catalyx-system get validators
kubectl -n catalyx-system get validators my-validator -o wide
```

The `Validator` resource prints a `READY` column, and `-o wide` adds the `REASON` for a validator that is not ready.

```bash
# Per-component detail
kubectl -n catalyx-system get validators my-validator -o jsonpath='{.status.applications}' | jq

# The child applications and their workloads
kubectl -n catalyx-system get applications
kubectl -n catalyx-system get pods -l app.kubernetes.io/instance=my-validator
```

Or open the console and watch the validator's [Summary](/catalyx-blockchain-manager/canton-network/version-2.0/console-guide-canton/validators/summary.md) and [Status](/catalyx-blockchain-manager/canton-network/version-2.0/console-guide-canton/validators/status-and-specification.md) tabs, which refresh automatically.

## If it does not become ready

The `Ready` condition carries a reason that tells you which kind of problem you have:

<table><thead><tr><th width="200">Reason</th><th>Meaning</th></tr></thead><tbody><tr><td><code>InvalidSpec</code></td><td>A configuration problem the operator detected. The condition message names the exact field. Fix the <code>Validator</code> and re-apply.</td></tr><tr><td><code>ReconcileError</code></td><td>Something went wrong that is not a configuration error — for example the database or identity provider was unreachable. Check the operator logs.</td></tr><tr><td><code>ApplicationNotReady</code></td><td>The configuration is accepted but a component has not come up. Look at <code>status.applications</code> to see which one, then at that component's pods.</td></tr></tbody></table>

```bash
kubectl -n catalyx-system logs deploy/catalyx-canton-operator
```

{% hint style="info" %}
Unknown fields are **silently pruned** by the Kubernetes API server. A misspelled field name is dropped without an error, and the setting simply has no effect. If a value seems to be ignored, check the spelling against the [CRD reference](/catalyx-blockchain-manager/canton-network/version-2.0/validator-crd.md) and confirm it survived with `kubectl get validator <name> -o yaml`.
{% endhint %}

***

## Deleting a validator

```bash
kubectl -n catalyx-system delete validator my-validator
```

Kubernetes garbage-collects the child `Application` resources and their workloads.

{% hint style="danger" %}
Deleting a `Validator` does **not** remove:

* the **databases** — participant, validator, PQS, and Wallet Gateway data all remain;
* the **identity provider objects** created by managed authentication — clients, scopes, and users stay in the realm;
* the **managed authentication secret** `<validator-name>-managed-ledger-api-auth`.

Clean these up yourself if you are decommissioning a validator permanently. Retaining them is what makes it possible to recreate a validator against its existing state.
{% endhint %}


---

# 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/create-a-validator.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.
