Configuration
Everything that isn’t the database layout or ingress: how settings reach the services, where secrets come from, and how to substitute your own infrastructure.Application settings
Anything that would otherwise be a bespoke env var — encryption keys, timeouts, log levels, model config — goes underappSettings, and lands as an
env var on every service.
Each entry takes one of three shapes:
env: entries — scalars as value:, maps as
valueFrom.secretKeyRef or valueFrom.configMapKeyRef. A map that is neither
shape fails the install rather than rendering something odd.
Per-service overrides
services.<name>.settings takes the same three shapes and wins over
appSettings for the same key:
The defaults ship
ENCRYPTION_KEY and AUDIT_HASHCHAIN_SIGNING_KEYS wired to
the chart-generated Secret, plus LOG_LEVEL=info — enough for a first install
to work with no input. Override them with your own key management when you go
to production.Secrets
The chart generates a Secret namedswarmd-generated-credentials at install:
Passwords are 24 random alphanumeric characters. On
helm upgrade the chart
reads the existing Secret via lookup and reuses the values — upgrades do
not rotate credentials.
The Secret carries helm.sh/resource-policy: keep, so helm uninstall leaves
it behind.
Supplying your own
SMTP
tenant-auth sends email for verification, password reset and team invites. Withsmtp.enabled: false — the default — every one of those is logged and
dropped. Users can register, but nothing arrives.
smtp.enabled: true and any of host,
from or credentialsSecret missing.
Bring your own infrastructure
Every optional component follows the same three-state pattern:enabled: false · enabled: true, deploy: true · enabled: true, deploy: false plus an external block. The chart fails the render if you
choose the third and leave a required URL empty.
Bring your own Keycloak
adminSecret holds master-realm admin credentials. Registry, relay,
tenant-auth and teams call the Admin API to manage agent service accounts, so
this is not optional.
PII detection
Both analyzers are off by default. With neither enabled, prompts pass through the LLM path unfiltered.a2a-payments
Off by default, and the only service that genuinely cannot start without configuration: itsX402_WALLET_PRIVATE_KEY is @NotBlank-validated with no
degraded mode.
Turning services off
Settings that bite later
Some settings don’t block startup but fail the first time a feature is used. The chart can’t enforce them, because the service boots fine without them.
Provide them under
services.<name>.settings when you enable the feature.
Scaling: core and worker
Every DB-backed service ships as one image that can run three ways, and the chart splits every one of them by default:
The worker’s web server stays up so health probes work, but the Service never
routes traffic to it. Worker sizing falls back to the service’s own
replicaCount / resources when left empty.
Why this is the default. In the combined topology, scaling the API to N
replicas also runs N copies of every
@Scheduled job — outbox drainers and
monitor evaluators racing each other, which is a data problem rather than a
performance one. Splitting also stops a slow scheduler starving the API’s
thread pool, and takes Flyway out of pod startup so a long migration can’t
trip readiness on every replica at once.Collapsing a service back
Observability
Verifying a change before you apply it
template, so a bad combination fails here
— before it touches your cluster.
Next
Presets
Tested values files that combine all of this.
Databases
Layouts, external Postgres, ClickHouse and backups.
