Files
probo/contrib/claude/config.md
Bryan Frimin c4e81ed092 Inline OAuth2 signing key in config
The OAuth2/OIDC server accepted its signing key via a file path
(key-file), while every other PEM key in the probod config (SAML
private key, ACME account key) is embedded inline. Switch the
field to a private-key string so the convention is uniform.

The signing key is operator-supplied material that must outlive
any process restart, so the bootstrap builder now treats
OAUTH2_SERVER_SIGNING_KEY as required and refuses to start
without one; silently minting a fresh key per boot would break
token validation across rollouts. The OAUTH2_SERVER_* env vars
otherwise flow through builder.Build like the existing SAML
block so the new OAuth2Server section is populated end-to-end.

Rework the e2e harness to render its config via bootstrap at
test setup, which removes the static
e2e/console/testdata/config.yaml and the previously generated
test-only PEM file. A per-run RSA key is minted via
bootstrap.GenerateOAuth2SigningKey (kept public for test
tooling) and injected through the builder env map. CI now
passes ACME_ROOT_CA inline instead of mutating a YAML on disk.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-04-21 17:56:00 +02:00

3.3 KiB

Configuration Propagation

When a configuration field is added, renamed, or removed in the Go config structs, all downstream consumers must be updated in the same change. The config struct in pkg/probod/ is the source of truth.

Files to update (checklist)

# File Role
1 pkg/probod/*.go Go config structs — source of truth
2 pkg/probod/probod.go New() Default values for new fields
3 pkg/bootstrap/builder.go Env-var → struct mapping (Build() method)
4 pkg/bootstrap/builder.go Required-env validation (validateRequired())
5 cfg/dev.yaml Local development config
6 e2e/internal/testutil/testutil.go E2E env-var map fed to bootstrap.NewBuilder
7 contrib/lima/provision.sh Sandbox env vars passed to probod-bootstrap
8 contrib/helm/charts/probo/values.yaml Helm default values
9 contrib/helm/charts/probo/values-production.yaml.example Helm production template
10 contrib/helm/charts/probo/templates/deployment.yaml Helm deployment — maps values → env vars
11 contrib/helm/charts/probo/templates/secret.yaml Helm secret — sensitive values

Flow

Go struct (pkg/probod/)
  │
  ├─► probod New() defaults
  │
  ├─► bootstrap builder.go (env var → struct)
  │     │
  │     ├─► cfg/dev.yaml              (static YAML, local dev)
  │     ├─► e2e/internal/testutil/    (env map → bootstrap.Build, tests)
  │     ├─► contrib/lima/provision.sh  (env vars → probod-bootstrap)
  │     └─► Helm chart
  │           ├─ values.yaml           (user-facing knobs)
  │           ├─ values-production.yaml.example
  │           ├─ templates/deployment.yaml (values → env vars)
  │           └─ templates/secret.yaml     (sensitive values)
  │
  └─► probod.go Run() (wiring into services)

Rules

  1. Never add a Go config field without updating every file in the checklist.
  2. Env var naming — follow the existing convention in builder.go: SECTION_FIELD_NAME (e.g. AUTH_COOKIE_DOMAIN, CUSTOM_DOMAINS_RENEWAL_INTERVAL).
  3. Secrets go through secret.yaml and are referenced via secretKeyRef in deployment.yaml. Non-secret values are set inline.
  4. cfg/dev.yaml uses safe, non-production defaults (plaintext passwords, localhost, secure: false).
  5. e2e/internal/testutil/testutil.go builds the e2e config through bootstrap.NewBuilder with a test-only env-var map (different ports, probod_test DB, shorter intervals). Any new field whose test value differs from the bootstrap default must be added to that map.
  6. provision.sh only sets env vars that differ from builder.go defaults (e.g. PROBOD_BASE_URL, AUTH_COOKIE_DOMAIN, AUTH_COOKIE_SECURE). If the new field's default is acceptable in the sandbox, no env var is needed.
  7. Helm values.yaml exposes the field under the appropriate probo.* key with a sensible default. values-production.yaml.example includes it only when the production value differs or the user must set it.
  8. Optional features (custom domains, SAML, connectors, tracing) are gated by {{- if }} blocks in the Helm templates; follow the same pattern for new optional fields.
  9. Bootstrap tests (pkg/bootstrap/builder_test.go) must cover the new env var mapping.