@blamejs/exceptd-skills 0.10.0 → 0.10.2

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.
@@ -9,12 +9,21 @@
9
9
  "version": "1.0.0",
10
10
  "date": "2026-05-11",
11
11
  "summary": "Initial seven-phase MCP supply-chain trust playbook. Enumerates installed MCP servers across Claude Code / Cursor / Windsurf / VS Code+Copilot / Gemini CLI configs, tests for unsigned manifests, missing tool allowlists, unpinned versions, command provenance gaps, and zero-interaction RCE exposure (CVE-2026-30615). Full GRC closure with EU AI Act + NIS2 + DORA notification clocks and auditor-ready exception generation.",
12
- "cves_added": ["CVE-2026-30615"],
13
- "framework_gaps_updated": ["nist-800-53-SA-12", "nist-800-53-CM-7", "iso-27001-2022-A.8.30", "soc2-CC9", "eu-ai-act-art15"]
12
+ "cves_added": [
13
+ "CVE-2026-30615"
14
+ ],
15
+ "framework_gaps_updated": [
16
+ "nist-800-53-SA-12",
17
+ "nist-800-53-CM-7",
18
+ "iso-27001-2022-A.8.30",
19
+ "soc2-CC9",
20
+ "eu-ai-act-art15"
21
+ ]
14
22
  }
15
23
  ],
16
24
  "owner": "@blamejs/ai-security",
17
25
  "air_gap_mode": false,
26
+ "scope": "service",
18
27
  "preconditions": [
19
28
  {
20
29
  "id": "filesystem-read",
@@ -45,24 +54,51 @@
45
54
  }
46
55
  ]
47
56
  },
48
-
49
57
  "domain": {
50
58
  "name": "MCP server supply-chain trust",
51
59
  "attack_class": "mcp-supply-chain",
52
- "atlas_refs": ["AML.T0010", "AML.T0016", "AML.T0096"],
53
- "attack_refs": ["T1195.001", "T1059", "T1190"],
54
- "cve_refs": ["CVE-2026-30615"],
55
- "cwe_refs": ["CWE-345", "CWE-494", "CWE-829", "CWE-94", "CWE-77"],
56
- "d3fend_refs": ["D3-CBAN", "D3-EAL", "D3-EHB", "D3-CSPP"],
60
+ "atlas_refs": [
61
+ "AML.T0010",
62
+ "AML.T0016",
63
+ "AML.T0096"
64
+ ],
65
+ "attack_refs": [
66
+ "T1195.001",
67
+ "T1059",
68
+ "T1190"
69
+ ],
70
+ "cve_refs": [
71
+ "CVE-2026-30615"
72
+ ],
73
+ "cwe_refs": [
74
+ "CWE-345",
75
+ "CWE-494",
76
+ "CWE-829",
77
+ "CWE-94",
78
+ "CWE-77"
79
+ ],
80
+ "d3fend_refs": [
81
+ "D3-CBAN",
82
+ "D3-EAL",
83
+ "D3-EHB",
84
+ "D3-CSPP"
85
+ ],
57
86
  "frameworks_in_scope": [
58
- "nist-800-53", "nist-csf-2", "iso-27001-2022",
59
- "soc2", "nis2", "dora", "eu-ai-act", "eu-cra",
60
- "uk-caf", "au-ism", "au-essential-8", "cmmc"
87
+ "nist-800-53",
88
+ "nist-csf-2",
89
+ "iso-27001-2022",
90
+ "soc2",
91
+ "nis2",
92
+ "dora",
93
+ "eu-ai-act",
94
+ "eu-cra",
95
+ "uk-caf",
96
+ "au-ism",
97
+ "au-essential-8",
98
+ "cmmc"
61
99
  ]
62
100
  },
