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

# appliance.yaml reference

> Every setting in the appliance's configuration file: what it does, its default, and the rules the appliance checks before it starts anything.

`/etc/celum-appliance/appliance.yaml` is the appliance's whole configuration. Every way of configuring the appliance ends up in this one file:

* **The OVA's deploy form:** on the first boot, the appliance writes the file from the form's answers.
* **The OVA's Full configuration (base64 YAML) field:** you give the whole file, base64-encoded. See [Configure it with a file instead](https://partner.celum.io/appliance/deploy-ova.md#configure-it-with-a-file-instead).
* **cloud-init on the qcow2:** the user-data writes the file. See [Deploy on KVM (qcow2)](https://partner.celum.io/appliance/deploy-qcow2.md).
* **By hand,** on the appliance.

After the first boot the file is the configuration, and the appliance no longer reads the form. To check a file, run `celum-appliance config` on the appliance: it prints the configuration as the appliance reads it, with defaults filled in, warnings, and the error that would stop the boot. To apply a change after the first boot, see [Change the configuration later](https://partner.celum.io/appliance/deploy-qcow2.md#change-the-configuration-later).

> [!NOTE]
>
> The appliance refuses a file with an unknown key, and the error names its line. A typo stops the boot instead of being silently ignored.

## The smallest file

Only `domain` and `admin.email` are required. Everything else has a default.

```yaml theme={null}
domain: celum.example.com
admin:
  email: ops@example.com
```

This gives you DHCP, a self-signed certificate, every component on and IAM off. In practice, add `admin.sshKeys`, because key login is the only way in, and a static `network` block if you run Omni.

## A full example

```yaml theme={null}
domain: celum.example.com          # required

hostnames:                         # optional: move a service to another name
  harbor: registry                 # registry.celum.example.com

network:                           # leave out for DHCP
  address: 10.20.30.40/24
  gateway: 10.20.30.1
  nameservers: [10.20.30.2, 10.20.30.3]
  searchDomains: [example.com]
  # interface: ens18               # only with more than one NIC

admin:
  email: ops@example.com           # required
  # password: ""                   # blank: generated
  sshKeys:
    - ssh-ed25519 AAAA... ops@laptop

tls:
  mode: selfsigned                 # selfsigned | byo | acme-dns01

components:
  home:
    enabled: true
    username: admin
  harbor:
    enabled: true
    project: celum
  authentik:
    enabled: true
    adminGroup: celum-admins
  omni:
    enabled: true
    eula:
      name: Jane Doe
    # wireguardAddress: 203.0.113.10:50180
  celum:
    enabled: true
    iamEnabled: false
    airGap: "off"                  # off | strict
    imageLibrary:
      endpoint: https://s3.example.com
      bucket: celum-images
      accessKey: "AKIA..."
      secretKey: "..."
  vault:
    enabled: true
  dns:
    enabled: true
    zones: [apps.example.com]

updates:
  username: "robot$example"
  password: "..."

backup:
  s3:
    endpoint: https://s3.example.com
    bucket: celum-backups
    accessKey: "AKIA..."
    secretKey: "..."
    keepRemote: 30
  # escrow:
  #   recipients: [age1...]
```

Certificates and keys go in as PEM, indented under `|`; see [Optional settings](https://partner.celum.io/appliance/deploy-qcow2.md#optional-settings) for examples.

## Domain and names

| Key | Default | Description |
| - | - | - |
| `domain` | none, **required** | The appliance's DNS domain, with at least two labels, for example `celum.example.com`. Every name the appliance serves is derived from it. |
| `hostnames` | see below | Moves a service to another name. A value without a dot is a label under `domain`; a value with a dot is used as the full name. |

The services and their default names:

| Key in `hostnames` | Default name | Service |
| - | - | - |
| `home` | `home.DOMAIN` | The start page |
| `celum` | `app.DOMAIN` | Celum's web interface |
| `api` | `api.DOMAIN` | Celum's API |
| `harbor` | `harbor.DOMAIN` | Harbor |
| `auth` | `auth.DOMAIN` | Authentik |
| `omni` | `omni.DOMAIN` | Omni |
| `vault` | `vault.DOMAIN` | OpenBao |
| `pdns-api` | `pdns-api.DOMAIN` | PowerDNS's API, for external-dns in tenant clusters |
| `pdns` | `pdns.DOMAIN` | PowerDNS's web interface |

Any other key is refused.

## network

Leave the whole block out for DHCP on the first Ethernet interface.

| Key | Default | Description |
| - | - | - |
| `network.address` | none | The static address, as CIDR: `10.20.30.40/24`. Set it together with `gateway`. |
| `network.gateway` | none | The default gateway. |
| `network.nameservers` | none | DNS servers, as IP addresses. Without any, the appliance resolves nothing and warns. |
| `network.searchDomains` | none | DNS search domains. |
| `network.interface` | the first interface | The interface to configure. Needed when the VM has more than one NIC and the first boot cannot tell them apart. |

## admin

| Key | Default | Description |
| - | - | - |
| `admin.email` | none, **required** | The first administrator in Authentik and Harbor, and Omni's initial user. |
| `admin.password` | generated | The administrator's password. Leave it blank: the generated one is printed on the console and written to `/root/celum-appliance-credentials.txt`. |
| `admin.sshKeys` | none | SSH public keys authorised for root. Key login is the only way in, so give at least one. They also seal the key escrow, unless `backup.escrow.recipients` is set. |
| `admin.sshRootPassword` | none | Gives root a password and turns SSH password login on. Leave it blank unless you have no other way in. |

## tls

| Key | Default | Description |
| - | - | - |
| `tls.mode` | `selfsigned` | `selfsigned`: the appliance signs its own certificates. `byo`: you supply one. `acme-dns01`: the appliance obtains one through a DNS-01 challenge. There is no plain-HTTP mode. |
| `tls.cert` | none | `byo`: the certificate chain as PEM, the server certificate first. It must cover every name the appliance serves; the boot stops if it misses any name other than `home`. |
| `tls.key` | none | `byo`: the private key as PEM. |
| `tls.ca.cert` | a new CA on every deployment | `selfsigned`: your own signing CA as PEM, the CA first, then any chain above it. With your own CA, clients keep trusting the appliance after a redeploy. |
| `tls.ca.key` | none | `selfsigned`: the CA's private key as PEM: PKCS#8, PKCS#1 or EC. Give both or neither. |
| `tls.acme.email` | none | `acme-dns01`, required: the ACME account email. |
| `tls.acme.provider` | none | `acme-dns01`, required: a lego DNS provider code, such as `cloudflare`, `route53` or `godaddy`. |
| `tls.acme.credentials` | none | `acme-dns01`, required: the provider's environment variables, as a map: `CF_DNS_API_TOKEN: "..."`. |
| `tls.acme.caServer` | Let's Encrypt | `acme-dns01`: another ACME directory URL. |

> [!WARNING]
>
> `acme-dns01` cannot serve Omni, which presents its own certificate. In this mode the appliance switches Omni off and says so. For Omni, use `selfsigned` or `byo` with a publicly trusted certificate.

## components

Every component is on by default. Set `enabled: false` to leave one out.

### home: the start page

| Key | Default | Description |
| - | - | - |
| `components.home.enabled` | `true` | The start page at `home.DOMAIN`. |
| `components.home.username` | `admin` | The start page's user name, one word. |
| `components.home.password` | generated | At least 12 characters. Read on the first boot only: to change it later, use `celum-appliance home password set`. |

### harbor

| Key | Default | Description |
| - | - | - |
| `components.harbor.enabled` | `true` | The container and Helm chart registry. It is also Celum's default chart and image repository. |
| `components.harbor.project` | `celum` | The Harbor project Celum mirrors charts and images into: lower-case letters and digits, separated by single `.`, `_` or `-`. |

### authentik

| Key | Default | Description |
| - | - | - |
| `components.authentik.enabled` | `true` | The identity provider: sign-in for Celum, Harbor, Omni, OpenBao and PowerDNS. Without it, Celum runs without sign-in and Omni cannot run. |
| `components.authentik.adminGroup` | `celum-admins` | The Authentik group whose members are Celum administrators. |

### omni

| Key | Default | Description |
| - | - | - |
| `components.omni.enabled` | `true` | Talos fleet management. Omni is under the Business Source License: production use needs an agreement with Sidero Labs. Needs Authentik. |
| `components.omni.eula.name` | none | Your full name, to accept Sidero's EULA at first start. Without it, Omni refuses every call, Celum's included, until someone accepts it in the Omni interface. |
| `components.omni.eula.email` | `initialUser` | The email recorded with the acceptance. |
| `components.omni.initialUser` | `admin.email` | Omni's first user. |
| `components.omni.wireguardAddress` | `network.address`, port `50180` | The `ip:port` Talos nodes dial for SideroLink. Set it when nodes reach the appliance through NAT or a load balancer. Under DHCP, the address at boot is used, and the appliance warns. |
| `components.omni.accountUUID` | generated | Omni's account ID. Leave it blank. |

### celum

| Key | Default | Description |
| - | - | - |
| `components.celum.enabled` | `true` | Celum itself. |
| `components.celum.iamEnabled` | `false` | Enforce IAM policies. Turn it on once you have signed in and confirmed you are in the admin group. With Authentik off, `true` is refused. |
| `components.celum.airGap` | `off` | `strict` makes a cluster's nodes fail an image pull the appliance's Harbor cannot serve, instead of fetching it from the internet. Use it only when the appliance carries every image your clusters run. |
| `components.celum.imageLibrary.endpoint` | none | The S3 endpoint Celum's Image Library imports guest images from, as `scheme://host`, with no path. |
| `components.celum.imageLibrary.bucket` | none | The bucket. |
| `components.celum.imageLibrary.accessKey` | none | The access key. |
| `components.celum.imageLibrary.secretKey` | none | The secret key. |

Set all four `imageLibrary` keys or none. The supervisors' nodes download from the endpoint directly, so it must be reachable from them and serve a certificate they trust.

### vault and dns

| Key | Default | Description |
| - | - | - |
| `components.vault.enabled` | `true` | OpenBao, the secret store Celum writes cluster secrets into. Without it, Celum cannot store secrets for clusters, and there is nothing to back up. |
| `components.dns.enabled` | `true` | PowerDNS and CoreDNS. The appliance serves its own domain, with a record for every service, and forwards everything else to your DNS. |
| `components.dns.zones` | none | Further zones to create empty, for external-dns in tenant clusters to fill. |

## updates

| Key | Default | Description |
| - | - | - |
| `updates.username` | none | The robot account from your licence. Set it together with `password`. |
| `updates.password` | none | Its secret. |
| `updates.registry` | `registry.celum.io` | The release registry, as a host name. Leave the default. |
| `updates.project` | `app` | The registry project Celum releases are published to. Leave the default. |

You can also enter the account later, on the start page's **Updates** tab.

## backup

| Key | Default | Description |
| - | - | - |
| `backup.s3.endpoint` | none | The S3 endpoint for off-box backups, as `scheme://host`, with no path. |
| `backup.s3.bucket` | none | The bucket. It must exist; the appliance never creates it. |
| `backup.s3.accessKey` | none | Needs PutObject, and ListBucket and DeleteObject to remove old snapshots. |
| `backup.s3.secretKey` | none | The secret key. |
| `backup.s3.prefix` | `celum-appliance/DOMAIN/` | Where in the bucket the snapshots go. |
| `backup.s3.region` | none | Most S3-compatible stores ignore it. |
| `backup.s3.ca` | none | A PEM bundle trusted in addition to the system's, for an endpoint under a private CA. |
| `backup.s3.keepRemote` | `30` | How many snapshots stay in the bucket. A negative number never deletes any, and leaves retention to the bucket's own rules. |
| `backup.escrow.recipients` | `admin.sshKeys` | Public keys the key escrow is sealed to: age keys (`age1...`) or SSH keys (`ssh-ed25519`, or `ssh-rsa` of at least 2048 bits). More than one gives a second person who can restore. |

Set the four required `backup.s3` keys or none. The key escrow holds the secrets a restore cannot do without, encrypted to these keys; their private halves never touch the appliance.

## experimental

| Key | Default | Description |
| - | - | - |
| `experimental.poc.enabled` | `false` | Adds the start page's **Experimental: PoC** tab and `celum-appliance poc`: Talos node VMs on your vCenter, and a cluster on them through the appliance's Omni. Experimental: it may change between releases. |

## Keys not described here

The file also accepts `metrics`, `e2e` and `sizing`. The first two are for Nuvira's own test infrastructure, and nothing reads `sizing` yet. Leave them out.


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