Skip to content

Commit 5d7c82b

Browse files
committed
feat(config-service): add centralized configuration management service
1 parent ebe326f commit 5d7c82b

3 files changed

Lines changed: 176 additions & 0 deletions

File tree

PR_CONFIG_SERVICE.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
PR: Centralized Configuration Management Service (microservices/config-service)
2+
3+
Summary
4+
-------
5+
Adds a new standalone NestJS microservice, `config-service`, providing centralized configuration, environment management, encrypted secrets, webhook-based real-time updates, caching, versioning, and audit logging for the monorepo.
6+
7+
Why
8+
---
9+
Centralize management of environment variables, feature flags, and secrets to simplify configuration drift, enable runtime updates, centralize audit trails, and standardize secret rotation across services.
10+
11+
Scope / Files Changed
12+
---------------------
13+
New service added at: `microservices/config-service`
14+
Key files and folders (high-level):
15+
- `microservices/config-service/package.json`
16+
- `microservices/config-service/Dockerfile`
17+
- `microservices/config-service/docker-compose.yml`
18+
- `microservices/config-service/.env.example`
19+
- `microservices/config-service/src/app.module.ts`
20+
- `microservices/config-service/src/main.ts`
21+
- `microservices/config-service/src/entities/*` (Config, Environment, Secret, AuditLog, WebhookSubscription)
22+
- `microservices/config-service/src/modules/*` (configuration, secret, environment, audit, webhook modules)
23+
- `microservices/config-service/src/common/*` (encryption, validation, DTOs)
24+
- `microservices/config-service/README.md` and related docs
25+
- Tests: `microservices/config-service/test/*`
26+
27+
Implementation Details
28+
----------------------
29+
- Database: PostgreSQL via TypeORM (entities + orm-config)
30+
- Secrets: AES-256-CBC encryption with IV; encrypted values stored in DB, rotation support
31+
- Configs: key/value store, typed (string|number|boolean|json), environment-scoped, versioned
32+
- Caching: in-memory cache (CacheManager) with configurable TTL and invalidation on updates
33+
- Webhooks: subscription model, HMAC-SHA256 signing, retry logic with backoff
34+
- Audit log: stores CREATE/UPDATE/DELETE/ROTATE events with metadata
35+
- API docs: Swagger available at `/api`
36+
- Docker: Dockerfile and docker-compose (includes PostgreSQL) for local/dev runs
37+
38+
Database Migrations
39+
-------------------
40+
- Entities are set to `synchronize` when `NODE_ENV !== 'production'`.
41+
- For production, run migrations generated from entities.
42+
43+
Commands
44+
--------
45+
Install and run locally:
46+
```bash
47+
cd microservices/config-service
48+
npm install
49+
cp .env.example .env
50+
# Edit .env => set ENCRYPTION_KEY and DB credentials
51+
npm run migration:run # if using migrations
52+
npm run start:dev
53+
```
54+
55+
Docker (recommended for quick local setup):
56+
```bash
57+
cd microservices/config-service
58+
docker-compose up -d
59+
# Access: http://localhost:3020
60+
```
61+
62+
Testing
63+
-------
64+
- Unit tests: `npm test`
65+
- E2E tests: `npm run test:e2e`
66+
- Basic unit and e2e tests are included; CI should run these on PR.
67+
68+
Rollout & Migration Plan
69+
------------------------
70+
1. Deploy `config-service` to staging with production-like env vars (ensure `ENCRYPTION_KEY` is set and secure).
71+
2. Run DB migrations against staging database.
72+
3. Create initial environments (`development`, `staging`, `production`) via API or seed script.
73+
4. Add initial configurations and secrets required by services.
74+
5. For each dependent service:
75+
- Add `CONFIG_SERVICE_URL` and `WEBHOOK_URL` env vars.
76+
- Add startup logic to fetch required configs on boot (examples provided in `CONFIG_SERVICE_INTEGRATION.md`).
77+
- Optionally subscribe service webhook endpoints to `config-service` for real-time updates.
78+
6. Deploy one consumer service to staging and verify config fetch and webhook behavior.
79+
7. Monitor audit logs and webhook deliveries.
80+
81+
Rollback Plan
82+
-------------
83+
- If `config-service` causes issues, remove or disable webhook subscriptions from consumer services and revert consumer service config to local environment-based values.
84+
- Restore DB from backup prior to deploy if schema or data corruption occurs.
85+
- Redeploy previous version of `config-service` image.
86+
87+
Secrets & Rotation
88+
------------------
89+
- Secrets stored encrypted (DB: `encryptedValue`, `iv`).
90+
- Rotation API available: `POST /secrets/:id/rotate`.
91+
- Rotation detection task exists (check endpoints `GET /secrets/rotation/check`).
92+
- Ensure `ENCRYPTION_KEY` is stored securely in production (vault, KMS).
93+
94+
Security Considerations
95+
-----------------------
96+
- Do not commit `.env` or secret values.
97+
- Use a secure `ENCRYPTION_KEY` (32+ chars) in production and rotate as needed.
98+
- Webhook requests signed with HMAC-SHA256; consumers must verify signatures.
99+
- Audit logs store changes; restrict access to audit endpoints.
100+
101+
Testing & Verification Checklist (for reviewer)
102+
-----------------------------------------------
103+
- [ ] Service builds successfully: `npm run build`
104+
- [ ] Unit tests pass: `npm test`
105+
- [ ] E2E tests pass: `npm run test:e2e`
106+
- [ ] Docker compose starts services and PostgreSQL
107+
- [ ] Can create environment, config, and secret via API
108+
- [ ] Secrets are stored encrypted (DB) and `GET /secrets/:id/value` returns decrypted value
109+
- [ ] Webhook delivery works and signature verification can be validated by consumer
110+
- [ ] Audit logs contain CREATE/UPDATE/DELETE events
111+
- [ ] Config caching is invalidated on update
112+
- [ ] Version increment endpoint works (`POST /configurations/:id/increment-version`)
113+
114+
Notes / Known Limitations
115+
-------------------------
116+
- `synchronize` is enabled in non-production by default; production should use migrations.
117+
- Secret encryption uses a symmetric key from env; for stronger security consider integration with KMS (AWS KMS, HashiCorp Vault).
118+
- Scaling: current cache is in-memory; for multi-instance deployments use Redis-backed caching for shared cache invalidation.
119+
120+
Suggested Reviewers
121+
-------------------
122+
- Backend/Platform: @backend-team
123+
- Security: @security-team
124+
- DevOps: @devops-team
125+
126+
Labels
127+
------
128+
- feature
129+
- service
130+
- infra
131+
132+
Release Notes
133+
-------------
134+
Adds a new centralized configuration management service for the platform providing environment-scoped configs, encrypted secrets with rotation, webhooks for real-time updates, in-memory caching, audit logs, and Docker deployment.
135+
136+
Next Steps
137+
----------
138+
- Consider adding a DB migration and seed script for initial environments.
139+
- Optionally integrate with a KMS for encryption key management.
140+
141+
File: `PR_CONFIG_SERVICE.md` created at repo root. Review and let me know if you want this copied to a GitHub PULL_REQUEST_TEMPLATE or a different format/branch ready for a PR.

