ctrl configuration
This page lists every table and key of the ctrl configuration file, generated from the annotated example ctrl.example.toml, which the ctrl tests check against the keys ctrl reads. A table or key the example leaves commented out is optional.
[database]
| Key | Type | Example | Description |
|---|---|---|---|
dsn | string | "postgresql://kibotos@127.0.0.1:5432/kibotos" | Every read and write must reach the PostgreSQL primary. A connection proxy or a pooler such as PgBouncer in between is fine, but kibotos-ctrl migrate must connect directly: run it with a configuration whose dsn names the primary. |
dsn_file | string | "/run/kibotos/ctrl-dsn" | Optional. Use dsn_file instead of dsn when another process materializes the complete DSN. |
max_connections | integer | 32 | Optional. The most connections ctrl holds while serving, 32 by default. PostgreSQL's max_connections must leave room for it and for every other client. Set the limit here, not as pool_max_conns in the DSN. |
[identity]
| Key | Type | Example | Description |
|---|---|---|---|
trust_domain | string | "kibotos.example" | trust_domain is the only identity input: a lowercase DNS-shaped name that every Operator and node identity lives under. It cannot change after init. |
host | string | "ctrl.kibotos.example" | host is the exact host both listeners present: a lowercase DNS name or an IP literal, without wildcard or port. serve signs its certificate with the server CA that init created; clients trust that CA through their enrollment key, so no public certificate or DNS is involved. |
[storage]
| Key | Type | Example | Description |
|---|---|---|---|
root | string | "/var/lib/kibotos/ctrl" | Managed PKI state lives here; /etc/kibotos/ctrl/ holds only config. |
[api]
The ctrl API: the Workspace face and the Operator face share this one mTLS listener. kibo and, later, a tenant platform connect here with identities the control-client CA issued; there is no plaintext or unauthenticated Workspace endpoint.
| Key | Type | Example | Description |
|---|---|---|---|
listen | string | "0.0.0.0:18092" |
[node_api]
| Key | Type | Example | Description |
|---|---|---|---|
listen | string | "0.0.0.0:18101" |
[telemetry]
Optional.
Optional. ctrl's own metrics in the Prometheus text format at GET /metrics, including the cluster state it reads from the database when scraped. Plain HTTP without authentication: bind loopback and scrape from this host, or bind 0.0.0.0 in a container and let only the collector reach the port. Omit the section to open no listener. [metrics] below is a different thing: the store for per-Instance readings.
| Key | Type | Example | Description |
|---|---|---|---|
listen | string | "127.0.0.1:18192" |
[data_plane]
How ctrl names node data-plane certificates. ctrl derives every node's primary data-plane host as "<node_id>.<host_suffix>" and signs it with the internal server CA. default_extra_hosts are deployment-wide extra names (an IP, a loopback address, or an external DNS name) added to every node's leaf beyond that derived host and the per-node extras an Operator declares on the enrollment grant. None of them may be the ctrl identity.host. host_suffix is required.
| Key | Type | Example | Description |
|---|---|---|---|
host_suffix | string | "nodes.example" | |
default_extra_hosts | array | [] |
[exposure]
The registrable domain Exposure hostnames live under. Every Exposure is "<random label>.<zone>", served through the deployment tunnel and the gateway. Leave it empty to refuse CreateExposure on this deployment. It must not share a registrable domain with identity.host or data_plane.host_suffix: the pages behind it are written by an Agent, and sharing a domain would pull cookie scope and the phishing surface onto the control plane.
| Key | Type | Example | Description |
|---|---|---|---|
zone | string | "" |
[workspace]
How many accepted Workspace commands ctrl runs at once, across every node: this many creates, starts and transfer restores; separately this many stops, deletes and data-plane revocations; and half as many (at least one) transfer exports and imports. A command holds a database connection only while it reads or writes, not while it waits on the node.
| Key | Type | Example | Description |
|---|---|---|---|
execution_concurrency | integer | 16 |
[transfer]
Optional. Workspace transfer archives live in the artifact store below. An export larger than max_archive_bytes fails (at most 5368709120, one upload request); an archive is deleted archive_retention_seconds after its export completed, and a Transfer not imported by then becomes EXPIRED. These are the defaults.
| Key | Type | Example | Description |
|---|---|---|---|
max_archive_bytes | integer | 1073741824 | |
archive_retention_seconds | integer | 86400 |
[template_artifact_store]
Required for node_api artifact tickets, Operator publication, and Workspace transfer archives. The runtime identity needs both the kibotos-template/v1/ and kibotos-transfer/v1/ prefixes of the bucket; transfer archives are user data, so enable encryption at rest on it.
| Key | Type | Example | Description |
|---|---|---|---|
endpoint | string | "objects.example:443" | |
region | string | "us-east-1" | |
bucket | string | "kibotos-template-artifacts" | |
namespace | string | "primary" | |
secure | boolean | true | |
path_style | boolean | false | |
credential_source | string | "static" | |
access_key_id | string | "replace-me" | |
secret_access_key | string | "replace-me" | |
session_token | string | "" | |
credential_process | string | "/usr/local/libexec/kibotos/artifact-store-credentials" | Optional. With credential_source = "process", ctrl runs the helper at the absolute path credential_process with credential_process_args, without a shell, for short-lived credentials; access_key_id, secret_access_key and session_token must then be absent. The helper prints one JSON object with version 1, access_key_id, secret_access_key, session_token and expiration (RFC 3339). ctrl runs it again 5 minutes before the expiration and stops a run after 10 seconds. |
credential_process_args | array | [] | Optional. |
[metrics]
Optional.
Optional. ctrl writes the instance info series kibotos_instance_info (value 1, labels instance_id, workspace_id and the Workspace labels listed below) to the metrics store as soon as it sees an Instance running and again every 60 s, and hands every node the store's address with a write token so the nodes push their guest samples there. Omit the section to write nothing: nodes then sample nothing. Every kibotos-ctrl command that loads this file validates the section and reads the key and CA files, so kibotos-ctrl must be able to read them.
| Key | Type | Example | Description |
|---|---|---|---|
remote_write_url | string | "https://metrics.example.com:8427/api/v1/write" | The complete remote write URL, without credentials. With vmauth in front of VictoriaMetrics: http(s)://host:8427/api/v1/write. |
signing_key_file | string | "/etc/kibotos/ctrl/metrics-signing-key.pem" | The P-256 private key, PKCS#8 or SEC 1 PEM, that signs the one-hour write tokens of ctrl and the nodes. The proxy in front of the store verifies them with the matching public key. |
ca_file | string | "/etc/kibotos/ctrl/metrics-ca.pem" | A PEM bundle, at most 64 KiB, that replaces the system roots for an https URL. ctrl hands it to the nodes with the address. |
instance_info_labels | array of strings | ["e2b.kibotos.app/namespace", "e2b.kibotos.io/namespace"] | Workspace label keys copied onto the series as label_<key>, every character outside [a-zA-Z0-9_] replaced by _. An E2B deployment lists exactly the namespace keys below; the second is the spelling gateways before v0.3.0 wrote, dropped in v0.4.0. Never list the labels generated from E2B sandbox metadata: they are caller data. |
query_url | string | "https://metrics.example.com:8427" | The base URL of the store's Prometheus query API, for the Native API's GetWorkspaceMetrics and kibo workspace metrics. ctrl queries it with its own token, the one it writes with, so the proxy in front must also let the ctrl role reach /api/v1/query and /api/v1/query_range. ca_file applies to it too. Omit it to write without reading: the method then answers that this deployment has no metrics store, and GetServerInfo does not announce workspace.metrics.get. With vmauth in front of VictoriaMetrics: http(s)://host:8427. |
retention_seconds | integer | 604800 | How long the store keeps samples, 3600 to 315360000. Reads never reach further back. Default 604800 (7 days), the reference deployment's. |
query_delay_seconds | integer | 30 | How long a written sample takes to become visible, 0 to 3600. Buckets newer than this are not answered yet, so an answered bucket never changes. Default 30, VictoriaMetrics' -search.latencyOffset. |
[traces]
Optional.
Optional: the trace store. ctrl pushes its own spans there and hands every node the address with a push token, so the nodes push theirs too. Omit the section to produce no spans anywhere. Every kibotos-ctrl command that loads this file validates the section and reads the key and CA files.
| Key | Type | Example | Description |
|---|---|---|---|
endpoint | string | "https://traces.example.com:8427/insert/opentelemetry/v1/traces" | The complete OTLP/HTTP traces URL, without credentials. With vmauth in front of VictoriaTraces: http(s)://host:8427/insert/opentelemetry/v1/traces. |
signing_key_file | string | "/etc/kibotos/ctrl/traces-signing-key.pem" | The P-256 private key that signs the one-hour push tokens of ctrl and the nodes; same rules as [metrics].signing_key_file, and it may be the same file. |
ca_file | string | "/etc/kibotos/ctrl/traces-ca.pem" | A PEM bundle, at most 64 KiB, that replaces the system roots for an https URL. ctrl hands it to the nodes with the address. |
sample_ratio | float | 0.01 | The share of node data-plane requests sampled, 0 to 1. Keep it equal to the gateways' *_TRACES_SAMPLE_RATIO. |
kibotos.service.v1 types
This page lists the messages and enums of kibotos.service.v1 that the API packages use, generated from the proto file and its comments.
node configuration
This page lists every table and key of the node configuration file, generated from the annotated example node.example.toml, which the node tests check against the keys node reads. A table or key the example leaves commented out is optional.