Service configuration: required config surface (TOML/env via viper)
closedGoal
Track the required service configuration for sovrnd (and the app-view/webmail
surfaces). This is a living inventory: the pieces below are what we know today;
new required config is appended here as development uncovers it. At startup sovrn
will consume this from a TOML file and/or environment variables (Go viper
if the mixed-file/env precedence gets unwieldy), not from scattered os.Getenv
calls in the codebase.
Current ad-hoc surface (integration-test env, not yet a real config)
STALWART_URL— Stalwart HTTP/JMAP base (defaulthttp://127.0.0.1:8080,/jmapappended)STALWART_USERNAME— Stalwart service account (defaultsovrn-admin)STALWART_SECRET_FILE— path to the Stalwart service-secret (default<SOVRN_DATA_DIR>/stalwart/service-secret)SOVRN_DATA_DIR— sovrn data directory (defaultdata/dev)SOVRN_OIDC_ISSUER_HOST— host the Stalwart container reaches the tokenissuer at (host.containers.internal)SOVRN_INTEGRATION— test-only gate, not runtime config
Network / endpoints
- Mail ingress hostname — the value published as the MX record (dev:
mail.sovrn.testviaSTALWART_HOSTNAME); the domaindomain.detail.dns.mx/spfare derived from this + ingress config. - Listening port — Stalwart HTTP/JMAP
:8080; PDS XRPC:3000. SMTP (:25/465/587) and IMAP (:143/993) listener ports are added when the data plane lands (docs/01 §5). - App-view base URL — written into
at.sovrn.mail.service.appview. - Webmail URL — written into
at.sovrn.mail.service.webmail(+ JMAP/IMAP/SMTP hosts if webmail doesn’t proxy; buga472ea3). - OIDC issuer URL — the tokenissuer base URL (
issclaim); audience = Stalwart resource id (sovrn-mail). - OAuth client-metadata URL — the stable HTTPS URL serving sovrn’s confidential-client metadata (docs/02 §2.3).
Credentials / secrets (secret-store: file dev provider now, KMS in prod — docs/07 §4)
- Stalwart admin credential — service account + secret (file path above).
- OIDC signing key — ECDSA P-256, with
kid(docs/02 §4). - OAuth attestation key — ES256,
private_key_jwt(docs/02 §2.3). - Postmaster DID + keys — authority DID,
#atproto_spaceverification key,#atproto_space_hostservice entry (bugee2256b); separate from OIDC/attestation keys (docs/04 §2). - Postmaster PDS URL — the spaces-capable PDS hosting the postmaster’s repos.
Paths / data
- Sovrn data directory (
SOVRN_DATA_DIR) — root for Stalwart data, PDS data, and the app DB. - Stalwart keys/secret file path —
stalwart/service-secret. - App DB path — SQLite file location (docs/01 §2).
Consumption plan
- One
configpackage loads TOML (sovrn.toml) with env-var overrides; viper only if the precedence/merging gets complicated. Asecret-storeinterface hides file/KMS behind the same surface (docs/07 §4, docs/01 A3). - Fields above map to a typed struct; secrets resolve through the store, never inline in the TOML.
Related
ee2256b(postmaster DID ceremony + KMS),a472ea3(mail.service endpoints),ac83db8(webmail fork), docs/01 §8, docs/07 §4.
2 Comments
Remaining config values to implement/define
The
Configstruct (root config.go) is wired and consumed bysovrn.NewApp. The following are defined-but-not-yet-consumed, or still need defining as the dependencies land. Add rows to this list (and fields to the struct) as work progresses.Consumed today (wired through NewApp): -
server.host/server.port— app-view bind address (cmd/sovrnd). -datadir— app-DB location (datadir/sovrn.db). -stalwart.url/stalwart.username/stalwart.secretfile— Stalwart client. -mail.hostname(→ MX) /mail.spf— MailDefaults for getDnsState. -devauth.did— stub auth identity.Defined in the struct but not yet consumed (need wiring): -
appview.url/webmail.url— written intoat.sovrn.mail.serviceat first login (buga472ea3); no publisher exists yet. -oidc.issuer/oidc.audience— the tokenissuer identity; consumed when the tokenissuer is constructed inside sovrnd (today it runs in-process only in integration tests).Still to define (new fields, when their bug lands): - Postmaster DID +
#atproto_spacekey +#atproto_space_hostPDS URL —ee2256b. - Real auth (svcverifier) config: OAuth client-metadata URL, attestation key ref (KMS), audience — replacesdevauth.did—a589d34/c1c7e19. - Real DNS prober config (resolver endpoints, probe schedule) —b5a31bd. - SMTP/IMAP listener hostnames + ports for the data plane (docs/01 §5). - Secret-store backend selection (file dev provider vs KMS) + KMS endpoint — docs/07 §4, docs/08 §3. - OIDC signing-key reference (kid → KMS slot) — docs/02 §4. - Observability (Prometheus listen port, log level) — docs/01 A4.Note: env naming is
SOVRN_<KEY>(dots → underscores); the olderSTALWART_*vars in the integration-test helpers predate this and should be folded in during the secret-store/config cleanup.Complete: the config surface is implemented — typed Config struct, viper TOML (sovrn.toml) + SOVRN_* env overrides, and ValidateSecrets fail-loud gating in config.go, consumed by sovrn.NewApp. Remaining fields are gated on future features (postmaster/KMS via the Spaces epic; DNS-prober tuning; data-plane listeners) and tracked by those features. Closing this living-inventory tracker.