security-mcp 1.0.5 → 1.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.
Files changed (35) hide show
  1. package/defaults/checklists/ai.json +25 -0
  2. package/defaults/checklists/api.json +27 -0
  3. package/defaults/checklists/infra.json +27 -0
  4. package/defaults/checklists/mobile.json +25 -0
  5. package/defaults/checklists/payments.json +25 -0
  6. package/defaults/checklists/web.json +30 -0
  7. package/defaults/control-catalog.json +392 -0
  8. package/defaults/evidence-map.json +194 -0
  9. package/defaults/security-policy.json +41 -2
  10. package/dist/cli/index.js +13 -8
  11. package/dist/cli/install.js +11 -0
  12. package/dist/cli/onboarding.js +590 -0
  13. package/dist/gate/baseline.js +115 -0
  14. package/dist/gate/checks/ai-redteam.js +374 -0
  15. package/dist/gate/checks/api.js +93 -0
  16. package/dist/gate/checks/crypto.js +153 -0
  17. package/dist/gate/checks/database.js +144 -0
  18. package/dist/gate/checks/dependencies.js +126 -0
  19. package/dist/gate/checks/dlp.js +153 -0
  20. package/dist/gate/checks/graphql.js +122 -0
  21. package/dist/gate/checks/infra.js +126 -12
  22. package/dist/gate/checks/k8s.js +190 -0
  23. package/dist/gate/checks/playbook.js +160 -0
  24. package/dist/gate/checks/runtime.js +263 -0
  25. package/dist/gate/checks/sbom.js +199 -0
  26. package/dist/gate/checks/scanners.js +373 -7
  27. package/dist/gate/checks/secrets.js +85 -20
  28. package/dist/gate/policy.js +85 -19
  29. package/dist/gate/threat-intel.js +157 -0
  30. package/dist/mcp/server.js +500 -5
  31. package/dist/repo/search.js +13 -1
  32. package/dist/review/store.js +128 -0
  33. package/package.json +1 -1
  34. package/prompts/SECURITY_PROMPT.md +415 -1
  35. package/skills/senior-security-engineer/SKILL.md +35 -3
@@ -122,5 +122,199 @@
122
122
  "src/**/tool-router*.ts",
123
123
  "src/**/tool*.ts",
124
124
  "src/**/agent*.ts"
125
+ ],
126
+ "mfa_enforced": [
127
+ "src/**/mfa*.ts",
128
+ "src/**/mfa*.js",
129
+ "src/**/totp*.ts",
130
+ "src/**/webauthn*.ts",
131
+ "src/**/passkey*.ts",
132
+ "src/**/two-factor*.ts",
133
+ "src/**/2fa*.ts",
134
+ "infra/**",
135
+ "terraform/**",
136
+ "k8s/**"
137
+ ],
138
+ "audit_logging_configured": [
139
+ "src/**/audit*.ts",
140
+ "src/**/audit*.js",
141
+ "src/**/logger*.ts",
142
+ "src/**/logging*.ts",
143
+ "src/**/log*.ts",
144
+ "lib/**/audit*.ts",
145
+ "infra/**",
146
+ "terraform/**",
147
+ "k8s/**",
148
+ "helm/**"
149
+ ],
150
+ "log_retention_policy": [
151
+ "infra/**",
152
+ "terraform/**",
153
+ "k8s/**",
154
+ "helm/**",
155
+ "docs/**",
156
+ "security/**",
157
+ ".mcp/**"
158
+ ],
159
+ "alerting_configured": [
160
+ "infra/**",
161
+ "terraform/**",
162
+ "k8s/**",
163
+ "helm/**",
164
+ "src/**/alert*.ts",
165
+ "src/**/alarm*.ts",
166
+ "src/**/monitor*.ts",
167
+ "src/**/pagerduty*.ts",
168
+ "src/**/opsgenie*.ts"
169
+ ],
170
+ "email_filtering": [
171
+ "infra/**",
172
+ "terraform/**",
173
+ "docs/**",
174
+ "security/**"
175
+ ],
176
+ "public_surface_hardened": [
177
+ "infra/**",
178
+ "terraform/**",
179
+ "k8s/**",
180
+ "helm/**",
181
+ "src/**/waf*.ts",
182
+ "src/**/ddos*.ts",
183
+ "nginx/**",
184
+ "caddy/**"
185
+ ],
186
+ "rate_limiting_present": [
187
+ "src/**/rate-limit*.ts",
188
+ "src/**/rateLimit*.ts",
189
+ "src/**/throttle*.ts",
190
+ "src/**/middleware*.ts",
191
+ "middleware.ts",
192
+ "middleware.js",
193
+ "app/api/**",
194
+ "src/api/**"
195
+ ],
196
+ "egress_controls": [
197
+ "infra/**",
198
+ "terraform/**",
199
+ "k8s/**",
200
+ "helm/**",
201
+ "src/**/egress*.ts",
202
+ "src/**/firewall*.ts",
203
+ "src/**/network*.ts"
204
+ ],
205
+ "dlp_configured": [
206
+ "src/**/dlp*.ts",
207
+ "src/**/dlp*.js",
208
+ "src/**/pii*.ts",
209
+ "src/**/redact*.ts",
210
+ "src/**/sanitize*.ts",
211
+ "infra/**",
212
+ "terraform/**"
213
+ ],
214
+ "artifact_signing": [
215
+ ".github/workflows/**",
216
+ ".gitlab-ci.yml",
217
+ "cloudbuild.yaml",
218
+ "Makefile",
219
+ "scripts/**",
220
+ "infra/**",
221
+ "cosign.pub",
222
+ "*.pub"
223
+ ],
224
+ "hermetic_build_configured": [
225
+ ".github/workflows/**",
226
+ ".gitlab-ci.yml",
227
+ "cloudbuild.yaml",
228
+ "Makefile",
229
+ "scripts/**",
230
+ "BUILD",
231
+ "BUILD.bazel"
232
+ ],
233
+ "ir_playbook_present": [
234
+ "security/**",
235
+ "docs/security/**",
236
+ "runbooks/**",
237
+ "playbooks/**",
238
+ ".mcp/**"
239
+ ],
240
+ "ir_playbook_tested": [
241
+ "security/**",
242
+ "docs/security/**",
243
+ "runbooks/**",
244
+ "playbooks/**"
245
+ ],
246
+ "network_segmentation": [
247
+ "infra/**",
248
+ "terraform/**",
249
+ "k8s/**",
250
+ "helm/**"
251
+ ],
252
+ "zero_trust_network": [
253
+ "infra/**",
254
+ "terraform/**",
255
+ "k8s/**",
256
+ "helm/**",
257
+ "src/**/mtls*.ts",
258
+ "src/**/spiffe*.ts",
259
+ "src/**/zero-trust*.ts"
260
+ ],
261
+ "backup_encryption": [
262
+ "infra/**",
263
+ "terraform/**",
264
+ "k8s/**"
265
+ ],
266
+ "backup_tested": [
267
+ "docs/**",
268
+ "security/**",
269
+ "runbooks/**"
270
+ ],
271
+ "dns_monitoring": [
272
+ "infra/**",
273
+ "terraform/**"
274
+ ],
275
+ "pan_encryption_configured": [
276
+ "infra/**",
277
+ "terraform/**",
278
+ "src/**/payment*.ts",
279
+ "src/**/card*.ts",
280
+ "src/**/stripe*.ts",
281
+ "src/**/braintree*.ts"
282
+ ],
283
+ "no_plaintext_pan": [
284
+ "**/*.ts",
285
+ "**/*.js",
286
+ "**/*.py",
287
+ "**/*.go",
288
+ "**/*.java"
289
+ ],
290
+ "input_validation_schema": [
291
+ "src/**",
292
+ "app/**",
293
+ "lib/**",
294
+ "server/**"
295
+ ],
296
+ "output_encoding_present": [
297
+ "src/**",
298
+ "app/**",
299
+ "lib/**"
300
+ ],
301
+ "service_account_per_workload": [
302
+ "infra/**",
303
+ "terraform/**",
304
+ "k8s/**",
305
+ "helm/**"
306
+ ],
307
+ "human_in_loop_for_actions": [
308
+ "ai/**",
309
+ "src/**/agent*.ts",
310
+ "src/**/tool*.ts",
311
+ "src/**/confirm*.ts",
312
+ "src/**/approval*.ts"
313
+ ],
314
+ "input_length_limits": [
315
+ "src/**",
316
+ "app/**",
317
+ "middleware.ts",
318
+ "middleware.js"
125
319
  ]
126
320
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "security-policy",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Default security gate policy for security-mcp. Copy to .mcp/policies/security-policy.json and customize for your project.",
5
5
  "required_checks": {
6
6
  "secrets_scan": { "severity_block": ["HIGH", "CRITICAL"] },
@@ -8,6 +8,44 @@
8
8
  "sast": { "severity_block": ["CRITICAL"] },
9
9
  "iac_scan": { "severity_block": ["HIGH", "CRITICAL"] }
10
10
  },
