fullshield 0.1.1 → 0.1.3

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 (52) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +43 -5
  3. package/dist/agent.js +3408 -607
  4. package/dist/bench/score.js +118 -0
  5. package/dist/cli/index.js +7137 -3385
  6. package/dist/compliance.js +31 -2
  7. package/dist/dashboard.js +20 -1
  8. package/dist/index.d.ts +152 -2
  9. package/dist/index.js +3773 -670
  10. package/dist/mcp.js +3430 -629
  11. package/dist/runtime/auto.js +100 -3
  12. package/dist/runtime/dlp.js +313 -0
  13. package/dist/runtime/express.js +337 -0
  14. package/dist/runtime/fastify.js +325 -0
  15. package/dist/runtime/hono.js +570 -0
  16. package/dist/runtime/koa.js +573 -0
  17. package/dist/runtime/rasp.js +100 -3
  18. package/dist/runtime/register.js +100 -3
  19. package/dist/supply.js +87 -1
  20. package/dist/vex.js +178 -0
  21. package/package.json +12 -1
  22. package/rules/CONFIG-DIRLIST-001.md +9 -0
  23. package/rules/CONFIG-TRUSTPROXY-001.md +11 -0
  24. package/rules/DLP-CARD-001.md +9 -0
  25. package/rules/DLP-INTERNAL-001.md +9 -0
  26. package/rules/DLP-PII-001.md +9 -0
  27. package/rules/DLP-SECRET-001.md +9 -0
  28. package/rules/DLP-STACK-001.md +9 -0
  29. package/rules/HOST-SSH-001.md +13 -0
  30. package/rules/HOST-SSH-002.md +11 -0
  31. package/rules/HOST-SSH-003.md +11 -0
  32. package/rules/MCP-001.md +7 -0
  33. package/rules/MCP-002.md +7 -0
  34. package/rules/MCP-003.md +7 -0
  35. package/rules/MCP-004.md +7 -0
  36. package/rules/MCP-005.md +7 -0
  37. package/rules/README.md +47 -1
  38. package/rules/SAST-COOKIE-001.md +11 -0
  39. package/rules/SAST-CSRF-001.md +11 -0
  40. package/rules/SAST-DESER-001.md +11 -0
  41. package/rules/SAST-GQL-001.md +11 -0
  42. package/rules/SAST-HASH-001.md +11 -0
  43. package/rules/SAST-MASSASSIGN-001.md +11 -0
  44. package/rules/SAST-NOSQLI-001.md +6 -2
  45. package/rules/SAST-REDOS-001.md +11 -0
  46. package/rules/SAST-TIMING-001.md +11 -0
  47. package/rules/SAST-UPLOAD-001.md +11 -0
  48. package/rules/SAST-XXE-001.md +11 -0
  49. package/rules/SECRET-BUNDLE-001.md +11 -0
  50. package/rules/SECRET-SESSION-001.md +9 -0
  51. package/rules/SUPPLY-WORKFLOW-001.md +9 -0
  52. package/rules/SUPPLY-WORM-001.md +9 -0
