> ## Documentation Index
> Fetch the complete documentation index at: https://docs.celum.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Settings

> Platform-wide configuration — supervisor kubeconfigs, DNS domains, sites, SSO, the AI assistant, database backup, the licence, and API tokens.

**/settings** holds what is true for the whole platform rather than for one supervisor: which clusters Celum knows about, which DNS domains and sites exist, how SSO and the assistant are wired, and how to take a backup of the control plane's own database.

Eight tabs: Kubeconfigs, Domains & DNS, vCenters, Sites, SSO, AI Assistant, Database Backup and Licence. API tokens live on your own identity page.

> [!NOTE]
>
> Container registries are **not** here. They were moved out to their own page because a registry carries credentials and a chart/image role that the rest of the platform resolves per supervisor — see [Registries](https://docs.celum.io/gitops/registries.md).

## Kubeconfigs

The list of supervisors Celum can reach. A supervisor is a kubeconfig uploaded here and kept in Celum's database; nothing else adds one. Each row can be checked, downloaded, toggled active, and deleted. A row also carries the **site** it belongs to and, when it serves web endpoints, a **subdomain** plus the **domain** those endpoints hang off — which is what makes the two tabs below more than catalogues.

The full walk-through is on [Register a supervisor](https://docs.celum.io/get-started/register-a-supervisor.md).

## Domains

A DNS domain the platform may issue certificates under and publish services on. A domain is a name and a description; the binding that matters is on the supervisor, which points at one domain and adds its own subdomain.

That binding has one visible consequence worth stating: **Settings → SSO** can generate the complete list of Grafana redirect URIs Dex must allow, one per supervisor that has a domain attached. Supervisors *without* a domain are reported back separately — not silently skipped — because a missing redirect URI shows up much later as a login that fails only for that cluster.

The same tab registers **DNS providers**: the DNS servers (PowerDNS and the other external-dns backends) that a supervisor's DNS Publishing step can bind to. A registered provider keeps its key in the secret store, and a supervisor that binds to it gets read access to that one path rather than a copy; binding needs `dnsprovider:Use` on the provider.

## vCenters

vCenters registered once for the platform: server, user, password (kept in the secret store) and the pinned TLS thumbprint. The Cluster API step's vSphere kind and a migration source both pick a registered vCenter instead of typing credentials, and using one needs `vcenter:Use` on it. When a vCenter's certificate is renewed it is re-pinned here, once, for everything that uses it.

## Sites

A site is a managed location — `waw`, `internal`, whatever your estate calls them. The catalogue backs the picker during onboarding, and the name you choose is stored **verbatim** on the supervisor's kubeconfig row.

That verbatim storage is the thing to be careful with: the site name also drives image-library S3 bucket inheritance, so two spellings of the same place become two places, and an image library will inherit from neither.

## SSO

The secrets of Grafana's OIDC clients, set **once** here so every supervisor's Monitoring step can turn Grafana SSO on without asking for them again:

* **Platform `grafana` client secret** — the platform identity provider's own `grafana` client, used by the Monitoring step's **Platform client** mode. On an appliance it is created at install and this value is seeded with it.
* **Dex `grafana` client secret** — the static `grafana` client of the Dex broker, used by the **Dex broker** mode.

Both are stored **unencrypted** in Celum's database. The API never returns them (a read shows them masked, and a save that keeps the mask keeps the stored value), but a [database backup](#database-backup) contains them, and each Monitoring apply copies the one in use into that supervisor's Grafana OIDC Secret. Treat a backup file as holding these secrets.

The tab also lists the redirect URIs the Dex static client must allow, one per supervisor with a domain, derived from the domains above, as a plain YAML list. Add them to the `redirectURIs` of the `grafana` static client in your Dex configuration, then redeploy Dex with the new configuration.

## AI Assistant

Which LLM backs the in-app assistant. Providers are keyed by id — `anthropic`, `openai`, `ollama` — each with `enabled`, an API key, an optional base URL and a model; one of them is the `defaultProvider`.

`baseUrl` is required for Ollama and optional for OpenAI-compatible endpoints, which is how a self-hosted model is pointed at. The API key is **masked on read** and the mask is honoured on write: saving the form without retyping the key keeps the stored one, the same convention registry passwords use.

What the assistant can then *do* is a separate question, answered on [Celum AI and MCP](https://docs.celum.io/concepts/celum-ai.md).

## Database backup

The control plane's own PostgreSQL — audit log, IAM policies, templates, API tokens, supervisor rows. Not any supervisor's data.

**Export** streams a plain-SQL `pg_dump` with `DROP … IF EXISTS` guards, so the same file restores through **Import**. Restore runs in a **single transaction** with `ON_ERROR_STOP`, which is the property that matters: a bad file leaves the database as it was rather than half-replaced.

> [!WARNING]
>
> Import **replaces** the control plane's data. It requires an explicit `X-Confirm-Restore: yes` header — a deliberate second step so the operation cannot be reached by a mis-aimed `POST`. The body is capped at 500 MB, which is far past any realistic snapshot; the audit log is the table that will get there first.

Import works **without a licence**, even while Celum is read-only. The database carries the installation ID and the licence, so a replacement installation restored from its predecessor's backup gets both back and needs no new licence. Import also brings an older backup's schema up to date before Celum reads the licence again.

## Licence

What this installation is licensed for, and where a new licence goes in. The tab shows:

* the **installation ID** a licence must be issued for;
* the installed licence, its tier and customer;
* when it ends, or when the current state ends.

Its three actions are **Upload licence file**, **Paste licence** and **Download activation request**.

![The Licence tab showing the installation ID, a Standard licence for Acme that ends Nov 25, 2026 with 30 days left and the state Expiring, when and by whom it was installed, and the buttons Upload licence file, Paste licence and Download activation request](https://mintcdn.com/celum-e0119be0/5TBCdXcIMj9zFqpL/images/settings/licence-tab.png?fit=max\&auto=format\&n=5TBCdXcIMj9zFqpL\&q=85\&s=fb345f0ddde1e7d0ba6ec18d360f00be)

Settings → Licence with a licence installed, 30 days before it ends

A licence is a signed token bound to the installation ID. Celum checks it offline, against keys built into the release, before it stores it. It refuses a licence:

* issued for another installation;
* signed by a key this release does not trust;
* already past its end.

**Where it is enforced.** The Celum appliance enforces the licence (`LICENSE_ENFORCED=true`). Every installation is fully usable for 30 days from its first start. After that, without a licence, or once a licence and its grace period have ended, Celum is read-only: changes answer `402`, and everything can still be viewed. Celum deployed outside the appliance only logs what a licence would refuse.

[Deploy the appliance → Activate Celum](https://docs.celum.io/get-started/deploy-the-appliance.md#step-6--activate-celum) walks through activation from start to finish.

## API tokens

A token authenticates a headless client — a script, a CI job, an MCP client — as **you**. There are two ways to get one, and they are deliberately different.

| | Self-service | Administrative |
| - | - | - |
| Route | `POST /api/iam/me/tokens` | `POST /api/iam/tokens` |
| Mints for | yourself | another identity |
| Authorised by | nothing — `/api/iam/me/*` is self-service and carries no action | `iam:MintToken` |
| In the audit log | no (the response *is* the credential) | yes |

Celum stores a SHA-256 hash and a short prefix, never the token: it is shown **once**, at creation. A token may carry an expiry in days; without one it lasts until revoked. Each row records when it was last used, which is how a forgotten integration is found.

> [!WARNING]
>
> **A token freezes your identity-provider groups at the moment it is minted.** The groups your sign-in token carried are copied onto it, so a token issued while you were in an administrators group at the identity provider keeps that reach after you leave it — and a token minted before you joined a group there never gains it. Revoke and re-mint after such a change; the token list is the place to audit that.
>
> Changes made in Celum are not frozen: being added to or removed from a Celum group as a manual member, and any change to a policy, apply to the token without re-minting it.

## Global overrides without a UI

Two fields on the settings object have **no tab**: `componentOverrides`, which pins a specific image coordinate for a single component, and `chartOverrides`, which forces a chart to `upstream` or `internal` regardless of the registry defaults. They lost their screen when the registry settings tab moved out and remain an API-only surface on `PUT /api/settings`.

Before reaching for `chartOverrides`, read how a chart source is actually resolved: the decision is made **per supervisor**, and a supervisor's own declaration beats a global flag. See [Charts & the mirror](https://docs.celum.io/gitops/charts.md).

> [!NOTE]
>
> `PUT /api/settings` merges at the **top level**: a key you omit is left alone, a key you send **replaces that whole sub-object**. Sending `ai` with one provider therefore removes the others. Read the current settings, edit, and send the complete sub-object back.

> [tab] UI
>
> **/settings** — Kubeconfigs, Domains & DNS, vCenters, Sites, SSO, AI Assistant, Database Backup, Licence. API tokens are on **/iam/me**.

> [tab] API
>
> ```text theme={null}
> GET  /api/settings
> PUT  /api/settings
> GET  /api/settings/sso/grafana-redirect-uris
> GET  /api/settings/database/export
> POST /api/settings/database/import      (X-Confirm-Restore: yes)
>
> GET  /api/license
> GET  /api/license/activation-request
> PUT  /api/license                       {"token": "<licence>"}
>
> GET|POST /api/domains          DELETE /api/domains/{id}
> GET|POST /api/sites            DELETE /api/sites/{id}
> GET|POST /api/kubeconfigs      DELETE /api/kubeconfigs/{id}
>
> GET|POST /api/iam/me/tokens    DELETE /api/iam/me/tokens/{id}
> GET|POST /api/iam/tokens       DELETE /api/iam/tokens/{id}
> ```

> [tab] MCP
>
> `get_platform_settings`, `list_domains`, `create_domain`, `list_sites`, `create_site`, `list_kubeconfigs`, `add_kubeconfig`, `check_kubeconfig`, `get_onboarding_registries_settings`, `set_onboarding_registries_settings`, `get_license_status`, `get_license_activation_request`, `install_license`.
>
> **No tool writes the global settings, mints or revokes a token, deletes a domain or a site, or runs a database backup.** An assistant can read this configuration and add to the catalogues; the destructive and credential-issuing halves are deliberately left to a person.

## Permissions

| Task | Action | KRN |
| - | - | - |
| Read global settings | `settings:Read` | `krn:celum:settings:global` |
| Change global settings | `settings:Update` | `krn:celum:settings:global` |
| Export or import the database | `database:Backup` | `krn:celum:system:database` |
| Install a licence, download the activation request | `license:Update` | `krn:celum:license:global` |
| List / add / delete domains | `domain:List`, `domain:Create`, `domain:Delete` | `krn:celum:domain:*` |
| List / add / delete sites | `site:List`, `site:Create`, `site:Delete` | `krn:celum:site:*` |
| Manage kubeconfigs | `kubeconfig:List` / `:Upload` / `:Check` / `:Download` / `:Replace` / `:Toggle` / `:Delete` | `krn:celum:kubeconfig:*` |
| Register and use DNS providers | `dnsprovider:List` / `:Get` / `:Create` / `:Update` / `:Delete`, `dnsprovider:Use` | `krn:celum:dnsprovider:*` |
| Register and use vCenters | `vcenter:List` / `:Get` / `:Create` / `:Update` / `:Delete`, `vcenter:Use` | `krn:celum:vcenter:*` |
| Mint, list or revoke a token for someone else | `iam:MintToken`, `iam:ListTokens`, `iam:RevokeToken` | `krn:celum:iam:*` |

Export and import share one action. There is no read-only backup permission: being able to take a full copy of the control-plane database and being able to overwrite it are treated as the same level of trust.

## What commonly goes wrong

| Symptom | Cause and fix |
| - | - |
| Everything on this page returns `503` | No `DATABASE_URL`. Settings, domains, sites, tokens and the audit log are all database-backed. |
| Grafana SSO works on one supervisor and not another | The other supervisor has no domain attached, so no redirect URI was generated for it. The SSO tab lists which. |
| An image library inherits no S3 bucket | Two spellings of the same site. The name is stored verbatim from the picker. |
| A saved AI provider disappeared | `PUT /api/settings` replaced the whole `ai` object. Send the complete provider map. |
| A script still has access after the owner left a group at the identity provider | Tokens freeze identity-provider groups at mint time. Revoke it. |
| Import returns `400` | The `X-Confirm-Restore: yes` header is missing. |
| Every change returns `402` | The licence is missing or has ended on an appliance. See the Licence tab. Reading the licence status needs no permission; the banner shows it to everyone signed in. |

## Related

> [card] [Audit log](https://docs.celum.io/administration/audit-log.md)
>
> The record of every change made here and everywhere else.

> [card] [Register a supervisor](https://docs.celum.io/get-started/register-a-supervisor.md)
>
> The Kubeconfigs tab, walked through end to end.

> [card] [Registries](https://docs.celum.io/gitops/registries.md)
>
> Where charts and images come from — moved out of Settings on purpose.

> [card] [Authentication & IAM](https://docs.celum.io/get-started/authentication.md)
>
> Sessions, groups and how a token's frozen groups are evaluated.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.