@dotsetlabs/tollgate 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +885 -0
- package/dist/analyzers/filesystem.d.ts +26 -0
- package/dist/analyzers/filesystem.d.ts.map +1 -0
- package/dist/analyzers/filesystem.js +284 -0
- package/dist/analyzers/filesystem.js.map +1 -0
- package/dist/analyzers/http.d.ts +90 -0
- package/dist/analyzers/http.d.ts.map +1 -0
- package/dist/analyzers/http.js +433 -0
- package/dist/analyzers/http.js.map +1 -0
- package/dist/analyzers/index.d.ts +101 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +342 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/loader.d.ts +114 -0
- package/dist/analyzers/loader.d.ts.map +1 -0
- package/dist/analyzers/loader.js +184 -0
- package/dist/analyzers/loader.js.map +1 -0
- package/dist/analyzers/prompt-injection.d.ts +95 -0
- package/dist/analyzers/prompt-injection.d.ts.map +1 -0
- package/dist/analyzers/prompt-injection.js +725 -0
- package/dist/analyzers/prompt-injection.js.map +1 -0
- package/dist/analyzers/sdk.d.ts +230 -0
- package/dist/analyzers/sdk.d.ts.map +1 -0
- package/dist/analyzers/sdk.js +283 -0
- package/dist/analyzers/sdk.js.map +1 -0
- package/dist/analyzers/shell.d.ts +20 -0
- package/dist/analyzers/shell.d.ts.map +1 -0
- package/dist/analyzers/shell.js +297 -0
- package/dist/analyzers/shell.js.map +1 -0
- package/dist/analyzers/sql.d.ts +37 -0
- package/dist/analyzers/sql.d.ts.map +1 -0
- package/dist/analyzers/sql.js +455 -0
- package/dist/analyzers/sql.js.map +1 -0
- package/dist/analyzers/types.d.ts +117 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +46 -0
- package/dist/analyzers/types.js.map +1 -0
- package/dist/approval/interactive.d.ts +72 -0
- package/dist/approval/interactive.d.ts.map +1 -0
- package/dist/approval/interactive.js +550 -0
- package/dist/approval/interactive.js.map +1 -0
- package/dist/approval/terminal.d.ts +59 -0
- package/dist/approval/terminal.d.ts.map +1 -0
- package/dist/approval/terminal.js +238 -0
- package/dist/approval/terminal.js.map +1 -0
- package/dist/approval/types.d.ts +66 -0
- package/dist/approval/types.d.ts.map +1 -0
- package/dist/approval/types.js +2 -0
- package/dist/approval/types.js.map +1 -0
- package/dist/audit/exporter.d.ts +138 -0
- package/dist/audit/exporter.d.ts.map +1 -0
- package/dist/audit/exporter.js +366 -0
- package/dist/audit/exporter.js.map +1 -0
- package/dist/audit/logger.d.ts +156 -0
- package/dist/audit/logger.d.ts.map +1 -0
- package/dist/audit/logger.js +406 -0
- package/dist/audit/logger.js.map +1 -0
- package/dist/audit/redaction.d.ts +110 -0
- package/dist/audit/redaction.d.ts.map +1 -0
- package/dist/audit/redaction.js +307 -0
- package/dist/audit/redaction.js.map +1 -0
- package/dist/audit/schema.d.ts +76 -0
- package/dist/audit/schema.d.ts.map +1 -0
- package/dist/audit/schema.js +122 -0
- package/dist/audit/schema.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +34 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +431 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export.d.ts +18 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +63 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/init.d.ts +12 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +102 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +11 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +60 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +29 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/scan.js +251 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +26 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +424 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/start.d.ts +20 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +82 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +10 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +42 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/templates.d.ts +26 -0
- package/dist/cli/commands/templates.d.ts.map +1 -0
- package/dist/cli/commands/templates.js +221 -0
- package/dist/cli/commands/templates.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +12 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +107 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/commands/wrap.d.ts +19 -0
- package/dist/cli/commands/wrap.d.ts.map +1 -0
- package/dist/cli/commands/wrap.js +59 -0
- package/dist/cli/commands/wrap.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +202 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui.d.ts +139 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +271 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/constants.d.ts +33 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +54 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +28 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +37 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/index.d.ts +11 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +10 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/manager.d.ts +127 -0
- package/dist/orchestrator/manager.d.ts.map +1 -0
- package/dist/orchestrator/manager.js +498 -0
- package/dist/orchestrator/manager.js.map +1 -0
- package/dist/orchestrator/types.d.ts +141 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +9 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/policy/engine.d.ts +55 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +288 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/natural-language.d.ts +141 -0
- package/dist/policy/natural-language.d.ts.map +1 -0
- package/dist/policy/natural-language.js +552 -0
- package/dist/policy/natural-language.js.map +1 -0
- package/dist/policy/parser.d.ts +141 -0
- package/dist/policy/parser.d.ts.map +1 -0
- package/dist/policy/parser.js +314 -0
- package/dist/policy/parser.js.map +1 -0
- package/dist/policy/types.d.ts +428 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +32 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/policy/validator.d.ts +72 -0
- package/dist/policy/validator.d.ts.map +1 -0
- package/dist/policy/validator.js +453 -0
- package/dist/policy/validator.js.map +1 -0
- package/dist/proxy/bridge.d.ts +84 -0
- package/dist/proxy/bridge.d.ts.map +1 -0
- package/dist/proxy/bridge.js +217 -0
- package/dist/proxy/bridge.js.map +1 -0
- package/dist/proxy/client.d.ts +130 -0
- package/dist/proxy/client.d.ts.map +1 -0
- package/dist/proxy/client.js +290 -0
- package/dist/proxy/client.js.map +1 -0
- package/dist/proxy/server.d.ts +111 -0
- package/dist/proxy/server.d.ts.map +1 -0
- package/dist/proxy/server.js +444 -0
- package/dist/proxy/server.js.map +1 -0
- package/dist/scanner.d.ts +91 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +373 -0
- package/dist/scanner.js.map +1 -0
- package/dist/session/index.d.ts +32 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +31 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/manager.d.ts +166 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +454 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/sqlite-store.d.ts +54 -0
- package/dist/session/sqlite-store.d.ts.map +1 -0
- package/dist/session/sqlite-store.js +209 -0
- package/dist/session/sqlite-store.js.map +1 -0
- package/dist/session/types.d.ts +179 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +38 -0
- package/dist/session/types.js.map +1 -0
- package/dist/templates.d.ts +64 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +451 -0
- package/dist/templates.js.map +1 -0
- package/dist/utils/config.d.ts +57 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +104 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/errors.d.ts +18 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +35 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +144 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +300 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/wizard.d.ts +68 -0
- package/dist/wizard.d.ts.map +1 -0
- package/dist/wizard.js +395 -0
- package/dist/wizard.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Engine for Tollgate
|
|
3
|
+
*
|
|
4
|
+
* Evaluates policies against tool call contexts and returns decisions.
|
|
5
|
+
* Supports exact matches, glob patterns, smart content analysis,
|
|
6
|
+
* guardrails, and hierarchical defaults (tool → server → global).
|
|
7
|
+
*/
|
|
8
|
+
import type { TollgateConfig, PolicyDecision, ToolCallContext } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* PolicyEngine evaluates tool calls against configured policies.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const engine = new PolicyEngine(config);
|
|
15
|
+
*
|
|
16
|
+
* const decision = engine.evaluate({
|
|
17
|
+
* server: 'postgres',
|
|
18
|
+
* tool: 'query',
|
|
19
|
+
* args: { sql: 'SELECT * FROM users' },
|
|
20
|
+
* timestamp: new Date(),
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* if (decision.action === 'prompt') {
|
|
24
|
+
* // Ask user for approval
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class PolicyEngine {
|
|
29
|
+
private readonly config;
|
|
30
|
+
constructor(config: TollgateConfig);
|
|
31
|
+
evaluate(context: ToolCallContext): PolicyDecision;
|
|
32
|
+
/**
|
|
33
|
+
* Check all enabled guardrails against the tool call context.
|
|
34
|
+
* Returns the first triggered guardrail result, or null if none triggered.
|
|
35
|
+
*/
|
|
36
|
+
private checkGuardrails;
|
|
37
|
+
/**
|
|
38
|
+
* Determine if a guardrail should trigger based on risk level and sensitivity.
|
|
39
|
+
*/
|
|
40
|
+
private shouldTriggerGuardrail;
|
|
41
|
+
/**
|
|
42
|
+
* Get the action to take based on guardrail configuration.
|
|
43
|
+
*/
|
|
44
|
+
private getGuardrailAction;
|
|
45
|
+
private findMatchingPolicy;
|
|
46
|
+
private applyPolicy;
|
|
47
|
+
private applySmartAnalysis;
|
|
48
|
+
private applyGlobalDefault;
|
|
49
|
+
/**
|
|
50
|
+
* Gets the current configuration.
|
|
51
|
+
* Useful for inspecting policies at runtime.
|
|
52
|
+
*/
|
|
53
|
+
getConfig(): TollgateConfig;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/policy/engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,eAAe,EAKhB,MAAM,YAAY,CAAC;AAYpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;gBAE5B,MAAM,EAAE,cAAc;IAIlC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc;IAoFlD;;;OAGG;IACH,OAAO,CAAC,eAAe;IA8CvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAgB9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,kBAAkB;IA0C1B,OAAO,CAAC,WAAW;IAsCnB,OAAO,CAAC,kBAAkB;IA2C1B,OAAO,CAAC,kBAAkB;IAmB1B;;;OAGG;IACH,SAAS,IAAI,cAAc;CAG5B"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Engine for Tollgate
|
|
3
|
+
*
|
|
4
|
+
* Evaluates policies against tool call contexts and returns decisions.
|
|
5
|
+
* Supports exact matches, glob patterns, smart content analysis,
|
|
6
|
+
* guardrails, and hierarchical defaults (tool → server → global).
|
|
7
|
+
*/
|
|
8
|
+
import { minimatch } from 'minimatch';
|
|
9
|
+
import { normalizeToolPolicy } from './parser.js';
|
|
10
|
+
import { analyzerRegistry, inferAnalyzer, extractAnalyzableContent, riskToAction, DEFAULT_RISK_MAPPING, } from '../analyzers/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* PolicyEngine evaluates tool calls against configured policies.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const engine = new PolicyEngine(config);
|
|
17
|
+
*
|
|
18
|
+
* const decision = engine.evaluate({
|
|
19
|
+
* server: 'postgres',
|
|
20
|
+
* tool: 'query',
|
|
21
|
+
* args: { sql: 'SELECT * FROM users' },
|
|
22
|
+
* timestamp: new Date(),
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* if (decision.action === 'prompt') {
|
|
26
|
+
* // Ask user for approval
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class PolicyEngine {
|
|
31
|
+
config;
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.config = config;
|
|
34
|
+
}
|
|
35
|
+
evaluate(context) {
|
|
36
|
+
// Step 1: Check guardrails FIRST (before any policy evaluation)
|
|
37
|
+
const guardrailResult = this.checkGuardrails(context);
|
|
38
|
+
if (guardrailResult) {
|
|
39
|
+
const guardrailAction = this.getGuardrailAction(guardrailResult);
|
|
40
|
+
if (guardrailAction === 'deny') {
|
|
41
|
+
return {
|
|
42
|
+
action: 'deny',
|
|
43
|
+
reason: guardrailResult.reason,
|
|
44
|
+
matchedRule: `guardrail:${guardrailResult.guardrail}`,
|
|
45
|
+
guardrail: guardrailResult,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
else if (guardrailAction === 'prompt') {
|
|
49
|
+
return {
|
|
50
|
+
action: 'prompt',
|
|
51
|
+
reason: guardrailResult.reason,
|
|
52
|
+
message: `Security warning: ${guardrailResult.reason}. Do you want to proceed?`,
|
|
53
|
+
matchedRule: `guardrail:${guardrailResult.guardrail}`,
|
|
54
|
+
guardrail: guardrailResult,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// For 'warn', we log but continue with normal policy evaluation
|
|
58
|
+
// The guardrail result is still attached to the decision
|
|
59
|
+
}
|
|
60
|
+
// Step 2: Normal policy evaluation
|
|
61
|
+
const serverConfig = this.config.servers?.[context.server];
|
|
62
|
+
if (!serverConfig) {
|
|
63
|
+
const decision = this.applyGlobalDefault('No server config found');
|
|
64
|
+
if (guardrailResult) {
|
|
65
|
+
decision.guardrail = guardrailResult;
|
|
66
|
+
}
|
|
67
|
+
return decision;
|
|
68
|
+
}
|
|
69
|
+
const toolPolicies = serverConfig.tools ?? {};
|
|
70
|
+
const matchedPolicy = this.findMatchingPolicy(context.tool, toolPolicies);
|
|
71
|
+
if (matchedPolicy) {
|
|
72
|
+
const policy = normalizeToolPolicy(matchedPolicy.policy);
|
|
73
|
+
const decision = this.applyPolicy(policy, matchedPolicy.pattern, context, serverConfig.defaults?.analyzer);
|
|
74
|
+
if (guardrailResult) {
|
|
75
|
+
decision.guardrail = guardrailResult;
|
|
76
|
+
}
|
|
77
|
+
return decision;
|
|
78
|
+
}
|
|
79
|
+
// Check if server has a default analyzer configured
|
|
80
|
+
if (serverConfig.defaults?.action === 'smart' || serverConfig.defaults?.analyzer) {
|
|
81
|
+
const analyzerName = serverConfig.defaults.analyzer ?? inferAnalyzer(context.server, context.tool, context.args);
|
|
82
|
+
if (analyzerName) {
|
|
83
|
+
const decision = this.applySmartAnalysis(analyzerName, context, undefined, `${context.server}:defaults`);
|
|
84
|
+
if (guardrailResult) {
|
|
85
|
+
decision.guardrail = guardrailResult;
|
|
86
|
+
}
|
|
87
|
+
return decision;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (serverConfig.defaults?.action && serverConfig.defaults.action !== 'smart') {
|
|
91
|
+
const decision = {
|
|
92
|
+
action: serverConfig.defaults.action,
|
|
93
|
+
reason: 'Applied server default',
|
|
94
|
+
matchedRule: `${context.server}:defaults`,
|
|
95
|
+
};
|
|
96
|
+
if (guardrailResult) {
|
|
97
|
+
decision.guardrail = guardrailResult;
|
|
98
|
+
}
|
|
99
|
+
return decision;
|
|
100
|
+
}
|
|
101
|
+
const decision = this.applyGlobalDefault('No matching tool policy');
|
|
102
|
+
if (guardrailResult) {
|
|
103
|
+
decision.guardrail = guardrailResult;
|
|
104
|
+
}
|
|
105
|
+
return decision;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check all enabled guardrails against the tool call context.
|
|
109
|
+
* Returns the first triggered guardrail result, or null if none triggered.
|
|
110
|
+
*/
|
|
111
|
+
checkGuardrails(context) {
|
|
112
|
+
const guardrailsConfig = this.config.guardrails;
|
|
113
|
+
// Check prompt injection guardrail
|
|
114
|
+
if (guardrailsConfig?.promptInjection?.enabled) {
|
|
115
|
+
const piConfig = guardrailsConfig.promptInjection;
|
|
116
|
+
// Check server allowlist
|
|
117
|
+
if (piConfig.serverAllowlist?.includes(context.server)) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
// Check tool allowlist
|
|
121
|
+
if (piConfig.allowlist?.includes(context.tool)) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
// Extract all string content from arguments
|
|
125
|
+
const content = extractAnalyzableContent('prompt-injection', context.tool, context.args);
|
|
126
|
+
if (content) {
|
|
127
|
+
const analysisResult = analyzerRegistry.analyze('prompt-injection', content, {
|
|
128
|
+
tool: context.tool,
|
|
129
|
+
server: context.server,
|
|
130
|
+
args: context.args,
|
|
131
|
+
});
|
|
132
|
+
// Apply sensitivity threshold
|
|
133
|
+
const sensitivity = piConfig.sensitivity ?? 'balanced';
|
|
134
|
+
const shouldTrigger = this.shouldTriggerGuardrail(analysisResult.risk, sensitivity);
|
|
135
|
+
if (shouldTrigger) {
|
|
136
|
+
return {
|
|
137
|
+
triggered: true,
|
|
138
|
+
guardrail: 'prompt-injection',
|
|
139
|
+
risk: analysisResult.risk,
|
|
140
|
+
reason: analysisResult.reason,
|
|
141
|
+
triggers: analysisResult.triggers,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Determine if a guardrail should trigger based on risk level and sensitivity.
|
|
150
|
+
*/
|
|
151
|
+
shouldTriggerGuardrail(risk, sensitivity) {
|
|
152
|
+
switch (sensitivity) {
|
|
153
|
+
case 'strict':
|
|
154
|
+
// Trigger on write, destructive, or dangerous
|
|
155
|
+
return ['write', 'destructive', 'dangerous'].includes(risk);
|
|
156
|
+
case 'balanced':
|
|
157
|
+
// Trigger on destructive or dangerous
|
|
158
|
+
return ['destructive', 'dangerous'].includes(risk);
|
|
159
|
+
case 'permissive':
|
|
160
|
+
// Only trigger on dangerous
|
|
161
|
+
return risk === 'dangerous';
|
|
162
|
+
default:
|
|
163
|
+
return risk === 'dangerous';
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get the action to take based on guardrail configuration.
|
|
168
|
+
*/
|
|
169
|
+
getGuardrailAction(result) {
|
|
170
|
+
const guardrailsConfig = this.config.guardrails;
|
|
171
|
+
if (result.guardrail === 'prompt-injection') {
|
|
172
|
+
return guardrailsConfig?.promptInjection?.action ?? 'deny';
|
|
173
|
+
}
|
|
174
|
+
return 'deny';
|
|
175
|
+
}
|
|
176
|
+
findMatchingPolicy(toolName, policies) {
|
|
177
|
+
// First, check for exact match
|
|
178
|
+
if (policies[toolName]) {
|
|
179
|
+
return { pattern: toolName, policy: policies[toolName] };
|
|
180
|
+
}
|
|
181
|
+
// Then check glob patterns, sorted by specificity
|
|
182
|
+
// Specificity is determined by: fewer wildcards = more specific,
|
|
183
|
+
// wildcard position later = more specific (exact prefix match)
|
|
184
|
+
const patterns = Object.keys(policies)
|
|
185
|
+
.filter((p) => p !== toolName && p.includes('*'))
|
|
186
|
+
.sort((a, b) => {
|
|
187
|
+
// Count wildcards - fewer is more specific
|
|
188
|
+
const aWildcards = (a.match(/\*/g) ?? []).length;
|
|
189
|
+
const bWildcards = (b.match(/\*/g) ?? []).length;
|
|
190
|
+
if (aWildcards !== bWildcards) {
|
|
191
|
+
return aWildcards - bWildcards;
|
|
192
|
+
}
|
|
193
|
+
// Find position of first wildcard - later is more specific
|
|
194
|
+
const aFirstWild = a.indexOf('*');
|
|
195
|
+
const bFirstWild = b.indexOf('*');
|
|
196
|
+
if (aFirstWild !== bFirstWild) {
|
|
197
|
+
return bFirstWild - aFirstWild;
|
|
198
|
+
}
|
|
199
|
+
// Fall back to length comparison
|
|
200
|
+
return b.length - a.length;
|
|
201
|
+
});
|
|
202
|
+
for (const pattern of patterns) {
|
|
203
|
+
if (minimatch(toolName, pattern)) {
|
|
204
|
+
return { pattern, policy: policies[pattern] };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
applyPolicy(policy, matchedPattern, context, defaultAnalyzer) {
|
|
210
|
+
// Handle smart action
|
|
211
|
+
if (policy.action === 'smart') {
|
|
212
|
+
const analyzerName = policy.analyzer ?? defaultAnalyzer ?? inferAnalyzer(context.server, context.tool, context.args);
|
|
213
|
+
if (!analyzerName) {
|
|
214
|
+
// Can't determine analyzer, fall back to prompt
|
|
215
|
+
return {
|
|
216
|
+
action: 'prompt',
|
|
217
|
+
reason: 'Smart analysis requested but no analyzer available',
|
|
218
|
+
message: policy.message,
|
|
219
|
+
matchedRule: matchedPattern,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return this.applySmartAnalysis(analyzerName, context, policy.risks, matchedPattern, policy.message);
|
|
223
|
+
}
|
|
224
|
+
// Regular action
|
|
225
|
+
return {
|
|
226
|
+
action: policy.action,
|
|
227
|
+
reason: policy.reason,
|
|
228
|
+
message: policy.message,
|
|
229
|
+
matchedRule: matchedPattern,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
applySmartAnalysis(analyzerName, context, riskMapping, matchedRule, customMessage) {
|
|
233
|
+
// Extract content to analyze
|
|
234
|
+
const content = extractAnalyzableContent(analyzerName, context.tool, context.args);
|
|
235
|
+
if (!content) {
|
|
236
|
+
// Can't extract content, fall back to prompt
|
|
237
|
+
return {
|
|
238
|
+
action: 'prompt',
|
|
239
|
+
reason: `Could not extract content for ${analyzerName} analysis`,
|
|
240
|
+
matchedRule,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
// Run analysis
|
|
244
|
+
const result = analyzerRegistry.analyze(analyzerName, content, {
|
|
245
|
+
tool: context.tool,
|
|
246
|
+
server: context.server,
|
|
247
|
+
args: context.args,
|
|
248
|
+
});
|
|
249
|
+
// Map risk to action
|
|
250
|
+
const mapping = { ...DEFAULT_RISK_MAPPING, ...riskMapping };
|
|
251
|
+
const action = riskToAction(result.risk, mapping);
|
|
252
|
+
return {
|
|
253
|
+
action,
|
|
254
|
+
reason: result.reason,
|
|
255
|
+
message: customMessage,
|
|
256
|
+
matchedRule,
|
|
257
|
+
analysis: {
|
|
258
|
+
analyzer: analyzerName,
|
|
259
|
+
risk: result.risk,
|
|
260
|
+
triggers: result.triggers,
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
applyGlobalDefault(reason) {
|
|
265
|
+
const defaultAction = this.config.defaults?.action ?? 'prompt';
|
|
266
|
+
// smart as global default doesn't make sense without context
|
|
267
|
+
if (defaultAction === 'smart') {
|
|
268
|
+
return {
|
|
269
|
+
action: 'prompt',
|
|
270
|
+
reason: `${reason}; smart analysis requires tool-specific config`,
|
|
271
|
+
matchedRule: 'defaults',
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
action: defaultAction,
|
|
276
|
+
reason: `${reason}; applied global default`,
|
|
277
|
+
matchedRule: 'defaults',
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Gets the current configuration.
|
|
282
|
+
* Useful for inspecting policies at runtime.
|
|
283
|
+
*/
|
|
284
|
+
getConfig() {
|
|
285
|
+
return this.config;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/policy/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Natural Language Policy Parser
|
|
3
|
+
*
|
|
4
|
+
* Converts human-readable policy statements into structured ToolPolicy objects.
|
|
5
|
+
* Uses rule-based pattern matching to interpret common policy expressions.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { parsePolicy, parseNaturalPolicies } from '@dotsetlabs/tollgate/policy';
|
|
10
|
+
*
|
|
11
|
+
* const policy = parsePolicy('Allow read operations on postgres');
|
|
12
|
+
* // { action: 'smart', analyzer: 'sql', risks: { read: 'allow', write: 'deny', ... } }
|
|
13
|
+
*
|
|
14
|
+
* const policies = parseNaturalPolicies([
|
|
15
|
+
* 'Allow read operations on postgres',
|
|
16
|
+
* 'Deny destructive queries on any database',
|
|
17
|
+
* 'Prompt for file writes outside /tmp'
|
|
18
|
+
* ]);
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module policy/natural-language
|
|
22
|
+
*/
|
|
23
|
+
import type { PolicyAction, ToolPolicy } from './types.js';
|
|
24
|
+
/**
|
|
25
|
+
* Result of parsing a natural language policy.
|
|
26
|
+
*/
|
|
27
|
+
export interface ParsedPolicy {
|
|
28
|
+
/** Whether parsing succeeded */
|
|
29
|
+
success: boolean;
|
|
30
|
+
/** The parsed tool policy (if successful) */
|
|
31
|
+
policy?: ToolPolicy;
|
|
32
|
+
/** Server pattern to match (e.g., 'postgres', '*') */
|
|
33
|
+
serverPattern?: string;
|
|
34
|
+
/** Tool pattern to match (e.g., 'query', '*') */
|
|
35
|
+
toolPattern?: string;
|
|
36
|
+
/** Error message (if failed) */
|
|
37
|
+
error?: string;
|
|
38
|
+
/** The original input string */
|
|
39
|
+
input: string;
|
|
40
|
+
/** Explanation of how the policy was interpreted */
|
|
41
|
+
interpretation?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Configuration for the natural language parser.
|
|
45
|
+
*/
|
|
46
|
+
export interface ParserOptions {
|
|
47
|
+
/** Whether to require explicit server/tool targets (default: false) */
|
|
48
|
+
requireTarget?: boolean;
|
|
49
|
+
/** Default action when risk level not specified (default: 'prompt') */
|
|
50
|
+
defaultAction?: PolicyAction;
|
|
51
|
+
/** Whether to allow fuzzy matching (default: true) */
|
|
52
|
+
fuzzyMatching?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Parse a single natural language policy statement.
|
|
56
|
+
*
|
|
57
|
+
* @param input - The natural language policy statement
|
|
58
|
+
* @param options - Parser options
|
|
59
|
+
* @returns Parsed policy result
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const result = parsePolicy('Allow read operations on postgres');
|
|
64
|
+
* if (result.success) {
|
|
65
|
+
* console.log(result.policy); // { action: 'smart', analyzer: 'sql', ... }
|
|
66
|
+
* console.log(result.serverPattern); // 'postgres'
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare function parsePolicy(input: string, options?: ParserOptions): ParsedPolicy;
|
|
71
|
+
/**
|
|
72
|
+
* Parse multiple natural language policy statements.
|
|
73
|
+
*
|
|
74
|
+
* @param inputs - Array of natural language policy statements
|
|
75
|
+
* @param options - Parser options
|
|
76
|
+
* @returns Array of parsed policy results
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const results = parseNaturalPolicies([
|
|
81
|
+
* 'Allow read operations on postgres',
|
|
82
|
+
* 'Deny destructive queries on any database',
|
|
83
|
+
* 'Prompt for file writes',
|
|
84
|
+
* ]);
|
|
85
|
+
*
|
|
86
|
+
* const successful = results.filter(r => r.success);
|
|
87
|
+
* const failed = results.filter(r => !r.success);
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function parseNaturalPolicies(inputs: string[], options?: ParserOptions): ParsedPolicy[];
|
|
91
|
+
/**
|
|
92
|
+
* Convert parsed natural language policies to a server configuration.
|
|
93
|
+
*
|
|
94
|
+
* Groups policies by server pattern and builds tool configurations.
|
|
95
|
+
*
|
|
96
|
+
* @param policies - Array of parsed policies
|
|
97
|
+
* @returns Object mapping server patterns to their tool configurations
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const parsed = parseNaturalPolicies([
|
|
102
|
+
* 'Allow read operations on postgres',
|
|
103
|
+
* 'Deny dangerous operations on postgres',
|
|
104
|
+
* ]);
|
|
105
|
+
*
|
|
106
|
+
* const config = policiesToConfig(parsed);
|
|
107
|
+
* // { 'postgres': { tools: { '*': { action: 'smart', ... } } } }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function policiesToConfig(policies: ParsedPolicy[]): Record<string, {
|
|
111
|
+
tools: Record<string, ToolPolicy>;
|
|
112
|
+
}>;
|
|
113
|
+
/**
|
|
114
|
+
* Validate a natural language policy statement without parsing.
|
|
115
|
+
*
|
|
116
|
+
* @param input - The policy statement to validate
|
|
117
|
+
* @returns Whether the statement appears valid
|
|
118
|
+
*/
|
|
119
|
+
export declare function isValidPolicyStatement(input: string): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Get suggestions for fixing an invalid policy statement.
|
|
122
|
+
*
|
|
123
|
+
* @param input - The invalid policy statement
|
|
124
|
+
* @returns Array of suggested corrections
|
|
125
|
+
*/
|
|
126
|
+
export declare function getSuggestions(input: string): string[];
|
|
127
|
+
/**
|
|
128
|
+
* Common policy templates for quick reference.
|
|
129
|
+
*/
|
|
130
|
+
export declare const POLICY_TEMPLATES: {
|
|
131
|
+
readonly allowReadOnly: "Allow read operations on ${server}";
|
|
132
|
+
readonly denyDangerous: "Deny dangerous operations on any server";
|
|
133
|
+
readonly promptForWrites: "Prompt for write operations on ${server}";
|
|
134
|
+
readonly allowAll: "Allow all operations on ${server}";
|
|
135
|
+
readonly denyAll: "Deny all operations on ${server}";
|
|
136
|
+
readonly promptAll: "Prompt for all operations on ${server}";
|
|
137
|
+
readonly readOnlyDatabase: "Allow read operations and deny mutations on ${server}";
|
|
138
|
+
readonly safeFileAccess: "Allow read operations and prompt for writes on filesystem";
|
|
139
|
+
readonly restrictedShell: "Deny dangerous commands and prompt for destructive operations on shell";
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=natural-language.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"natural-language.d.ts","sourceRoot":"","sources":["../../src/policy/natural-language.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG3D;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,sDAAsD;IACtD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAsXD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAmGd;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE,aAAkB,GAC1B,YAAY,EAAE,CAEhB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EAAE,GACvB,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CAAE,CAAC,CAwBvD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAI7D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAgCtD;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;CAUnB,CAAC"}
|