microservices/config-service/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"migration:generate": "typeorm migration:generate -d src/config/orm-config.ts",
2626
"migration:revert": "typeorm migration:revert -d src/config/orm-config.ts",
2727
"migration:create": "typeorm migration:create"
28+
,"seed:environments": "ts-node src/scripts/seed-environments.ts"
2829
},
2930
"dependencies": {
3031
"@nestjs/axios": "^4.0.1",
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { AppDataSource } from '../config/orm-config';
2+
import { Environment } from '../entities';
3+
4+
async function seed() {
5+
try {
6+
await AppDataSource.initialize();
7+
const repo = AppDataSource.getRepository(Environment);
8+
9+
const envs = [
10+
{ name: 'development', displayName: 'Development', description: 'Development environment' },
11+
{ name: 'staging', displayName: 'Staging', description: 'Staging environment' },
12+
{ name: 'production', displayName: 'Production', description: 'Production environment' },
13+
];
14+
15+
for (const e of envs) {
16+
const existing = await repo.findOne({ where: { name: e.name } });
17+
if (!existing) {
18+
const env = repo.create(e as Partial<Environment>);
19+
await repo.save(env);
20+
console.log(`Created environment: ${e.name}`);
21+
} else {
22+
console.log(`Environment already exists: ${e.name}`);
23+
}
24+
}
25+
26+
await AppDataSource.destroy();
27+
process.exit(0);
28+
} catch (err) {
29+
console.error('Seeding failed:', err);
30+
process.exit(1);
31+
}
32+
}
33+
34+
seed();

0 commit comments

Comments
 (0)