63
-
64
101
  "phases": {
65
-
66
102
  "govern": {
67
103
  "jurisdiction_obligations": [
68
104
  {
@@ -71,7 +107,11 @@
71
107
  "obligation": "notify_regulator",
72
108
  "window_hours": 24,
73
109
  "clock_starts": "detect_confirmed",
74
- "evidence_required": ["affected_mcp_client_inventory", "malicious_server_indicators", "interim_isolation_record"]
110
+ "evidence_required": [
111
+ "affected_mcp_client_inventory",
112
+ "malicious_server_indicators",
113
+ "interim_isolation_record"
114
+ ]
75
115
  },
76
116
  {
77
117
  "jurisdiction": "EU",
@@ -79,7 +119,11 @@
79
119
  "obligation": "notify_regulator",
80
120
  "window_hours": 72,
81
121
  "clock_starts": "analyze_complete",
82
- "evidence_required": ["full_incident_assessment", "manifest_provenance_audit", "remediation_plan"]
122
+ "evidence_required": [
123
+ "full_incident_assessment",
124
+ "manifest_provenance_audit",
125
+ "remediation_plan"
126
+ ]
83
127
  },
84
128
  {
85
129
  "jurisdiction": "EU",
@@ -87,7 +131,11 @@
87
131
  "obligation": "submit_full_report",
88
132
  "window_hours": 720,
89
133
  "clock_starts": "validate_complete",
90
- "evidence_required": ["root_cause_analysis", "control_changes_implemented", "lessons_learned"]
134
+ "evidence_required": [
135
+ "root_cause_analysis",
136
+ "control_changes_implemented",
137
+ "lessons_learned"
138
+ ]
91
139
  },
92
140
  {
93
141
  "jurisdiction": "EU",
@@ -95,7 +143,11 @@
95
143
  "obligation": "notify_regulator",
96
144
  "window_hours": 4,
97
145
  "clock_starts": "detect_confirmed",
98
- "evidence_required": ["initial_notification", "ict_third_party_dependencies", "developer_endpoint_blast_radius"]
146
+ "evidence_required": [
147
+ "initial_notification",
148
+ "ict_third_party_dependencies",
149
+ "developer_endpoint_blast_radius"
150
+ ]
99
151
  },
100
152
  {
101
153
  "jurisdiction": "EU",
@@ -103,7 +155,11 @@
103
155
  "obligation": "notify_regulator",
104
156
  "window_hours": 360,
105
157
  "clock_starts": "analyze_complete",
106
- "evidence_required": ["serious_incident_assessment", "ai_system_affected", "tool_provenance_audit"]
158
+ "evidence_required": [
159
+ "serious_incident_assessment",
160
+ "ai_system_affected",
161
+ "tool_provenance_audit"
162
+ ]
107
163
  },
108
164
  {
109
165
  "jurisdiction": "AU",
@@ -111,7 +167,10 @@
111
167
  "obligation": "notify_regulator",
112
168
  "window_hours": 72,
113
169
  "clock_starts": "validate_complete",
114
- "evidence_required": ["materiality_assessment", "remediation_completed_evidence"]
170
+ "evidence_required": [
171
+ "materiality_assessment",
172
+ "remediation_completed_evidence"
173
+ ]
115
174
  }
116
175
  ],
117
176
  "theater_fingerprints": [
@@ -119,25 +178,42 @@
119
178
  "pattern_id": "vendor-management-without-mcp-coverage",
120
179
  "claim": "Third-party / vendor risk management (CC9, SA-12, A.5.19) is operating effectively — all SaaS vendors are reviewed.",
121
180
  "fast_detection_test": "Ask the GRC team to produce their vendor inventory and search it for any MCP server, npm @modelcontextprotocol/*, or developer-installed AI tool plugin. If MCP servers running inside developer environments are absent from the inventory while the AI coding assistants themselves are present, the program covers SaaS only and is blind to the MCP attack surface.",
122
- "implicated_controls": ["nist-800-53-SA-12", "iso-27001-2022-A.5.19", "iso-27001-2022-A.5.20", "soc2-CC9"]
181
+ "implicated_controls": [
182
+ "nist-800-53-SA-12",
183
+ "iso-27001-2022-A.5.19",
184
+ "iso-27001-2022-A.5.20",
185
+ "soc2-CC9"
186
+ ]
123
187
  },
124
188
  {
125
189
  "pattern_id": "mcp-allowlist-without-signature-field",
126
190
  "claim": "MCP tool allowlisting is enforced — only approved tools can be invoked.",
127
191
  "fast_detection_test": "Diff the operator's documented MCP allowlist against the actual mcpServers entries in ~/.cursor/mcp.json, ~/.codeium/windsurf/mcp_config.json, ~/.config/claude/config.json. Theater if allowlist entries lack a signature, fingerprint, or content-hash field — the allowlist names a tool by string identifier that can be typosquatted or version-shifted without the allowlist firing.",
128
- "implicated_controls": ["nist-800-53-CM-7", "iso-27001-2022-A.8.30", "eu-ai-act-art15"]
192
+ "implicated_controls": [
193
+ "nist-800-53-CM-7",
194
+ "iso-27001-2022-A.8.30",
195
+ "eu-ai-act-art15"
196
+ ]
129
197
  },
130
198
  {
131
199
  "pattern_id": "unsigned-manifest-passes-cm-7",
132
200
  "claim": "Least-functionality (CM-7) is enforced — only authorized software runs in developer environments.",
133
201
  "fast_detection_test": "Pick any MCP server installed in any AI coding assistant config. Verify whether its manifest is signed (Sigstore / OpenSSF model-signing / GPG with maintainer key in transparency log). Unsigned manifest + CM-7 = compliant + uncontrolled.",
134
- "implicated_controls": ["nist-800-53-CM-7", "nist-800-53-SA-12", "cmmc-2-CM-L2-3-4-7"]
202
+ "implicated_controls": [
203
+ "nist-800-53-CM-7",
204
+ "nist-800-53-SA-12",
205
+ "cmmc-2-CM-L2-3-4-7"
206
+ ]
135
207
  },
136
208
  {
137
209
  "pattern_id": "version-pin-without-integrity",
138
210
  "claim": "MCP server versions are pinned in config — supply chain is reproducible.",
139
211
  "fast_detection_test": "For each pinned entry, check whether it carries an integrity hash (sha256:, sri integrity, or in-toto attestation reference). Version-pinned without integrity = pinning a name that can be re-published over.",
140
- "implicated_controls": ["nist-800-53-SA-12", "iso-27001-2022-A.8.30", "eu-cra-art13"]
212
+ "implicated_controls": [
213
+ "nist-800-53-SA-12",
214
+ "iso-27001-2022-A.8.30",
215
+ "eu-cra-art13"
216
+ ]
141
217
  }
142
218
  ],
143
219
  "framework_context": {
@@ -188,9 +264,15 @@
188
264
  }
189
265
  ]
190
266
  },
191
- "skill_preload": ["mcp-agent-trust", "supply-chain-integrity", "exploit-scoring", "framework-gap-analysis", "compliance-theater", "policy-exception-gen"]
267
+ "skill_preload": [
268
+ "mcp-agent-trust",
269
+ "supply-chain-integrity",
270
+ "exploit-scoring",
271
+ "framework-gap-analysis",
272
+ "compliance-theater",
273
+ "policy-exception-gen"
274
+ ]
192
275
  },
