PR: feat(config-service): add centralized configuration management service
This PR adds a new, standalone NestJS microservice at microservices/config-service that centralizes runtime configuration, environment-scoped settings, feature flags, and encrypted secret management for the platform.
- Typed key/value configurations with environment scoping and versioning
- Encrypted secret storage and rotation (AES-256-CBC)
- In-memory config caching with TTL and invalidation on update
- Real-time update propagation via webhook subscriptions (HMAC-SHA256 signed)
- Comprehensive audit logging for create/update/delete/rotate events
- Docker +
docker-composedev setup and TypeORM integration
Centralized configuration simplifies operations, reduces environment drift, enables runtime toggles and feature flags, standardizes secret encryption and rotation, and gives a single audit trail for config changes.
All changes live under microservices/config-service (new folder). Highlights:
microservices/config-service/package.json(scripts, deps)microservices/config-service/Dockerfileand.dockerignoremicroservices/config-service/docker-compose.yml(service + Postgres)microservices/config-service/.env.examplemicroservices/config-service/src/config/orm-config.tsmicroservices/config-service/src/entities/*(Config, Environment, Secret, AuditLog, WebhookSubscription)microservices/config-service/src/modules/*(configuration, secret, environment, audit, webhook)microservices/config-service/src/common/*(encryption, validation, DTOs)microservices/config-service/src/scripts/seed-environments.ts(seed script)microservices/config-service/README.mdand docs- Tests:
microservices/config-service/test/*
- Development: TypeORM
synchronizeis enabled whenNODE_ENV !== 'production'for convenience. - Production: generate migrations and run them as part of deployment pipeline. DO NOT rely on
synchronizein production.
- Quick start using Docker (recommended):
cd microservices/config-service
docker-compose up -d
# Service will be available at http://localhost:3020- Run locally against a Postgres instance:
cd microservices/config-service
npm install
cp .env.example .env
# Edit .env: set ENCRYPTION_KEY (secure), DB_HOST, DB_USER, DB_PASSWORD
npm run seed:environments
npm run start:devGET /health— health checkGET /api— Swagger UIPOST /environments— create environmentGET /environments— list environmentsPOST /configurations— create config (key/value)GET /configurations/key/:key— get config by keyPOST /configurations/:id/increment-version— bump versionPOST /secrets— create secret (stored encrypted)GET /secrets/:id/value— get decrypted secret value (requires auth in prod)POST /webhooks— create webhook subscriptionPOST /webhooks/:id/trigger— trigger webhook (for testing)GET /audit-logs— view recent audit logs
- Secrets are encrypted using AES-256-CBC. The
ENCRYPTION_KEYenv var must be populated in production from a secure store (Vault/KMS). - Webhook payloads are signed with HMAC-SHA256. Consumers MUST verify
X-Webhook-Signature(orX-Webhook-Signatureheader). - Audit endpoints should be protected in production (RBAC / internal network only).
This change is additive: it introduces a new service and does not modify existing services. Consumer services must opt-in to use the config service by fetching configuration on startup and/or subscribing to webhooks.
- Health check:
curl http://localhost:3020/health- Create environments (seed script also available):
curl -X POST http://localhost:3020/environments \
-H "Content-Type: application/json" \
-d '{"name":"development","displayName":"Development"}'- Create a configuration and retrieve it:
curl -X POST http://localhost:3020/configurations \
-H "Content-Type: application/json" \
-d '{"key":"FEATURE_X_ENABLED","value":"true","type":"boolean","description":"Toggle for feature X"}'
curl http://localhost:3020/configurations/key/FEATURE_X_ENABLED- Create and read a secret (decrypted):
curl -X POST http://localhost:3020/secrets \
-H "Content-Type: application/json" \
-d '{"name":"DB_PASSWORD","value":"s3cr3t"}'
# then
curl http://localhost:3020/secrets/<secret-id>/value- Subscribe a webhook and trigger an event (consumer must validate signature):
curl -X POST http://localhost:3020/webhooks \
-H "Content-Type: application/json" \
-d '{"serviceName":"payment-service","webhookUrl":"http://payment-service:3019/webhooks/config-update","events":["CONFIG_UPDATED"],"secret":"payment-secret"}'
# Trigger update
curl -X POST http://localhost:3020/webhooks/<id>/trigger -d '{"event":"CONFIG_UPDATED","data":{}}'- Unit tests:
npm test - E2E tests:
npm run test:e2e - Include CI jobs to run both unit and E2E tests (E2E should provision Postgres or use Docker Compose)
src/scripts/seed-environments.tsseedsdevelopment,staging, andproduction.- Before production deploy: run
npm run migration:generate(or create a migration by hand) and apply withnpm run migration:run.
- Deploy
config-serviceto staging with secure environment variables (setENCRYPTION_KEYvia vault/KMS). - Run DB migrations against staging DB.
- Run
npm run seed:environmentson staging to create base environments. - Update a single consumer service to fetch config on startup and optionally subscribe to webhooks; deploy and verify behavior.
- Monitor audit logs and webhook delivery. If stable, onboard additional services in waves.
- Disable webhook subscriptions for consumers and revert them to local environment variables.
- Revert
config-servicedeployment to previous image. - If DB schema or data is damaged, restore DB from pre-deploy backup.
- Build passes:
npm run buildinmicroservices/config-service - Unit tests:
npm test - E2E tests:
npm run test:e2e - Docker compose starts without errors
- Seed script creates environments:
npm run seed:environments - Configs and secrets can be created and retrieved via API
- Webhook delivery and signature verification verified by a consumer service
- Audit logs contain expected events
- Reviewers: backend/platform, security, devops
- Labels:
feature,service,infra
- In-memory cache is not clustered; for multi-instance deployments use Redis.
ENCRYPTION_KEYcurrently comes from env — consider KMS integration.synchronizeMUST be disabled for production; use explicit migrations.
- Add a production migration and include it in the deployment pipeline.
- Add Redis-backed cache and update invalidation strategy for multi-instance clusters.
- Integrate
ENCRYPTION_KEYwith a managed KMS and remove raw key usage in env for production.
PR body created at PR_CONFIG_SERVICE.md — review and let me know if you want this formatted differently for GitHub or shortened for a release note.