@guava-parity/guard-scanner 16.0.1 → 17.0.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.
@@ -0,0 +1,214 @@
1
+ import { ScannerOptions, GuardScannerInstance } from './types.cjs';
2
+ export { CapabilityMetrics, CustomRule, Finding, GuardMode, GuardScannerConstructor, McpRequest, PluginConfig, RuntimeCheckStats, RuntimeDecision, SarifReport, ScanReport, ScanResult, Severity } from './types.cjs';
3
+ export { MCPServer, TOOLS, startServer } from './mcp-server.cjs';
4
+
5
+ declare const SEVERITY_WEIGHTS: {
6
+ CRITICAL: number;
7
+ HIGH: number;
8
+ MEDIUM: number;
9
+ LOW: number;
10
+ };
11
+
12
+ /**
13
+ * guard-scanner — Runtime Guard Module
14
+ *
15
+ * @security-manifest
16
+ * env-read: []
17
+ * env-write: []
18
+ * network: none
19
+ * fs-read: [~/.openclaw/openclaw.json (config), ~/.openclaw/guava-suite/token.jwt]
20
+ * fs-write: [~/.openclaw/guard-scanner/audit.jsonl]
21
+ * exec: none
22
+ * purpose: Runtime threat pattern matching for agent tool calls
23
+ *
24
+ * 26 threat patterns across 5 layers:
25
+ * Layer 1: Threat Detection (12) — reverse shells, exfil, guardrail bypass
26
+ * Layer 2: Trust Defense (4) — memory, SOUL, config tampering
27
+ * Layer 3: Safety Judge (3) — prompt injection, trust bypass, shutdown refusal
28
+ * Layer 4: Brain/Behavioral (3) — research skip, blind trust, chain bypass
29
+ * Layer 5: Trust Exploitation (4) — OWASP ASI09 authority/trust/audit abuse
30
+ *
31
+ * Modes:
32
+ * monitor — log only, never block
33
+ * enforce — block CRITICAL threats (default)
34
+ * strict — block HIGH + CRITICAL threats
35
+ *
36
+ * Based on hooks/guard-scanner/plugin.ts (TypeScript version for OpenClaw Plugin API)
37
+ * This module is the zero-dependency JavaScript equivalent for CLI and programmatic use.
38
+ *
39
+ * @author Guava 🍈 & Dee
40
+ * @version 3.4.0
41
+ * @license MIT
42
+ */
43
+ declare const RUNTIME_CHECKS: {
44
+ id: string;
45
+ severity: string;
46
+ layer: number;
47
+ desc: string;
48
+ test: (s: any) => boolean;
49
+ }[];
50
+ /**
51
+ * Scan a tool call for runtime threats.
52
+ *
53
+ * @param {string} toolName - Name of the tool being called
54
+ * @param {object} params - Tool call parameters
55
+ * @param {object} [options] - Options
56
+ * @param {string} [options.mode] - Override mode ('monitor' | 'enforce' | 'strict')
57
+ * @param {boolean} [options.auditLog=true] - Enable audit logging
58
+ * @param {string} [options.sessionKey] - Session identifier for audit
59
+ * @param {string} [options.sessionId] - Ephemeral OpenClaw session UUID for audit
60
+ * @param {string} [options.runId] - Stable OpenClaw run identifier for audit
61
+ * @param {string} [options.toolCallId] - Provider tool call identifier for audit
62
+ * @param {string} [options.agentId] - Agent identifier for audit
63
+ * @param {object} [options.policy] - Session policy contract
64
+ * @returns {{ blocked: boolean, detections: Array<{id: string, severity: string, layer: number, desc: string, action: string}> }}
65
+ */
66
+ declare function scanToolCall(toolName: any, params: any, options?: {}): {
67
+ blocked: boolean;
68
+ blockReason: null;
69
+ detections: never[];
70
+ mode: any;
71
+ toolName: any;
72
+ matchedPolicyId: null;
73
+ policyRationale: null;
74
+ riskAmplificationReasons: never[];
75
+ remediationSuggestion: null;
76
+ policyDecision: null;
77
+ contract_violations: never[];
78
+ behavioral_sequences: never[];
79
+ };
80
+ /**
81
+ * Get runtime check statistics.
82
+ * @returns {{ total: number, byLayer: object, bySeverity: object }}
83
+ */
84
+ declare function getCheckStats(): {
85
+ total: number;
86
+ byLayer: {};
87
+ bySeverity: {};
88
+ };
89
+ declare const LAYER_NAMES: {
90
+ 1: string;
91
+ 2: string;
92
+ 3: string;
93
+ 4: string;
94
+ 5: string;
95
+ };
96
+
97
+ /**
98
+ * guard-scanner v2.1.0 — Agent Skill Security Scanner 🛡️
99
+ *
100
+ * @security-manifest
101
+ * env-read: []
102
+ * env-write: []
103
+ * network: none
104
+ * fs-read: [scan target directory (user-specified)]
105
+ * fs-write: [JSON/SARIF/HTML reports to scan directory]
106
+ * exec: none
107
+ * purpose: Static analysis of agent skill files for threat patterns
108
+ *
109
+ * Based on GuavaGuard v9.0.0 (OSS extraction)
110
+ * 20 threat categories • Snyk ToxicSkills + OWASP MCP Top 10
111
+ * Lightweight runtime footprint • CLI + JSON + SARIF + HTML output
112
+ * Plugin API for custom detection rules
113
+ *
114
+ * Born from a real 3-day agent identity hijack (2026-02-12)
115
+ *
116
+ * License: MIT
117
+ */
118
+
119
+ declare const VERSION: string;
120
+ declare const THRESHOLDS: {
121
+ normal: {
122
+ suspicious: number;
123
+ malicious: number;
124
+ };
125
+ strict: {
126
+ suspicious: number;
127
+ malicious: number;
128
+ };
129
+ };
130
+ declare class GuardScanner {
131
+ constructor(options?: {});
132
+ loadPlugin(pluginPath: any): void;
133
+ loadCustomRules(rulesFile: any): void;
134
+ loadIgnoreFile(scanDir: any): void;
135
+ /**
136
+ * Scan raw text for threats (used for Discord incoming messages, etc.)
137
+ * @param {string} text - Raw text to scan
138
+ * @returns {{ safe: boolean, risk: number, detections: Array }}
139
+ */
140
+ scanText(text: any): {
141
+ safe: boolean;
142
+ risk: any;
143
+ detections: any[];
144
+ };
145
+ scanDirectory(dir: any): any;
146
+ scanTarget(targetPath: any): any;
147
+ scanSkill(skillPath: any, skillName: any): void;
148
+ classifyFile(ext: any, relFile: any): any;
149
+ isSelfNoisePath(skillName: any, relFile: any): any;
150
+ isSelfThreatCorpus(skillName: any, relFile: any): any;
151
+ checkIoCs(content: any, relFile: any, findings: any): void;
152
+ annotateV16Findings(findings: any): void;
153
+ pushUniqueFinding(findings: any, finding: any): void;
154
+ analyzeProtocolFindings(content: any, relFile: any, fileType: any, findings: any): void;
155
+ analyzeCognitiveFindings(content: any, relFile: any, fileType: any, findings: any): void;
156
+ analyzeThreatIntelFindings(content: any, relFile: any, fileType: any, findings: any): void;
157
+ checkPatterns(content: any, relFile: any, fileType: any, findings: any, patterns?: null): void;
158
+ checkHardcodedSecrets(content: any, relFile: any, findings: any): void;
159
+ shannonEntropy(str: any): number;
160
+ checkStructure(skillPath: any, skillName: any, findings: any): void;
161
+ checkDependencies(skillPath: any, skillName: any, findings: any): void;
162
+ checkSkillManifest(skillPath: any, skillName: any, findings: any): void;
163
+ checkComplexity(skillPath: any, skillName: any, findings: any): void;
164
+ checkConfigImpact(skillPath: any, skillName: any, findings: any): void;
165
+ checkHiddenFiles(skillPath: any, skillName: any, findings: any): void;
166
+ checkJSDataFlow(content: any, relFile: any, findings: any): void;
167
+ checkCrossFile(skillPath: any, skillName: any, findings: any): void;
168
+ checkRuntimeIntegration(skillPath: any, skillName: any, findings: any): void;
169
+ calculateRisk(findings: any): any;
170
+ getVerdict(risk: any): any;
171
+ getFiles(dir: any): any;
172
+ printSummary(): any;
173
+ toJSON(): any;
174
+ toSARIF(scanDir: any): any;
175
+ toHTML(): any;
176
+ /**
177
+ * Generate a Threat Model based on the scan findings.
178
+ * @param {Array<Object>} findings - The array of findings from the scan.
179
+ * @returns {Object} The generated threat model.
180
+ */
181
+ /**
182
+ * Check AST for contextual validation of high-risk chains.
183
+ * Separates heuristic-only matches from validated chains.
184
+ */
185
+ checkASTValidation(content: any, relFile: any, findings: any): any;
186
+ appendThreatModelFindings(content: any, findings: any, relFile?: string): void;
187
+ generateThreatModel(findings: any): {
188
+ timestamp: string;
189
+ surface: {
190
+ network: boolean;
191
+ file_system: boolean;
192
+ code_execution: boolean;
193
+ credential_exposure: boolean;
194
+ external_ingestion: boolean;
195
+ persistence: boolean;
196
+ };
197
+ capabilities: any;
198
+ compounded_risks: any;
199
+ lethal_trifecta: any;
200
+ summary: string;
201
+ owasp_asi: unknown[];
202
+ protocol_surfaces: unknown[];
203
+ layer_summary: {
204
+ layer: any;
205
+ layer_name: any;
206
+ }[];
207
+ };
208
+ generatePopulationMonitor(): any;
209
+ generateMetaGuard(): any;
210
+ }
211
+
212
+ declare function createScanner(options?: ScannerOptions): GuardScannerInstance;
213
+
214
+ export { GuardScanner, GuardScannerInstance, LAYER_NAMES, RUNTIME_CHECKS, SEVERITY_WEIGHTS, ScannerOptions, THRESHOLDS, VERSION, createScanner, getCheckStats, scanToolCall };
package/dist/index.d.ts CHANGED
@@ -1,17 +1,214 @@
1
- import { GuardScannerConstructor, ScannerOptions, GuardScannerInstance, RuntimeCheckStats, RuntimeDecision } from './types.js';
2
- export { CapabilityMetrics, CustomRule, Finding, GuardMode, McpRequest, PluginConfig, SarifReport, ScanReport, ScanResult, Severity } from './types.js';
1
+ import { ScannerOptions, GuardScannerInstance } from './types.js';
2
+ export { CapabilityMetrics, CustomRule, Finding, GuardMode, GuardScannerConstructor, McpRequest, PluginConfig, RuntimeCheckStats, RuntimeDecision, SarifReport, ScanReport, ScanResult, Severity } from './types.js';
3
+ export { MCPServer, TOOLS, startServer } from './mcp-server.js';
4
+
5
+ declare const SEVERITY_WEIGHTS: {
6
+ CRITICAL: number;
7
+ HIGH: number;
8
+ MEDIUM: number;
9
+ LOW: number;
10
+ };
11
+
12
+ /**
13
+ * guard-scanner — Runtime Guard Module
14
+ *
15
+ * @security-manifest
16
+ * env-read: []
17
+ * env-write: []
18
+ * network: none
19
+ * fs-read: [~/.openclaw/openclaw.json (config), ~/.openclaw/guava-suite/token.jwt]
20
+ * fs-write: [~/.openclaw/guard-scanner/audit.jsonl]
21
+ * exec: none
22
+ * purpose: Runtime threat pattern matching for agent tool calls
23
+ *
24
+ * 26 threat patterns across 5 layers:
25
+ * Layer 1: Threat Detection (12) — reverse shells, exfil, guardrail bypass
26
+ * Layer 2: Trust Defense (4) — memory, SOUL, config tampering
27
+ * Layer 3: Safety Judge (3) — prompt injection, trust bypass, shutdown refusal
28
+ * Layer 4: Brain/Behavioral (3) — research skip, blind trust, chain bypass
29
+ * Layer 5: Trust Exploitation (4) — OWASP ASI09 authority/trust/audit abuse
30
+ *
31
+ * Modes:
32
+ * monitor — log only, never block
33
+ * enforce — block CRITICAL threats (default)
34
+ * strict — block HIGH + CRITICAL threats
35
+ *
36
+ * Based on hooks/guard-scanner/plugin.ts (TypeScript version for OpenClaw Plugin API)
37
+ * This module is the zero-dependency JavaScript equivalent for CLI and programmatic use.
38
+ *
39
+ * @author Guava 🍈 & Dee
40
+ * @version 3.4.0
41
+ * @license MIT
42
+ */
43
+ declare const RUNTIME_CHECKS: {
44
+ id: string;
45
+ severity: string;
46
+ layer: number;
47
+ desc: string;
48
+ test: (s: any) => boolean;
49
+ }[];
50
+ /**
51
+ * Scan a tool call for runtime threats.
52
+ *
53
+ * @param {string} toolName - Name of the tool being called
54
+ * @param {object} params - Tool call parameters
55
+ * @param {object} [options] - Options
56
+ * @param {string} [options.mode] - Override mode ('monitor' | 'enforce' | 'strict')
57
+ * @param {boolean} [options.auditLog=true] - Enable audit logging
58
+ * @param {string} [options.sessionKey] - Session identifier for audit
59
+ * @param {string} [options.sessionId] - Ephemeral OpenClaw session UUID for audit
60
+ * @param {string} [options.runId] - Stable OpenClaw run identifier for audit
61
+ * @param {string} [options.toolCallId] - Provider tool call identifier for audit
62
+ * @param {string} [options.agentId] - Agent identifier for audit
63
+ * @param {object} [options.policy] - Session policy contract
64
+ * @returns {{ blocked: boolean, detections: Array<{id: string, severity: string, layer: number, desc: string, action: string}> }}
65
+ */
66
+ declare function scanToolCall(toolName: any, params: any, options?: {}): {
67
+ blocked: boolean;
68
+ blockReason: null;
69
+ detections: never[];
70
+ mode: any;
71
+ toolName: any;
72
+ matchedPolicyId: null;
73
+ policyRationale: null;
74
+ riskAmplificationReasons: never[];
75
+ remediationSuggestion: null;
76
+ policyDecision: null;
77
+ contract_violations: never[];
78
+ behavioral_sequences: never[];
79
+ };
80
+ /**
81
+ * Get runtime check statistics.
82
+ * @returns {{ total: number, byLayer: object, bySeverity: object }}
83
+ */
84
+ declare function getCheckStats(): {
85
+ total: number;
86
+ byLayer: {};
87
+ bySeverity: {};
88
+ };
89
+ declare const LAYER_NAMES: {
90
+ 1: string;
91
+ 2: string;
92
+ 3: string;
93
+ 4: string;
94
+ 5: string;
95
+ };
96
+
97
+ /**
98
+ * guard-scanner v2.1.0 — Agent Skill Security Scanner 🛡️
99
+ *
100
+ * @security-manifest
101
+ * env-read: []
102
+ * env-write: []
103
+ * network: none
104
+ * fs-read: [scan target directory (user-specified)]
105
+ * fs-write: [JSON/SARIF/HTML reports to scan directory]
106
+ * exec: none
107
+ * purpose: Static analysis of agent skill files for threat patterns
108
+ *
109
+ * Based on GuavaGuard v9.0.0 (OSS extraction)
110
+ * 20 threat categories • Snyk ToxicSkills + OWASP MCP Top 10
111
+ * Lightweight runtime footprint • CLI + JSON + SARIF + HTML output
112
+ * Plugin API for custom detection rules
113
+ *
114
+ * Born from a real 3-day agent identity hijack (2026-02-12)
115
+ *
116
+ * License: MIT
117
+ */
3
118
 