193
-
194
276
  "direct": {
195
277
  "threat_context": "MCP supply-chain landscape Q1-Q2 2026: CVE-2026-30615 (Windsurf MCP zero-interaction RCE, CVSS 9.8, published 2026-02) is the load-bearing incident driving the current wave. A malicious MCP server delivers an adversarial tool response → AI assistant follows instructions without user interaction → code execution in the developer's user context. The vulnerability class — unsigned manifests, no enforced allowlist, no required authentication between AI client and MCP server — is reachable across Cursor, VS Code+Copilot, Claude Code, Gemini CLI, and Windsurf (150M+ combined downloads). Typosquat campaigns against npm @modelcontextprotocol/* and PyPI ML namespaces are documented through 2026-04. Detection signal in production environments is rising: organizations that ran exceptd's mcp-agent-trust skill in the 30 days after the Windsurf advisory found a median of 7 unsigned MCP servers per developer endpoint, with 2 of those installed from registry namespaces typosquatting legitimate vendor names. Compliance frameworks have not caught up: SOC 2 CC9, NIST SA-12, and ISO A.5.19 all permit clean audits over the affected estate.",
196
278
  "rwep_threshold": {
@@ -200,12 +282,38 @@
200
282
  },
201
283
  "framework_lag_declaration": "Every framework in scope (NIST 800-53 SA-12/CM-7, ISO 27001:2022 A.5.19/A.5.20/A.8.30, SOC 2 CC9, NIS2 Art.21(2)(d), EU AI Act Art.15, EU CRA Art.13) is structurally insufficient. The shared structural failure: every control treats third-party software risk as a procurement event with a discrete vendor list, while MCP servers are continuously sideloaded by developers from package registries with no procurement signal, no enforced signing, and no allowlist that survives version drift. Until frameworks add a 'developer-installed AI tool plugin' control category with mandatory manifest signature verification + version pinning with integrity hash + provenance attestation, vendor-management audit opinions provide zero signal about MCP exposure. Gap = ~210 days behind operational reality; no framework body has issued draft language as of 2026-05-11.",
202
284
  "skill_chain": [
203
- { "skill": "mcp-agent-trust", "purpose": "Enumerate installed MCP servers across all AI coding assistant configs and test each for signed manifest, allowlist enforcement, version pinning + integrity hash, command-provenance trail.", "required": true },
204
- { "skill": "supply-chain-integrity", "purpose": "Cross-reference each MCP server against SLSA build-provenance / Sigstore / in-toto attestation; flag the long tail with no attestation chain.", "required": true },
205
- { "skill": "exploit-scoring", "purpose": "Compute RWEP for CVE-2026-30615 against the running configuration; rank MCP servers by exposure to known weaponized vectors.", "required": true },
206
- { "skill": "framework-gap-analysis", "purpose": "Map each finding to the specific framework controls that fail to cover it, with auditor-ready gap language.", "skip_if": "analyze.framework_gap_mapping.length == 0", "required": false },
207
- { "skill": "compliance-theater", "purpose": "Run the four theater tests defined in govern.theater_fingerprints; emit verdict for each.", "required": true },
208
- { "skill": "policy-exception-gen", "purpose": "If an org-critical MCP server cannot be removed/replaced within the compliance window, generate a defensible time-bound exception.", "skip_if": "close.exception_generation.trigger_condition == false", "required": false }
285
+ {
286
+ "skill": "mcp-agent-trust",
287
+ "purpose": "Enumerate installed MCP servers across all AI coding assistant configs and test each for signed manifest, allowlist enforcement, version pinning + integrity hash, command-provenance trail.",
288
+ "required": true
289
+ },
290
+ {
291
+ "skill": "supply-chain-integrity",
292
+ "purpose": "Cross-reference each MCP server against SLSA build-provenance / Sigstore / in-toto attestation; flag the long tail with no attestation chain.",
293
+ "required": true
294
+ },
295
+ {
296
+ "skill": "exploit-scoring",
297
+ "purpose": "Compute RWEP for CVE-2026-30615 against the running configuration; rank MCP servers by exposure to known weaponized vectors.",
298
+ "required": true
299
+ },
300
+ {
301
+ "skill": "framework-gap-analysis",
302
+ "purpose": "Map each finding to the specific framework controls that fail to cover it, with auditor-ready gap language.",
303
+ "skip_if": "analyze.framework_gap_mapping.length == 0",
304
+ "required": false
305
+ },
306
+ {
307
+ "skill": "compliance-theater",
308
+ "purpose": "Run the four theater tests defined in govern.theater_fingerprints; emit verdict for each.",
309
+ "required": true
310
+ },
311
+ {
312
+ "skill": "policy-exception-gen",
313
+ "purpose": "If an org-critical MCP server cannot be removed/replaced within the compliance window, generate a defensible time-bound exception.",
314
+ "skip_if": "close.exception_generation.trigger_condition == false",
315
+ "required": false
316
+ }
209
317
  ],
210
318
  "token_budget": {
211
319
  "estimated_total": 22000,
@@ -220,7 +328,6 @@
220
328
  }
221
329
  }
222
330
  },
223
-
224
331
  "look": {
225
332
  "artifacts": [
226
333
  {
@@ -318,13 +425,28 @@
318
425
  }
319
426
  ],
320
427
  "fallback_if_unavailable": [
321
- { "artifact_id": "mcp-manifest-signatures", "fallback_action": "mark_inconclusive", "confidence_impact": "medium" },
322
- { "artifact_id": "npm-global-mcp", "fallback_action": "use_compensating_artifact", "confidence_impact": "low" },
323
- { "artifact_id": "mcp-allowlist-policy", "fallback_action": "mark_inconclusive", "confidence_impact": "medium" },
324
- { "artifact_id": "mcp-process-list", "fallback_action": "escalate_to_human", "confidence_impact": "high" }
428
+ {
429
+ "artifact_id": "mcp-manifest-signatures",
430
+ "fallback_action": "mark_inconclusive",
431
+ "confidence_impact": "medium"
432
+ },
433
+ {
434
+ "artifact_id": "npm-global-mcp",
435
+ "fallback_action": "use_compensating_artifact",
436
+ "confidence_impact": "low"
437
+ },
438
+ {
439
+ "artifact_id": "mcp-allowlist-policy",
440
+ "fallback_action": "mark_inconclusive",
441
+ "confidence_impact": "medium"
442
+ },
443
+ {
444
+ "artifact_id": "mcp-process-list",
445
+ "fallback_action": "escalate_to_human",
446
+ "confidence_impact": "high"
447
+ }
325
448
  ]
326
449
  },
