Configuration, Environments, and Secrets
Configuration in this platform must be typed, layered, and validated early. The system is too operationally significant to rely on a loose collection of environment variables and module-specific conventions. Core, official modules, and customer apps all need configuration, but they do not own the same kinds of settings and should not read them in the same way.
Core configuration covers transport, HTTP behavior, TLS mode, cache backends, queueing, storage drivers, object-store settings, observability, database access, and extension-host policy. Official modules add their own structured settings for domain features such as CMS workflows, catalog behavior, events, bookings, or search. Customer-app configuration adds site definitions, hostname and locale policy, theme selection, storage rules, capability bindings, and enabled integrations. Keeping these layers separate makes it possible to explain how one deployment differs from another without guessing.
Environment variables are only one delivery mechanism. The runtime should load configuration into typed structures, apply defaults, validate invariants, and fail fast if critical settings are missing or inconsistent. That is especially important for auth model packages, certificate strategy, storage policy, and cache topology, where a partially valid boot state can lead to subtle failures later.
Secrets deserve their own handling path. API keys, signing keys, database credentials, ACME account material, Cloudflare credentials, and other sensitive values should come from environment variables, secret managers, or deployment tooling, but downstream code should consume them through typed interfaces rather than reading raw process environment at arbitrary points. A module should not be able to bypass the platform's secret model simply because it knows an environment variable name.
Configuration layering should follow an explicit precedence order. Platform defaults are the base. Deployment-environment overrides come next. Module configuration and customer-app overrides are then applied in a documented order. The final effective configuration should be inspectable for operators, even if secret values themselves are redacted. That inspectability matters when debugging why a site is using a specific locale strategy, host binding, storage rule, or certificate mode.
Because customer apps are first-class deployments rather than mere tenants, configuration must support per-app and per-site policy without turning the platform into an arbitrary runtime-shaping machine. The goal is explicit composition. A customer app can choose ACME with Cloudflare DNS automation, define folder-based storage defaults, replace the default auth model, or install only selected modules. A site within that app can then define host bindings, canonical-host policy, and locale policy for public delivery. What the system should not do is force core to become a giant bag of untyped per-project conditionals.