4
- declare const GuardScanner: GuardScannerConstructor;
5
119
  declare const VERSION: string;
6
- declare const THRESHOLDS: Record<string, unknown>;
7
- declare const SEVERITY_WEIGHTS: Record<string, number>;
8
- declare const scanToolCall: (toolName: string, params: Record<string, unknown> | string, options?: Record<string, unknown>) => RuntimeDecision;
9
- declare const RUNTIME_CHECKS: Record<string, unknown>[];
10
- declare const getCheckStats: () => RuntimeCheckStats;
11
- declare const LAYER_NAMES: Record<number, string>;
12
- declare const MCPServer: new () => unknown;
13
- declare const startServer: () => void;
14
- declare const TOOLS: Record<string, unknown>[];
120
+ declare const THRESHOLDS: {
121
+ normal: {
122
+ suspicious: number;
123
+ malicious: number;
124
+ };
125
+ strict: {
126
+ suspicious: number;
127
+ malicious: number;
128
+ };
129
+ };
130
+ declare class GuardScanner {
131
+ constructor(options?: {});
132
+ loadPlugin(pluginPath: any): void;
133
+ loadCustomRules(rulesFile: any): void;
134
+ loadIgnoreFile(scanDir: any): void;
135
+ /**
136
+ * Scan raw text for threats (used for Discord incoming messages, etc.)
137
+ * @param {string} text - Raw text to scan
138
+ * @returns {{ safe: boolean, risk: number, detections: Array }}
139
+ */
140
+ scanText(text: any): {
141
+ safe: boolean;
142
+ risk: any;
143
+ detections: any[];
144
+ };
145
+ scanDirectory(dir: any): any;
146
+ scanTarget(targetPath: any): any;
147
+ scanSkill(skillPath: any, skillName: any): void;
148
+ classifyFile(ext: any, relFile: any): any;
149
+ isSelfNoisePath(skillName: any, relFile: any): any;
150
+ isSelfThreatCorpus(skillName: any, relFile: any): any;
151
+ checkIoCs(content: any, relFile: any, findings: any): void;
152
+ annotateV16Findings(findings: any): void;
153
+ pushUniqueFinding(findings: any, finding: any): void;
154
+ analyzeProtocolFindings(content: any, relFile: any, fileType: any, findings: any): void;
155
+ analyzeCognitiveFindings(content: any, relFile: any, fileType: any, findings: any): void;
156
+ analyzeThreatIntelFindings(content: any, relFile: any, fileType: any, findings: any): void;
157
+ checkPatterns(content: any, relFile: any, fileType: any, findings: any, patterns?: null): void;
158
+ checkHardcodedSecrets(content: any, relFile: any, findings: any): void;
159
+ shannonEntropy(str: any): number;
160
+ checkStructure(skillPath: any, skillName: any, findings: any): void;
161
+ checkDependencies(skillPath: any, skillName: any, findings: any): void;
162
+ checkSkillManifest(skillPath: any, skillName: any, findings: any): void;
163
+ checkComplexity(skillPath: any, skillName: any, findings: any): void;
164
+ checkConfigImpact(skillPath: any, skillName: any, findings: any): void;
165
+ checkHiddenFiles(skillPath: any, skillName: any, findings: any): void;
166
+ checkJSDataFlow(content: any, relFile: any, findings: any): void;
167
+ checkCrossFile(skillPath: any, skillName: any, findings: any): void;
168
+ checkRuntimeIntegration(skillPath: any, skillName: any, findings: any): void;
169
+ calculateRisk(findings: any): any;
170
+ getVerdict(risk: any): any;
171
+ getFiles(dir: any): any;
172
+ printSummary(): any;
173
+ toJSON(): any;
174
+ toSARIF(scanDir: any): any;
175
+ toHTML(): any;
176
+ /**
177
+ * Generate a Threat Model based on the scan findings.
178
+ * @param {Array<Object>} findings - The array of findings from the scan.
179
+ * @returns {Object} The generated threat model.
180
+ */
181
+ /**
182
+ * Check AST for contextual validation of high-risk chains.
183
+ * Separates heuristic-only matches from validated chains.
184
+ */
185
+ checkASTValidation(content: any, relFile: any, findings: any): any;
186
+ appendThreatModelFindings(content: any, findings: any, relFile?: string): void;
187
+ generateThreatModel(findings: any): {
188
+ timestamp: string;
189
+ surface: {
190
+ network: boolean;
191
+ file_system: boolean;
192
+ code_execution: boolean;
193
+ credential_exposure: boolean;
194
+ external_ingestion: boolean;
195
+ persistence: boolean;
196
+ };
197
+ capabilities: any;
198
+ compounded_risks: any;
199
+ lethal_trifecta: any;
200
+ summary: string;
201
+ owasp_asi: unknown[];
202
+ protocol_surfaces: unknown[];
203
+ layer_summary: {
204
+ layer: any;
205
+ layer_name: any;
206
+ }[];
207
+ };
208
+ generatePopulationMonitor(): any;
209
+ generateMetaGuard(): any;
210
+ }
211
+
15
212
  declare function createScanner(options?: ScannerOptions): GuardScannerInstance;
16
213
 
17
- export { GuardScanner, GuardScannerConstructor, GuardScannerInstance, LAYER_NAMES, MCPServer, RUNTIME_CHECKS, RuntimeCheckStats, RuntimeDecision, SEVERITY_WEIGHTS, ScannerOptions, THRESHOLDS, TOOLS, VERSION, createScanner, getCheckStats, scanToolCall, startServer };
214
+ export { GuardScanner, GuardScannerInstance, LAYER_NAMES, RUNTIME_CHECKS, SEVERITY_WEIGHTS, ScannerOptions, THRESHOLDS, VERSION, createScanner, getCheckStats, scanToolCall };