GitHub
08/15/2026, 9:18 PMservice.serviceConfigEnabled — a per-deployment switch that decides whether the service configuration is manageable from osctrl-api and the SPA. It does not change how configuration is loaded.
Loading model (unchanged, and unaffected by the switch)
YAML remains the source of truth on disk. Every boot, both services:
1. read their YAML file,
2. seed the sections into the service_config table (create-if-missing),
3. resolve the stored rows back over the YAML values.
Services therefore always run on the DB rows. That means the rows can be edited directly — from a hypervisor/infra perspective, or any DB client — and are picked up on the next restart, with no YAML edit needed.
What the switch changes
| serviceConfigEnabled: false (default) | serviceConfigEnabled: true | |
| ----------------------------------------- | -------------------------- | -------------------- |
| YAML → service_config seeding | yes | yes |
| Startup resolve from DB rows | yes | yes |
| /api/v1/service-config/* routes | not registered (404) | registered |
| GET /api/v1/features | service_config: false | service_config: true |
| SPA "Service Config" nav entry | hidden | shown |
| Editing / Write to Disk / Apply & Restart | unavailable | available |
Deep-linking to /config/api with the feature off renders an empty state explaining that values live in the service_config table and how to turn the API on — and issues no requests to the missing endpoints.
Consumed by osctrl-api only. The key is present in tls.yml so the service section still round-trips through the API unchanged; osctrl-tls seeds and resolves either way.
Configuration
service:
serviceConfigEnabled: false
Also settable as --service-config-enabled or SERVICE_CONFIG_ENABLED=true. Enabled in docker-compose-dev.yml for both services so local dev keeps the UI.
Changes
• pkg/config/types.go, pkg/config/flags.go — new Service.ServiceConfigEnabled field, CLI flag and env var (default false).
• cmd/api/main.go — seeding/resolving/file-status reporting stay unconditional; the whole /api/v1/service-config route block (reads, section update, apply, persist, and its rate limiter) is registered only when enabled. Logs a line at boot when off.
• cmd/api/handlers/{handlers,features}.go — WithServiceConfigEnabled option; /api/v1/features advertises service_config.
• frontend/ — `Features.service_config`; SideNav hides the entry; ServiceConfigPage shows the disabled state and skips its queries and the impact-warning modal when off.
• deploy/config/{api,tls}.yml — annotated sample values.
Testing
• go build ./..., go test ./... — pass. New: flag defaults-off test, features-response test.
• Frontend: 229 tests pass, tsc clean. New: disabled-state test asserting the page requests nothing.
jmpsec/osctrlGitHub
08/15/2026, 9:55 PM