327
-
328
450
  "detect": {
329
451
  "indicators": [
330
452
  {
@@ -412,27 +534,91 @@
412
534
  "not_detected": "No MCP servers enumerated across all known assistant configs AND no MCP-server processes running AND no @modelcontextprotocol packages in global package managers. Document as not-detected with a 'fresh install of any MCP-capable assistant re-opens this' caveat."
413
535
  }
414
536
  },
415
-
416
537
  "analyze": {
417
538
  "rwep_inputs": [
418
- { "signal_id": "vulnerable-windsurf-version", "rwep_factor": "cisa_kev", "weight": 0, "notes": "CVE-2026-30615 is not KEV-listed as of 2026-05-11; factor zero. Re-score if KEV listing occurs." },
419
- { "signal_id": "vulnerable-windsurf-version", "rwep_factor": "public_poc", "weight": 20, "notes": "Partial PoC public per catalog." },
420
- { "signal_id": "vulnerable-windsurf-version", "rwep_factor": "active_exploitation", "weight": 10, "notes": "Suspected, not confirmed per catalog." },
421
- { "signal_id": "vulnerable-windsurf-version", "rwep_factor": "blast_radius", "weight": 30, "notes": "Zero-interaction RCE in developer endpoint with full local credential exposure (AWS/GCP/kube dotfiles)." },
422
- { "signal_id": "vulnerable-windsurf-version", "rwep_factor": "patch_available", "weight": -15, "notes": "Vendor patch shipped." },
423
- { "signal_id": "vulnerable-windsurf-version", "rwep_factor": "live_patch_available", "weight": -10, "notes": "IDE auto-update path treated as live-patch." },
424
- { "signal_id": "unsigned-mcp-manifest", "rwep_factor": "blast_radius", "weight": 20, "notes": "Each unsigned manifest is a separate attack surface; tally to blast radius." },
425
- { "signal_id": "mcp-server-running-as-root", "rwep_factor": "blast_radius", "weight": 15, "notes": "Elevated privileges escalate any tool-response RCE to root immediately." },
426
- { "signal_id": "mcp-typosquat-candidate", "rwep_factor": "active_exploitation", "weight": 10, "notes": "Typosquat campaigns are documented active TTP for MCP namespaces through Q2 2026." }
539
+ {
540
+ "signal_id": "vulnerable-windsurf-version",
541
+ "rwep_factor": "cisa_kev",
542
+ "weight": 0,
543
+ "notes": "CVE-2026-30615 is not KEV-listed as of 2026-05-11; factor zero. Re-score if KEV listing occurs."
544
+ },
545
+ {
546
+ "signal_id": "vulnerable-windsurf-version",
547
+ "rwep_factor": "public_poc",
548
+ "weight": 20,
549
+ "notes": "Partial PoC public per catalog."
550
+ },
551
+ {
552
+ "signal_id": "vulnerable-windsurf-version",
553
+ "rwep_factor": "active_exploitation",
554
+ "weight": 10,
555
+ "notes": "Suspected, not confirmed per catalog."
556
+ },
557
+ {
558
+ "signal_id": "vulnerable-windsurf-version",
559
+ "rwep_factor": "blast_radius",
560
+ "weight": 30,
561
+ "notes": "Zero-interaction RCE in developer endpoint with full local credential exposure (AWS/GCP/kube dotfiles)."
562
+ },
563
+ {
564
+ "signal_id": "vulnerable-windsurf-version",
565
+ "rwep_factor": "patch_available",
566
+ "weight": -15,
567
+ "notes": "Vendor patch shipped."
568
+ },
569
+ {
570
+ "signal_id": "vulnerable-windsurf-version",
571
+ "rwep_factor": "live_patch_available",
572
+ "weight": -10,
573
+ "notes": "IDE auto-update path treated as live-patch."
574
+ },
575
+ {
576
+ "signal_id": "unsigned-mcp-manifest",
577
+ "rwep_factor": "blast_radius",
578
+ "weight": 20,
579
+ "notes": "Each unsigned manifest is a separate attack surface; tally to blast radius."
580
+ },
581
+ {
582
+ "signal_id": "mcp-server-running-as-root",
583
+ "rwep_factor": "blast_radius",
584
+ "weight": 15,
585
+ "notes": "Elevated privileges escalate any tool-response RCE to root immediately."
586
+ },
587
+ {
588
+ "signal_id": "mcp-typosquat-candidate",
589
+ "rwep_factor": "active_exploitation",
590
+ "weight": 10,
591
+ "notes": "Typosquat campaigns are documented active TTP for MCP namespaces through Q2 2026."
592
+ }
427
593
  ],
428
594
  "blast_radius_model": {
429
595
  "scope_question": "If a malicious or compromised MCP server delivers an adversarial tool response on this developer endpoint, what scope of compromise is the endpoint realistically delivering to the attacker?",
430
596
  "scoring_rubric": [
431
- { "condition": "endpoint has no cloud-IAM credentials, no kube context, no SSH key material, isolated dev VM", "blast_radius_score": 1, "description": "RCE in developer-user context only; lateral movement requires separate exploit chain." },
432
- { "condition": "endpoint has personal git credentials and project-scoped tokens but no production access", "blast_radius_score": 2, "description": "Source-code theft + commit-rewrite vector via stolen git creds." },
433
- { "condition": "endpoint has ~/.aws/credentials, ~/.config/gcloud, or ~/.kube/config with read access to non-production environments", "blast_radius_score": 3, "description": "Cloud read across staging/dev; data exfil + IAM enumeration." },
434
- { "condition": "endpoint has production-scoped IAM roles, kube admin contexts, or signing keys (cosign, sigstore, GPG)", "blast_radius_score": 4, "description": "Production tenancy + supply-chain-publishing capability." },
435
- { "condition": "endpoint is a release-engineering / CI/CD bootstrap host with cross-account assume-role + package-publishing rights to org namespaces", "blast_radius_score": 5, "description": "Org-wide pivot via supply-chain re-publication. Single endpoint compromises entire downstream." }
597
+ {
598
+ "condition": "endpoint has no cloud-IAM credentials, no kube context, no SSH key material, isolated dev VM",
599
+ "blast_radius_score": 1,
600
+ "description": "RCE in developer-user context only; lateral movement requires separate exploit chain."
601
+ },
602
+ {
603
+ "condition": "endpoint has personal git credentials and project-scoped tokens but no production access",
604
+ "blast_radius_score": 2,
605
+ "description": "Source-code theft + commit-rewrite vector via stolen git creds."
606
+ },
607
+ {
608
+ "condition": "endpoint has ~/.aws/credentials, ~/.config/gcloud, or ~/.kube/config with read access to non-production environments",
609
+ "blast_radius_score": 3,
610
+ "description": "Cloud read across staging/dev; data exfil + IAM enumeration."
611
+ },
612
+ {
613
+ "condition": "endpoint has production-scoped IAM roles, kube admin contexts, or signing keys (cosign, sigstore, GPG)",
614
+ "blast_radius_score": 4,
615
+ "description": "Production tenancy + supply-chain-publishing capability."
616
+ },
617
+ {
618
+ "condition": "endpoint is a release-engineering / CI/CD bootstrap host with cross-account assume-role + package-publishing rights to org namespaces",
619
+ "blast_radius_score": 5,
620
+ "description": "Org-wide pivot via supply-chain re-publication. Single endpoint compromises entire downstream."
621
+ }
436
622
  ]
437
623
  },
438
624
  "compliance_theater_check": {
@@ -493,21 +679,43 @@
493
679
  }
494
680
  ],
495
681
  "escalation_criteria": [
496
- { "condition": "rwep >= 80 AND vulnerable-windsurf-version == true", "action": "page_on_call" },
497
- { "condition": "rwep >= 80 AND mcp-server-running-as-root == true", "action": "page_on_call" },
498
- { "condition": "mcp-typosquat-candidate == true AND no benign_match", "action": "raise_severity" },
499
- { "condition": "blast_radius_score >= 4", "action": "trigger_playbook", "target_playbook": "sbom" },
500
- { "condition": "compliance_theater_check.verdict == 'theater' AND jurisdiction_obligations contains 'EU'", "action": "notify_legal" },
501
- { "condition": "any unsigned-mcp-manifest with cloud credentials detected", "action": "trigger_playbook", "target_playbook": "ai-api" }
682
+ {
683
+ "condition": "rwep >= 80 AND vulnerable-windsurf-version == true",
684
+ "action": "page_on_call"
685
+ },
686
+ {
687
+ "condition": "rwep >= 80 AND mcp-server-running-as-root == true",
688
+ "action": "page_on_call"
689
+ },
690
+ {
691
+ "condition": "mcp-typosquat-candidate == true AND no benign_match",
692
+ "action": "raise_severity"
693
+ },
694
+ {
695
+ "condition": "blast_radius_score >= 4",
696
+ "action": "trigger_playbook",
697
+ "target_playbook": "sbom"
698
+ },
699
+ {
700
+ "condition": "compliance_theater_check.verdict == 'theater' AND jurisdiction_obligations contains 'EU'",
701
+ "action": "notify_legal"
702
+ },
703
+ {
704
+ "condition": "any unsigned-mcp-manifest with cloud credentials detected",
705
+ "action": "trigger_playbook",
706
+ "target_playbook": "ai-api"
707
+ }
502
708
  ]
503
709
  },
