feat: runtime config-drift auditor with baseline, diff, alerting and cert management routes - #240
Merged
JamesEjembi merged 4 commits intoAug 25, 2026
Conversation
…rage and alerting - src/config-drift/types.ts — DriftFinding, DriftReport, ConfigSnapshot, DriftEvent types - src/config-drift/flatten.ts — flattenConfig, computeHashFromFlattened, keyMatchesPrefix - src/config-drift/diff.ts — diffFlattenedConfigs, computeDriftReport, classifyKey - src/config-drift/baseline.ts — BaselineJsonFileSource, ExampleConfigBaselineSource, loadBaselineSnapshot - src/config-drift/storage.ts — DriftStorage in-memory ring buffer + JSONL + PostgreSQL - src/config-drift/pagerduty.ts — HttpPagerDutyClient, buildAlertIfCritical, buildAlertIfWarning - src/config-drift/slack.ts — HttpSlackClient, createSlackClientFromEnv - src/config-drift/remediation.ts — AutoRemediationEngine with built-in safe-drift rules - src/config-drift/auditor.ts — ConfigDriftAuditor, createConfigDriftAuditorFromEnv - src/config-drift/routes.ts — registerConfigDriftRoutes (HTTP dashboard + REST endpoints) - src/config-drift/index.ts — barrel exports - src/database/migrations/013_config_drift_events.sql — config_drift_events table
…miting for drift endpoints - index.js: init ConfigDriftAuditor after config, register drift routes, add shutdown hook - index.js: extend rate-limiter endpointTiers with /config/snapshot, /config/drift-events, /debug/config-drift, /debug/config-drift/history, /debug/config-drift/ui (all 'pro' tier) - token_validator.ts / prometheus.ts: incidental updates from same session
- tests/config/config_drift.test.ts: 14 assertions covering flattenConfig, hash determinism, classifyKey, all four diff categories (value_change, key_added, key_removed, type_change), DriftStorage ring buffer and JSONL persistence, alert routing (PagerDuty / Slack), AutoRemediationEngine evaluate + applyToBaseline, and BaselineJsonFileSource load/save/fallback - scripts/run-tests.cjs: prepend tests/config/config_drift.test.ts to TEST_FILES
…rift dashboard/docs - src/tls/acme_rotation.ts: export registerCertManagementRoutes(app, mgr) that registers GET /api/v1/certs/status and POST /api/v1/certs/renew on a CertLifecycleManager instance (fixes 4 previously failing tls_rotation tests — all 37 now pass) - deploy/monitoring/config-drift-dashboard.json: Grafana dashboard for config drift metrics - deploy/localnet/grafana/dashboards/config-drift-dashboard.json: localnet version - docs/docker-ci-cache.md, docs/operations/github-actions-optimization.md: operational docs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR delivers the runtime config-drift auditing subsystem and resolves two outstanding issues:
persists findings to PostgreSQL, and supports auto-remediation of known-safe drifts.
registerCertManagementRoutesexport — the TLS certificate management API routes were expected by existing tests but the function was never exported fromacme_rotation.ts, causing 4 tests to fail. This is now fixed.Changes
New:
src/config-drift/— Runtime Config-Drift Subsystemtypes.tsDriftFinding,DriftReport,ConfigSnapshot,DriftEvent,CriticalDriftPolicyflatten.tsflattenConfig(deep object → dot-key map),computeHashFromFlattened(SHA-256),keyMatchesPrefixdiff.tsdiffFlattenedConfigs— detects all 4 drift categories;computeDriftReport— builds sorted, summarised report;classifyKey— maps key prefix tocritical / warning / infoseveritybaseline.tsExampleConfigBaselineSource(readsconfig.json.example),BaselineJsonFileSource(readsconfig/*.baseline.json, falls back to example),loadBaselineSnapshot,buildDefaultBaselineSourcesstorage.tsDriftStorage— in-memory ring buffer (default 240 records ≈ 20 h at 5-min interval), optional JSONL on-disk durability, optional PostgreSQL persistence viaconfig_drift_eventstablepagerduty.tsHttpPagerDutyClient,buildAlertIfCritical,buildAlertIfWarning,alertIdForslack.tsHttpSlackClient,createSlackClientFromEnvremediation.tsAutoRemediationEnginewith three built-in safe-drift rules: autoscaled numeric keys, OTel sampling ratio, feature-flag overrides. Critical findings are never auto-remediated.auditor.tsConfigDriftAuditor— 5-minute polling loop,init/start/stop,captureSnapshot,history/latest;createConfigDriftAuditorFromEnvfactoryroutes.tsregisterConfigDriftRoutes— registers 5 HTTP endpoints on the Express appindex.tsHTTP Endpoints Registered
GET/config/snapshotGET/config/drift-eventsGET/debug/config-driftGET/debug/config-drift/historyGET/debug/config-drift/uiAll drift endpoints are gated at the
prorate-limit tier inindex.js.Drift Detection Logic
Four finding categories are detected per snapshot cycle:
value_change— key exists in both baseline and runtime but value differskey_added— key present in runtime but absent from baselinekey_removed— key present in baseline but absent from runtimetype_change— key present in both buttypeofvalue changed (e.g.number → string)Severity is assigned by key prefix:
criticaldb,mtls,tls,auth,stakingwarningcapacity_shedding,performance,telemetryinfoCritical findings always trigger a PagerDuty alert. Warning-only findings (no critical present) trigger a Slack notification. Both are skipped gracefully when the respective client is not configured.
Auto-Remediation
The
AutoRemediationEngineevaluates each finding against built-in safe-drift rules:autoscaled-numeric— numeric values on auto-scaler-managed keys (e.g.staking.maxConcurrentWorkers,capacity_shedding.thresholds.*) are safe to baseline automatically.telemetry-sampling-ratio—telemetry.otel.samplingRatioin[0, 1]is auto-adjusted by the telemetry subsystem.feature-flag-info—feature_flags.*value/key changes atinfoseverity are safe to baseline.Critical-severity findings are always skipped — they require human review.
When a finding is remediated the engine updates the in-memory baseline and annotates the
config_drift_eventsrow withauto_remediated = trueand the rule note.New:
src/database/migrations/013_config_drift_events.sqlCreates the
config_drift_eventstable used for persistent drift storage: