proagents 1.6.16 → 1.6.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +169 -0
- package/COMMANDS.md +595 -0
- package/README.md +22 -64
- package/bin/proagents.js +0 -2
- package/lib/commands/init.js +4 -174
- package/package.json +2 -7
- package/.proagents/ai-models/README.md +0 -141
- package/.proagents/ai-models/cost-management.md +0 -362
- package/.proagents/ai-models/fallbacks.md +0 -342
- package/.proagents/ai-models/model-config.md +0 -318
- package/.proagents/ai-models/task-routing.md +0 -503
- package/.proagents/ai-training/README.md +0 -155
- package/.proagents/ai-training/continuous-learning.md +0 -413
- package/.proagents/ai-training/domain-knowledge.md +0 -378
- package/.proagents/ai-training/pattern-learning.md +0 -455
- package/.proagents/ai-training/training-data.md +0 -337
- package/.proagents/ai-training/user-preferences.md +0 -346
- package/.proagents/approval-workflows/README.md +0 -146
- package/.proagents/approval-workflows/approval-config.md +0 -332
- package/.proagents/approval-workflows/approval-stages.md +0 -503
- package/.proagents/approval-workflows/emergency-bypass.md +0 -351
- package/.proagents/approval-workflows/examples.md +0 -859
- package/.proagents/approval-workflows/notifications.md +0 -320
- package/.proagents/compliance/README.md +0 -206
- package/.proagents/compliance/access-control.md +0 -310
- package/.proagents/compliance/audit-logging.md +0 -444
- package/.proagents/compliance/compliance-frameworks.md +0 -429
- package/.proagents/compliance/reports.md +0 -491
- package/.proagents/compliance/retention-policies.md +0 -454
- package/.proagents/config-versioning/README.md +0 -120
- package/.proagents/config-versioning/changelog.md +0 -300
- package/.proagents/config-versioning/rollback.md +0 -283
- package/.proagents/config-versioning/versioning.md +0 -330
- package/.proagents/contract-testing/README.md +0 -223
- package/.proagents/contract-testing/contract-testing.md +0 -614
- package/.proagents/contract-testing/pact-integration.md +0 -507
- package/.proagents/contract-testing/schema-validation.md +0 -565
- package/.proagents/dependency-management/README.md +0 -140
- package/.proagents/dependency-management/automation.md +0 -363
- package/.proagents/dependency-management/compatibility.md +0 -319
- package/.proagents/dependency-management/security-scanning.md +0 -413
- package/.proagents/dependency-management/update-policies.md +0 -374
- package/.proagents/disaster-recovery/README.md +0 -247
- package/.proagents/disaster-recovery/automation.md +0 -366
- package/.proagents/disaster-recovery/backup-recovery.md +0 -571
- package/.proagents/disaster-recovery/incident-response.md +0 -565
- package/.proagents/disaster-recovery/rollback-procedures.md +0 -499
- package/.proagents/disaster-recovery/runbooks.md +0 -603
- package/.proagents/disaster-recovery/scenarios.md +0 -892
- package/.proagents/disaster-recovery/testing.md +0 -438
- package/.proagents/environments/README.md +0 -244
- package/.proagents/environments/configuration.md +0 -437
- package/.proagents/environments/promotion.md +0 -434
- package/.proagents/environments/setup.md +0 -420
- package/.proagents/examples/README.md +0 -55
- package/.proagents/examples/backend-nodejs/README.md +0 -188
- package/.proagents/examples/backend-nodejs/complete-conversation.md +0 -601
- package/.proagents/examples/backend-nodejs/proagents.config.yaml +0 -415
- package/.proagents/examples/backend-nodejs/workflow-example.md +0 -909
- package/.proagents/examples/fullstack-nextjs/README.md +0 -155
- package/.proagents/examples/fullstack-nextjs/complete-conversation.md +0 -604
- package/.proagents/examples/fullstack-nextjs/proagents.config.yaml +0 -287
- package/.proagents/examples/fullstack-nextjs/workflow-example.md +0 -553
- package/.proagents/examples/mobile-react-native/README.md +0 -171
- package/.proagents/examples/mobile-react-native/complete-conversation.md +0 -825
- package/.proagents/examples/mobile-react-native/proagents.config.yaml +0 -330
- package/.proagents/examples/mobile-react-native/workflow-example.md +0 -723
- package/.proagents/examples/web-frontend-react/README.md +0 -125
- package/.proagents/examples/web-frontend-react/complete-conversation.md +0 -556
- package/.proagents/examples/web-frontend-react/proagents.config.yaml +0 -183
- package/.proagents/examples/web-frontend-react/workflow-example.md +0 -603
- package/.proagents/existing-projects/README.md +0 -65
- package/.proagents/existing-projects/challenges.md +0 -861
- package/.proagents/existing-projects/coexistence-mode.md +0 -483
- package/.proagents/existing-projects/compatibility-assessment.md +0 -541
- package/.proagents/existing-projects/gradual-adoption.md +0 -515
- package/.proagents/existing-projects/migration-strategies.md +0 -788
- package/.proagents/existing-projects/pattern-reconciliation.md +0 -489
- package/.proagents/existing-projects/team-onboarding.md +0 -617
- package/.proagents/existing-projects/technical-debt-handling.md +0 -644
- package/.proagents/feature-flags/README.md +0 -263
- package/.proagents/feature-flags/ab-testing.md +0 -413
- package/.proagents/feature-flags/configuration.md +0 -420
- package/.proagents/feature-flags/kill-switches.md +0 -444
- package/.proagents/feature-flags/rollout-strategies.md +0 -392
- package/.proagents/history.log +0 -12
- package/.proagents/i18n/README.md +0 -133
- package/.proagents/i18n/extraction.md +0 -433
- package/.proagents/i18n/tms-integration.md +0 -332
- package/.proagents/i18n/translation-workflow.md +0 -413
- package/.proagents/i18n/validation.md +0 -355
- package/.proagents/logging/README.md +0 -276
- package/.proagents/logging/aggregation.md +0 -475
- package/.proagents/logging/log-levels.md +0 -376
- package/.proagents/logging/sensitive-data.md +0 -423
- package/.proagents/logging/structured-logging.md +0 -406
- package/.proagents/metrics/README.md +0 -69
- package/.proagents/metrics/code-quality-kpis.md +0 -461
- package/.proagents/metrics/deployment-metrics.md +0 -517
- package/.proagents/metrics/developer-productivity.md +0 -368
- package/.proagents/metrics/learning-effectiveness.md +0 -478
- package/.proagents/migrations/README.md +0 -77
- package/.proagents/migrations/from-claude-projects.md +0 -313
- package/.proagents/migrations/from-cursor-rules.md +0 -345
- package/.proagents/migrations/from-custom-workflows.md +0 -410
- package/.proagents/monitoring/README.md +0 -308
- package/.proagents/monitoring/alerting.md +0 -449
- package/.proagents/monitoring/dashboards.md +0 -454
- package/.proagents/monitoring/health-checks.md +0 -436
- package/.proagents/monitoring/metrics.md +0 -434
- package/.proagents/multi-project/README.md +0 -170
- package/.proagents/multi-project/coordinated-deploy.md +0 -510
- package/.proagents/multi-project/cross-project-deps.md +0 -395
- package/.proagents/multi-project/unified-changelog.md +0 -477
- package/.proagents/multi-project/walkthroughs/monorepo-setup.md +0 -787
- package/.proagents/multi-project/workspace-config.md +0 -408
- package/.proagents/notifications/README.md +0 -151
- package/.proagents/notifications/channels.md +0 -457
- package/.proagents/notifications/preferences.md +0 -415
- package/.proagents/notifications/routing.md +0 -449
- package/.proagents/notifications/scheduling.md +0 -425
- package/.proagents/notifications/templates.md +0 -446
- package/.proagents/offline-mode/README.md +0 -145
- package/.proagents/offline-mode/caching.md +0 -344
- package/.proagents/offline-mode/offline-operations.md +0 -312
- package/.proagents/offline-mode/queue-specifications.md +0 -679
- package/.proagents/offline-mode/sync.md +0 -475
- package/.proagents/parallel-features/README.md +0 -85
- package/.proagents/parallel-features/conflict-detection.md +0 -226
- package/.proagents/parallel-features/dependency-management.md +0 -392
- package/.proagents/parallel-features/merge-coordination.md +0 -506
- package/.proagents/parallel-features/tracking-system.md +0 -416
- package/.proagents/performance/README.md +0 -59
- package/.proagents/performance/bundle-analysis.md +0 -375
- package/.proagents/performance/load-testing.md +0 -563
- package/.proagents/performance/runtime-metrics.md +0 -489
- package/.proagents/performance/web-vitals.md +0 -425
- package/.proagents/plugins/README.md +0 -139
- package/.proagents/plugins/creating-plugins.md +0 -504
- package/.proagents/plugins/plugin-api.md +0 -467
- package/.proagents/plugins/plugin-registry.md +0 -276
- package/.proagents/reporting/README.md +0 -158
- package/.proagents/reporting/dashboards.md +0 -366
- package/.proagents/reporting/exports.md +0 -524
- package/.proagents/reporting/quality-metrics.md +0 -385
- package/.proagents/reporting/templates/README.md +0 -56
- package/.proagents/reporting/templates/dashboard-config.json +0 -187
- package/.proagents/reporting/templates/metrics-queries.md +0 -427
- package/.proagents/reporting/templates/react-dashboard.tsx +0 -544
- package/.proagents/reporting/templates/widgets.md +0 -451
- package/.proagents/reporting/velocity-metrics.md +0 -340
- package/.proagents/reverse-engineering/README.md +0 -151
- package/.proagents/reverse-engineering/architecture-extraction.md +0 -325
- package/.proagents/reverse-engineering/code-analysis.md +0 -377
- package/.proagents/reverse-engineering/dependency-mapping.md +0 -567
- package/.proagents/reverse-engineering/diagram-generation.md +0 -586
- package/.proagents/reverse-engineering/documentation-generation.md +0 -468
- package/.proagents/reverse-engineering/pattern-detection.md +0 -569
- package/.proagents/reverse-engineering/quality-assessment.md +0 -733
- package/.proagents/secrets/README.md +0 -278
- package/.proagents/secrets/access-control.md +0 -443
- package/.proagents/secrets/rotation.md +0 -403
- package/.proagents/secrets/scanning.md +0 -487
- package/.proagents/secrets/storage.md +0 -394
- package/.proagents/webhooks/README.md +0 -126
- package/.proagents/webhooks/endpoints.md +0 -298
- package/.proagents/webhooks/events.md +0 -316
- package/.proagents/webhooks/payloads.md +0 -325
- package/.proagents/webhooks/reliability.md +0 -363
- package/.proagents/webhooks/security.md +0 -380
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
# Secret Rotation
|
|
2
|
-
|
|
3
|
-
Automated and manual secret rotation procedures.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Rotation Strategy
|
|
8
|
-
|
|
9
|
-
| Secret Type | Rotation Frequency | Method |
|
|
10
|
-
|-------------|-------------------|--------|
|
|
11
|
-
| API Keys | 90 days | Automated |
|
|
12
|
-
| Database Passwords | 30 days | Automated |
|
|
13
|
-
| JWT Signing Keys | 7 days | Automated (graceful) |
|
|
14
|
-
| Encryption Keys | 365 days | Manual + automated |
|
|
15
|
-
| Service Account Keys | 90 days | Automated |
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Automated Rotation
|
|
20
|
-
|
|
21
|
-
### Configuration
|
|
22
|
-
|
|
23
|
-
```yaml
|
|
24
|
-
# proagents.config.yaml
|
|
25
|
-
secrets:
|
|
26
|
-
rotation:
|
|
27
|
-
enabled: true
|
|
28
|
-
|
|
29
|
-
# Default schedule
|
|
30
|
-
default_schedule: "90d"
|
|
31
|
-
|
|
32
|
-
# Secret-specific schedules
|
|
33
|
-
schedules:
|
|
34
|
-
database_password:
|
|
35
|
-
frequency: "30d"
|
|
36
|
-
method: "automated"
|
|
37
|
-
pre_rotation_hook: "prepare-database"
|
|
38
|
-
post_rotation_hook: "verify-connection"
|
|
39
|
-
|
|
40
|
-
jwt_signing_key:
|
|
41
|
-
frequency: "7d"
|
|
42
|
-
method: "graceful"
|
|
43
|
-
overlap_period: "24h"
|
|
44
|
-
|
|
45
|
-
api_keys:
|
|
46
|
-
frequency: "90d"
|
|
47
|
-
method: "automated"
|
|
48
|
-
notify_before: "7d"
|
|
49
|
-
|
|
50
|
-
# Notifications
|
|
51
|
-
notifications:
|
|
52
|
-
before_rotation:
|
|
53
|
-
channels: ["slack"]
|
|
54
|
-
lead_time: "24h"
|
|
55
|
-
|
|
56
|
-
after_rotation:
|
|
57
|
-
channels: ["slack", "email"]
|
|
58
|
-
|
|
59
|
-
on_failure:
|
|
60
|
-
channels: ["pagerduty", "slack"]
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### AWS Secrets Manager Rotation
|
|
64
|
-
|
|
65
|
-
```yaml
|
|
66
|
-
secrets:
|
|
67
|
-
rotation:
|
|
68
|
-
aws:
|
|
69
|
-
# Lambda rotation function
|
|
70
|
-
lambda:
|
|
71
|
-
function_name: "secret-rotation-function"
|
|
72
|
-
runtime: "nodejs18.x"
|
|
73
|
-
|
|
74
|
-
# Rotation configuration
|
|
75
|
-
config:
|
|
76
|
-
database_secrets:
|
|
77
|
-
rotation_lambda_arn: "arn:aws:lambda:us-east-1:123456789:function:rotate-db"
|
|
78
|
-
automatically_after_days: 30
|
|
79
|
-
|
|
80
|
-
api_keys:
|
|
81
|
-
rotation_lambda_arn: "arn:aws:lambda:us-east-1:123456789:function:rotate-api"
|
|
82
|
-
automatically_after_days: 90
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Vault Dynamic Secrets
|
|
86
|
-
|
|
87
|
-
```yaml
|
|
88
|
-
secrets:
|
|
89
|
-
rotation:
|
|
90
|
-
vault:
|
|
91
|
-
# Database dynamic credentials
|
|
92
|
-
database:
|
|
93
|
-
enabled: true
|
|
94
|
-
mount: "database"
|
|
95
|
-
role: "myapp"
|
|
96
|
-
ttl: "1h"
|
|
97
|
-
max_ttl: "24h"
|
|
98
|
-
|
|
99
|
-
# Automatic renewal
|
|
100
|
-
renewal:
|
|
101
|
-
enabled: true
|
|
102
|
-
threshold: "15m" # Renew when 15 min left
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## Graceful Key Rotation
|
|
108
|
-
|
|
109
|
-
### JWT Key Rotation
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
// rotation/jwtKeys.ts
|
|
113
|
-
interface KeyPair {
|
|
114
|
-
id: string;
|
|
115
|
-
privateKey: string;
|
|
116
|
-
publicKey: string;
|
|
117
|
-
createdAt: Date;
|
|
118
|
-
expiresAt: Date;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
class JWTKeyManager {
|
|
122
|
-
private keys: KeyPair[] = [];
|
|
123
|
-
|
|
124
|
-
async rotate(): Promise<void> {
|
|
125
|
-
// Generate new key pair
|
|
126
|
-
const newKey = await this.generateKeyPair();
|
|
127
|
-
|
|
128
|
-
// Add to active keys
|
|
129
|
-
this.keys.push(newKey);
|
|
130
|
-
|
|
131
|
-
// Update secrets store
|
|
132
|
-
await this.storeKeys();
|
|
133
|
-
|
|
134
|
-
// Schedule old key removal
|
|
135
|
-
const oldKey = this.keys[0];
|
|
136
|
-
if (oldKey && this.keys.length > 2) {
|
|
137
|
-
await this.scheduleKeyRemoval(oldKey.id, '24h');
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Sign with newest key
|
|
142
|
-
sign(payload: object): string {
|
|
143
|
-
const currentKey = this.keys[this.keys.length - 1];
|
|
144
|
-
return jwt.sign(payload, currentKey.privateKey, {
|
|
145
|
-
algorithm: 'RS256',
|
|
146
|
-
keyid: currentKey.id,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Verify with any valid key
|
|
151
|
-
verify(token: string): object {
|
|
152
|
-
const decoded = jwt.decode(token, { complete: true });
|
|
153
|
-
const key = this.keys.find(k => k.id === decoded.header.kid);
|
|
154
|
-
|
|
155
|
-
if (!key) {
|
|
156
|
-
throw new Error('Invalid key ID');
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return jwt.verify(token, key.publicKey);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### Encryption Key Rotation
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
// rotation/encryptionKeys.ts
|
|
168
|
-
interface EncryptionKey {
|
|
169
|
-
id: string;
|
|
170
|
-
key: Buffer;
|
|
171
|
-
version: number;
|
|
172
|
-
status: 'active' | 'decrypt-only' | 'disabled';
|
|
173
|
-
createdAt: Date;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
class EncryptionKeyManager {
|
|
177
|
-
private keys: Map<string, EncryptionKey> = new Map();
|
|
178
|
-
private activeKeyId: string;
|
|
179
|
-
|
|
180
|
-
async rotate(): Promise<void> {
|
|
181
|
-
// Mark current key as decrypt-only
|
|
182
|
-
const currentKey = this.keys.get(this.activeKeyId);
|
|
183
|
-
if (currentKey) {
|
|
184
|
-
currentKey.status = 'decrypt-only';
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Generate new key
|
|
188
|
-
const newKey: EncryptionKey = {
|
|
189
|
-
id: crypto.randomUUID(),
|
|
190
|
-
key: crypto.randomBytes(32),
|
|
191
|
-
version: (currentKey?.version || 0) + 1,
|
|
192
|
-
status: 'active',
|
|
193
|
-
createdAt: new Date(),
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
this.keys.set(newKey.id, newKey);
|
|
197
|
-
this.activeKeyId = newKey.id;
|
|
198
|
-
|
|
199
|
-
// Store in secrets manager
|
|
200
|
-
await this.persistKeys();
|
|
201
|
-
|
|
202
|
-
logger.info('Encryption key rotated', {
|
|
203
|
-
newKeyId: newKey.id,
|
|
204
|
-
version: newKey.version,
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
encrypt(data: Buffer): { keyId: string; ciphertext: Buffer } {
|
|
209
|
-
const key = this.keys.get(this.activeKeyId)!;
|
|
210
|
-
const iv = crypto.randomBytes(16);
|
|
211
|
-
const cipher = crypto.createCipheriv('aes-256-gcm', key.key, iv);
|
|
212
|
-
const ciphertext = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
213
|
-
const authTag = cipher.getAuthTag();
|
|
214
|
-
|
|
215
|
-
return {
|
|
216
|
-
keyId: key.id,
|
|
217
|
-
ciphertext: Buffer.concat([iv, authTag, ciphertext]),
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
decrypt(keyId: string, ciphertext: Buffer): Buffer {
|
|
222
|
-
const key = this.keys.get(keyId);
|
|
223
|
-
if (!key || key.status === 'disabled') {
|
|
224
|
-
throw new Error('Invalid or disabled key');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const iv = ciphertext.slice(0, 16);
|
|
228
|
-
const authTag = ciphertext.slice(16, 32);
|
|
229
|
-
const encrypted = ciphertext.slice(32);
|
|
230
|
-
|
|
231
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', key.key, iv);
|
|
232
|
-
decipher.setAuthTag(authTag);
|
|
233
|
-
|
|
234
|
-
return Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## Database Password Rotation
|
|
242
|
-
|
|
243
|
-
### Rotation Procedure
|
|
244
|
-
|
|
245
|
-
```yaml
|
|
246
|
-
secrets:
|
|
247
|
-
rotation:
|
|
248
|
-
database:
|
|
249
|
-
procedure:
|
|
250
|
-
steps:
|
|
251
|
-
- name: "Create new credentials"
|
|
252
|
-
action: |
|
|
253
|
-
CREATE USER 'myapp_new' IDENTIFIED BY '{{new_password}}';
|
|
254
|
-
GRANT ALL ON mydb.* TO 'myapp_new';
|
|
255
|
-
|
|
256
|
-
- name: "Update application"
|
|
257
|
-
action: "update_secret"
|
|
258
|
-
target: "DATABASE_URL"
|
|
259
|
-
value: "postgresql://myapp_new:{{new_password}}@host/db"
|
|
260
|
-
|
|
261
|
-
- name: "Verify connectivity"
|
|
262
|
-
action: "health_check"
|
|
263
|
-
timeout: "30s"
|
|
264
|
-
retries: 3
|
|
265
|
-
|
|
266
|
-
- name: "Remove old credentials"
|
|
267
|
-
action: |
|
|
268
|
-
DROP USER 'myapp_old';
|
|
269
|
-
delay: "5m"
|
|
270
|
-
|
|
271
|
-
rollback:
|
|
272
|
-
- name: "Restore old credentials"
|
|
273
|
-
action: "revert_secret"
|
|
274
|
-
target: "DATABASE_URL"
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### Implementation
|
|
278
|
-
|
|
279
|
-
```typescript
|
|
280
|
-
// rotation/database.ts
|
|
281
|
-
async function rotateDatabasePassword(
|
|
282
|
-
secretName: string
|
|
283
|
-
): Promise<void> {
|
|
284
|
-
// Generate new password
|
|
285
|
-
const newPassword = generateSecurePassword();
|
|
286
|
-
|
|
287
|
-
// Create new database user
|
|
288
|
-
await db.query(`
|
|
289
|
-
CREATE USER 'app_new' IDENTIFIED BY '${newPassword}';
|
|
290
|
-
GRANT ALL PRIVILEGES ON mydb.* TO 'app_new';
|
|
291
|
-
FLUSH PRIVILEGES;
|
|
292
|
-
`);
|
|
293
|
-
|
|
294
|
-
// Update secret in secrets manager
|
|
295
|
-
await secretsManager.update(secretName, {
|
|
296
|
-
username: 'app_new',
|
|
297
|
-
password: newPassword,
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
// Wait for applications to pick up new credentials
|
|
301
|
-
await sleep(60000);
|
|
302
|
-
|
|
303
|
-
// Verify new credentials work
|
|
304
|
-
const testConnection = await testDatabaseConnection(newPassword);
|
|
305
|
-
if (!testConnection.success) {
|
|
306
|
-
throw new Error('New credentials failed verification');
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Remove old user
|
|
310
|
-
await db.query(`DROP USER IF EXISTS 'app_old'`);
|
|
311
|
-
|
|
312
|
-
logger.info('Database password rotated successfully');
|
|
313
|
-
}
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## Rotation Monitoring
|
|
319
|
-
|
|
320
|
-
### Metrics
|
|
321
|
-
|
|
322
|
-
```yaml
|
|
323
|
-
secrets:
|
|
324
|
-
rotation:
|
|
325
|
-
monitoring:
|
|
326
|
-
metrics:
|
|
327
|
-
- name: "secret_rotation_age_days"
|
|
328
|
-
type: "gauge"
|
|
329
|
-
labels: ["secret_name", "secret_type"]
|
|
330
|
-
|
|
331
|
-
- name: "secret_rotation_total"
|
|
332
|
-
type: "counter"
|
|
333
|
-
labels: ["secret_name", "status"]
|
|
334
|
-
|
|
335
|
-
- name: "secret_rotation_duration_seconds"
|
|
336
|
-
type: "histogram"
|
|
337
|
-
|
|
338
|
-
alerts:
|
|
339
|
-
- name: "SecretRotationOverdue"
|
|
340
|
-
condition: "secret_rotation_age_days > secret_max_age_days"
|
|
341
|
-
severity: "warning"
|
|
342
|
-
|
|
343
|
-
- name: "SecretRotationFailed"
|
|
344
|
-
condition: "secret_rotation_total{status='failed'} > 0"
|
|
345
|
-
severity: "critical"
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### Audit Logging
|
|
349
|
-
|
|
350
|
-
```yaml
|
|
351
|
-
secrets:
|
|
352
|
-
rotation:
|
|
353
|
-
audit:
|
|
354
|
-
enabled: true
|
|
355
|
-
|
|
356
|
-
log_events:
|
|
357
|
-
- "rotation_started"
|
|
358
|
-
- "rotation_completed"
|
|
359
|
-
- "rotation_failed"
|
|
360
|
-
- "secret_accessed"
|
|
361
|
-
|
|
362
|
-
retention: "2 years"
|
|
363
|
-
|
|
364
|
-
destinations:
|
|
365
|
-
- type: "cloudwatch"
|
|
366
|
-
log_group: "/security/secret-rotation"
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
---
|
|
370
|
-
|
|
371
|
-
## Commands
|
|
372
|
-
|
|
373
|
-
```bash
|
|
374
|
-
# Rotate specific secret
|
|
375
|
-
proagents secrets rotate DATABASE_PASSWORD
|
|
376
|
-
|
|
377
|
-
# Rotate all secrets due for rotation
|
|
378
|
-
proagents secrets rotate --all-due
|
|
379
|
-
|
|
380
|
-
# Check rotation status
|
|
381
|
-
proagents secrets rotation-status
|
|
382
|
-
|
|
383
|
-
# View rotation history
|
|
384
|
-
proagents secrets rotation-history --secret API_KEY
|
|
385
|
-
|
|
386
|
-
# Schedule rotation
|
|
387
|
-
proagents secrets schedule-rotation JWT_SECRET --in 7d
|
|
388
|
-
|
|
389
|
-
# Test rotation procedure
|
|
390
|
-
proagents secrets test-rotation DATABASE_PASSWORD --dry-run
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
## Best Practices
|
|
396
|
-
|
|
397
|
-
1. **Automate Everything**: Manual rotation is error-prone
|
|
398
|
-
2. **Graceful Rotation**: Overlap validity periods for zero downtime
|
|
399
|
-
3. **Test Procedures**: Regularly test rotation in staging
|
|
400
|
-
4. **Monitor Age**: Alert on secrets approaching rotation date
|
|
401
|
-
5. **Audit Trail**: Log all rotation events
|
|
402
|
-
6. **Rollback Plan**: Have a plan if rotation fails
|
|
403
|
-
7. **Verify After**: Always verify new credentials work
|