Profiles & adapter selection
Recap: one deployment is one Profile — an
implementation choice plus settings, per seam. internal/config.Load builds it from
environment variables; there's no file-based config in Phase 1.
How cmd/cns-server picks an implementation
For each seam, main.go switches on cfg.Profile.<Seam>.Impl and constructs the
matching adapter — falling back to that seam's noop implementation for any value it
doesn't recognize (including the empty/default case), so the server always boots,
regardless of how incomplete its configuration is. A freshly cloned repo with zero
environment variables set boots cleanly and logs store=noop bus=direct realtime=noop identity=noop — every route that needs a real adapter then fails
per-request (typically 501/403, adapter-dependent), not at startup.
This matters operationally: you can stand up cns-server incrementally — wire
identity first and confirm auth works, then store, then realtime — without the
service being unavailable at any point in between.
Which environment variable selects which implementation
internal/config.Load inspects presence, not an explicit _IMPL switch, for
most seams — the first matching case wins:
| Seam | Selects a real implementation when... | Otherwise |
|---|---|---|
| Store | CNS_CLICKHOUSE_ENDPOINT is set → clickhouse; else CNS_STORE_IMPL=memory → in-process memory | noop |
| Bus | (always direct, no variable) | — |
| Realtime | CNS_CENTRIFUGO_ADDR is set → centrifugo | noop |
| Identity | CNS_SSO_JWT_HMAC_SECRET set → sso-jwt (HMAC); else CNS_SSO_JWT_JWKS_URL set → sso-jwt (JWKS) | noop |
| Secrets | CNS_SECRETS_IMPL (default ssm; memory or noop also accepted) | (always has a value — defaults to ssm) |
| Channels | (always [{Impl: "inapp"}], no variable) | — |
Full variable-by-variable reference, including every identity/store/secrets setting: Environment variables.
The dev-fixture guard rail
Config.DevFixture (CNS_DEV_FIXTURE=1) is not just a convenience flag — Load
actively refuses to boot unless the rest of the configuration is provably
harmless: a loopback listen address, CNS_ENV=dev, store and secrets both set to the
in-process memory implementation, and realtime left as noop. This exists
specifically so a dev-fixture script can never accidentally be pointed at production
settings by a copy-paste mistake — see The dev fixture.