@panguard-ai/atr 1.5.0 → 1.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action-executor.d.ts +44 -0
- package/dist/action-executor.d.ts.map +1 -0
- package/dist/action-executor.js +130 -0
- package/dist/action-executor.js.map +1 -0
- package/dist/adapters/default-adapter.d.ts +24 -0
- package/dist/adapters/default-adapter.d.ts.map +1 -0
- package/dist/adapters/default-adapter.js +51 -0
- package/dist/adapters/default-adapter.js.map +1 -0
- package/dist/adapters/stdio-adapter.d.ts +30 -0
- package/dist/adapters/stdio-adapter.d.ts.map +1 -0
- package/dist/adapters/stdio-adapter.js +128 -0
- package/dist/adapters/stdio-adapter.js.map +1 -0
- package/dist/badge.d.ts +42 -0
- package/dist/badge.d.ts.map +1 -0
- package/dist/badge.js +163 -0
- package/dist/badge.js.map +1 -0
- package/dist/capability-extractor.d.ts +35 -0
- package/dist/capability-extractor.d.ts.map +1 -0
- package/dist/capability-extractor.js +91 -0
- package/dist/capability-extractor.js.map +1 -0
- package/dist/cli/scan-handler.d.ts +21 -0
- package/dist/cli/scan-handler.d.ts.map +1 -0
- package/dist/cli/scan-handler.js +276 -0
- package/dist/cli/scan-handler.js.map +1 -0
- package/dist/cli/tc-pipeline.d.ts +18 -0
- package/dist/cli/tc-pipeline.d.ts.map +1 -0
- package/dist/cli/tc-pipeline.js +295 -0
- package/dist/cli/tc-pipeline.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +894 -0
- package/dist/cli.js.map +1 -0
- package/dist/content-hash.d.ts +7 -0
- package/dist/content-hash.d.ts.map +1 -0
- package/dist/content-hash.js +10 -0
- package/dist/content-hash.js.map +1 -0
- package/dist/converters/elastic.d.ts +36 -0
- package/dist/converters/elastic.d.ts.map +1 -0
- package/dist/converters/elastic.js +125 -0
- package/dist/converters/elastic.js.map +1 -0
- package/dist/converters/generic-regex.d.ts +37 -0
- package/dist/converters/generic-regex.d.ts.map +1 -0
- package/dist/converters/generic-regex.js +59 -0
- package/dist/converters/generic-regex.js.map +1 -0
- package/dist/converters/index.d.ts +32 -0
- package/dist/converters/index.d.ts.map +1 -0
- package/dist/converters/index.js +38 -0
- package/dist/converters/index.js.map +1 -0
- package/dist/converters/sarif.d.ts +18 -0
- package/dist/converters/sarif.d.ts.map +1 -0
- package/dist/converters/sarif.js +142 -0
- package/dist/converters/sarif.js.map +1 -0
- package/dist/converters/splunk.d.ts +19 -0
- package/dist/converters/splunk.d.ts.map +1 -0
- package/dist/converters/splunk.js +148 -0
- package/dist/converters/splunk.js.map +1 -0
- package/dist/coverage-analyzer.d.ts +43 -0
- package/dist/coverage-analyzer.d.ts.map +1 -0
- package/dist/coverage-analyzer.js +329 -0
- package/dist/coverage-analyzer.js.map +1 -0
- package/dist/embedding/build-corpus.d.ts +15 -0
- package/dist/embedding/build-corpus.d.ts.map +1 -0
- package/dist/embedding/build-corpus.js +105 -0
- package/dist/embedding/build-corpus.js.map +1 -0
- package/dist/embedding/model-loader.d.ts +41 -0
- package/dist/embedding/model-loader.d.ts.map +1 -0
- package/dist/embedding/model-loader.js +90 -0
- package/dist/embedding/model-loader.js.map +1 -0
- package/dist/embedding/vector-store.d.ts +41 -0
- package/dist/embedding/vector-store.d.ts.map +1 -0
- package/dist/embedding/vector-store.js +70 -0
- package/dist/embedding/vector-store.js.map +1 -0
- package/dist/engine.d.ts +222 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1185 -0
- package/dist/engine.js.map +1 -0
- package/dist/eval/corpus.d.ts +42 -0
- package/dist/eval/corpus.d.ts.map +1 -0
- package/dist/eval/corpus.js +427 -0
- package/dist/eval/corpus.js.map +1 -0
- package/dist/eval/eval-harness.d.ts +44 -0
- package/dist/eval/eval-harness.d.ts.map +1 -0
- package/dist/eval/eval-harness.js +296 -0
- package/dist/eval/eval-harness.js.map +1 -0
- package/dist/eval/index.d.ts +13 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +9 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/metrics.d.ts +74 -0
- package/dist/eval/metrics.d.ts.map +1 -0
- package/dist/eval/metrics.js +108 -0
- package/dist/eval/metrics.js.map +1 -0
- package/dist/eval/pint-corpus.d.ts +34 -0
- package/dist/eval/pint-corpus.d.ts.map +1 -0
- package/dist/eval/pint-corpus.js +113 -0
- package/dist/eval/pint-corpus.js.map +1 -0
- package/dist/eval/rule-corpus.d.ts +9 -0
- package/dist/eval/rule-corpus.d.ts.map +1 -0
- package/dist/eval/rule-corpus.js +4780 -0
- package/dist/eval/rule-corpus.js.map +1 -0
- package/dist/eval/rule-metrics.d.ts +34 -0
- package/dist/eval/rule-metrics.d.ts.map +1 -0
- package/dist/eval/rule-metrics.js +92 -0
- package/dist/eval/rule-metrics.js.map +1 -0
- package/dist/eval/run-eval.d.ts +7 -0
- package/dist/eval/run-eval.d.ts.map +1 -0
- package/dist/eval/run-eval.js +11 -0
- package/dist/eval/run-eval.js.map +1 -0
- package/dist/eval/run-pint-benchmark.d.ts +18 -0
- package/dist/eval/run-pint-benchmark.d.ts.map +1 -0
- package/dist/eval/run-pint-benchmark.js +159 -0
- package/dist/eval/run-pint-benchmark.js.map +1 -0
- package/dist/eval/skill-benchmark.d.ts +66 -0
- package/dist/eval/skill-benchmark.d.ts.map +1 -0
- package/dist/eval/skill-benchmark.js +194 -0
- package/dist/eval/skill-benchmark.js.map +1 -0
- package/dist/flywheel.d.ts +54 -0
- package/dist/flywheel.d.ts.map +1 -0
- package/dist/flywheel.js +121 -0
- package/dist/flywheel.js.map +1 -0
- package/dist/hook-handler.d.ts +61 -0
- package/dist/hook-handler.d.ts.map +1 -0
- package/dist/hook-handler.js +178 -0
- package/dist/hook-handler.js.map +1 -0
- package/dist/layer-integration.d.ts +55 -0
- package/dist/layer-integration.d.ts.map +1 -0
- package/dist/layer-integration.js +187 -0
- package/dist/layer-integration.js.map +1 -0
- package/dist/loader.d.ts +18 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +129 -0
- package/dist/loader.js.map +1 -0
- package/dist/mcp-server.d.ts +13 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +246 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp-tools/coverage-gaps.d.ts +13 -0
- package/dist/mcp-tools/coverage-gaps.d.ts.map +1 -0
- package/dist/mcp-tools/coverage-gaps.js +55 -0
- package/dist/mcp-tools/coverage-gaps.js.map +1 -0
- package/dist/mcp-tools/list-rules.d.ts +17 -0
- package/dist/mcp-tools/list-rules.d.ts.map +1 -0
- package/dist/mcp-tools/list-rules.js +45 -0
- package/dist/mcp-tools/list-rules.js.map +1 -0
- package/dist/mcp-tools/scan-skill.d.ts +17 -0
- package/dist/mcp-tools/scan-skill.d.ts.map +1 -0
- package/dist/mcp-tools/scan-skill.js +65 -0
- package/dist/mcp-tools/scan-skill.js.map +1 -0
- package/dist/mcp-tools/scan.d.ts +24 -0
- package/dist/mcp-tools/scan.d.ts.map +1 -0
- package/dist/mcp-tools/scan.js +94 -0
- package/dist/mcp-tools/scan.js.map +1 -0
- package/dist/mcp-tools/submit-proposal.d.ts +12 -0
- package/dist/mcp-tools/submit-proposal.d.ts.map +1 -0
- package/dist/mcp-tools/submit-proposal.js +103 -0
- package/dist/mcp-tools/submit-proposal.js.map +1 -0
- package/dist/mcp-tools/threat-summary.d.ts +12 -0
- package/dist/mcp-tools/threat-summary.d.ts.map +1 -0
- package/dist/mcp-tools/threat-summary.js +74 -0
- package/dist/mcp-tools/threat-summary.js.map +1 -0
- package/dist/mcp-tools/validate.d.ts +15 -0
- package/dist/mcp-tools/validate.d.ts.map +1 -0
- package/dist/mcp-tools/validate.js +51 -0
- package/dist/mcp-tools/validate.js.map +1 -0
- package/dist/modules/embedding.d.ts +71 -0
- package/dist/modules/embedding.d.ts.map +1 -0
- package/dist/modules/embedding.js +141 -0
- package/dist/modules/embedding.js.map +1 -0
- package/dist/modules/index.d.ts +144 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +82 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/semantic.d.ts +106 -0
- package/dist/modules/semantic.d.ts.map +1 -0
- package/dist/modules/semantic.js +359 -0
- package/dist/modules/semantic.js.map +1 -0
- package/dist/modules/session.d.ts +70 -0
- package/dist/modules/session.d.ts.map +1 -0
- package/dist/modules/session.js +128 -0
- package/dist/modules/session.js.map +1 -0
- package/dist/quality/adapters/atr.d.ts +65 -0
- package/dist/quality/adapters/atr.d.ts.map +1 -0
- package/dist/quality/adapters/atr.js +154 -0
- package/dist/quality/adapters/atr.js.map +1 -0
- package/dist/quality/adapters/index.d.ts +10 -0
- package/dist/quality/adapters/index.d.ts.map +1 -0
- package/dist/quality/adapters/index.js +10 -0
- package/dist/quality/adapters/index.js.map +1 -0
- package/dist/quality/compute-confidence.d.ts +45 -0
- package/dist/quality/compute-confidence.d.ts.map +1 -0
- package/dist/quality/compute-confidence.js +133 -0
- package/dist/quality/compute-confidence.js.map +1 -0
- package/dist/quality/index.d.ts +36 -0
- package/dist/quality/index.d.ts.map +1 -0
- package/dist/quality/index.js +39 -0
- package/dist/quality/index.js.map +1 -0
- package/dist/quality/quality-gate.d.ts +86 -0
- package/dist/quality/quality-gate.d.ts.map +1 -0
- package/dist/quality/quality-gate.js +187 -0
- package/dist/quality/quality-gate.js.map +1 -0
- package/dist/quality/types.d.ts +129 -0
- package/dist/quality/types.d.ts.map +1 -0
- package/dist/quality/types.js +10 -0
- package/dist/quality/types.js.map +1 -0
- package/dist/quality/validate-maturity.d.ts +51 -0
- package/dist/quality/validate-maturity.d.ts.map +1 -0
- package/dist/quality/validate-maturity.js +134 -0
- package/dist/quality/validate-maturity.js.map +1 -0
- package/dist/rule-scaffolder.d.ts +53 -0
- package/dist/rule-scaffolder.d.ts.map +1 -0
- package/dist/rule-scaffolder.js +301 -0
- package/dist/rule-scaffolder.js.map +1 -0
- package/dist/session-tracker.d.ts +58 -0
- package/dist/session-tracker.d.ts.map +1 -0
- package/dist/session-tracker.js +176 -0
- package/dist/session-tracker.js.map +1 -0
- package/dist/shadow-evaluator.d.ts +48 -0
- package/dist/shadow-evaluator.d.ts.map +1 -0
- package/dist/shadow-evaluator.js +129 -0
- package/dist/shadow-evaluator.js.map +1 -0
- package/dist/skill-fingerprint.d.ts +85 -0
- package/dist/skill-fingerprint.d.ts.map +1 -0
- package/dist/skill-fingerprint.js +284 -0
- package/dist/skill-fingerprint.js.map +1 -0
- package/dist/tc-reporter.d.ts +50 -0
- package/dist/tc-reporter.d.ts.map +1 -0
- package/dist/tc-reporter.js +164 -0
- package/dist/tc-reporter.js.map +1 -0
- package/dist/tier0-invariant.d.ts +49 -0
- package/dist/tier0-invariant.d.ts.map +1 -0
- package/dist/tier0-invariant.js +185 -0
- package/dist/tier0-invariant.js.map +1 -0
- package/dist/tier1-blacklist.d.ts +48 -0
- package/dist/tier1-blacklist.d.ts.map +1 -0
- package/dist/tier1-blacklist.js +92 -0
- package/dist/tier1-blacklist.js.map +1 -0
- package/dist/types.d.ts +232 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/verdict.d.ts +26 -0
- package/dist/verdict.d.ts.map +1 -0
- package/dist/verdict.js +127 -0
- package/dist/verdict.js.map +1 -0
- package/package.json +9 -10
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action Executor - Executes ATR response actions via platform adapters.
|
|
3
|
+
*
|
|
4
|
+
* Deduplicates actions, sorts by priority, and delegates execution
|
|
5
|
+
* to a PlatformAdapter. Handles per-action errors so one failure
|
|
6
|
+
* does not block the rest.
|
|
7
|
+
*
|
|
8
|
+
* @module agent-threat-rules/action-executor
|
|
9
|
+
*/
|
|
10
|
+
import type { ActionResult, ExecutionContext, PlatformAdapter } from './types.js';
|
|
11
|
+
export interface ActionExecutorConfig {
|
|
12
|
+
readonly adapter: PlatformAdapter;
|
|
13
|
+
readonly dryRun?: boolean;
|
|
14
|
+
readonly onActionComplete?: (result: ActionResult) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class ActionExecutor {
|
|
17
|
+
private readonly adapter;
|
|
18
|
+
private readonly dryRun;
|
|
19
|
+
private readonly onActionComplete?;
|
|
20
|
+
constructor(config: ActionExecutorConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Execute all actions from the verdict context.
|
|
23
|
+
*
|
|
24
|
+
* Actions are deduplicated, sorted by priority, and executed
|
|
25
|
+
* sequentially. Each action is wrapped in try/catch so a single
|
|
26
|
+
* failure does not prevent subsequent actions from running.
|
|
27
|
+
*
|
|
28
|
+
* Returns a frozen array of ActionResult.
|
|
29
|
+
*/
|
|
30
|
+
execute(context: ExecutionContext): Promise<readonly ActionResult[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Deduplicate actions and sort by priority (highest priority first).
|
|
33
|
+
*/
|
|
34
|
+
private deduplicateAndSort;
|
|
35
|
+
/**
|
|
36
|
+
* Execute a single action, returning a result even on failure.
|
|
37
|
+
*/
|
|
38
|
+
private executeOne;
|
|
39
|
+
/** Get the adapter name for diagnostics */
|
|
40
|
+
getAdapterName(): string;
|
|
41
|
+
/** Check if dry-run mode is enabled */
|
|
42
|
+
isDryRun(): boolean;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=action-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-executor.d.ts","sourceRoot":"","sources":["../src/action-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAEV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAChB,MAAM,YAAY,CAAC;AA8BpB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;CAC5D;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAiC;gBAEvD,MAAM,EAAE,oBAAoB;IAMxC;;;;;;;;OAQG;IACG,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAgB1E;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;OAEG;YACW,UAAU;IAmDxB,2CAA2C;IAC3C,cAAc,IAAI,MAAM;IAIxB,uCAAuC;IACvC,QAAQ,IAAI,OAAO;CAGpB"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action Executor - Executes ATR response actions via platform adapters.
|
|
3
|
+
*
|
|
4
|
+
* Deduplicates actions, sorts by priority, and delegates execution
|
|
5
|
+
* to a PlatformAdapter. Handles per-action errors so one failure
|
|
6
|
+
* does not block the rest.
|
|
7
|
+
*
|
|
8
|
+
* @module agent-threat-rules/action-executor
|
|
9
|
+
*/
|
|
10
|
+
/** Priority order: lower number = higher priority (executed first) */
|
|
11
|
+
const ACTION_PRIORITY = {
|
|
12
|
+
kill_agent: 0,
|
|
13
|
+
block_input: 1,
|
|
14
|
+
block_output: 2,
|
|
15
|
+
block_tool: 3,
|
|
16
|
+
quarantine_session: 4,
|
|
17
|
+
reduce_permissions: 5,
|
|
18
|
+
reset_context: 6,
|
|
19
|
+
alert: 7,
|
|
20
|
+
escalate: 8,
|
|
21
|
+
snapshot: 9,
|
|
22
|
+
};
|
|
23
|
+
/** Map action names to PlatformAdapter method names */
|
|
24
|
+
const ACTION_METHOD_MAP = {
|
|
25
|
+
block_input: 'blockInput',
|
|
26
|
+
block_output: 'blockOutput',
|
|
27
|
+
block_tool: 'blockTool',
|
|
28
|
+
quarantine_session: 'quarantineSession',
|
|
29
|
+
reset_context: 'resetContext',
|
|
30
|
+
alert: 'alert',
|
|
31
|
+
snapshot: 'snapshot',
|
|
32
|
+
escalate: 'escalate',
|
|
33
|
+
reduce_permissions: 'reducePermissions',
|
|
34
|
+
kill_agent: 'killAgent',
|
|
35
|
+
};
|
|
36
|
+
export class ActionExecutor {
|
|
37
|
+
adapter;
|
|
38
|
+
dryRun;
|
|
39
|
+
onActionComplete;
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this.adapter = config.adapter;
|
|
42
|
+
this.dryRun = config.dryRun ?? false;
|
|
43
|
+
this.onActionComplete = config.onActionComplete;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Execute all actions from the verdict context.
|
|
47
|
+
*
|
|
48
|
+
* Actions are deduplicated, sorted by priority, and executed
|
|
49
|
+
* sequentially. Each action is wrapped in try/catch so a single
|
|
50
|
+
* failure does not prevent subsequent actions from running.
|
|
51
|
+
*
|
|
52
|
+
* Returns a frozen array of ActionResult.
|
|
53
|
+
*/
|
|
54
|
+
async execute(context) {
|
|
55
|
+
const actions = this.deduplicateAndSort(context.verdict.actions);
|
|
56
|
+
const results = [];
|
|
57
|
+
for (const action of actions) {
|
|
58
|
+
const result = await this.executeOne(action, context);
|
|
59
|
+
results.push(result);
|
|
60
|
+
if (this.onActionComplete) {
|
|
61
|
+
this.onActionComplete(result);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return Object.freeze(results);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Deduplicate actions and sort by priority (highest priority first).
|
|
68
|
+
*/
|
|
69
|
+
deduplicateAndSort(actions) {
|
|
70
|
+
const unique = [...new Set(actions)];
|
|
71
|
+
return unique.sort((a, b) => {
|
|
72
|
+
const pa = ACTION_PRIORITY[a] ?? 99;
|
|
73
|
+
const pb = ACTION_PRIORITY[b] ?? 99;
|
|
74
|
+
return pa - pb;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Execute a single action, returning a result even on failure.
|
|
79
|
+
*/
|
|
80
|
+
async executeOne(action, context) {
|
|
81
|
+
const timestamp = new Date().toISOString();
|
|
82
|
+
if (this.dryRun) {
|
|
83
|
+
return Object.freeze({
|
|
84
|
+
action,
|
|
85
|
+
success: true,
|
|
86
|
+
message: `[dry-run] Would execute: ${action}`,
|
|
87
|
+
timestamp,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const methodName = ACTION_METHOD_MAP[action];
|
|
92
|
+
if (!methodName) {
|
|
93
|
+
return Object.freeze({
|
|
94
|
+
action,
|
|
95
|
+
success: false,
|
|
96
|
+
message: `Unknown action: ${action}`,
|
|
97
|
+
timestamp,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const method = this.adapter[methodName];
|
|
101
|
+
if (typeof method !== 'function') {
|
|
102
|
+
return Object.freeze({
|
|
103
|
+
action,
|
|
104
|
+
success: false,
|
|
105
|
+
message: `Adapter "${this.adapter.name}" does not implement: ${methodName}`,
|
|
106
|
+
timestamp,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return await method.call(this.adapter, context);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
113
|
+
return Object.freeze({
|
|
114
|
+
action,
|
|
115
|
+
success: false,
|
|
116
|
+
message: `Action "${action}" failed: ${message}`,
|
|
117
|
+
timestamp,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Get the adapter name for diagnostics */
|
|
122
|
+
getAdapterName() {
|
|
123
|
+
return this.adapter.name;
|
|
124
|
+
}
|
|
125
|
+
/** Check if dry-run mode is enabled */
|
|
126
|
+
isDryRun() {
|
|
127
|
+
return this.dryRun;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=action-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-executor.js","sourceRoot":"","sources":["../src/action-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,sEAAsE;AACtE,MAAM,eAAe,GAAwC;IAC3D,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC;IACd,YAAY,EAAE,CAAC;IACf,UAAU,EAAE,CAAC;IACb,kBAAkB,EAAE,CAAC;IACrB,kBAAkB,EAAE,CAAC;IACrB,aAAa,EAAE,CAAC;IAChB,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF,uDAAuD;AACvD,MAAM,iBAAiB,GAAuD;IAC5E,WAAW,EAAE,YAAY;IACzB,YAAY,EAAE,aAAa;IAC3B,UAAU,EAAE,WAAW;IACvB,kBAAkB,EAAE,mBAAmB;IACvC,aAAa,EAAE,cAAc;IAC7B,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,kBAAkB,EAAE,mBAAmB;IACvC,UAAU,EAAE,WAAW;CACxB,CAAC;AAQF,MAAM,OAAO,cAAc;IACR,OAAO,CAAkB;IACzB,MAAM,CAAU;IAChB,gBAAgB,CAAkC;IAEnE,YAAY,MAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC;QACrC,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;IAClD,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO,CAAC,OAAyB;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjE,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAErB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC1B,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACK,kBAAkB,CACxB,OAA6B;QAE7B,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1B,MAAM,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,EAAE,GAAG,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CACtB,MAAiB,EACjB,OAAyB;QAEzB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,MAAM,CAAC,MAAM,CAAC;gBACnB,MAAM;gBACN,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,4BAA4B,MAAM,EAAE;gBAC7C,SAAS;aACV,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,MAAM,CAAC,MAAM,CAAC;oBACnB,MAAM;oBACN,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,mBAAmB,MAAM,EAAE;oBACpC,SAAS;iBACV,CAAC,CAAC;YACL,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAEzB,CAAC;YAEd,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,MAAM,CAAC,MAAM,CAAC;oBACnB,MAAM;oBACN,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,YAAY,IAAI,CAAC,OAAO,CAAC,IAAI,yBAAyB,UAAU,EAAE;oBAC3E,SAAS;iBACV,CAAC,CAAC;YACL,CAAC;YAED,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,MAAM,CAAC,MAAM,CAAC;gBACnB,MAAM;gBACN,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,WAAW,MAAM,aAAa,OAAO,EAAE;gBAChD,SAAS;aACV,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,cAAc;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,uCAAuC;IACvC,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Platform Adapter - No-op implementation for CLI and testing.
|
|
3
|
+
*
|
|
4
|
+
* Every method logs the action and returns a success result.
|
|
5
|
+
* This adapter is safe to use in any environment as it performs
|
|
6
|
+
* no actual enforcement.
|
|
7
|
+
*
|
|
8
|
+
* @module agent-threat-rules/adapters/default-adapter
|
|
9
|
+
*/
|
|
10
|
+
import type { ActionResult, ExecutionContext, PlatformAdapter } from '../types.js';
|
|
11
|
+
export declare class DefaultAdapter implements PlatformAdapter {
|
|
12
|
+
readonly name = "default";
|
|
13
|
+
blockInput(ctx: ExecutionContext): Promise<ActionResult>;
|
|
14
|
+
blockOutput(ctx: ExecutionContext): Promise<ActionResult>;
|
|
15
|
+
blockTool(ctx: ExecutionContext): Promise<ActionResult>;
|
|
16
|
+
quarantineSession(ctx: ExecutionContext): Promise<ActionResult>;
|
|
17
|
+
resetContext(ctx: ExecutionContext): Promise<ActionResult>;
|
|
18
|
+
alert(ctx: ExecutionContext): Promise<ActionResult>;
|
|
19
|
+
snapshot(ctx: ExecutionContext): Promise<ActionResult>;
|
|
20
|
+
escalate(ctx: ExecutionContext): Promise<ActionResult>;
|
|
21
|
+
reducePermissions(ctx: ExecutionContext): Promise<ActionResult>;
|
|
22
|
+
killAgent(ctx: ExecutionContext): Promise<ActionResult>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=default-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/default-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAChB,MAAM,aAAa,CAAC;AAcrB,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAEpB,UAAU,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAIxD,WAAW,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAIzD,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAIvD,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/D,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAI1D,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAInD,QAAQ,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAItD,QAAQ,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAItD,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/D,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;CAG9D"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Platform Adapter - No-op implementation for CLI and testing.
|
|
3
|
+
*
|
|
4
|
+
* Every method logs the action and returns a success result.
|
|
5
|
+
* This adapter is safe to use in any environment as it performs
|
|
6
|
+
* no actual enforcement.
|
|
7
|
+
*
|
|
8
|
+
* @module agent-threat-rules/adapters/default-adapter
|
|
9
|
+
*/
|
|
10
|
+
function createResult(action, ctx) {
|
|
11
|
+
return Object.freeze({
|
|
12
|
+
action,
|
|
13
|
+
success: true,
|
|
14
|
+
message: `[${action}] logged (no-op) for verdict: ${ctx.verdict.outcome}`,
|
|
15
|
+
timestamp: new Date().toISOString(),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export class DefaultAdapter {
|
|
19
|
+
name = 'default';
|
|
20
|
+
async blockInput(ctx) {
|
|
21
|
+
return createResult('block_input', ctx);
|
|
22
|
+
}
|
|
23
|
+
async blockOutput(ctx) {
|
|
24
|
+
return createResult('block_output', ctx);
|
|
25
|
+
}
|
|
26
|
+
async blockTool(ctx) {
|
|
27
|
+
return createResult('block_tool', ctx);
|
|
28
|
+
}
|
|
29
|
+
async quarantineSession(ctx) {
|
|
30
|
+
return createResult('quarantine_session', ctx);
|
|
31
|
+
}
|
|
32
|
+
async resetContext(ctx) {
|
|
33
|
+
return createResult('reset_context', ctx);
|
|
34
|
+
}
|
|
35
|
+
async alert(ctx) {
|
|
36
|
+
return createResult('alert', ctx);
|
|
37
|
+
}
|
|
38
|
+
async snapshot(ctx) {
|
|
39
|
+
return createResult('snapshot', ctx);
|
|
40
|
+
}
|
|
41
|
+
async escalate(ctx) {
|
|
42
|
+
return createResult('escalate', ctx);
|
|
43
|
+
}
|
|
44
|
+
async reducePermissions(ctx) {
|
|
45
|
+
return createResult('reduce_permissions', ctx);
|
|
46
|
+
}
|
|
47
|
+
async killAgent(ctx) {
|
|
48
|
+
return createResult('kill_agent', ctx);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=default-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-adapter.js","sourceRoot":"","sources":["../../src/adapters/default-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,SAAS,YAAY,CACnB,MAA8B,EAC9B,GAAqB;IAErB,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,MAAM;QACN,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,IAAI,MAAM,iCAAiC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE;QACzE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,SAAS,CAAC;IAE1B,KAAK,CAAC,UAAU,CAAC,GAAqB;QACpC,OAAO,YAAY,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAqB;QACrC,OAAO,YAAY,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAqB;QACnC,OAAO,YAAY,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,GAAqB;QAC3C,OAAO,YAAY,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAqB;QACtC,OAAO,YAAY,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAqB;QAC/B,OAAO,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAqB;QAClC,OAAO,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAqB;QAClC,OAAO,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,GAAqB;QAC3C,OAAO,YAAY,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAqB;QACnC,OAAO,YAAY,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio Platform Adapter - Adapter for Claude Code hook integration.
|
|
3
|
+
*
|
|
4
|
+
* Block actions write JSON responses to an internal buffer that can
|
|
5
|
+
* be flushed to stdout. Alert and snapshot actions log to stderr
|
|
6
|
+
* to avoid interfering with the JSON protocol on stdout.
|
|
7
|
+
*
|
|
8
|
+
* @module agent-threat-rules/adapters/stdio-adapter
|
|
9
|
+
*/
|
|
10
|
+
import type { ActionResult, ExecutionContext, PlatformAdapter } from '../types.js';
|
|
11
|
+
export declare class StdioAdapter implements PlatformAdapter {
|
|
12
|
+
readonly name = "stdio";
|
|
13
|
+
private readonly responseBuffer;
|
|
14
|
+
/**
|
|
15
|
+
* Get buffered responses and clear the buffer.
|
|
16
|
+
* Returns a frozen copy.
|
|
17
|
+
*/
|
|
18
|
+
flushResponses(): readonly unknown[];
|
|
19
|
+
blockInput(ctx: ExecutionContext): Promise<ActionResult>;
|
|
20
|
+
blockOutput(ctx: ExecutionContext): Promise<ActionResult>;
|
|
21
|
+
blockTool(ctx: ExecutionContext): Promise<ActionResult>;
|
|
22
|
+
quarantineSession(ctx: ExecutionContext): Promise<ActionResult>;
|
|
23
|
+
resetContext(ctx: ExecutionContext): Promise<ActionResult>;
|
|
24
|
+
alert(ctx: ExecutionContext): Promise<ActionResult>;
|
|
25
|
+
snapshot(ctx: ExecutionContext): Promise<ActionResult>;
|
|
26
|
+
escalate(ctx: ExecutionContext): Promise<ActionResult>;
|
|
27
|
+
reducePermissions(ctx: ExecutionContext): Promise<ActionResult>;
|
|
28
|
+
killAgent(ctx: ExecutionContext): Promise<ActionResult>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=stdio-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/stdio-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAChB,MAAM,aAAa,CAAC;AAcrB,qBAAa,YAAa,YAAW,eAAe;IAClD,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAEhD;;;OAGG;IACH,cAAc,IAAI,SAAS,OAAO,EAAE;IAM9B,UAAU,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAUxD,WAAW,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAUzD,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAWvD,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAU/D,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAS1D,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAWnD,QAAQ,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAetD,QAAQ,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAWtD,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;IAU/D,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;CAS9D"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio Platform Adapter - Adapter for Claude Code hook integration.
|
|
3
|
+
*
|
|
4
|
+
* Block actions write JSON responses to an internal buffer that can
|
|
5
|
+
* be flushed to stdout. Alert and snapshot actions log to stderr
|
|
6
|
+
* to avoid interfering with the JSON protocol on stdout.
|
|
7
|
+
*
|
|
8
|
+
* @module agent-threat-rules/adapters/stdio-adapter
|
|
9
|
+
*/
|
|
10
|
+
function makeResult(action, message) {
|
|
11
|
+
return Object.freeze({
|
|
12
|
+
action,
|
|
13
|
+
success: true,
|
|
14
|
+
message,
|
|
15
|
+
timestamp: new Date().toISOString(),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export class StdioAdapter {
|
|
19
|
+
name = 'stdio';
|
|
20
|
+
responseBuffer = [];
|
|
21
|
+
/**
|
|
22
|
+
* Get buffered responses and clear the buffer.
|
|
23
|
+
* Returns a frozen copy.
|
|
24
|
+
*/
|
|
25
|
+
flushResponses() {
|
|
26
|
+
const copy = Object.freeze([...this.responseBuffer]);
|
|
27
|
+
this.responseBuffer.length = 0;
|
|
28
|
+
return copy;
|
|
29
|
+
}
|
|
30
|
+
async blockInput(ctx) {
|
|
31
|
+
const entry = {
|
|
32
|
+
action: 'block_input',
|
|
33
|
+
verdict: ctx.verdict.outcome,
|
|
34
|
+
reason: ctx.verdict.reason,
|
|
35
|
+
};
|
|
36
|
+
this.responseBuffer.push(entry);
|
|
37
|
+
return makeResult('block_input', 'Input blocked via stdio protocol');
|
|
38
|
+
}
|
|
39
|
+
async blockOutput(ctx) {
|
|
40
|
+
const entry = {
|
|
41
|
+
action: 'block_output',
|
|
42
|
+
verdict: ctx.verdict.outcome,
|
|
43
|
+
reason: ctx.verdict.reason,
|
|
44
|
+
};
|
|
45
|
+
this.responseBuffer.push(entry);
|
|
46
|
+
return makeResult('block_output', 'Output blocked via stdio protocol');
|
|
47
|
+
}
|
|
48
|
+
async blockTool(ctx) {
|
|
49
|
+
const entry = {
|
|
50
|
+
action: 'block_tool',
|
|
51
|
+
verdict: ctx.verdict.outcome,
|
|
52
|
+
reason: ctx.verdict.reason,
|
|
53
|
+
tool: ctx.event.fields?.['tool_name'] ?? 'unknown',
|
|
54
|
+
};
|
|
55
|
+
this.responseBuffer.push(entry);
|
|
56
|
+
return makeResult('block_tool', 'Tool blocked via stdio protocol');
|
|
57
|
+
}
|
|
58
|
+
async quarantineSession(ctx) {
|
|
59
|
+
const entry = {
|
|
60
|
+
action: 'quarantine_session',
|
|
61
|
+
verdict: ctx.verdict.outcome,
|
|
62
|
+
sessionId: ctx.sessionId ?? 'unknown',
|
|
63
|
+
};
|
|
64
|
+
this.responseBuffer.push(entry);
|
|
65
|
+
return makeResult('quarantine_session', 'Session quarantined via stdio protocol');
|
|
66
|
+
}
|
|
67
|
+
async resetContext(ctx) {
|
|
68
|
+
const entry = {
|
|
69
|
+
action: 'reset_context',
|
|
70
|
+
verdict: ctx.verdict.outcome,
|
|
71
|
+
};
|
|
72
|
+
this.responseBuffer.push(entry);
|
|
73
|
+
return makeResult('reset_context', 'Context reset via stdio protocol');
|
|
74
|
+
}
|
|
75
|
+
async alert(ctx) {
|
|
76
|
+
const alertMsg = {
|
|
77
|
+
type: 'alert',
|
|
78
|
+
severity: ctx.verdict.highestSeverity,
|
|
79
|
+
reason: ctx.verdict.reason,
|
|
80
|
+
matchCount: ctx.verdict.matchCount,
|
|
81
|
+
};
|
|
82
|
+
process.stderr.write(JSON.stringify(alertMsg) + '\n');
|
|
83
|
+
return makeResult('alert', 'Alert written to stderr');
|
|
84
|
+
}
|
|
85
|
+
async snapshot(ctx) {
|
|
86
|
+
const snapshotData = {
|
|
87
|
+
type: 'snapshot',
|
|
88
|
+
event: {
|
|
89
|
+
type: ctx.event.type,
|
|
90
|
+
contentPreview: ctx.event.content.slice(0, 200),
|
|
91
|
+
},
|
|
92
|
+
verdict: ctx.verdict.outcome,
|
|
93
|
+
matchCount: ctx.verdict.matchCount,
|
|
94
|
+
timestamp: new Date().toISOString(),
|
|
95
|
+
};
|
|
96
|
+
process.stderr.write(JSON.stringify(snapshotData) + '\n');
|
|
97
|
+
return makeResult('snapshot', 'Snapshot written to stderr');
|
|
98
|
+
}
|
|
99
|
+
async escalate(ctx) {
|
|
100
|
+
const escalation = {
|
|
101
|
+
type: 'escalation',
|
|
102
|
+
severity: ctx.verdict.highestSeverity,
|
|
103
|
+
reason: ctx.verdict.reason,
|
|
104
|
+
matchCount: ctx.verdict.matchCount,
|
|
105
|
+
};
|
|
106
|
+
process.stderr.write(JSON.stringify(escalation) + '\n');
|
|
107
|
+
return makeResult('escalate', 'Escalation written to stderr');
|
|
108
|
+
}
|
|
109
|
+
async reducePermissions(ctx) {
|
|
110
|
+
const entry = {
|
|
111
|
+
action: 'reduce_permissions',
|
|
112
|
+
verdict: ctx.verdict.outcome,
|
|
113
|
+
reason: ctx.verdict.reason,
|
|
114
|
+
};
|
|
115
|
+
this.responseBuffer.push(entry);
|
|
116
|
+
return makeResult('reduce_permissions', 'Permissions reduced via stdio protocol');
|
|
117
|
+
}
|
|
118
|
+
async killAgent(ctx) {
|
|
119
|
+
const entry = {
|
|
120
|
+
action: 'kill_agent',
|
|
121
|
+
verdict: ctx.verdict.outcome,
|
|
122
|
+
reason: ctx.verdict.reason,
|
|
123
|
+
};
|
|
124
|
+
this.responseBuffer.push(entry);
|
|
125
|
+
return makeResult('kill_agent', 'Agent kill requested via stdio protocol');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=stdio-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio-adapter.js","sourceRoot":"","sources":["../../src/adapters/stdio-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/badge.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ATR Badge Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates shields.io-compatible SVG badges and JSON endpoints
|
|
5
|
+
* for ATR scan results.
|
|
6
|
+
*
|
|
7
|
+
* Badge states:
|
|
8
|
+
* - Green: "ATR Scanned - No Issues" (scan passed, no findings)
|
|
9
|
+
* - Yellow: "ATR Scanned - Issues Found" (scan found potential threats)
|
|
10
|
+
* - Red: "ATR Scanned - Critical" (critical threats detected)
|
|
11
|
+
* - Gray: "Not Yet Scanned" (no scan data available)
|
|
12
|
+
*
|
|
13
|
+
* @module agent-threat-rules/badge
|
|
14
|
+
*/
|
|
15
|
+
export interface BadgeData {
|
|
16
|
+
readonly schemaVersion: 1;
|
|
17
|
+
readonly label: string;
|
|
18
|
+
readonly message: string;
|
|
19
|
+
readonly color: string;
|
|
20
|
+
readonly namedLogo?: string;
|
|
21
|
+
readonly logoSvg?: string;
|
|
22
|
+
}
|
|
23
|
+
export type BadgeStatus = 'clean' | 'issues' | 'critical' | 'unknown';
|
|
24
|
+
export interface ScanSummary {
|
|
25
|
+
readonly packageName: string;
|
|
26
|
+
readonly version?: string;
|
|
27
|
+
readonly scannedAt?: string;
|
|
28
|
+
readonly riskLevel: string;
|
|
29
|
+
readonly riskScore: number;
|
|
30
|
+
readonly findings: {
|
|
31
|
+
readonly critical: number;
|
|
32
|
+
readonly high: number;
|
|
33
|
+
readonly medium: number;
|
|
34
|
+
readonly low: number;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export declare function determineBadgeStatus(summary: ScanSummary): BadgeStatus;
|
|
38
|
+
export declare function generateBadgeEndpoint(summary: ScanSummary | null): BadgeData;
|
|
39
|
+
export declare function generateBadgeSvg(summary: ScanSummary | null): string;
|
|
40
|
+
export declare function lookupPackageScan(auditDataPath: string, packageName: string): ScanSummary | null;
|
|
41
|
+
export declare function generateBadgeMarkdown(packageName: string, repoUrl?: string): string;
|
|
42
|
+
//# sourceMappingURL=badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../src/badge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAiBD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,CActE;AAMD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CA+B5E;AAoBD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CA+BpE;AAMD,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,WAAW,GAAG,IAAI,CA6BpB;AAMD,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,MAAkE,GAC1E,MAAM,CAIR"}
|
package/dist/badge.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ATR Badge Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates shields.io-compatible SVG badges and JSON endpoints
|
|
5
|
+
* for ATR scan results.
|
|
6
|
+
*
|
|
7
|
+
* Badge states:
|
|
8
|
+
* - Green: "ATR Scanned - No Issues" (scan passed, no findings)
|
|
9
|
+
* - Yellow: "ATR Scanned - Issues Found" (scan found potential threats)
|
|
10
|
+
* - Red: "ATR Scanned - Critical" (critical threats detected)
|
|
11
|
+
* - Gray: "Not Yet Scanned" (no scan data available)
|
|
12
|
+
*
|
|
13
|
+
* @module agent-threat-rules/badge
|
|
14
|
+
*/
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Badge colors
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const BADGE_COLORS = {
|
|
20
|
+
clean: '#2ea44f', // GitHub green
|
|
21
|
+
issues: '#dfb317', // Warning yellow
|
|
22
|
+
critical: '#e05d44', // Alert red
|
|
23
|
+
unknown: '#9f9f9f', // Gray
|
|
24
|
+
};
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Determine badge status from scan data
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
export function determineBadgeStatus(summary) {
|
|
29
|
+
// Check ATR rule findings first
|
|
30
|
+
if (summary.findings.critical > 0)
|
|
31
|
+
return 'critical';
|
|
32
|
+
if (summary.findings.high > 0)
|
|
33
|
+
return 'critical';
|
|
34
|
+
if (summary.findings.medium > 0)
|
|
35
|
+
return 'issues';
|
|
36
|
+
if (summary.findings.low > 0)
|
|
37
|
+
return 'issues';
|
|
38
|
+
// Fall back to overall risk assessment (from code analysis, supply chain, etc.)
|
|
39
|
+
const level = summary.riskLevel.toUpperCase();
|
|
40
|
+
if (level === 'CRITICAL' || level === 'HIGH')
|
|
41
|
+
return 'critical';
|
|
42
|
+
if (level === 'MEDIUM')
|
|
43
|
+
return 'issues';
|
|
44
|
+
if (level === 'LOW')
|
|
45
|
+
return 'issues';
|
|
46
|
+
return 'clean';
|
|
47
|
+
}
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Generate shields.io endpoint JSON
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
export function generateBadgeEndpoint(summary) {
|
|
52
|
+
if (!summary) {
|
|
53
|
+
return {
|
|
54
|
+
schemaVersion: 1,
|
|
55
|
+
label: 'ATR',
|
|
56
|
+
message: 'Not Yet Scanned',
|
|
57
|
+
color: BADGE_COLORS.unknown,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const status = determineBadgeStatus(summary);
|
|
61
|
+
const totalFindings = summary.findings.critical + summary.findings.high + summary.findings.medium + summary.findings.low;
|
|
62
|
+
const messages = {
|
|
63
|
+
clean: 'Scanned - No Issues',
|
|
64
|
+
issues: totalFindings > 0
|
|
65
|
+
? `Scanned - ${totalFindings} Issue${totalFindings > 1 ? 's' : ''}`
|
|
66
|
+
: `Scanned - ${summary.riskLevel}`,
|
|
67
|
+
critical: totalFindings > 0
|
|
68
|
+
? `Scanned - ${summary.findings.critical + summary.findings.high} Critical`
|
|
69
|
+
: `Scanned - ${summary.riskLevel}`,
|
|
70
|
+
unknown: 'Not Yet Scanned',
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
schemaVersion: 1,
|
|
74
|
+
label: 'ATR',
|
|
75
|
+
message: messages[status],
|
|
76
|
+
color: BADGE_COLORS[status],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// Generate standalone SVG badge
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
function escapeXml(str) {
|
|
83
|
+
return str
|
|
84
|
+
.replace(/&/g, '&')
|
|
85
|
+
.replace(/</g, '<')
|
|
86
|
+
.replace(/>/g, '>')
|
|
87
|
+
.replace(/"/g, '"')
|
|
88
|
+
.replace(/'/g, ''');
|
|
89
|
+
}
|
|
90
|
+
function measureText(text) {
|
|
91
|
+
// Approximate character width for Verdana 11px (shields.io standard)
|
|
92
|
+
return text.length * 6.8 + 10;
|
|
93
|
+
}
|
|
94
|
+
export function generateBadgeSvg(summary) {
|
|
95
|
+
const data = generateBadgeEndpoint(summary);
|
|
96
|
+
const label = escapeXml(data.label);
|
|
97
|
+
const message = escapeXml(data.message);
|
|
98
|
+
const color = data.color;
|
|
99
|
+
const labelWidth = measureText(label);
|
|
100
|
+
const messageWidth = measureText(message);
|
|
101
|
+
const totalWidth = labelWidth + messageWidth;
|
|
102
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${totalWidth}" height="20" role="img" aria-label="${label}: ${message}">
|
|
103
|
+
<title>${label}: ${message}</title>
|
|
104
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
105
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
106
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
107
|
+
</linearGradient>
|
|
108
|
+
<clipPath id="r">
|
|
109
|
+
<rect width="${totalWidth}" height="20" rx="3" fill="#fff"/>
|
|
110
|
+
</clipPath>
|
|
111
|
+
<g clip-path="url(#r)">
|
|
112
|
+
<rect width="${labelWidth}" height="20" fill="#555"/>
|
|
113
|
+
<rect x="${labelWidth}" width="${messageWidth}" height="20" fill="${color}"/>
|
|
114
|
+
<rect width="${totalWidth}" height="20" fill="url(#s)"/>
|
|
115
|
+
</g>
|
|
116
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
|
|
117
|
+
<text aria-hidden="true" x="${labelWidth * 5}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">${label}</text>
|
|
118
|
+
<text x="${labelWidth * 5}" y="140" transform="scale(.1)" fill="#fff">${label}</text>
|
|
119
|
+
<text aria-hidden="true" x="${(labelWidth + messageWidth / 2) * 10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">${message}</text>
|
|
120
|
+
<text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff">${message}</text>
|
|
121
|
+
</g>
|
|
122
|
+
</svg>`;
|
|
123
|
+
}
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// Load scan result from audit data file
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
export function lookupPackageScan(auditDataPath, packageName) {
|
|
128
|
+
try {
|
|
129
|
+
const data = JSON.parse(readFileSync(auditDataPath, 'utf-8'));
|
|
130
|
+
const results = data.results ?? [];
|
|
131
|
+
const entry = results.find((r) => r.package === packageName);
|
|
132
|
+
if (!entry)
|
|
133
|
+
return null;
|
|
134
|
+
const atrMatches = entry.atrMatches ?? [];
|
|
135
|
+
const findings = { critical: 0, high: 0, medium: 0, low: 0 };
|
|
136
|
+
for (const m of atrMatches) {
|
|
137
|
+
const sev = (m.severity ?? m.rule?.severity ?? 'low').toLowerCase();
|
|
138
|
+
if (sev in findings) {
|
|
139
|
+
findings[sev]++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
packageName: entry.package,
|
|
144
|
+
version: entry.version,
|
|
145
|
+
scannedAt: entry.auditedAt ?? data.auditedAt,
|
|
146
|
+
riskLevel: entry.riskLevel ?? 'UNKNOWN',
|
|
147
|
+
riskScore: entry.riskScore ?? 0,
|
|
148
|
+
findings,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// Generate markdown badge snippet
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
export function generateBadgeMarkdown(packageName, repoUrl = 'https://github.com/Agent-Threat-Rule/agent-threat-rules') {
|
|
159
|
+
// Static badge URL using shields.io
|
|
160
|
+
const encodedName = encodeURIComponent(packageName);
|
|
161
|
+
return `[](${repoUrl})`;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=badge.js.map
|