GitHub
08/09/2026, 7:44 PMpkg/serviceconfig with YAML→DB seeding and read-only GET endpoints, but there was no way to modify the persisted configuration sections from the API. Operators had to edit the YAML file and restart the service to change any section.
Changes
pkg/serviceconfig
• UpdateSection(service, name, value, envID) method — validates the section is editable, validates the new value is valid JSON, updates the Value field, and flips Source from yaml to db so subsequent boots won't clobber the change (the Seed create-if-missing semantics already protect DB-edited rows).
• IsEditable(service, section) helper — looks up the Editable flag from the SectionRegistry.
• ErrSectionNotEditable sentinel error for the handler to return a 409 Conflict.
• debug section marked Editable: true for both TLS and API services — a low-risk first editable section (HTTP debug dump settings).
pkg/types
• ServiceConfigUpdateRequest with Value json.RawMessage — the PUT body carries the new section contents as a raw JSON object.
API handler (cmd/api/handlers/service_config.go)
• PUT /api/v1/service-config/{service}/{section} — `ServiceConfigUpdateHandler`:
• Requires AdminLevel + NoEnvironment permissions.
• Validates service and section against the registry.
• Decodes the request body, calls UpdateSection, and returns the updated row.
• 409 Conflict for non-editable sections, 404 for missing sections, 400 for invalid body.
• Audit-logged via AuditLog.SettingsAction.
Route registered in cmd/api/main.go alongside the existing GET routes.
Tests (7 new in pkg/serviceconfig/serviceconfig_test.go)
• TestUpdateSection_Success — updates an editable section, verifies value and source=db.
• TestUpdateSection_NotEditable — rejects a non-editable section with ErrSectionNotEditable.
• TestUpdateSection_InvalidJSON — rejects non-JSON values.
• TestUpdateSection_UnknownService — rejects unknown service.
• TestUpdateSection_SectionNotFound — rejects when section doesn't exist in DB.
• TestIsEditable — verifies the editable flag lookup.
• TestUpdateSection_SeedDoesNotClobber — verifies that re-seeding after an edit preserves the DB value and source.
Validation
• go build ./... — clean
• go test ./... — all packages pass (17 new tests in pkg/serviceconfig)
• golangci-lint run ./pkg/serviceconfig/... — 0 issues
• gofmt clean on all modified files
Security notes
• Connection/secret sections (db, redis) remain editable=false and can never be written through the API.
• The Editable flag is enforced both in the manager (UpdateSection checks IsEditable) and in the handler (returns 409 before reaching the manager).
• All writes are audit-logged via SettingsAction.
jmpsec/osctrlGitHub
08/09/2026, 7:54 PM