@patricio0312rev/skillset 0.1.0
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/CHANGELOG.md +29 -0
- package/LICENSE +21 -0
- package/README.md +176 -0
- package/bin/cli.js +37 -0
- package/package.json +55 -0
- package/src/commands/init.js +301 -0
- package/src/index.js +168 -0
- package/src/lib/config.js +200 -0
- package/src/lib/generator.js +166 -0
- package/src/utils/display.js +95 -0
- package/src/utils/readme.js +196 -0
- package/src/utils/tool-specific.js +233 -0
- package/templates/ai-engineering/agent-orchestration-planner/ SKILL.md +266 -0
- package/templates/ai-engineering/cost-latency-optimizer/ SKILL.md +270 -0
- package/templates/ai-engineering/doc-to-vector-dataset-generator/ SKILL.md +239 -0
- package/templates/ai-engineering/evaluation-harness/ SKILL.md +219 -0
- package/templates/ai-engineering/guardrails-safety-filter-builder/ SKILL.md +226 -0
- package/templates/ai-engineering/llm-debugger/ SKILL.md +283 -0
- package/templates/ai-engineering/prompt-regression-tester/ SKILL.md +216 -0
- package/templates/ai-engineering/prompt-template-builder/ SKILL.md +393 -0
- package/templates/ai-engineering/rag-pipeline-builder/ SKILL.md +244 -0
- package/templates/ai-engineering/tool-function-schema-designer/ SKILL.md +219 -0
- package/templates/architecture/adr-writer/ SKILL.md +250 -0
- package/templates/architecture/api-versioning-deprecation-planner/ SKILL.md +331 -0
- package/templates/architecture/domain-model-boundaries-mapper/ SKILL.md +300 -0
- package/templates/architecture/migration-planner/ SKILL.md +376 -0
- package/templates/architecture/performance-budget-setter/ SKILL.md +318 -0
- package/templates/architecture/reliability-strategy-builder/ SKILL.md +286 -0
- package/templates/architecture/rfc-generator/ SKILL.md +362 -0
- package/templates/architecture/scalability-playbook/ SKILL.md +279 -0
- package/templates/architecture/system-design-generator/ SKILL.md +339 -0
- package/templates/architecture/tech-debt-prioritizer/ SKILL.md +329 -0
- package/templates/backend/api-contract-normalizer/ SKILL.md +487 -0
- package/templates/backend/api-endpoint-generator/ SKILL.md +415 -0
- package/templates/backend/auth-module-builder/ SKILL.md +99 -0
- package/templates/backend/background-jobs-designer/ SKILL.md +166 -0
- package/templates/backend/caching-strategist/ SKILL.md +190 -0
- package/templates/backend/error-handling-standardizer/ SKILL.md +174 -0
- package/templates/backend/rate-limiting-abuse-protection/ SKILL.md +147 -0
- package/templates/backend/rbac-permissions-builder/ SKILL.md +158 -0
- package/templates/backend/service-layer-extractor/ SKILL.md +269 -0
- package/templates/backend/webhook-receiver-hardener/ SKILL.md +211 -0
- package/templates/ci-cd/artifact-sbom-publisher/ SKILL.md +236 -0
- package/templates/ci-cd/caching-strategy-optimizer/ SKILL.md +195 -0
- package/templates/ci-cd/deployment-checklist-generator/ SKILL.md +381 -0
- package/templates/ci-cd/github-actions-pipeline-creator/ SKILL.md +348 -0
- package/templates/ci-cd/monorepo-ci-optimizer/ SKILL.md +298 -0
- package/templates/ci-cd/preview-environments-builder/ SKILL.md +187 -0
- package/templates/ci-cd/quality-gates-enforcer/ SKILL.md +342 -0
- package/templates/ci-cd/release-automation-builder/ SKILL.md +281 -0
- package/templates/ci-cd/rollback-workflow-builder/ SKILL.md +372 -0
- package/templates/ci-cd/secrets-env-manager/ SKILL.md +242 -0
- package/templates/db-management/backup-restore-runbook-generator/ SKILL.md +505 -0
- package/templates/db-management/data-integrity-auditor/ SKILL.md +505 -0
- package/templates/db-management/data-retention-archiving-planner/ SKILL.md +430 -0
- package/templates/db-management/data-seeding-fixtures-builder/ SKILL.md +375 -0
- package/templates/db-management/db-performance-watchlist/ SKILL.md +425 -0
- package/templates/db-management/etl-sync-job-builder/ SKILL.md +457 -0
- package/templates/db-management/multi-tenant-safety-checker/ SKILL.md +398 -0
- package/templates/db-management/prisma-migration-assistant/ SKILL.md +379 -0
- package/templates/db-management/schema-consistency-checker/ SKILL.md +440 -0
- package/templates/db-management/sql-query-optimizer/ SKILL.md +324 -0
- package/templates/foundation/changelog-writer/ SKILL.md +431 -0
- package/templates/foundation/code-formatter-installer/ SKILL.md +320 -0
- package/templates/foundation/codebase-summarizer/ SKILL.md +360 -0
- package/templates/foundation/dependency-doctor/ SKILL.md +163 -0
- package/templates/foundation/dev-environment-bootstrapper/ SKILL.md +259 -0
- package/templates/foundation/dev-onboarding-builder/ SKILL.md +556 -0
- package/templates/foundation/docs-starter-kit/ SKILL.md +574 -0
- package/templates/foundation/explaining-code/SKILL.md +13 -0
- package/templates/foundation/git-hygiene-enforcer/ SKILL.md +455 -0
- package/templates/foundation/project-scaffolder/ SKILL.md +65 -0
- package/templates/foundation/project-scaffolder/references/templates.md +126 -0
- package/templates/foundation/repo-structure-linter/ SKILL.md +0 -0
- package/templates/foundation/repo-structure-linter/references/conventions.md +98 -0
- package/templates/frontend/animation-micro-interaction-pack/ SKILL.md +41 -0
- package/templates/frontend/component-scaffold-generator/ SKILL.md +562 -0
- package/templates/frontend/design-to-component-translator/ SKILL.md +547 -0
- package/templates/frontend/form-wizard-builder/ SKILL.md +553 -0
- package/templates/frontend/frontend-refactor-planner/ SKILL.md +37 -0
- package/templates/frontend/i18n-frontend-implementer/ SKILL.md +44 -0
- package/templates/frontend/modal-drawer-system/ SKILL.md +377 -0
- package/templates/frontend/page-layout-builder/ SKILL.md +630 -0
- package/templates/frontend/state-ux-flow-builder/ SKILL.md +23 -0
- package/templates/frontend/table-builder/ SKILL.md +350 -0
- package/templates/performance/alerting-dashboard-builder/ SKILL.md +162 -0
- package/templates/performance/backend-latency-profiler-helper/ SKILL.md +108 -0
- package/templates/performance/caching-cdn-strategy-planner/ SKILL.md +150 -0
- package/templates/performance/capacity-planning-helper/ SKILL.md +242 -0
- package/templates/performance/core-web-vitals-tuner/ SKILL.md +126 -0
- package/templates/performance/incident-runbook-generator/ SKILL.md +162 -0
- package/templates/performance/load-test-scenario-builder/ SKILL.md +256 -0
- package/templates/performance/observability-setup/ SKILL.md +232 -0
- package/templates/performance/postmortem-writer/ SKILL.md +203 -0
- package/templates/performance/structured-logging-standardizer/ SKILL.md +122 -0
- package/templates/security/auth-security-reviewer/ SKILL.md +428 -0
- package/templates/security/dependency-vulnerability-triage/ SKILL.md +495 -0
- package/templates/security/input-validation-sanitization-auditor/ SKILL.md +76 -0
- package/templates/security/pii-redaction-logging-policy-builder/ SKILL.md +65 -0
- package/templates/security/rbac-policy-tester/ SKILL.md +80 -0
- package/templates/security/secrets-scanner/ SKILL.md +462 -0
- package/templates/security/secure-headers-csp-builder/ SKILL.md +404 -0
- package/templates/security/security-incident-playbook-generator/ SKILL.md +76 -0
- package/templates/security/security-pr-checklist-skill/ SKILL.md +62 -0
- package/templates/security/threat-model-generator/ SKILL.md +394 -0
- package/templates/testing/contract-testing-builder/ SKILL.md +492 -0
- package/templates/testing/coverage-strategist/ SKILL.md +436 -0
- package/templates/testing/e2e-test-builder/ SKILL.md +382 -0
- package/templates/testing/flaky-test-detective/ SKILL.md +416 -0
- package/templates/testing/integration-test-builder/ SKILL.md +525 -0
- package/templates/testing/mocking-assistant/ SKILL.md +383 -0
- package/templates/testing/snapshot-test-refactorer/ SKILL.md +375 -0
- package/templates/testing/test-data-factory-builder/ SKILL.md +449 -0
- package/templates/testing/test-reporting-triage-skill/ SKILL.md +469 -0
- package/templates/testing/unit-test-generator/ SKILL.md +548 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: secrets-scanner
|
|
3
|
+
description: Detects leaked API keys, tokens, passwords, and credentials in code with pre-commit hooks, CI checks, scanning rules, and remediation procedures. Use for "secret scanning", "credential detection", "API key leaks", or "secret management".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Secrets Scanner
|
|
7
|
+
|
|
8
|
+
Detect and prevent leaked credentials in your codebase.
|
|
9
|
+
|
|
10
|
+
## Secret Detection Patterns
|
|
11
|
+
|
|
12
|
+
````yaml
|
|
13
|
+
# .gitleaks.toml
|
|
14
|
+
title = "Gitleaks Configuration"
|
|
15
|
+
|
|
16
|
+
[[rules]]
|
|
17
|
+
id = "aws-access-key"
|
|
18
|
+
description = "AWS Access Key"
|
|
19
|
+
regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}'''
|
|
20
|
+
tags = ["key", "AWS"]
|
|
21
|
+
|
|
22
|
+
[[rules]]
|
|
23
|
+
id = "aws-secret-key"
|
|
24
|
+
description = "AWS Secret Key"
|
|
25
|
+
regex = '''(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]'''
|
|
26
|
+
tags = ["key", "AWS"]
|
|
27
|
+
|
|
28
|
+
[[rules]]
|
|
29
|
+
id = "github-token"
|
|
30
|
+
description = "GitHub Personal Access Token"
|
|
31
|
+
regex = '''ghp_[0-9a-zA-Z]{36}'''
|
|
32
|
+
tags = ["key", "GitHub"]
|
|
33
|
+
|
|
34
|
+
[[rules]]
|
|
35
|
+
id = "github-oauth"
|
|
36
|
+
description = "GitHub OAuth Token"
|
|
37
|
+
regex = '''gho_[0-9a-zA-Z]{36}'''
|
|
38
|
+
tags = ["key", "GitHub"]
|
|
39
|
+
|
|
40
|
+
[[rules]]
|
|
41
|
+
id = "slack-webhook"
|
|
42
|
+
description = "Slack Webhook URL"
|
|
43
|
+
regex = '''https://hooks\.slack\.com/services/T[a-zA-Z0-9_]{8,10}/B[a-zA-Z0-9_]{8,10}/[a-zA-Z0-9_]{24}'''
|
|
44
|
+
tags = ["webhook", "Slack"]
|
|
45
|
+
|
|
46
|
+
[[rules]]
|
|
47
|
+
id = "private-key"
|
|
48
|
+
description = "Private Key"
|
|
49
|
+
regex = '''-----BEGIN (RSA|OPENSSH|DSA|EC|PGP) PRIVATE KEY-----'''
|
|
50
|
+
tags = ["key", "private"]
|
|
51
|
+
|
|
52
|
+
[[rules]]
|
|
53
|
+
id = "generic-api-key"
|
|
54
|
+
description = "Generic API Key"
|
|
55
|
+
regex = '''(?i)(api[_-]?key|apikey|access[_-]?key)(.{0,20})?['"][0-9a-zA-Z]{32,}['"]'''
|
|
56
|
+
tags = ["key", "generic"]
|
|
57
|
+
|
|
58
|
+
[[rules]]
|
|
59
|
+
id = "database-connection"
|
|
60
|
+
description = "Database Connection String"
|
|
61
|
+
regex = '''(?i)(postgresql|mysql|mongodb):\/\/[^\s:]+:[^\s@]+@[^\s\/]+'''
|
|
62
|
+
tags = ["database", "credentials"]
|
|
63
|
+
|
|
64
|
+
[allowlist]
|
|
65
|
+
description = "Allowlist"
|
|
66
|
+
paths = [
|
|
67
|
+
'''node_modules/''',
|
|
68
|
+
'''\.git/''',
|
|
69
|
+
'''\.lock$''',
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
regexes = [
|
|
73
|
+
'''EXAMPLE_KEY_123''',
|
|
74
|
+
'''your_api_key_here''',
|
|
75
|
+
'''<API_KEY>''',
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
## Pre-commit Hook Setup
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
# .pre-commit-config.yaml
|
|
82
|
+
repos:
|
|
83
|
+
- repo: https://github.com/gitleaks/gitleaks
|
|
84
|
+
rev: v8.18.0
|
|
85
|
+
hooks:
|
|
86
|
+
- id: gitleaks
|
|
87
|
+
|
|
88
|
+
- repo: https://github.com/Yelp/detect-secrets
|
|
89
|
+
rev: v1.4.0
|
|
90
|
+
hooks:
|
|
91
|
+
- id: detect-secrets
|
|
92
|
+
args: ['--baseline', '.secrets.baseline']
|
|
93
|
+
|
|
94
|
+
- repo: local
|
|
95
|
+
hooks:
|
|
96
|
+
- id: check-env-files
|
|
97
|
+
name: Check for .env files
|
|
98
|
+
entry: bash -c 'if git diff --cached --name-only | grep -E "\.env$"; then echo "❌ .env file detected! Add to .gitignore"; exit 1; fi'
|
|
99
|
+
language: system
|
|
100
|
+
pass_filenames: false
|
|
101
|
+
````
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Install pre-commit
|
|
105
|
+
pip install pre-commit
|
|
106
|
+
|
|
107
|
+
# Install hooks
|
|
108
|
+
pre-commit install
|
|
109
|
+
|
|
110
|
+
# Run on all files
|
|
111
|
+
pre-commit run --all-files
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## CI Integration
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
# .github/workflows/secrets-scan.yml
|
|
118
|
+
name: Secrets Scan
|
|
119
|
+
|
|
120
|
+
on:
|
|
121
|
+
push:
|
|
122
|
+
branches: [main, develop]
|
|
123
|
+
pull_request:
|
|
124
|
+
branches: [main, develop]
|
|
125
|
+
|
|
126
|
+
jobs:
|
|
127
|
+
gitleaks:
|
|
128
|
+
runs-on: ubuntu-latest
|
|
129
|
+
steps:
|
|
130
|
+
- uses: actions/checkout@v4
|
|
131
|
+
with:
|
|
132
|
+
fetch-depth: 0 # Full history for scanning
|
|
133
|
+
|
|
134
|
+
- name: Run Gitleaks
|
|
135
|
+
uses: gitleaks/gitleaks-action@v2
|
|
136
|
+
env:
|
|
137
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
138
|
+
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
|
|
139
|
+
|
|
140
|
+
trufflehog:
|
|
141
|
+
runs-on: ubuntu-latest
|
|
142
|
+
steps:
|
|
143
|
+
- uses: actions/checkout@v4
|
|
144
|
+
with:
|
|
145
|
+
fetch-depth: 0
|
|
146
|
+
|
|
147
|
+
- name: TruffleHog OSS
|
|
148
|
+
uses: trufflesecurity/trufflehog@main
|
|
149
|
+
with:
|
|
150
|
+
path: ./
|
|
151
|
+
base: ${{ github.event.repository.default_branch }}
|
|
152
|
+
head: HEAD
|
|
153
|
+
extra_args: --debug --only-verified
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Custom Secret Scanner
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// scripts/scan-secrets.ts
|
|
160
|
+
import * as fs from "fs";
|
|
161
|
+
import * as path from "path";
|
|
162
|
+
|
|
163
|
+
interface SecretPattern {
|
|
164
|
+
name: string;
|
|
165
|
+
regex: RegExp;
|
|
166
|
+
severity: "critical" | "high" | "medium";
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const SECRET_PATTERNS: SecretPattern[] = [
|
|
170
|
+
{
|
|
171
|
+
name: "AWS Access Key",
|
|
172
|
+
regex: /(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}/g,
|
|
173
|
+
severity: "critical",
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: "Private Key",
|
|
177
|
+
regex: /-----BEGIN (RSA|OPENSSH|DSA|EC|PGP) PRIVATE KEY-----/g,
|
|
178
|
+
severity: "critical",
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: "Generic API Key",
|
|
182
|
+
regex:
|
|
183
|
+
/['"]?[a-zA-Z0-9_-]*api[_-]?key['"]?\s*[:=]\s*['"][a-zA-Z0-9]{32,}['"]/gi,
|
|
184
|
+
severity: "high",
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: "Database URL",
|
|
188
|
+
regex: /(postgresql|mysql|mongodb):\/\/[^\s:]+:[^\s@]+@[^\s\/]+/gi,
|
|
189
|
+
severity: "critical",
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: "JWT Token",
|
|
193
|
+
regex: /eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/g,
|
|
194
|
+
severity: "high",
|
|
195
|
+
},
|
|
196
|
+
];
|
|
197
|
+
|
|
198
|
+
interface SecretFinding {
|
|
199
|
+
file: string;
|
|
200
|
+
line: number;
|
|
201
|
+
column: number;
|
|
202
|
+
pattern: string;
|
|
203
|
+
match: string;
|
|
204
|
+
severity: string;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function scanFile(filePath: string): SecretFinding[] {
|
|
208
|
+
const findings: SecretFinding[] = [];
|
|
209
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
210
|
+
const lines = content.split("\n");
|
|
211
|
+
|
|
212
|
+
lines.forEach((line, lineIndex) => {
|
|
213
|
+
SECRET_PATTERNS.forEach((pattern) => {
|
|
214
|
+
const matches = line.matchAll(pattern.regex);
|
|
215
|
+
|
|
216
|
+
for (const match of matches) {
|
|
217
|
+
findings.push({
|
|
218
|
+
file: filePath,
|
|
219
|
+
line: lineIndex + 1,
|
|
220
|
+
column: match.index || 0,
|
|
221
|
+
pattern: pattern.name,
|
|
222
|
+
match: match[0].substring(0, 50) + "...",
|
|
223
|
+
severity: pattern.severity,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
return findings;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function scanDirectory(dir: string): SecretFinding[] {
|
|
233
|
+
const findings: SecretFinding[] = [];
|
|
234
|
+
const files = fs.readdirSync(dir, { withFileTypes: true });
|
|
235
|
+
|
|
236
|
+
const ignorePaths = ["node_modules", ".git", "dist", "build"];
|
|
237
|
+
|
|
238
|
+
files.forEach((file) => {
|
|
239
|
+
const fullPath = path.join(dir, file.name);
|
|
240
|
+
|
|
241
|
+
if (file.isDirectory() && !ignorePaths.includes(file.name)) {
|
|
242
|
+
findings.push(...scanDirectory(fullPath));
|
|
243
|
+
} else if (file.isFile()) {
|
|
244
|
+
findings.push(...scanFile(fullPath));
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
return findings;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Run scan
|
|
252
|
+
const findings = scanDirectory("./src");
|
|
253
|
+
|
|
254
|
+
if (findings.length > 0) {
|
|
255
|
+
console.error("🚨 Secrets detected!\n");
|
|
256
|
+
|
|
257
|
+
findings.forEach((f) => {
|
|
258
|
+
console.error(
|
|
259
|
+
`[${f.severity.toUpperCase()}] ${f.file}:${f.line}:${f.column}`
|
|
260
|
+
);
|
|
261
|
+
console.error(` Pattern: ${f.pattern}`);
|
|
262
|
+
console.error(` Match: ${f.match}\n`);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
process.exit(1);
|
|
266
|
+
} else {
|
|
267
|
+
console.log("✅ No secrets detected");
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Remediation Steps
|
|
272
|
+
|
|
273
|
+
````markdown
|
|
274
|
+
# Secret Leak Remediation Checklist
|
|
275
|
+
|
|
276
|
+
## Immediate Actions (< 1 hour)
|
|
277
|
+
|
|
278
|
+
1. **Revoke the compromised secret**
|
|
279
|
+
|
|
280
|
+
- [ ] Deactivate API key/token immediately
|
|
281
|
+
- [ ] Rotate credentials in production
|
|
282
|
+
- [ ] Update all services using the secret
|
|
283
|
+
|
|
284
|
+
2. **Remove from git history**
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Using BFG Repo-Cleaner
|
|
288
|
+
bfg --replace-text secrets.txt repo.git
|
|
289
|
+
git reflog expire --expire=now --all
|
|
290
|
+
git gc --prune=now --aggressive
|
|
291
|
+
|
|
292
|
+
# Force push (requires team coordination)
|
|
293
|
+
git push --force --all
|
|
294
|
+
```
|
|
295
|
+
````
|
|
296
|
+
|
|
297
|
+
3. **Notify stakeholders**
|
|
298
|
+
- [ ] Security team
|
|
299
|
+
- [ ] DevOps team
|
|
300
|
+
- [ ] Service owners
|
|
301
|
+
- [ ] Management (if public repo)
|
|
302
|
+
|
|
303
|
+
## Short-term Actions (< 24 hours)
|
|
304
|
+
|
|
305
|
+
4. **Audit access logs**
|
|
306
|
+
|
|
307
|
+
- [ ] Check CloudWatch/CloudTrail for suspicious activity
|
|
308
|
+
- [ ] Review API usage for unauthorized access
|
|
309
|
+
- [ ] Check for data exfiltration
|
|
310
|
+
|
|
311
|
+
5. **Update secret management**
|
|
312
|
+
|
|
313
|
+
- [ ] Store in vault (AWS Secrets Manager, HashiCorp Vault)
|
|
314
|
+
- [ ] Use environment variables
|
|
315
|
+
- [ ] Remove hardcoded secrets
|
|
316
|
+
|
|
317
|
+
6. **Add scanning**
|
|
318
|
+
- [ ] Install pre-commit hooks
|
|
319
|
+
- [ ] Add CI secret scanning
|
|
320
|
+
- [ ] Set up monitoring alerts
|
|
321
|
+
|
|
322
|
+
## Long-term Actions (< 1 week)
|
|
323
|
+
|
|
324
|
+
7. **Review and improve**
|
|
325
|
+
- [ ] Conduct security training
|
|
326
|
+
- [ ] Update secret management policies
|
|
327
|
+
- [ ] Implement secret rotation schedule
|
|
328
|
+
- [ ] Document incident and lessons learned
|
|
329
|
+
|
|
330
|
+
````
|
|
331
|
+
|
|
332
|
+
## Secret Management Best Practices
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
// ❌ BAD: Hardcoded secrets
|
|
336
|
+
const API_KEY = 'sk_live_abc123xyz789';
|
|
337
|
+
const db = connect('mongodb://admin:password@localhost');
|
|
338
|
+
|
|
339
|
+
// ✅ GOOD: Environment variables
|
|
340
|
+
const API_KEY = process.env.API_KEY;
|
|
341
|
+
const db = connect(process.env.DATABASE_URL);
|
|
342
|
+
|
|
343
|
+
// ✅ BETTER: Secret management service
|
|
344
|
+
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
|
|
345
|
+
|
|
346
|
+
async function getSecret(secretName: string): Promise<string> {
|
|
347
|
+
const client = new SecretsManagerClient({ region: 'us-east-1' });
|
|
348
|
+
const response = await client.send(
|
|
349
|
+
new GetSecretValueCommand({ SecretId: secretName })
|
|
350
|
+
);
|
|
351
|
+
return response.SecretString!;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const apiKey = await getSecret('prod/api/stripe-key');
|
|
355
|
+
````
|
|
356
|
+
|
|
357
|
+
## GitHub Secret Scanning
|
|
358
|
+
|
|
359
|
+
```yaml
|
|
360
|
+
# Enable GitHub secret scanning (Enterprise)
|
|
361
|
+
# Settings → Security & analysis → Secret scanning
|
|
362
|
+
|
|
363
|
+
# Configure custom patterns
|
|
364
|
+
# .github/secret_scanning.yml
|
|
365
|
+
patterns:
|
|
366
|
+
- name: Company API Key
|
|
367
|
+
pattern: "company_[a-zA-Z0-9]{32}"
|
|
368
|
+
secret_type: company_api_key
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Environment Variable Validation
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
// config/env-validation.ts
|
|
375
|
+
import { z } from "zod";
|
|
376
|
+
|
|
377
|
+
const envSchema = z
|
|
378
|
+
.object({
|
|
379
|
+
NODE_ENV: z.enum(["development", "production", "test"]),
|
|
380
|
+
DATABASE_URL: z.string().url(),
|
|
381
|
+
API_KEY: z.string().min(32),
|
|
382
|
+
JWT_SECRET: z.string().min(64),
|
|
383
|
+
// Never allow default/example values in production
|
|
384
|
+
})
|
|
385
|
+
.refine((env) => {
|
|
386
|
+
if (env.NODE_ENV === "production") {
|
|
387
|
+
const invalidValues = ["example", "test", "localhost", "changeme"];
|
|
388
|
+
return !invalidValues.some((val) =>
|
|
389
|
+
Object.values(env).some((envVal) =>
|
|
390
|
+
String(envVal).toLowerCase().includes(val)
|
|
391
|
+
)
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
return true;
|
|
395
|
+
}, "Production environment cannot use example/test values");
|
|
396
|
+
|
|
397
|
+
// Validate on startup
|
|
398
|
+
try {
|
|
399
|
+
envSchema.parse(process.env);
|
|
400
|
+
} catch (error) {
|
|
401
|
+
console.error("❌ Invalid environment configuration:", error);
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Monitoring & Alerts
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
// monitoring/secret-monitoring.ts
|
|
410
|
+
import {
|
|
411
|
+
CloudWatchClient,
|
|
412
|
+
PutMetricDataCommand,
|
|
413
|
+
} from "@aws-sdk/client-cloudwatch";
|
|
414
|
+
|
|
415
|
+
async function monitorSecretUsage(secretName: string) {
|
|
416
|
+
const cloudwatch = new CloudWatchClient();
|
|
417
|
+
|
|
418
|
+
await cloudwatch.send(
|
|
419
|
+
new PutMetricDataCommand({
|
|
420
|
+
Namespace: "Security/Secrets",
|
|
421
|
+
MetricData: [
|
|
422
|
+
{
|
|
423
|
+
MetricName: "SecretAccess",
|
|
424
|
+
Value: 1,
|
|
425
|
+
Unit: "Count",
|
|
426
|
+
Dimensions: [
|
|
427
|
+
{
|
|
428
|
+
Name: "SecretName",
|
|
429
|
+
Value: secretName,
|
|
430
|
+
},
|
|
431
|
+
],
|
|
432
|
+
},
|
|
433
|
+
],
|
|
434
|
+
})
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Alert on unusual secret access patterns
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Best Practices
|
|
442
|
+
|
|
443
|
+
1. **Never commit secrets**: Use .gitignore for .env files
|
|
444
|
+
2. **Use secret managers**: AWS Secrets Manager, Vault
|
|
445
|
+
3. **Rotate regularly**: 90-day rotation policy
|
|
446
|
+
4. **Scan continuously**: Pre-commit + CI + scheduled scans
|
|
447
|
+
5. **Least privilege**: Minimal secret access
|
|
448
|
+
6. **Audit logs**: Track secret access
|
|
449
|
+
7. **Incident response**: Have remediation playbook ready
|
|
450
|
+
|
|
451
|
+
## Output Checklist
|
|
452
|
+
|
|
453
|
+
- [ ] Gitleaks configuration created
|
|
454
|
+
- [ ] Pre-commit hooks installed
|
|
455
|
+
- [ ] CI secret scanning configured
|
|
456
|
+
- [ ] Custom scanner implemented (optional)
|
|
457
|
+
- [ ] Remediation playbook documented
|
|
458
|
+
- [ ] Secret management best practices
|
|
459
|
+
- [ ] Environment validation
|
|
460
|
+
- [ ] Monitoring and alerts
|
|
461
|
+
- [ ] .gitignore includes .env files
|
|
462
|
+
- [ ] Team trained on secret handling
|