504
-
505
710
  "validate": {
506
711
  "remediation_paths": [
507
712
  {
508
713
  "id": "vendor-patch-windsurf",
509
714
  "description": "Apply vendor patch for CVE-2026-30615 via Windsurf auto-update.",
510
- "preconditions": ["vulnerable_windsurf_version == true", "auto_update_available == true"],
715
+ "preconditions": [
716
+ "vulnerable_windsurf_version == true",
717
+ "auto_update_available == true"
718
+ ],
511
719
  "priority": 1,
512
720
  "compensating_controls": [],
513
721
  "estimated_time_hours": 0.5
@@ -515,33 +723,54 @@
515
723
  {
516
724
  "id": "remove-unsigned-mcp-servers",
517
725
  "description": "Remove every MCP server with unsigned-mcp-manifest=true OR mcp-typosquat-candidate=true. Document removed entries in change-management.",
518
- "preconditions": ["operator_authorized_to_modify_mcp_config == true"],
726
+ "preconditions": [
727
+ "operator_authorized_to_modify_mcp_config == true"
728
+ ],
519
729
  "priority": 2,
520
- "compensating_controls": ["mcp_egress_network_allowlist", "mcp_runs_as_non_root_enforced"],
730
+ "compensating_controls": [
731
+ "mcp_egress_network_allowlist",
732
+ "mcp_runs_as_non_root_enforced"
733
+ ],
521
734
  "estimated_time_hours": 2
522
735
  },
523
736
  {
524
737
  "id": "enforce-signed-allowlist",
525
738
  "description": "Adopt an enforced MCP allowlist with signature/fingerprint binding for each authorized tool. Configure Claude Code permissions.allow, Cursor allowed-tools, VS Code chat.mcp.allowlist, Windsurf workspace policy with signed fingerprints.",
526
- "preconditions": ["all_authorized_mcp_servers_have_published_signatures == true"],
739
+ "preconditions": [
740
+ "all_authorized_mcp_servers_have_published_signatures == true"
741
+ ],
527
742
  "priority": 3,
528
- "compensating_controls": ["pre-commit hook validates mcp config against signed allowlist", "CI gate rejects PRs that introduce unsigned mcp entries"],
743
+ "compensating_controls": [
744
+ "pre-commit hook validates mcp config against signed allowlist",
745
+ "CI gate rejects PRs that introduce unsigned mcp entries"
746
+ ],
529
747
  "estimated_time_hours": 6
530
748
  },
531
749
  {
532
750
  "id": "version-pin-with-integrity",
533
751
  "description": "For every authorized MCP server, replace bare version pin with integrity-hash pin (sha256 / sri-integrity / attestation reference) sourced from package lockfile or Sigstore rekor entry.",
534
- "preconditions": ["package_lockfile_exists == true OR sigstore_rekor_entry_available == true"],
752
+ "preconditions": [
753
+ "package_lockfile_exists == true OR sigstore_rekor_entry_available == true"
754
+ ],
535
755
  "priority": 4,
536
- "compensating_controls": ["scheduled re-pin job on every authorized MCP package release"],
756
+ "compensating_controls": [
757
+ "scheduled re-pin job on every authorized MCP package release"
758
+ ],
537
759
  "estimated_time_hours": 4
538
760
  },
539
761
  {
540
762
  "id": "policy-exception",
541
763
  "description": "Generate auditor-ready policy exception via policy-exception-gen if a business-critical MCP server cannot meet signing / allowlist / integrity-pin requirements within compliance window.",
542
- "preconditions": ["remediation_paths[1..4] blocked for at least one MCP server", "ciso_acceptance_obtainable == true"],
764
+ "preconditions": [
765
+ "remediation_paths[1..4] blocked for at least one MCP server",
766
+ "ciso_acceptance_obtainable == true"
767
+ ],
543
768
  "priority": 5,
544
- "compensating_controls": ["MCP process seccomp/AppArmor profile", "egress allowlist for MCP processes", "enhanced logging on tool invocation patterns"],
769
+ "compensating_controls": [
770
+ "MCP process seccomp/AppArmor profile",
771
+ "egress allowlist for MCP processes",
772
+ "enhanced logging on tool invocation patterns"
773
+ ],
545
774
  "estimated_time_hours": 8
546
775
  }
547
776
  ],
@@ -587,46 +816,87 @@
587
816
  "risk": "MCP servers remain a continuously-mutating supply-chain surface. Every new authorized MCP server introduces a fresh attestation requirement; every new release of an authorized MCP server requires re-validation. A future malicious update from a previously-trusted publisher would bypass signature-based controls until the publisher's transparency-log entry is itself revoked.",
588
817
  "why_remains": "Signature verification proves authorship, not safety. A compromised maintainer key produces validly-signed malware. Compensating coverage requires publisher-key transparency monitoring (revocation propagation) and behavioral detection on tool invocation patterns — both immature in mid-2026.",
589
818
  "acceptance_level": "ciso",
590
- "compensating_controls_in_place": ["mcp_egress_network_allowlist", "mcp_seccomp_apparmor_profile", "publisher_key_transparency_monitoring", "tool_invocation_behavioral_baseline"]
819
+ "compensating_controls_in_place": [
820
+ "mcp_egress_network_allowlist",
821
+ "mcp_seccomp_apparmor_profile",
822
+ "publisher_key_transparency_monitoring",
823
+ "tool_invocation_behavioral_baseline"
824
+ ]
591
825
  },
592
826
  "evidence_requirements": [
593
827
  {
594
828
  "evidence_type": "scan_report",
595
829
  "description": "Enumeration report of every MCP server across every AI assistant config on the endpoint, with signature / integrity / allowlist-binding status for each.",
596
830
  "retention_period": "7_years",
597
- "framework_satisfied": ["nist-800-53-SA-12", "iso-27001-2022-A.8.30", "soc2-CC9", "nis2-art21-2d"]
831
+ "framework_satisfied": [
832
+ "nist-800-53-SA-12",
833
+ "iso-27001-2022-A.8.30",
834
+ "soc2-CC9",
835
+ "nis2-art21-2d"
836
+ ]
598
837
  },
599
838
  {
600
839
  "evidence_type": "config_diff",
601
840
  "description": "Before / after diff of every assistant MCP config showing removed unsigned entries, added integrity hashes, allowlist binding to signed fingerprints.",
602
841
  "retention_period": "7_years",
603
- "framework_satisfied": ["nist-800-53-CM-3", "iso-27001-2022-A.8.32", "eu-ai-act-art15"]
842
+ "framework_satisfied": [
843
+ "nist-800-53-CM-3",
844
+ "iso-27001-2022-A.8.32",
845
+ "eu-ai-act-art15"
846
+ ]
604
847
  },
605
848
  {
606
849
  "evidence_type": "exploit_replay_negative",
607
850
  "description": "Allowlist-enforcement and typosquat-canary tests, with output proving the client rejected the deliberately-unauthorized entries.",
608
851
  "retention_period": "1_year",
609
- "framework_satisfied": ["soc2-CC9", "iso-27001-2022-A.8.30"]
852
+ "framework_satisfied": [
853
+ "soc2-CC9",
854
+ "iso-27001-2022-A.8.30"
855
+ ]
610
856
  },
611
857
  {
612
858
  "evidence_type": "attestation",
613
859
  "description": "Signed exceptd attestation file with evidence_hash, enumerated MCP server count, signed-vs-unsigned ratio at detection and post-remediation, RWEP delta.",
614
860
  "retention_period": "7_years",
615
- "framework_satisfied": ["nist-800-53-CA-7", "iso-27001-2022-A.5.36", "nis2-art21-2d", "eu-ai-act-art15"]
861
+ "framework_satisfied": [
862
+ "nist-800-53-CA-7",
863
+ "iso-27001-2022-A.5.36",
864
+ "nis2-art21-2d",
865
+ "eu-ai-act-art15"
866
+ ]
616
867
  }
617
868
  ],
618
869
  "regression_trigger": [
619
- { "condition": "new_cve_in_class == true", "interval": "on_event" },
620
- { "condition": "new_mcp_server_added_to_any_config", "interval": "on_event" },
621
- { "condition": "new_version_of_any_authorized_mcp_server", "interval": "on_event" },
622
- { "condition": "monthly", "interval": "30d" }
870
+ {
871
+ "condition": "new_cve_in_class == true",
872
+ "interval": "on_event"
873
+ },
874
+ {
875
+ "condition": "new_mcp_server_added_to_any_config",
876
+ "interval": "on_event"
877
+ },
878
+ {
879
+ "condition": "new_version_of_any_authorized_mcp_server",
880
+ "interval": "on_event"
881
+ },
882
+ {
883
+ "condition": "monthly",
884
+ "interval": "30d"
885
+ }
623
886
  ]
624
887
  },
