@lhi/tdd-audit 1.18.0 → 1.20.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/README.md +181 -106
- package/docs/configuration.md +236 -0
- package/lib/auditor.js +1 -0
- package/lib/badge.js +22 -2
- package/lib/config.js +38 -1
- package/lib/github.js +1 -1
- package/lib/reporter.js +18 -3
- package/package.json +1 -1
- package/prompts/auto-audit.md +193 -6
- package/prompts/security-test-patterns.md +522 -0
package/README.md
CHANGED
|
@@ -1,41 +1,124 @@
|
|
|
1
1
|
# @lhi/tdd-audit
|
|
2
|
-

|
|
3
3
|
[](https://www.npmjs.com/package/@lhi/tdd-audit) <!-- tdd-audit-badge -->
|
|
4
4
|
|
|
5
|
-
> **
|
|
5
|
+
> **Your AI-generated code is probably vulnerable right now.** SQL injection. Hardcoded secrets. Prompt injection backdoors. The same assistant that built your feature in 30 minutes didn't think twice about security. `tdd-audit` finds the holes, proves they're real, and closes them — every fix backed by a failing test before and a passing test after.
|
|
6
|
+
|
|
7
|
+
## One command. Proven secure.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @lhi/tdd-audit --local --claude
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
That's it. In seconds you get:
|
|
14
|
+
|
|
15
|
+
- A severity-ranked findings report (CRITICAL → LOW) with the exact file and line
|
|
16
|
+
- Exploit tests that **prove the vulnerability is real** — not theoretical
|
|
17
|
+
- Patches that close each hole, verified by a passing test suite
|
|
18
|
+
- ≥ 95% test coverage enforced, a README security badge, and a `SECURITY.md` ready for auditors
|
|
19
|
+
|
|
20
|
+
No security expertise required. No config needed to start.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Why this exists
|
|
25
|
+
|
|
26
|
+
Vibecoders move fast. AI assistants hallucinate security. The result: apps with SQL injection in the ORM layer, JWT algorithm confusion, hardcoded API keys one `git log` away from leaking, and LLM prompt injection that hands your backend to anyone who knows the trick.
|
|
27
|
+
|
|
28
|
+
PMs and security officers feel it too — "is this thing actually secure?" has no good answer when there are no tests proving it.
|
|
29
|
+
|
|
30
|
+
`tdd-audit` gives you the answer. Every vulnerability is proven closed by a test, not just patched and hoped for the best.
|
|
31
|
+
|
|
32
|
+
---
|
|
6
33
|
|
|
7
34
|
## Install
|
|
8
35
|
|
|
9
36
|
```bash
|
|
10
|
-
|
|
37
|
+
# Claude Code (recommended)
|
|
38
|
+
npx @lhi/tdd-audit --local --claude
|
|
39
|
+
|
|
40
|
+
# Gemini CLI / Codex / OpenCode / Cursor
|
|
41
|
+
npx @lhi/tdd-audit --local
|
|
11
42
|
```
|
|
12
43
|
|
|
13
44
|
On first run the installer:
|
|
14
45
|
|
|
15
|
-
1. Scaffolds `__tests__/security/` with
|
|
46
|
+
1. Scaffolds `__tests__/security/` with framework-matched exploit test boilerplate
|
|
16
47
|
2. Adds `test:security` to `package.json`
|
|
17
|
-
3. Creates `.github/workflows/security-tests.yml`
|
|
18
|
-
4. Installs the `/tdd-audit` skill
|
|
48
|
+
3. Creates `.github/workflows/security-tests.yml` — SHA-pinned actions, `npm audit` on every PR
|
|
49
|
+
4. Installs the `/tdd-audit` skill in your AI agent
|
|
19
50
|
|
|
20
|
-
|
|
51
|
+
Then open your agent and type `/tdd-audit`. It handles the rest.
|
|
21
52
|
|
|
22
|
-
|
|
53
|
+
### Install flags
|
|
54
|
+
|
|
55
|
+
| Flag | What it does |
|
|
23
56
|
|---|---|
|
|
24
|
-
| `--local` | Install into the current project
|
|
25
|
-
| `--claude` | Use `.claude/`
|
|
26
|
-
| `--with-hooks` |
|
|
27
|
-
| `--skip-scan` | Skip the vulnerability scan
|
|
28
|
-
| `--config <path>` | Load config from
|
|
57
|
+
| `--local` | Install into the current project (recommended) |
|
|
58
|
+
| `--claude` | Use `.claude/` for Claude Code |
|
|
59
|
+
| `--with-hooks` | Block commits that break security tests |
|
|
60
|
+
| `--skip-scan` | Skip the initial vulnerability scan |
|
|
61
|
+
| `--config <path>` | Load config from a specific path |
|
|
29
62
|
|
|
30
|
-
|
|
63
|
+
---
|
|
31
64
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
65
|
+
## What gets caught
|
|
66
|
+
|
|
67
|
+
100+ patterns across Node.js, Python, Go, React, React Native, Flutter, and Expo — including the AI-specific vulnerabilities that most scanners miss entirely:
|
|
68
|
+
|
|
69
|
+
**Standard OWASP holes** — SQL/NoSQL/Command injection · Path traversal · Broken auth · XSS · IDOR · Mass assignment · SSRF · Open redirect · XXE · Insecure deserialization · Prototype pollution · Weak crypto · Hardcoded secrets · TLS bypass
|
|
70
|
+
|
|
71
|
+
**AI / LLM-specific** (the ones that will actually get you hacked in 2025) — LLM prompt injection · Eval of model output · LangChain ShellTool / ExecChain · Unbounded agent loops · MCP credential leakage · GitHub Actions expression injection · Hardcoded provider keys (OpenAI, Anthropic, Gemini, Cohere, Mistral, HuggingFace) · Missing `max_tokens` · Dynamic require from user input · VM sandbox escape · Electron `nodeIntegration: true`
|
|
72
|
+
|
|
73
|
+
**Vibecoding anti-patterns** — `localStorage` token storage · `Math.random()` for session IDs · `process.env.SECRET || "hardcoded-fallback"` · Silent exception swallowing · Insecure WebSocket URLs
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## How it works
|
|
78
|
+
|
|
79
|
+
The full `/tdd-audit` skill run follows Red-Green-Refactor for every finding:
|
|
80
|
+
|
|
81
|
+
1. **Detect** — scans your stack, scopes patterns to what's actually relevant
|
|
82
|
+
2. **Report** — presents a CRITICAL → LOW findings table with plain-language risk and effort estimate. Waits for your sign-off before touching anything
|
|
83
|
+
3. **Red** — writes an exploit test that **fails** (proves the hole is real)
|
|
84
|
+
4. **Green** — applies the patch (test now passes)
|
|
85
|
+
5. **Refactor** — runs the full suite (zero regressions)
|
|
86
|
+
6. **Harden** — security headers, rate limiting, `npm audit`, secret scan, production error handling
|
|
87
|
+
7. **Coverage gate** — pushes test coverage to ≥ 95% line and branch
|
|
88
|
+
8. **Badge + SECURITY.md** — updates your README badge, creates `SECURITY.md` in GitHub Security Advisory format
|
|
89
|
+
|
|
90
|
+
Nothing is marked done until a test proves it.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## For PMs and security officers
|
|
95
|
+
|
|
96
|
+
You need evidence, not promises. `tdd-audit` produces:
|
|
97
|
+
|
|
98
|
+
- **Exploit tests** — a failing test per vulnerability, committed to source, proves the hole existed
|
|
99
|
+
- **Passing tests** — the fix is proven by the test suite, not just code review
|
|
100
|
+
- **`--format report`** — a markdown compliance report with findings table, fix evidence, patch commits, and coverage gate result; ready to attach to SOC 2, ISO 27001, or vendor security questionnaire
|
|
101
|
+
- **`--sbom`** — CycloneDX Software Bill of Materials (required for US federal contracts under EO 14028)
|
|
102
|
+
- **`SECURITY.md`** — GitHub Security Advisory format with your security contact, supported versions, and hardening summary
|
|
103
|
+
- **Webhook + Slack notifications** — findings summary delivered to your security channel on every scan
|
|
104
|
+
|
|
105
|
+
Configure your security contact in `.tdd-audit.json`:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"security_name": "Alice Smith",
|
|
110
|
+
"security_email": "security@yourorg.com"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Both fields are optional — use one, both, or neither. When set, they appear in SECURITY.md, the compliance report, and webhook payloads.
|
|
115
|
+
|
|
116
|
+
---
|
|
36
117
|
|
|
37
118
|
## AI Audit (`--ai`)
|
|
38
119
|
|
|
120
|
+
Let the LLM explore and report on your codebase directly:
|
|
121
|
+
|
|
39
122
|
```bash
|
|
40
123
|
npx @lhi/tdd-audit --ai \
|
|
41
124
|
--provider anthropic \
|
|
@@ -44,32 +127,27 @@ npx @lhi/tdd-audit --ai \
|
|
|
44
127
|
--format json
|
|
45
128
|
```
|
|
46
129
|
|
|
47
|
-
The `--ai` flag triggers a full agentic audit: the LLM explores your codebase using `read_file`, `list_files`, and `search_in_files` tool calls, then produces a structured findings report shaped by `--depth`.
|
|
48
|
-
|
|
49
130
|
### Depth tiers
|
|
50
131
|
|
|
51
|
-
| Tier | Mode |
|
|
132
|
+
| Tier | Mode | What you get | Billing unit |
|
|
52
133
|
|---|---|---|---|
|
|
53
|
-
| `tier-1` |
|
|
54
|
-
| `tier-2` |
|
|
55
|
-
| `tier-3` |
|
|
56
|
-
| `tier-4` |
|
|
134
|
+
| `tier-1` | Scan only | File, line, severity, snippet | per report |
|
|
135
|
+
| `tier-2` | Scan only | + risk explanation, effort estimate, CWE, OWASP, references | per report |
|
|
136
|
+
| `tier-3` | Full audit, read-only | + copy-ready patches and test snippets — you apply manually | per report |
|
|
137
|
+
| `tier-4` | Full audit, writes | LLM applies every patch via `write_file` | per applied patch |
|
|
57
138
|
|
|
58
139
|
```bash
|
|
59
|
-
#
|
|
140
|
+
# Fast scan — just the findings
|
|
60
141
|
npx @lhi/tdd-audit --ai --depth tier-1 --format json
|
|
61
142
|
|
|
62
|
-
#
|
|
143
|
+
# Full report with context, no changes made
|
|
63
144
|
npx @lhi/tdd-audit --ai --depth tier-2 --format json
|
|
64
145
|
|
|
65
|
-
# Copy-ready patches
|
|
146
|
+
# Copy-ready patches — apply yourself
|
|
66
147
|
npx @lhi/tdd-audit --ai --depth tier-3 --format json
|
|
67
148
|
|
|
68
|
-
# Let the LLM
|
|
149
|
+
# Let the LLM fix everything
|
|
69
150
|
npx @lhi/tdd-audit --ai --depth tier-4 --allow-writes
|
|
70
|
-
|
|
71
|
-
# Targeted apply: apply one specific patch from a prior tier-3 report
|
|
72
|
-
# (via REST API — see docs/rest-api.md)
|
|
73
151
|
```
|
|
74
152
|
|
|
75
153
|
### AI flags
|
|
@@ -77,132 +155,129 @@ npx @lhi/tdd-audit --ai --depth tier-4 --allow-writes
|
|
|
77
155
|
| Flag | Description |
|
|
78
156
|
|---|---|
|
|
79
157
|
| `--ai` | Enable LLM agentic audit |
|
|
80
|
-
| `--depth tier-1\|
|
|
158
|
+
| `--depth tier-1\|2\|3\|4` | Output depth tier (default: `tier-1`) |
|
|
81
159
|
| `--allow-writes` | Permit the LLM to write files (auto-enabled for `tier-4`) |
|
|
82
160
|
| `--provider <name>` | `anthropic` \| `openai` \| `gemini` \| `ollama` |
|
|
83
161
|
| `--api-key <key>` | Provider API key |
|
|
84
162
|
| `--model <name>` | Model override (e.g. `claude-opus-4-6`, `gpt-4o`) |
|
|
85
|
-
| `--base-url <url>` |
|
|
86
|
-
| `--format json\|sarif` | Structured output format
|
|
163
|
+
| `--base-url <url>` | Any OpenAI-compatible service |
|
|
164
|
+
| `--format json\|sarif\|report` | Structured output format |
|
|
87
165
|
| `--verbose` | Print tool call details to stderr |
|
|
88
166
|
|
|
89
|
-
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## CI integration
|
|
170
|
+
|
|
171
|
+
### PR gate — block merges on new findings
|
|
172
|
+
|
|
173
|
+
```yaml
|
|
174
|
+
- run: npx @lhi/tdd-audit@latest --pr --threshold HIGH
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Exits non-zero if any finding meets or exceeds the threshold. Sub-second — no AI, no agents, pure static scan. Wire into branch protection rules to stop vulnerable code from merging.
|
|
178
|
+
|
|
179
|
+
### Org-wide posture scan
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
npx @lhi/tdd-audit@latest --org my-github-org --format report
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Scans every repo in the org, produces a cross-org summary and a compliance report. Fires your webhook/Slack with the aggregate payload.
|
|
90
186
|
|
|
91
|
-
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Config file
|
|
92
190
|
|
|
93
191
|
```bash
|
|
94
|
-
npx @lhi/tdd-audit init
|
|
95
|
-
|
|
96
|
-
npx @lhi/tdd-audit init ~/configs/my-audit.json
|
|
192
|
+
npx @lhi/tdd-audit init # scaffold .tdd-audit.json
|
|
193
|
+
npx @lhi/tdd-audit init --provider anthropic # with Anthropic defaults
|
|
97
194
|
```
|
|
98
195
|
|
|
99
|
-
`.tdd-audit.json` —
|
|
196
|
+
`.tdd-audit.json` — everything settable here, CLI flags always win:
|
|
100
197
|
|
|
101
198
|
```json
|
|
102
199
|
{
|
|
103
|
-
"provider": "
|
|
104
|
-
"model": "
|
|
105
|
-
"apiKeyEnv": "
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
|
|
112
|
-
"
|
|
200
|
+
"provider": "anthropic",
|
|
201
|
+
"model": "claude-opus-4-6",
|
|
202
|
+
"apiKeyEnv": "ANTHROPIC_API_KEY",
|
|
203
|
+
"severityThreshold": "HIGH",
|
|
204
|
+
"ignore": ["node_modules", "dist", "coverage"],
|
|
205
|
+
|
|
206
|
+
"security_name": "Alice Smith",
|
|
207
|
+
"security_email": "security@yourorg.com",
|
|
208
|
+
|
|
209
|
+
"webhook_url": "https://hooks.yourorg.com/security",
|
|
210
|
+
"slack_webhook": "https://hooks.slack.com/services/...",
|
|
211
|
+
"slack_channel": "#security-alerts",
|
|
212
|
+
|
|
213
|
+
"severity_overrides": {
|
|
214
|
+
"CORS Wildcard": "CRITICAL"
|
|
215
|
+
}
|
|
113
216
|
}
|
|
114
217
|
```
|
|
115
218
|
|
|
116
|
-
|
|
219
|
+
Full schema → [docs/configuration.md](docs/configuration.md)
|
|
117
220
|
|
|
118
|
-
|
|
119
|
-
npx @lhi/tdd-audit serve --config ~/configs/prod-audit.json
|
|
120
|
-
```
|
|
221
|
+
---
|
|
121
222
|
|
|
122
223
|
## REST API
|
|
123
224
|
|
|
124
225
|
```bash
|
|
125
|
-
# Start the API server
|
|
126
226
|
npx @lhi/tdd-audit serve --port 3000 --api-key YOUR_SECRET
|
|
127
|
-
|
|
128
|
-
# AI audit — returns jobId immediately
|
|
129
|
-
curl -X POST http://localhost:3000/audit/ai \
|
|
130
|
-
-H "Authorization: Bearer YOUR_SECRET" \
|
|
131
|
-
-H "Content-Type: application/json" \
|
|
132
|
-
-d '{"provider": "anthropic", "apiKey": "sk-ant-...", "depth": "tier-2"}' \
|
|
133
|
-
| jq '.jobId'
|
|
134
|
-
|
|
135
|
-
# Poll job status
|
|
136
|
-
curl http://localhost:3000/jobs/<jobId>
|
|
137
|
-
|
|
138
|
-
# Or stream real-time LLM output via SSE
|
|
139
|
-
curl -N http://localhost:3000/jobs/<jobId>/stream
|
|
140
|
-
|
|
141
|
-
# Targeted apply: re-apply a specific patch from a tier-3 report
|
|
142
|
-
curl -X POST http://localhost:3000/audit/ai \
|
|
143
|
-
-H "Authorization: Bearer YOUR_SECRET" \
|
|
144
|
-
-H "Content-Type: application/json" \
|
|
145
|
-
-d '{
|
|
146
|
-
"provider": "anthropic",
|
|
147
|
-
"apiKey": "sk-ant-...",
|
|
148
|
-
"depth": "tier-4",
|
|
149
|
-
"findings": [{ "name": "SQL Injection", "file": "src/db.js", "line": 10, "patch": "..." }]
|
|
150
|
-
}'
|
|
151
|
-
|
|
152
|
-
# Use any OpenAI-compatible service (Groq, OpenRouter, Together AI, etc.)
|
|
153
|
-
npx @lhi/tdd-audit serve \
|
|
154
|
-
--provider openai \
|
|
155
|
-
--base-url https://api.groq.com/openai/v1 \
|
|
156
|
-
--api-key $GROQ_API_KEY \
|
|
157
|
-
--model llama-3.3-70b-versatile
|
|
158
227
|
```
|
|
159
228
|
|
|
160
|
-
Supported providers: `anthropic` · `openai` · `gemini` · `ollama` (local) · **any OpenAI-compatible endpoint via `--base-url`**
|
|
161
|
-
|
|
162
|
-
### Endpoints
|
|
163
|
-
|
|
164
229
|
| Method | Path | Auth | Description |
|
|
165
230
|
|---|---|---|---|
|
|
166
|
-
| `GET` | `/health` | No |
|
|
167
|
-
| `POST` | `/audit/ai` | Yes |
|
|
231
|
+
| `GET` | `/health` | No | Liveness check |
|
|
232
|
+
| `POST` | `/audit/ai` | Yes | LLM audit with depth tiers; returns `jobId` |
|
|
233
|
+
| `POST` | `/scan` | Yes | Static scan; returns findings immediately |
|
|
168
234
|
| `POST` | `/remediate` | Yes | AI-fix a provided findings list; returns `jobId` |
|
|
169
|
-
| `POST` | `/audit` | Yes | Static scan + AI remediation pipeline; returns `jobId` |
|
|
170
235
|
| `GET` | `/jobs/:id` | Yes | Poll job status |
|
|
171
|
-
| `GET` | `/jobs/:id/stream` | Yes | SSE stream
|
|
236
|
+
| `GET` | `/jobs/:id/stream` | Yes | SSE — stream live LLM output |
|
|
172
237
|
|
|
173
|
-
|
|
238
|
+
```bash
|
|
239
|
+
# Start an AI audit
|
|
240
|
+
curl -X POST http://localhost:3000/audit/ai \
|
|
241
|
+
-H "Authorization: Bearer YOUR_SECRET" \
|
|
242
|
+
-H "Content-Type: application/json" \
|
|
243
|
+
-d '{"provider": "anthropic", "apiKey": "sk-ant-...", "depth": "tier-2"}'
|
|
174
244
|
|
|
175
|
-
|
|
176
|
-
/
|
|
245
|
+
# Stream results live
|
|
246
|
+
curl -N http://localhost:3000/jobs/<jobId>/stream
|
|
177
247
|
```
|
|
178
248
|
|
|
179
|
-
|
|
249
|
+
Supported providers: `anthropic` · `openai` · `gemini` · `ollama` · **any OpenAI-compatible endpoint via `--base-url`**
|
|
180
250
|
|
|
181
|
-
|
|
251
|
+
---
|
|
182
252
|
|
|
183
|
-
|
|
253
|
+
## Testing
|
|
184
254
|
|
|
185
255
|
```bash
|
|
186
|
-
npm test # full suite
|
|
187
|
-
npm run test:unit # unit tests with coverage
|
|
256
|
+
npm test # full suite (841 tests)
|
|
257
|
+
npm run test:unit # unit tests with coverage
|
|
188
258
|
npm run test:security # security regression tests only
|
|
189
259
|
npm run test:e2e # end-to-end REST API tests
|
|
190
260
|
```
|
|
191
261
|
|
|
192
|
-
Security tests cover prompt injection
|
|
262
|
+
Security tests cover: prompt injection · path traversal · SSRF via webhook and baseUrl · rate limiting · timing-safe auth · XFF bypass · job store bounds · SARIF schema · AI key redaction · coverage skip detection · and more. Every past vulnerability is a permanent regression test.
|
|
263
|
+
|
|
264
|
+
---
|
|
193
265
|
|
|
194
266
|
## Documentation
|
|
195
267
|
|
|
196
268
|
| | |
|
|
197
269
|
|---|---|
|
|
270
|
+
| [Configuration](docs/configuration.md) | Full schema — all fields, CLI equivalents, payload schemas |
|
|
198
271
|
| [REST API](docs/rest-api.md) | Endpoints, auth, rate limiting, depth tiers, targeted apply |
|
|
199
|
-
| [AI Remediation](docs/ai-remediation.md) | Provider setup, `--base-url` for compatible APIs
|
|
200
|
-
| [Vulnerability Patterns](docs/vulnerability-patterns.md) | All
|
|
272
|
+
| [AI Remediation](docs/ai-remediation.md) | Provider setup, `--base-url` for compatible APIs |
|
|
273
|
+
| [Vulnerability Patterns](docs/vulnerability-patterns.md) | All 100+ patterns — descriptions, grep signatures, fix pointers |
|
|
201
274
|
| [TDD Protocol](docs/tdd-protocol.md) | Red-Green-Refactor in full, with framework templates for all 6 stacks |
|
|
202
275
|
| [Agentic AI Security](docs/agentic-ai-security.md) | ASI01–ASI10 — prompt injection, MCP supply chain, Actions injection |
|
|
203
276
|
| [Hardening](docs/hardening.md) | Phase 4 controls — Helmet, CSP, CSRF, rate limiting, gitleaks, SRI |
|
|
204
277
|
| [CI/CD](docs/ci-cd.md) | Workflow templates, existing pipeline integration, secret leak prevention |
|
|
205
278
|
|
|
279
|
+
---
|
|
280
|
+
|
|
206
281
|
## License
|
|
207
282
|
|
|
208
283
|
MIT
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Configuration Reference
|
|
2
|
+
|
|
3
|
+
All `tdd-audit` behaviour is controlled by `.tdd-audit.json` at your repo root. CLI flags override file config; file config overrides built-in defaults.
|
|
4
|
+
|
|
5
|
+
Generate a starter file:
|
|
6
|
+
```bash
|
|
7
|
+
npx @lhi/tdd-audit@latest init
|
|
8
|
+
npx @lhi/tdd-audit@latest init --provider anthropic
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Full schema
|
|
14
|
+
|
|
15
|
+
```jsonc
|
|
16
|
+
{
|
|
17
|
+
// ── Core ──────────────────────────────────────────────────────────────────
|
|
18
|
+
"output": "text", // "text" | "json" | "sarif" | "report"
|
|
19
|
+
"severityThreshold": "LOW", // minimum severity to include: "LOW" | "MEDIUM" | "HIGH" | "CRITICAL"
|
|
20
|
+
"ignore": [], // path prefixes to skip: ["node_modules", "dist"]
|
|
21
|
+
"port": 3000, // port for `tdd-audit serve`
|
|
22
|
+
"serverApiKey": null, // required on REST API calls; falls back to TDD_AUDIT_API_KEY env var
|
|
23
|
+
|
|
24
|
+
// ── AI provider ───────────────────────────────────────────────────────────
|
|
25
|
+
"provider": "anthropic", // "anthropic" | "openai" | "gemini" | "ollama"
|
|
26
|
+
"model": "claude-opus-4-6",
|
|
27
|
+
"apiKeyEnv": "ANTHROPIC_API_KEY", // env var to read the key from
|
|
28
|
+
"baseUrl": null, // override for OpenAI-compatible providers
|
|
29
|
+
|
|
30
|
+
// ── Branding ──────────────────────────────────────────────────────────────
|
|
31
|
+
// For wrapper/rebranded distributions. See docs/extensibility.md.
|
|
32
|
+
"org": "Daily Caller",
|
|
33
|
+
"project": "my-project",
|
|
34
|
+
"badge_label": "dc-audit", // replaces "tdd-audit" in the shields.io badge
|
|
35
|
+
"tdd_site": "https://security.example.com", // replaces npm link in badge + SARIF
|
|
36
|
+
"security_name": "Alice Smith", // name of the security contact — stamped into SECURITY.md, compliance reports, and webhook payloads
|
|
37
|
+
"security_email": "security@example.com", // email for the vulnerability reporting address in SECURITY.md and payloads
|
|
38
|
+
|
|
39
|
+
// ── Policy as code ────────────────────────────────────────────────────────
|
|
40
|
+
// Override the default severity for any named pattern.
|
|
41
|
+
// Useful when a pattern's default severity doesn't match your org's risk model.
|
|
42
|
+
"severity_overrides": {
|
|
43
|
+
"CORS Wildcard": "CRITICAL", // default: MEDIUM
|
|
44
|
+
"Sensitive Log": "HIGH", // default: MEDIUM
|
|
45
|
+
"Cleartext Traffic": "HIGH" // default: MEDIUM
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
// ── Notifications ─────────────────────────────────────────────────────────
|
|
49
|
+
// Fired when a scan completes. Both can be set simultaneously.
|
|
50
|
+
"webhook_url": "https://hooks.example.com/tdd-audit",
|
|
51
|
+
// POST body: { project, timestamp, summary: { critical, high, medium, low }, findings: [...] }
|
|
52
|
+
|
|
53
|
+
"slack_webhook": "https://hooks.slack.com/services/...",
|
|
54
|
+
"slack_channel": "#security", // optional override; uses webhook default if absent
|
|
55
|
+
|
|
56
|
+
// ── Workflow integration ───────────────────────────────────────────────────
|
|
57
|
+
"open_pr": true, // open a GitHub PR per finding instead of committing directly
|
|
58
|
+
"github_token": null, // falls back to GITHUB_TOKEN env var
|
|
59
|
+
"github_repo": null, // "owner/repo" — auto-detected from git remote if null
|
|
60
|
+
|
|
61
|
+
// ── CI / scheduled modes ──────────────────────────────────────────────────
|
|
62
|
+
"pr_mode": false, // lightweight static scan only — fast, designed for PR gates
|
|
63
|
+
"org_scan": null, // "my-github-org" — scan all repos in the org
|
|
64
|
+
"schedule": null, // cron expression for external schedulers: "0 2 * * *"
|
|
65
|
+
|
|
66
|
+
// ── Output additions ──────────────────────────────────────────────────────
|
|
67
|
+
"sbom": false, // generate CycloneDX SBOM alongside the audit
|
|
68
|
+
"report": false, // generate human-readable compliance report (markdown)
|
|
69
|
+
"watch": false, // re-scan affected files on save (watch mode)
|
|
70
|
+
|
|
71
|
+
// ── Secret rotation ───────────────────────────────────────────────────────
|
|
72
|
+
"rotate_secrets": false, // when a hardcoded key is detected, prompt to rotate via provider API
|
|
73
|
+
|
|
74
|
+
// ── Extensibility ─────────────────────────────────────────────────────────
|
|
75
|
+
// See docs/extensibility.md for full documentation.
|
|
76
|
+
"pattern_repos": [],
|
|
77
|
+
"extra_skill_dirs": [],
|
|
78
|
+
"extra_repos": [],
|
|
79
|
+
"mcp_services": [],
|
|
80
|
+
"extra_domains": []
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## CLI flag equivalents
|
|
87
|
+
|
|
88
|
+
| Config key | CLI flag |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `output: "json"` | `--json` or `--format json` |
|
|
91
|
+
| `output: "sarif"` | `--format sarif` |
|
|
92
|
+
| `output: "report"` | `--format report` |
|
|
93
|
+
| `pr_mode: true` | `--pr` |
|
|
94
|
+
| `org_scan: "myorg"` | `--org myorg` |
|
|
95
|
+
| `open_pr: true` | `--open-pr` |
|
|
96
|
+
| `sbom: true` | `--sbom` |
|
|
97
|
+
| `watch: true` | `--watch` |
|
|
98
|
+
| `report: true` | `--report` |
|
|
99
|
+
| `rotate_secrets: true` | `--rotate-secrets` |
|
|
100
|
+
| `provider: "openai"` | `--provider openai` |
|
|
101
|
+
| `model: "gpt-4o"` | `--model gpt-4o` |
|
|
102
|
+
| `severityThreshold: "HIGH"` | `--threshold HIGH` |
|
|
103
|
+
|
|
104
|
+
CLI flags always win over file config.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Policy as code
|
|
109
|
+
|
|
110
|
+
`severity_overrides` lets you redefine what severity means for your org without forking the scanner. The key is the exact pattern name from the [vulnerability patterns reference](./vulnerability-patterns.md).
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
"severity_overrides": {
|
|
114
|
+
"CORS Wildcard": "CRITICAL"
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This is applied before findings are reported, before notifications fire, and before PR gates are evaluated. A pattern overridden to `CRITICAL` will block a PR merge just like any built-in CRITICAL.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Notifications
|
|
123
|
+
|
|
124
|
+
Both `webhook_url` and `slack_webhook` fire after every scan (CLI, `--ai`, and `POST /scan`).
|
|
125
|
+
|
|
126
|
+
**Webhook payload:**
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"project": "my-project",
|
|
130
|
+
"org": "My Org",
|
|
131
|
+
"timestamp": "2026-03-26T12:00:00Z",
|
|
132
|
+
"duration_ms": 4200,
|
|
133
|
+
"summary": { "critical": 1, "high": 3, "medium": 2, "low": 0 },
|
|
134
|
+
"findings": [ ... ]
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Slack message format:**
|
|
139
|
+
```
|
|
140
|
+
🔴 tdd-audit — my-project
|
|
141
|
+
1 critical · 3 high · 2 medium
|
|
142
|
+
Run /caller-audit to remediate.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## PR mode (`--pr`)
|
|
148
|
+
|
|
149
|
+
Designed for CI PR gates. Runs only the static scanner — no AI agents, no RAG, no fixes. Completes in under a second.
|
|
150
|
+
|
|
151
|
+
```yaml
|
|
152
|
+
- run: npx @lhi/tdd-audit@latest --pr --threshold HIGH
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Exits non-zero if any finding meets or exceeds `severityThreshold`. Wire into your branch protection rules to block merges automatically.
|
|
156
|
+
|
|
157
|
+
Use `severity_overrides` to tune what counts as a blocker for your stack.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Auto-fix PR (`--open-pr`)
|
|
162
|
+
|
|
163
|
+
Instead of committing fixes directly to the working branch, opens a GitHub PR per finding. Each PR contains:
|
|
164
|
+
- The exploit test (Red)
|
|
165
|
+
- The patch (Green)
|
|
166
|
+
- A description linking to the vulnerability pattern
|
|
167
|
+
|
|
168
|
+
Requires `GITHUB_TOKEN` in the environment or `github_token` in config.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Watch mode (`--watch`)
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npx @lhi/tdd-audit@latest --watch
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Re-runs the static scanner on any modified file on save. Reports new findings immediately in the terminal. Does not run agents or apply fixes — use `/caller-audit` for that.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## SBOM (`--sbom`)
|
|
183
|
+
|
|
184
|
+
Generates a [CycloneDX](https://cyclonedx.org/) Software Bill of Materials in JSON format alongside the audit report. Output to `sbom.json` in the project root.
|
|
185
|
+
|
|
186
|
+
Required for US federal contracts (EO 14028), increasingly required in enterprise vendor questionnaires.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Compliance report (`--format report` / `--report`)
|
|
191
|
+
|
|
192
|
+
Generates a markdown report suitable for attaching to a SOC 2 audit, ISO 27001 evidence package, or vendor security questionnaire. Includes:
|
|
193
|
+
|
|
194
|
+
- Findings summary table (severity, location, status)
|
|
195
|
+
- Fix evidence (exploit test name, patch commit, suite result)
|
|
196
|
+
- Coverage gate result
|
|
197
|
+
- Hardening controls applied
|
|
198
|
+
- SBOM reference (if generated)
|
|
199
|
+
- Timestamp and auditor (org/project from config)
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Org scan (`--org`)
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npx @lhi/tdd-audit@latest --org my-github-org --format report
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Discovers all repos in a GitHub org, runs `--pr` mode on each, and produces a cross-org summary:
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
my-github-org security posture — 2026-03-26
|
|
213
|
+
|
|
214
|
+
✅ repo-a 0 critical · 0 high
|
|
215
|
+
⚠️ repo-b 0 critical · 2 high
|
|
216
|
+
🔴 repo-c 1 critical · 4 high
|
|
217
|
+
|
|
218
|
+
3 repos scanned · 1 critical · 6 high total
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Fires `webhook_url` and `slack_webhook` with the aggregate payload if configured.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Secret rotation (`--rotate-secrets`)
|
|
226
|
+
|
|
227
|
+
When a hardcoded API key is detected, prompts to rotate it via the provider's API. Supported providers:
|
|
228
|
+
|
|
229
|
+
| Secret type | Rotation method |
|
|
230
|
+
|---|---|
|
|
231
|
+
| OpenAI key (`sk-...`) | OpenAI API — revoke + generate new key |
|
|
232
|
+
| Anthropic key (`sk-ant-...`) | Anthropic console link + clipboard |
|
|
233
|
+
| GitHub token | GitHub API — revoke token |
|
|
234
|
+
| Supabase service key | Supabase API — regenerate |
|
|
235
|
+
|
|
236
|
+
After rotation, updates the relevant `.env` file and removes the hardcoded value from source. The old key is invalidated whether you commit the change or not.
|
package/lib/auditor.js
CHANGED
|
@@ -16,6 +16,7 @@ function loadSkillSuite(packageDir) {
|
|
|
16
16
|
['hardening-phase.md', path.join(packageDir, 'prompts', 'hardening-phase.md')],
|
|
17
17
|
['ai-security.md', path.join(packageDir, 'prompts', 'ai-security.md')],
|
|
18
18
|
['node-advanced-security.md', path.join(packageDir, 'prompts', 'node-advanced-security.md')],
|
|
19
|
+
['security-test-patterns.md', path.join(packageDir, 'prompts', 'security-test-patterns.md')],
|
|
19
20
|
];
|
|
20
21
|
const suite = {};
|
|
21
22
|
for (const [name, filePath] of entries) {
|