<#950 Persistance in backend for each service conf...
# osctrl
g
#950 Persistance in backend for each service configuration from YAML Pull request opened by javuto Summary Persists structured YAML configuration sections (logger, carver, SAML, OIDC, metrics, TLS, etc.) per service into a new
service_config
database table, seeded from the YAML file on first boot and exposed via read-only API endpoints. Problem Every service boots by loading a YAML file into
config.ServiceParameters
. The structured sections — logger, carver, SAML, OIDC, JWT, metrics, TLS, debug — are never persisted to the DB and can't be inspected from the UI. Only a handful of scalar runtime knobs live in
setting_values
. Changes New package
pkg/serviceconfig
•
ServiceConfig
GORM model: one row per (service, section, environment) with a unique composite index.
Value
holds the JSON-encoded YAML section;
Source
tracks
yaml
vs `db`;
Editable
gates future writes (all
false
in phase 1). •
SectionRegistry
declaratively maps which sections belong to which service (12 for TLS, 11 for API). Connection/secret sections (
db
,
redis
) are flagged non-editable. •
Seed
uses
ON CONFLICT DO NOTHING
for create-if-missing semantics — idempotent and never overwrites a DB-edited row. • 10 tests covering idempotency, no-overwrite of DB-edited rows, JSON round-trip, service-specific sections, per-environment isolation, and input validation. Seeding wired into startup •
cmd/tls/main.go
and
cmd/api/main.go
call
Seed
right after
loadingSettings
, persisting the YAML-loaded config into
service_config
. Read-only API handlers (
cmd/api/handlers/service_config.go
) | Method | Path | Description | | ------ | ------------------------------------------ | -------------------------------- | | GET | /api/v1/service-config | All sections across all services | | GET | /api/v1/service-config/{service} | All sections for one service | | GET | /api/v1/service-config/{service}/{section} | One section | All require
AdminLevel
permissions, validate service/section against the registry, audit-log reads, and return 404 for missing sections. Wired through
HandlersApi.ServiceConfig
+
WithServiceConfig
. Design notes • No risk to existing settings: new table, new package, no changes to
SettingValue
or
loadingSettings
. • No risk to runtime: phase 1 is read-only mirror; services still consume
ServiceParameters
from YAML exactly as before. • Security: connection sections (
db
,
redis
) are flagged
editable=false
and never writable through the API. • Auditable: every read hits `AuditLog.Visit`; future writes will hit
AuditLog.SettingsAction
. Validation •
go build ./...
•
go test ./...
— all packages pass, including 10 new tests in
pkg/serviceconfig
•
golangci-lint run ./pkg/serviceconfig/...
— 0 issues •
gofmt
clean on all new/modified files Evolution path | Phase | What changes | | ----------- | ------------------------------------------------------------------------------------------------- | | 1 (this PR) | Seed from YAML → DB. API read endpoints. YAML still live source of truth. | | 2 | editable sections can be PUT from the frontend. DB value takes precedence. | | 3 | Services read config from DB at startup; YAML becomes an override/bootstrap. | | 4 | YAML shrinks to db + redis + bootstrap. Logger, carver, auth, metrics, TLS, debug all DB-managed. | jmpsec/osctrl