@@ -29,6 +29,8 @@ var RULE_MAP = [
29
29
  ROW("SECRET-PRIVKEY-001", "A02:2021 Cryptographic Failures", "CWE-321", "V6.4.1", "PCI DSS 3.5 / 4.2"),
30
30
  ROW("SECRET-DBURL-001", "A02:2021 Cryptographic Failures", "CWE-798", "V6.4.1", "PCI DSS 3.2 / 8.3"),
31
31
  ROW("SECRET-JWT-001", "A02:2021 Cryptographic Failures", "CWE-798", "V6.4.1", "PCI DSS 3.5"),
32
+ ROW("SECRET-SESSION-001", "A02:2021 Cryptographic Failures", "CWE-798", "V6.4.1", "PCI DSS 3.5 / 6.2.4"),
33
+ ROW("CONFIG-DIRLIST-001", "A05:2021 Security Misconfiguration", "CWE-548", "V12.1.1", "PCI DSS 2.2 / 6.4.3"),
32
34
  ROW("SECRET-ENVFILE-001", "A02:2021 Cryptographic Failures", "CWE-312", "V8.3.4", "PCI DSS 3.2"),
33
35
  ROW("SECRET-ENTROPY-001", "A02:2021 Cryptographic Failures", "CWE-798", "V6.4.1", "PCI DSS 8.3"),
34
36
  ROW("DEPS-VULN-001", "A06:2021 Vulnerable Components", "CWE-1104", "V14.2.1", "PCI DSS 6.3.3"),
@@ -73,6 +75,8 @@ var RULE_MAP = [
73
75
  ROW("SUPPLY-LOCKURL-001", "A08:2021 Integrity Failures", "CWE-494", "V14.2.3", "PCI DSS 6.3.3"),
74
76
  ROW("SUPPLY-CONFUSION-001", "A08:2021 Integrity Failures", "CWE-494", "V14.2.3", "PCI DSS 6.3.3"),
75
77
  ROW("SUPPLY-PROVENANCE-001", "A08:2021 Integrity Failures", "CWE-494", "V14.2.3", "PCI DSS 6.3.3"),
78
+ ROW("SUPPLY-WORM-001", "A06:2021 Vulnerable Components", "CWE-506", "V14.2.1", "PCI DSS 6.3.3 / 12.10"),
79
+ ROW("SUPPLY-WORKFLOW-001", "A08:2021 Integrity Failures", "CWE-829", "V14.2.3", "PCI DSS 6.3.3"),
76
80
  ROW("IAC-GHA-UNPINNED-001", "A08:2021 Integrity Failures", "CWE-494", "V14.2.3", "PCI DSS 6.3.3"),
77
81
  ROW("IAC-GHA-PRTARGET-001", "A01:2021 Broken Access Control", "CWE-269", "V4.1.1", "PCI DSS 7.2"),
78
82
  ROW("IAC-GHA-PERMS-001", "A01:2021 Broken Access Control", "CWE-250", "V4.1.1", "PCI DSS 7.2"),
@@ -92,7 +96,32 @@ var RULE_MAP = [
92
96
  ROW("RUNTIME-BODY-001", "A05:2021 Security Misconfiguration", "CWE-400", "V13.1.1", "PCI DSS 6.2.4"),
93
97
  ROW("RUNTIME-ANOMALY-001", "A04:2021 Insecure Design", "CWE-754", "V14.4.3", "PCI DSS 10.2"),
94
98
  ROW("AI-IDOR-001", "A01:2021 Broken Access Control", "CWE-639", "V4.1.1", "PCI DSS 7.2"),
95
- ROW("AI-MASSASSIGN-001", "A01:2021 Broken Access Control", "CWE-915", "V5.1.1", "PCI DSS 6.2.4")
99
+ ROW("AI-MASSASSIGN-001", "A01:2021 Broken Access Control", "CWE-915", "V5.1.1", "PCI DSS 6.2.4"),
100
+ ROW("SAST-REDOS-001", "A05:2021 Security Misconfiguration", "CWE-1333", "V5.1.5", "PCI DSS 6.2.4"),
101
+ ROW("SAST-DESER-001", "A08:2021 Integrity Failures", "CWE-502", "V5.5.3", "PCI DSS 6.2.4"),
102
+ ROW("SAST-XXE-001", "A05:2021 Security Misconfiguration", "CWE-611", "V5.5.2", "PCI DSS 6.2.4"),
103
+ ROW("SAST-UPLOAD-001", "A04:2021 Insecure Design", "CWE-434", "V12.5.1", "PCI DSS 6.2.4"),
104
+ ROW("SAST-COOKIE-001", "A05:2021 Security Misconfiguration", "CWE-614/1004", "V3.4.2", "PCI DSS 6.2.4"),
105
+ ROW("SAST-CSRF-001", "A01:2021 Broken Access Control", "CWE-352", "V4.2.2", "PCI DSS 6.4.3"),
106
+ ROW("SAST-MASSASSIGN-001", "A01:2021 Broken Access Control", "CWE-915", "V5.1.1", "PCI DSS 6.2.4"),
107
+ ROW("SAST-TIMING-001", "A07:2021 Identification Failures", "CWE-208", "V2.10.3", "PCI DSS 8.3"),
108
+ ROW("SAST-HASH-001", "A02:2021 Cryptographic Failures", "CWE-916", "V6.2.2", "PCI DSS 8.3.1"),
109
+ ROW("SAST-GQL-001", "A04:2021 Insecure Design", "CWE-770/200", "V13.1.1", "PCI DSS 6.2.4"),
110
+ ROW("CONFIG-TRUSTPROXY-001", "A07:2021 Identification Failures", "CWE-290", "V2.2.1", "PCI DSS 8.3.4"),
111
+ ROW("SECRET-BUNDLE-001", "A02:2021 Cryptographic Failures", "CWE-798", "V6.4.1", "PCI DSS 3.2 / 8.3"),
112
+ ROW("DLP-SECRET-001", "A02:2021 Cryptographic Failures", "CWE-200", "V8.3.4", "PCI DSS 3.2 / 8.3"),
113
+ ROW("DLP-STACK-001", "A04:2021 Insecure Design", "CWE-209", "V7.4.1", "PCI DSS 6.2.4"),
114
+ ROW("DLP-INTERNAL-001", "A01:2021 Broken Access Control", "CWE-200", "V8.3.4", "PCI DSS 1.3 / 2.2"),
115
+ ROW("DLP-CARD-001", "A02:2021 Cryptographic Failures", "CWE-359", "V8.3.4", "PCI DSS 3.3 / 3.4"),
116
+ ROW("DLP-PII-001", "A01:2021 Broken Access Control", "CWE-359", "V8.3.4", "PCI DSS 3.2 / 6.4.2"),
117
+ ROW("MCP-001", "A02:2021 Cryptographic Failures", "CWE-798", "V6.4.1", "PCI DSS 3.2 / 8.3"),
118
+ ROW("MCP-002", "A08:2021 Integrity Failures", "CWE-494", "V14.2.3", "PCI DSS 6.3.3"),
119
+ ROW("MCP-003", "A01:2021 Broken Access Control", "CWE-250", "V4.1.1", "PCI DSS 7.2"),
120
+ ROW("MCP-004", "A03:2021 Injection", "CWE-74", "V5.3.3", "PCI DSS 6.2.4"),
121
+ ROW("MCP-005", "A02:2021 Cryptographic Failures", "CWE-319", "V9.1.1", "PCI DSS 4.2"),
122
+ ROW("HOST-SSH-001", "A06:2021 Vulnerable Components", "CWE-364", "V14.2.1", "PCI DSS 6.3.3"),
123
+ ROW("HOST-SSH-002", "A05:2021 Security Misconfiguration", "CWE-693", "V14.4.3", "PCI DSS 2.2"),
124
+ ROW("HOST-SSH-003", "A07:2021 Identification Failures", "CWE-307", "V7.1.1", "PCI DSS 10.2 / 11.5")
96
125
  ];
97
126
  var byId = new Map(RULE_MAP.map((r) => [r.ruleId, r]));
98
127
  function mappingFor(ruleId) {
@@ -115,7 +144,7 @@ function renderCompliance(findings, standard = "pci") {
115
144
  }
116
145
  function collectRuleIdsFromSources(texts) {
117
146
  const ids = /* @__PURE__ */ new Set();
118
- const re = /\b((?:SAST|SECRET|DEPS|CONFIG|EDGE|AI|LLM|SUPPLY|IAC|RASP|RUNTIME)-[A-Z0-9]+-\d{3})\b/g;
147
+ const re = /\b((?:SAST|SECRET|DEPS|CONFIG|EDGE|AI|LLM|SUPPLY|IAC|RASP|RUNTIME|DLP|MCP|HOST)(?:-[A-Z0-9]+)*-\d{3})\b/g;
119
148
  for (const text of texts) {
120
149
  let m;
121
150
  while ((m = re.exec(text)) !== null) ids.add(m[1] ?? "");
package/dist/dashboard.js CHANGED
@@ -13,6 +13,9 @@ function sqliteDb(file) {
13
13
  db.exec(
14
14
  "CREATE TABLE IF NOT EXISTS scans (scannedAt TEXT NOT NULL, total INTEGER NOT NULL, highCrit INTEGER NOT NULL)"
15
15
  );
16
+ db.exec(
17
+ "CREATE TABLE IF NOT EXISTS provenance (scannedAt TEXT NOT NULL, percent REAL NOT NULL, withProvenance INTEGER NOT NULL, total INTEGER NOT NULL)"
18
+ );
16
19
  } catch (error) {
17
20
  try {
18
21
  db?.close();
@@ -33,6 +36,16 @@ function sqliteDb(file) {
33
36
  row.highCrit
34
37
  );
35
38
  },
39
+ listProvenance() {
40
+ return handle.prepare(
41
+ "SELECT scannedAt, percent, withProvenance, total FROM provenance ORDER BY scannedAt"
42
+ ).all();
43
+ },
44
+ insertProvenance(row) {
45
+ handle.prepare(
46
+ "INSERT INTO provenance (scannedAt, percent, withProvenance, total) VALUES (?, ?, ?, ?)"
47
+ ).run(row.scannedAt, row.percent, row.withProvenance, row.total);
48
+ },
36
49
  close() {
37
50
  if (closed) return;
38
51
  closed = true;
@@ -51,6 +64,12 @@ function openHistory(dir) {
51
64
  function recordHistory(db, row) {
52
65
  db.insert(row);
53
66
  }
67
+ function recordProvenance(db, row) {
68
+ db.insertProvenance(row);
69
+ }
70
+ function listProvenance(db) {
71
+ return db.listProvenance();
72
+ }
54
73
  function assertDashboardHost(host) {
55
74
  if (host === void 0 || host.length === 0) return false;
56
75
  const h = host.split(":")[0]?.toLowerCase() ?? "";
@@ -140,4 +159,4 @@ function startDashboard(opts) {
140
159
  });
141
160
  }
142
161
 
143
- export { assertDashboardHost, createDashboardHandler, openHistory, recordHistory, startDashboard };
162
+ export { assertDashboardHost, createDashboardHandler, listProvenance, openHistory, recordHistory, recordProvenance, startDashboard };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
+ import * as zod from 'zod';
2
+
1
3
  declare const SEVERITIES: readonly ["info", "low", "medium", "high", "critical"];
2
4
  type Severity = (typeof SEVERITIES)[number];
3
5
  declare const MODULE_NAMES: readonly ["deps", "secrets", "sast", "config"];
4
6
  type ModuleName = (typeof MODULE_NAMES)[number];
5
7
  type Confidence = 'low' | 'medium' | 'high';
6
8
  interface FixProposal {
7
- kind: 'dependency-bump' | 'code-patch' | 'config-add';
9
+ kind: 'dependency-bump' | 'code-patch' | 'config-add' | 'dependency-override';
8
10
  /** Only safe fixes apply without --unsafe. */
9
11
  safe: boolean;
10
12
  /** Unified diff. */
@@ -49,6 +51,12 @@ interface Finding {
49
51
  aiReasoning?: string;
50
52
  exploitScenario?: string;
51
53
  explanation?: string;
54
+ /** Git commit that first introduced this secret (`scan --history`). */
55
+ introducedIn?: string;
56
+ /** Whether the secret still exists at HEAD (`scan --history`). */
57
+ stillAtHead?: boolean;
58
+ /** Read-only identity check (`scan --verify-secrets`). Never includes the secret. */
59
+ verification?: 'live' | 'revoked' | 'unknown';
52
60
  }
53
61
  interface FindingSummary {
54
62
  total: number;
@@ -103,6 +111,61 @@ declare class ConfigError extends Error {
103
111
  */
104
112
  declare function loadConfig(cwd: string, configPath?: string): Promise<ResolvedConfig>;
105
113
 
114
+ /** Stable GitHub URL for a shipped rule doc (also valid as a GitLab-comment link). */
115
+ declare function ruleDocsUrl(ruleId: string): string;
116
+ /**
117
+ * Deterministic Markdown for a GitHub/GitLab PR comment: new findings versus
118
+ * baseline (callers pass `applyBaseline` / `diffNewFindings` results). No AI.
119
+ */
120
+ declare function renderPrSummary(findings: readonly Finding[], opts?: {
121
+ baseLabel?: string;
122
+ }): string;
123
+
124
+ declare const POLICY_FILE_NAME = "fullshield.policy.json";
125
+ declare const POLICY_FLAG = "FULLSHIELD_EXPERIMENTAL_POLICY";
126
+ declare const POLICY_PEER_ERROR = "fullshield policy requires optional peer zod. Install with: npm i -D zod";
127
+ declare class PolicyError extends Error {
128
+ }
129
+ interface PolicyException {
130
+ ruleId: string;
131
+ file?: string;
132
+ id?: string;
133
+ owner: string;
134
+ reason: string;
135
+ /** ISO date (`YYYY-MM-DD`) or datetime. */
136
+ expires: string;
137
+ }
138
+ interface FullShieldPolicy {
139
+ requiredModules?: ModuleName[];
140
+ severityOverrides?: Partial<Record<string, Severity>>;
141
+ failOn?: Record<string, Severity>;
142
+ exceptions?: PolicyException[];
143
+ }
144
+ interface PolicyLoadOptions {
145
+ experimental?: boolean;
146
+ }
147
+ interface ApplyPolicyContext {
148
+ branch?: string;
149
+ modulesRun?: readonly ModuleName[];
150
+ now?: Date;
151
+ }
152
+ interface AppliedPolicy {
153
+ findings: Finding[];
154
+ failOn?: Severity;
155
+ errors: string[];
156
+ }
157
+ type ZodNamespace = typeof zod.z;
158
+ type ZodLoader = () => Promise<{
159
+ z: ZodNamespace;
160
+ }>;
161
+ declare function isPolicyEnabled(opts?: PolicyLoadOptions): boolean;
162
+ /** Parse and validate a policy document with the optional zod peer (lazy-imported). */
163
+ declare function parsePolicy(raw: unknown, source?: string, loadZod?: ZodLoader): Promise<FullShieldPolicy>;
164
+ /** Load `fullshield.policy.json` when the experimental flag is on. Missing file → undefined. */
165
+ declare function loadPolicy(cwd: string, opts?: PolicyLoadOptions, loadZod?: ZodLoader): Promise<FullShieldPolicy | undefined>;
166
+ /** Apply severity overrides, branch failOn, and exceptions. Expired exceptions become CI errors. */
167
+ declare function applyPolicy(findings: readonly Finding[], policy: FullShieldPolicy, ctx?: ApplyPolicyContext): AppliedPolicy;
168
+
106
169
  interface ModuleContext {
107
170
  cwd: string;
108
171
  /** Posix-style relative paths of every scannable file under cwd. */
@@ -133,6 +196,21 @@ interface ScanOptions {
133
196
  since?: string;
134
197
  experimentalIncremental?: boolean;
135
198
  changedFiles?: string[];
199
+ /** Phase 30: scan git history for secrets (`FULLSHIELD_EXPERIMENTAL_SECRETS_ADV=1`). */
200
+ history?: boolean;
201
+ /** Phase 30: scan a built client bundle directory. */
202
+ bundle?: string;
203
+ /** Phase 30: opt-in live identity check. Never default. Requires iOwnTheseCredentials. */
204
+ verifySecrets?: boolean;
205
+ iOwnTheseCredentials?: boolean;
206
+ /** Injected fetch for --verify-secrets tests. */
207
+ verifyFetch?: typeof fetch;
208
+ /** Phase 33: scan MCP configs under the user home (requires FULLSHIELD_EXPERIMENTAL_MCPCFG=1). */
209
+ includeHome?: boolean;
210
+ /** Phase 34 policy-as-code (`FULLSHIELD_EXPERIMENTAL_POLICY=1`). */
211
+ experimentalPolicy?: boolean;
212
+ /** Override git/CI branch when applying `failOn` per branch. */
213
+ policyBranch?: string;
136
214
  }
137
215
  interface ScanMetadata {
138
216
  version: string;
@@ -144,11 +222,20 @@ interface ScanMetadata {
144
222
  /** Requested modules that are actually implemented and ran. */
145
223
  modulesRun: ModuleName[];
146
224
  }
225
+ interface PolicyScanResult {
226
+ enabled: true;
227
+ file: string;
228
+ failOn?: Severity;
229
+ errors: string[];
230
+ policy: FullShieldPolicy;
231
+ }
147
232
  interface ScanResult {
148
233
  findings: Finding[];
149
234
  summary: FindingSummary;
150
235
  metadata: ScanMetadata;
151
236
  config: ResolvedConfig;
237
+ /** Present only when experimental policy was loaded from `fullshield.policy.json`. */
238
+ policy?: PolicyScanResult;
152
239
  }
153
240
  /**
154
241
  * Scanner modules register here as their phases are built.
@@ -203,6 +290,8 @@ interface FixResult {
203
290
  branch?: string;
204
291
  patches: FixPatch[];
205
292
  findings: Finding[];
293
+ /** Set when an override was written to package.json. The lockfile is left unchanged. */
294
+ notice?: string;
206
295
  }
207
296
  declare function runFix(options?: FixOptions): Promise<FixResult>;
208
297
 
@@ -254,6 +343,35 @@ declare function createAiClient(options: AiClientOptions): AiClient;
254
343
  /** Scan one file's text with every secrets rule. Secrets are always masked. */
255
344
  declare function scanTextForSecrets(path: string, text: string): Finding[];
256
345
 
346
+ declare function mcpCfgEnabled(): boolean;
347
+ interface McpScanOptions {
348
+ experimental?: boolean;
349
+ includeHome?: boolean;
350
+ }
351
+ /** Home MCP client config paths. Call only when `--include-home` is set. */
352
+ declare function mcpHomeConfigPaths(home: string): string[];
353
+ /** Experimental MCP client-config + server-code rules. Off unless experimental. No network. */
354
+ declare function scanMcpConfig(dir: string, opts?: McpScanOptions): Finding[];
355
+ interface GuardToolCall {
356
+ tool: string;
357
+ args: unknown;
358
+ result: 'ok' | 'denied' | 'unconfirmed';
359
+ }
360
+ interface GuardTool {
361
+ name: string;
362
+ description?: string;
363
+ execute: (...args: unknown[]) => unknown;
364
+ }
365
+ /**
366
+ * Optional runtime wrapper for LLM/MCP tools: deny-list dangerous capabilities,
367
+ * require `confirm` for writes/payments, and log every call.
368
+ */
369
+ declare function guardTools(tools: readonly GuardTool[], opts?: {
370
+ allow?: readonly string[];
371
+ confirm?: (tool: string, args: unknown) => boolean | Promise<boolean>;
372
+ log?: (event: GuardToolCall) => void;
373
+ }): GuardTool[];
374
+
257
375
  interface AiFixResult {
258
376
  accepted: boolean;
259
377
  attempts: number;
@@ -331,4 +449,36 @@ interface SbomInput {
331
449
  declare function validateCycloneDx15(doc: unknown): string[];
332
450
  declare function renderCycloneDx(input: SbomInput): Record<string, unknown>;
333
451
 
334
- export { type AiConfig, type BaselineFile, CONFIG_FILE_NAME, type Confidence, ConfigError, DEFAULT_CONFIG, type DepsConfig, type Finding, type FindingSummary, type FixOptions, type FixPatch, type FixProposal, type FixResult, IMPLEMENTED_MODULES, MODULE_NAMES, type ModuleContext, type ModuleName, type NotifyConfig, type ResolvedConfig, SEVERITIES, type SbomComponent, type SbomInput, type ScanMetadata, type ScanModule, type ScanOptions, type ScanResult, type Severity, type WalkOptions, applyBaseline, applyInlineSuppressions, buildSbom, builtinModules, createAiClient, failsCi, isInternalAi, isLiveAi, isModuleName, isSeverity, loadConfig, makeFindingId, meetsThreshold, packageVersion, parseIgnore, readBaseline, renderConsoleReport, renderCycloneDx, renderHtmlReport, renderJsonReport, renderMarkdownReport, renderSarifReport, runAiFix, runFix, runScan, scan, scanTextForSecrets, severityRank, sortFindings, summarize, validateCycloneDx15, validateSarif21, walkFiles, writeBaseline };
452
+ type VexFormat = 'openvex' | 'cyclonedx';
453
+ declare function buildOpenVex(findings: readonly Finding[]): Record<string, unknown>;
454
+ declare function validateOpenVex(doc: unknown): string[];
455
+ declare function buildCycloneDxVex(meta: {
456
+ name: string;
457
+ version: string;
458
+ }, findings: readonly Finding[]): Record<string, unknown>;
459
+ declare function validateCycloneDxVex(doc: unknown): string[];
460
+ declare function buildVex(findings: readonly Finding[], format: VexFormat, meta?: {
461
+ name: string;
462
+ version: string;
463
+ }): Record<string, unknown>;
464
+
465
+ /** Phase 31 worm / VEX / overrides / provenance. Off unless the env flag or CLI option is set. */
466
+ declare function experimentalVex(): boolean;
467
+
468
+ /** Static worm indicators: token read + publish / registry PUT / GitHub create / workflow write. */
469
+ declare function analyzeWormIndicators(dir: string): Finding[];
470
+ /** Static: install scripts or code writing .github/, .git/hooks/, or CI config. */
471
+ declare function analyzeWorkflowTampering(dir: string): Finding[];
472
+ interface ProvenanceScore {
473
+ total: number;
474
+ withProvenance: number;
475
+ percent: number;
476
+ unknown: number;
477
+ }
478
+ /** Percent of deps published with provenance. Unknown is not counted as present (never guess). */
479
+ declare function provenanceCoverage(packages: readonly {
480
+ name: string;
481
+ version: string;
482
+ }[], known: ReadonlyMap<string, boolean>): ProvenanceScore;
483
+
484
+ export { type AiConfig, type AppliedPolicy, type BaselineFile, CONFIG_FILE_NAME, type Confidence, ConfigError, DEFAULT_CONFIG, type DepsConfig, type Finding, type FindingSummary, type FixOptions, type FixPatch, type FixProposal, type FixResult, type FullShieldPolicy, type GuardTool, type GuardToolCall, IMPLEMENTED_MODULES, MODULE_NAMES, type McpScanOptions, type ModuleContext, type ModuleName, type NotifyConfig, POLICY_FILE_NAME, POLICY_FLAG, POLICY_PEER_ERROR, PolicyError, type PolicyException, type PolicyScanResult, type ResolvedConfig, SEVERITIES, type SbomComponent, type SbomInput, type ScanMetadata, type ScanModule, type ScanOptions, type ScanResult, type Severity, type WalkOptions, analyzeWorkflowTampering, analyzeWormIndicators, applyBaseline, applyInlineSuppressions, applyPolicy, buildCycloneDxVex, buildOpenVex, buildSbom, buildVex, builtinModules, createAiClient, experimentalVex, failsCi, guardTools, isInternalAi, isLiveAi, isModuleName, isPolicyEnabled, isSeverity, loadConfig, loadPolicy, makeFindingId, mcpCfgEnabled, mcpHomeConfigPaths, meetsThreshold, packageVersion, parseIgnore, parsePolicy, provenanceCoverage, readBaseline, renderConsoleReport, renderCycloneDx, renderHtmlReport, renderJsonReport, renderMarkdownReport, renderPrSummary, renderSarifReport, ruleDocsUrl, runAiFix, runFix, runScan, scan, scanMcpConfig, scanTextForSecrets, severityRank, sortFindings, summarize, validateCycloneDx15, validateCycloneDxVex, validateOpenVex, validateSarif21, walkFiles, writeBaseline };