625
-
626
888
  "close": {
627
889
  "evidence_package": {
628
890
  "bundle_format": "csaf-2.0",
629
- "contents": ["scan_report", "config_diff", "exploit_replay_negative", "attestation", "framework_gap_mapping", "compliance_theater_verdict", "residual_risk_statement"],
891
+ "contents": [
892
+ "scan_report",
893
+ "config_diff",
894
+ "exploit_replay_negative",
895
+ "attestation",
896
+ "framework_gap_mapping",
897
+ "compliance_theater_verdict",
898
+ "residual_risk_statement"
899
+ ],
630
900
  "destination": "local_only",
631
901
  "signed": true
632
902
  },
@@ -638,49 +908,78 @@
638
908
  "framework_gap": "NIST SA-12, ISO A.5.19/A.8.30, SOC 2 CC9 all treat third-party software as a procurement event. EU AI Act Art.15 draws the system boundary around the model, not the tool plugins. No mainstream framework currently requires signed-manifest + integrity-pinned + allowlist-bound MCP tool authorization. Lag against operational reality: ~210 days as of 2026-05-11.",
639
909
  "new_control_requirement": "Add a control class 'AI tool plugin authorization' with mandatory: (a) manifest signature verification against publisher transparency-log entry pre-execution; (b) version pinning with integrity hash; (c) per-assistant enforced allowlist with signed-fingerprint binding; (d) MCP process runs non-root with seccomp/AppArmor profile; (e) egress network allowlist for MCP processes."
640
910
  },
