Configuration
Soul Stack is configured by two typed YAML files:
keeper.yml— the config for one instance of a Keeper cluster (listeners, PostgreSQL/Redis/Vault, operator authentication, observability, background subsystems). Full reference — keeper.yml.soul.yml— the config for the agent on a managed host (identity, Keeper endpoints, TLS, paths, observability). Full reference — soul.yml.
Both files are validated against a typed schema at startup: unknown keys, wrong types, and violated invariants are rejected with a clear error instead of being silently ignored.
Where secrets live
Section titled “Where secrets live”Secrets are never written into the config in plaintext. Instead of a value you put a vault: reference, which Keeper resolves through its Vault client at startup:
postgres: dsn_ref: vault:secret/keeper/postgres # read from Vault, not stored in the fileThis is how the PostgreSQL DSN, the Redis password, the operator-token signing key, the host CA for push, and the rest are declared. Plaintext where a vault: ref is expected is rejected by the schema.
The agent (soul.yml) has no vault: refs: soul has no Vault client (a deliberate isolation measure — the agent has no way to read secrets). The few local secrets the agent does need (for example, the password for Basic auth on /metrics) are given as a path to a file with restricted permissions, not as a value in the YAML.
What you get out of the box
Section titled “What you get out of the box”Cross-cutting capabilities need no separate integration — they are built into both binaries and driven by config blocks:
| Capability | Keeper | Soul | Where it’s configured |
|---|---|---|---|
| Metrics (Prometheus) | mandatory listener (:9090) | optional, loopback by default | listen.metrics / metrics |
| OpenTelemetry (traces) | push to an OTLP collector | push to an OTLP collector | otel |
| Log rotation | built-in, no logrotate | built-in, no logrotate | logging.rotation |
| Config hot-reload | SIGHUP + write-back for API mutations | SIGHUP (pull daemon) | hot_reload |
| Vault integration | secrets + PKI + KV via vault: refs | — (no Vault client) | vault |
| RBAC | catalog in PostgreSQL, managed through the API | — | (in the DB, not the config) |
Details on each capability — in the corresponding sections of keeper.yml and soul.yml.
Hot-reload and restart
Section titled “Hot-reload and restart”Not every change applies without a restart. The general principle:
- Without a restart, parameters of a specific run or background-task iteration change: log level, timeouts, thresholds, limits, plugin policies.
- A restart is needed for changes to the process’s external surface: listener addresses, TLS certificates, PostgreSQL/Redis DSN, log-file paths.
Full “reload-able / restart-required” tables for each block — in keeper.yml → Hot-reload and soul.yml → Hot-reload.
Where to get a working example
Section titled “Where to get a working example”The soul-stack-keeper and soul-stack-soul packages drop a commented example config next to the binary. A minimal valid config with all required fields is given at the end of each reference: