deploy/server/config.required
Ref: Size: 3.9 KiB History
# The server config contract: every key the tagged tree's config schema declares,
# classified. scripts/ship.sh reads the schema out of
# internal/server/config/config.go on the tree being shipped, compares it against
# this file, and refuses to deploy a plane whose Secret and whose binary disagree.
#
# required the plane's server.json must set it to a non-empty value
# optional the server has a working default, or the key is a deliberate opt-in
# retired the field survives only so the server can spot it in an old config
# and say what to write instead; a plane still setting it gets a warning
#
# A key the tree declares and this file does not classify is a hard failure, on
# purpose: that is exactly the shape of the v0.0.3 release-day incident, where the
# struct grew default_images and every plane's Secret silently lacked it. The
# schema and its contract now move together or not at all.
#
# Nested structs reach this file through their JSON path, declared here so a new
# one cannot slip in unclassified — the extractor fails on a struct with no
# prefix. A "*" segment stands for a map key: the rule holds for every entry.
#
# struct-prefix: Config=
# struct-prefix: OIDC=oidc.
# struct-prefix: DefaultImage=default_images.*.
db_path required
http_listen required
quic_listen required
host_secret required
# Seals every piece of key material the plane holds — the host CA and the gate's
# host key, both files on the PVC — so the volume and its backups hold
# ciphertext. Tenant user CAs are not among them: those are public keys the
# tenant brings, and no user signing key is ever in the database to seal.
# 64 hex chars, minted with
# `openssl rand -hex 32`, and never rotated in place: a plane that loses it loses
# its host CA, and with it the identity every client pins and every VM's host
# certificate names. This Secret is that key's only home; keep the operator's
# copy of server.json.
key_encryption_key required
cidr_pool required
advertise_http required
advertise_quic required
# The gate's bind, and the name it answers to. A bind that names every interface
# (":2222", "0.0.0.0:…") gives the gate no name of its own, so the server refuses
# to boot without ssh_gate_domain: its host certificate would name localhost and
# every remote client would refuse it. This plane binds a wildcard, hence both
# required; a plane binding one concrete address may leave the domain out.
ssh_listen required
ssh_gate_domain required
ssh_ca_key required
ssh_host_key required
# One image per host architecture. A plane serving both arm64 and amd64 hosts
# needs both entries: a host handed an image it cannot execute fails at boot,
# which is the mistake this map exists to prevent.
default_images required
default_images.*.url required
default_images.*.sha256 required
oidc required
oidc.issuer required
oidc.client_id required
oidc.public_url required
# Confidential clients only — the bundled loopback issuer is public.
oidc.client_secret optional
# The signup gate. Empty means anyone the issuer authenticates gets a tenant, so
# a hosted plane that is not open for signups sets one of these.
oidc.allowed_domains optional
oidc.allowed_identities optional
# Absent means the built-in default (eitri.sh); an explicit empty string
# disables release discovery and every upgrade surface with it.
release_manifest_url optional
log_level optional
credential_max_age optional
# How long the append-only audit log keeps a row. Absent means 90 days; "0"
# keeps every row forever.
audit_retention optional
admin_token retired
default_image_url retired
default_image_sha256 retired