641
- "feeds_back_to_skills": ["mcp-agent-trust", "supply-chain-integrity", "framework-gap-analysis", "compliance-theater", "zeroday-gap-learn"]
911
+ "feeds_back_to_skills": [
912
+ "mcp-agent-trust",
913
+ "supply-chain-integrity",
914
+ "framework-gap-analysis",
915
+ "compliance-theater",
916
+ "zeroday-gap-learn"
917
+ ]
642
918
  },
643
919
  "notification_actions": [
644
920
  {
645
921
  "obligation_ref": "EU/NIS2 Art.23 24h",
646
922
  "deadline": "computed_at_runtime",
647
923
  "recipient": "internal_legal",
648
- "evidence_attached": ["affected_mcp_client_inventory", "malicious_server_indicators", "interim_isolation_record"],
924
+ "evidence_attached": [
925
+ "affected_mcp_client_inventory",
926
+ "malicious_server_indicators",
927
+ "interim_isolation_record"
928
+ ],
649
929
  "draft_notification": "Initial NIS2 Art.23 24-hour early-warning notification: MCP supply-chain exposure detected on ${affected_endpoint_count} developer endpoint(s). Enumerated MCP servers: ${total_mcp_count}; unsigned-manifest count: ${unsigned_count}; typosquat candidates: ${typosquat_count}; vulnerable Windsurf installs (CVE-2026-30615): ${windsurf_vuln_count}. Interim isolation: ${interim_isolation_status}. Full incident assessment to follow within 72 hours per Art.23(4)."
650
930
  },
651
931
  {
652
932
  "obligation_ref": "EU/NIS2 Art.23 72h",
653
933
  "deadline": "computed_at_runtime",
654
934
  "recipient": "regulator_email",
655
- "evidence_attached": ["full_incident_assessment", "manifest_provenance_audit", "remediation_plan"],
935
+ "evidence_attached": [
936
+ "full_incident_assessment",
937
+ "manifest_provenance_audit",
938
+ "remediation_plan"
939
+ ],
656
940
  "draft_notification": "NIS2 Art.23 incident notification (72-hour): Full assessment of MCP supply-chain incident. Affected systems: ${affected_systems}. Provenance audit findings: ${provenance_summary}. Remediation plan: vendor patch deployment, unsigned-manifest removal, allowlist enforcement with signed fingerprints, version pinning with integrity hash. Estimated completion: ${remediation_eta}."
657
941
  },
658
942
  {
659
943
  "obligation_ref": "EU/NIS2 Art.23 720h",
660
944
  "deadline": "computed_at_runtime",
661
945
  "recipient": "regulator_email",
662
- "evidence_attached": ["root_cause_analysis", "control_changes_implemented", "lessons_learned"],
946
+ "evidence_attached": [
947
+ "root_cause_analysis",
948
+ "control_changes_implemented",
949
+ "lessons_learned"
950
+ ],
663
951
  "draft_notification": "NIS2 Art.23 final report (1-month): Root cause — MCP server supply-chain trust controls were structurally insufficient at detection. Control changes implemented: ${control_changes}. Lessons learned: ${lessons}. Residual risk acceptance: ${residual_risk_owner} signed ${acceptance_date}."
664
952
  },
665
953
  {
666
954
  "obligation_ref": "EU/DORA Art.19 4h",
667
955
  "deadline": "computed_at_runtime",
668
956
  "recipient": "internal_legal",
669
- "evidence_attached": ["initial_notification", "ict_third_party_dependencies", "developer_endpoint_blast_radius"],
957
+ "evidence_attached": [
958
+ "initial_notification",
959
+ "ict_third_party_dependencies",
960
+ "developer_endpoint_blast_radius"
961
+ ],
670
962
  "draft_notification": "DORA Art.19 initial notification: Major ICT-related incident — MCP supply-chain exposure on ${affected_endpoint_count} developer endpoint(s) within financial-entity scope. CVE-2026-30615 exposure: ${windsurf_vuln_count}. ICT third-party dependencies (MCP publishers): ${ict_dependencies}. Full classification + impact assessment to follow within statutory windows."
671
963
  },
672
964
  {
673
965
  "obligation_ref": "EU/EU AI Act Art.73 360h",
674
966
  "deadline": "computed_at_runtime",
675
967
  "recipient": "regulator_email",
676
- "evidence_attached": ["serious_incident_assessment", "ai_system_affected", "tool_provenance_audit"],
968
+ "evidence_attached": [
969
+ "serious_incident_assessment",
970
+ "ai_system_affected",
971
+ "tool_provenance_audit"
972
+ ],
677
973
  "draft_notification": "EU AI Act Art.73 serious-incident notification: MCP tool-plugin supply-chain exposure on high-risk AI system ${ai_system_id}. Tool provenance audit: ${unsigned_count} of ${total_mcp_count} tool plugins lacked manifest attestation at detection. Affected AI system: ${ai_system_description}. Remediation per validate phase."
678
974
  },
679
975
  {
680
976
  "obligation_ref": "AU/APRA CPS 234 72h",
681
977
  "deadline": "computed_at_runtime",
682
978
  "recipient": "regulator_email",
683
- "evidence_attached": ["materiality_assessment", "remediation_completed_evidence"],
979
+ "evidence_attached": [
980
+ "materiality_assessment",
981
+ "remediation_completed_evidence"
982
+ ],
684
983
  "draft_notification": "APRA CPS 234 notification: Material information security incident — MCP supply-chain exposure on ${affected_endpoint_count} developer endpoint(s). Materiality determination: ${materiality_justification}. Remediation completed: ${remediation_summary}."
685
984
  }
686
985
  ],