11
+ "environments": {
12
+ "dev": {
13
+ "severity_block": ["CRITICAL"],
14
+ "required_scanners": ["gitleaks"],
15
+ "required_checks": ["secrets_scan"],
16
+ "vulnerability_slas": {
17
+ "CRITICAL": "7d",
18
+ "HIGH": "30d",
19
+ "MEDIUM": "90d",
20
+ "LOW": "never"
21
+ }
22
+ },
23
+ "staging": {
24
+ "severity_block": ["HIGH", "CRITICAL"],
25
+ "required_scanners": ["gitleaks", "semgrep", "osv-scanner"],
26
+ "required_checks": ["secrets_scan", "dependency_scan", "sast"],
27
+ "vulnerability_slas": {
28
+ "CRITICAL": "24h",
29
+ "HIGH": "7d",
30
+ "MEDIUM": "30d",
31
+ "LOW": "90d",
32
+ "CISA_KEV": "24h"
33
+ }
34
+ },
35
+ "prod": {
36
+ "severity_block": ["MEDIUM", "HIGH", "CRITICAL"],
37
+ "required_scanners": ["gitleaks", "semgrep", "osv-scanner", "trivy", "checkov"],
38
+ "required_checks": ["secrets_scan", "dependency_scan", "sast", "iac_scan"],
39
+ "vulnerability_slas": {
40
+ "CRITICAL": "24h",
41
+ "HIGH": "7d",
42
+ "MEDIUM": "30d",
43
+ "LOW": "90d",
44
+ "CISA_KEV": "24h",
45
+ "HIGH_EPSS": "48h"
46
+ }
47
+ }
48
+ },
11
49
  "requirements": [
12
50
  {
13
51
  "id": "ZERO_TRUST",
@@ -84,7 +122,8 @@
84
122
  "HIGH": "7d",
85
123
  "MEDIUM": "30d",
86
124
  "LOW": "90d",
87
- "CISA_KEV": "24h"
125
+ "CISA_KEV": "24h",
126
+ "HIGH_EPSS": "48h"
88
127
  },
89
128
  "exceptions": {
90
129
  "require_ticket": true,
package/dist/cli/index.js CHANGED
@@ -57,12 +57,14 @@ COMMANDS
57
57
  config Print MCP config JSON for manual editor setup
58
58
 
59
59
  OPTIONS (install)
60
- --claude-code Write config for Claude Code only
61
- --cursor Write config for Cursor only
62
- --vscode Write config for VS Code only
63
- --global Write to global editor config (default)
60
+ --claude-code Write config for Claude Code only
61
+ --cursor Write config for Cursor only
62
+ --vscode Write config for VS Code only
63
+ --global Write to global editor config (default)
64
64
  --use-global-binary Write configs that execute "security-mcp serve" instead of npx
65
- --dry-run Print what would change without writing
65
+ --dry-run Print what would change without writing
66
+ --yes Skip interactive setup questions (install with defaults)
67
+ --non-interactive Same as --yes (for CI environments)
66
68
 
67
69
  OPTIONS (general)
68
70
  --version Print version
@@ -131,26 +133,29 @@ async function main() {
131
133
  break;
132
134
  }
133
135
  case "install": {
136
+ const noEditorFlag = !args.includes("--claude-code") && !args.includes("--cursor") && !args.includes("--vscode");
134
137
  const options = {
135
138
  claudeCode: args.includes("--claude-code"),
136
139
  cursor: args.includes("--cursor"),
137
140
  vscode: args.includes("--vscode"),
138
141
  dryRun: args.includes("--dry-run"),
139
142
  useGlobalBinary,
140
- // If no editor flag specified, install to all detected
141
- all: !args.includes("--claude-code") && !args.includes("--cursor") && !args.includes("--vscode")
143
+ all: noEditorFlag,
144
+ interactive: !args.includes("--yes") && !args.includes("--non-interactive")
142
145
  };
143
146
  await runInstall(options);
144
147
  break;
145
148
  }
146
149
  case "install-global": {
150
+ const noEditorFlag = !args.includes("--claude-code") && !args.includes("--cursor") && !args.includes("--vscode");
147
151
  const options = {
148
152
  claudeCode: args.includes("--claude-code"),
149
153
  cursor: args.includes("--cursor"),
150
154
  vscode: args.includes("--vscode"),
151
155
  dryRun: args.includes("--dry-run"),
152
156
  useGlobalBinary: true,
153
- all: !args.includes("--claude-code") && !args.includes("--cursor") && !args.includes("--vscode")
157
+ all: noEditorFlag,
158
+ interactive: !args.includes("--yes") && !args.includes("--non-interactive")
154
159
  };
155
160
  await runInstall(options);
156
161
  break;
@@ -7,6 +7,7 @@ import { readFileSync, writeFileSync, mkdirSync, existsSync, copyFileSync } from
7
7
  import { dirname, join, resolve } from "node:path";
8
8
  import { homedir, platform } from "node:os";
9
9
  import { fileURLToPath } from "node:url";
10
+ import { runOnboarding, installSecurityTools, commandExists, SECURITY_TOOLS } from "./onboarding.js";
10
11
  const __dirname = dirname(fileURLToPath(import.meta.url));
11
12
  const PKG_ROOT = resolve(__dirname, "../..");
12
13
  function resolveHome(p) {
@@ -159,6 +160,16 @@ function installSkill(dryRun) {
159
160
  }
160
161
  export async function runInstall(opts) {
161
162
  const dryRun = opts.dryRun;
163
+ // ── Interactive onboarding (skipped when --yes or non-TTY) ──────────────
164
+ if (opts.interactive && !dryRun) {
165
+ const onboarding = await runOnboarding();
166
+ if (onboarding?.installTools) {
167
+ const toInstall = SECURITY_TOOLS.filter((t) => !commandExists(t.id));
168
+ process.stdout.write("\nInstalling security scanning tools...\n");
169
+ await installSecurityTools(toInstall);
170
+ process.stdout.write("\n");
171
+ }
172
+ }
162
173
  process.stdout.write(`\nsecurity-mcp installer${dryRun ? " (dry-run)" : ""}\n`);
163
174
  process.stdout.write("=".repeat(40) + "\n\n");
164
175
  const targets = getEditorTargets(opts);