mirror of
https://github.com/Such-Software/smirk-backend-core.git
synced 2026-10-17 15:31:38 +02:00
feat(config): operator settings overlay foundation (storage + validated merge)
Stage 1 of the operator-editable config layer (additive; no behavior change yet): - migration operator_settings: one MAC(ADMIN_KEY_INTEGRITY_SECRET) JSONB row per section, FK to admin_keys, audited on write. Missing section = env-only. - OperatorSettingRow model. - SettingsOverlay + section overlays (landing/retention/restore) with secrets EXCLUDED BY CONSTRUCTION; Config::apply_overlay merges onto the env-derived Config then re-runs the SAME Config::validate boot uses (a bad edit yields the identical error, nothing persists, the instance cannot be bricked). - runtime_class() single source of truth (RuntimeSafe hot-swap vs RestartRequired). - operator_settings storage: canonical-JSON MAC (stable across JSONB key reorder), load_settings_overlay (fail-closed per section -> env fallback), put_setting_audited (upsert + admin_audit append in one tx). - sqlx json feature. cargo check clean; 4 new unit tests pass. Next stages: ArcSwap AppState + ~59 read-site migration, GET/PUT /admin/config (+ restart_apply_mode), remaining sections.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
-- Operator-editable settings overlay: the DB precedence tier UNDER the env-derived
|
||||
-- Config (effective = defaults -> env -> DB overlay). One JSONB row per section; the
|
||||
-- effective Config is rebuilt from these at boot and on change. Each row is MAC'd with
|
||||
-- ADMIN_KEY_INTEGRITY_SECRET (same anchor as server_config / admin_keys) so a DB-write
|
||||
-- attacker cannot silently flip operator policy, and every write is appended to the
|
||||
-- hash-chained admin_audit log. A missing section = env-only (no seed rows). Secrets are
|
||||
-- NEVER stored here (overlays carry no secret fields by construction).
|
||||
CREATE TABLE operator_settings (
|
||||
section TEXT PRIMARY KEY,
|
||||
doc JSONB NOT NULL,
|
||||
version BIGINT NOT NULL DEFAULT 1,
|
||||
updated_by UUID REFERENCES admin_keys(id) ON DELETE SET NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
integrity_mac TEXT NOT NULL
|
||||
);
|
||||
Reference in New Issue
Block a user