@@ -689,7 +988,14 @@
689
988
  "exception_template": {
690
989
  "scope": "Business-critical MCP server(s) ${unauthorized_mcp_list} cannot meet manifest-signature, integrity-pin, or allowlist-binding requirements within the compliance window. Remediation paths 1-4 blocked.",
691
990
  "duration": "until_vendor_patch",
692
- "compensating_controls": ["mcp_egress_network_allowlist_restricting_to_known-good_endpoints", "mcp_process_seccomp_apparmor_profile", "mcp_runs_as_non_root_enforced", "tool_invocation_behavioral_baseline_with_alerting", "weekly_re-enumeration_and_diff_against_baseline", "publisher_key_transparency_monitoring"],
991
+ "compensating_controls": [
992
+ "mcp_egress_network_allowlist_restricting_to_known-good_endpoints",
993
+ "mcp_process_seccomp_apparmor_profile",
994
+ "mcp_runs_as_non_root_enforced",
995
+ "tool_invocation_behavioral_baseline_with_alerting",
996
+ "weekly_re-enumeration_and_diff_against_baseline",
997
+ "publisher_key_transparency_monitoring"
998
+ ],
693
999
  "risk_acceptance_owner": "ciso",
694
1000
  "auditor_ready_language": "Pursuant to ${framework_id} ${control_id} (Supply Chain Protection / Outsourced Development / Vendor and Business Partner Risk Management), the organization documents a time-bound risk acceptance for MCP server(s) ${unauthorized_mcp_list} executing within developer environments without manifest signature verification. Vendor-published signing infrastructure for these MCP servers: ${vendor_signing_status}. Replacement candidates evaluated: ${replacement_evaluation}. The organization accepts that current vendor-management, configuration-management, and supplier-relationship controls in NIST 800-53 (SA-12, CM-7), ISO 27001:2022 (A.5.19, A.5.20, A.8.30), SOC 2 (CC9.2), and EU AI Act (Art.15) do not adequately address the developer-installed AI tool plugin attack surface, that this gap is documented in ${exceptd_framework_gap_mapping_ref}, and that the organization's compensating controls are: ${compensating_controls}. Detection coverage during the exception window: behavioral baseline of tool invocation patterns with anomaly alerting, weekly re-enumeration with diff-from-baseline, egress monitoring on MCP processes. Risk accepted by ${ciso_name} on ${acceptance_date}. Time-bound until ${duration_expiry} (vendor signing infrastructure publication, replacement MCP server selection, OR ${default_30d_expiry}, whichever is first). Re-evaluation triggers: vendor publishes signed manifest, new CVE in MCP supply-chain class, behavioral anomaly fires, OR scheduled expiry."
695
1001
  }
@@ -701,27 +1007,36 @@
701
1007
  }
702
1008
  }
703
1009
  },
704
-
705
1010
  "directives": [
706
1011
  {
707
1012
  "id": "all-mcp-servers-trust-audit",
708
1013
  "title": "Enumerate every MCP server across every AI coding assistant config and audit trust posture",
709
- "applies_to": { "always": true }
1014
+ "applies_to": {
1015
+ "always": true
1016
+ }
710
1017
  },
711
1018
  {
712
1019
  "id": "cve-2026-30615-windsurf",
713
1020
  "title": "Targeted investigation for CVE-2026-30615 (Windsurf MCP zero-interaction RCE)",
714
- "applies_to": { "cve": "CVE-2026-30615" },
1021
+ "applies_to": {
1022
+ "cve": "CVE-2026-30615"
1023
+ },
715
1024
  "phase_overrides": {
716
1025
  "direct": {
717
- "rwep_threshold": { "escalate": 70, "monitor": 40, "close": 20 }
1026
+ "rwep_threshold": {
1027
+ "escalate": 70,
1028
+ "monitor": 40,
1029
+ "close": 20
1030
+ }
718
1031
  }
719
1032
  }
720
1033
  },
721
1034
  {
722
1035
  "id": "ml-supply-chain-compromise-atlas",
723
1036
  "title": "ATLAS AML.T0010 — ML Supply Chain Compromise via MCP namespace",
724
- "applies_to": { "atlas_ttp": "AML.T0010" }
1037
+ "applies_to": {
1038
+ "atlas_ttp": "AML.T0010"
1039
+ }
725
1040
  }
726
1041
  ]
727
1042
  }