@praxis.guard/auditor-cli 0.0.33 → 0.0.34
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/approval/argv-fingerprint.d.ts +10 -1
- package/dist/approval/argv-fingerprint.d.ts.map +1 -1
- package/dist/approval/argv-fingerprint.js +10 -1
- package/dist/approval/argv-fingerprint.js.map +1 -1
- package/dist/approval/hook-inline-approval.d.ts +2 -0
- package/dist/approval/hook-inline-approval.d.ts.map +1 -1
- package/dist/approval/hook-inline-approval.js +6 -2
- package/dist/approval/hook-inline-approval.js.map +1 -1
- package/dist/approval/mcp-flow.d.ts +4 -2
- package/dist/approval/mcp-flow.d.ts.map +1 -1
- package/dist/approval/mcp-flow.js +9 -3
- package/dist/approval/mcp-flow.js.map +1 -1
- package/dist/approval/redeem.d.ts +2 -0
- package/dist/approval/redeem.d.ts.map +1 -1
- package/dist/approval/redeem.js +7 -2
- package/dist/approval/redeem.js.map +1 -1
- package/dist/bridge/execution-ticket.d.ts +3 -0
- package/dist/bridge/execution-ticket.d.ts.map +1 -1
- package/dist/bridge/execution-ticket.js +38 -9
- package/dist/bridge/execution-ticket.js.map +1 -1
- package/dist/bridge/shell-approval-bridge.d.ts +14 -5
- package/dist/bridge/shell-approval-bridge.d.ts.map +1 -1
- package/dist/bridge/shell-approval-bridge.js +47 -24
- package/dist/bridge/shell-approval-bridge.js.map +1 -1
- package/dist/hooks/before-shell-io.d.ts +3 -0
- package/dist/hooks/before-shell-io.d.ts.map +1 -0
- package/dist/hooks/before-shell-io.js +26 -0
- package/dist/hooks/before-shell-io.js.map +1 -0
- package/dist/hooks/before-shell-mutate.d.ts +23 -0
- package/dist/hooks/before-shell-mutate.d.ts.map +1 -0
- package/dist/hooks/before-shell-mutate.js +74 -0
- package/dist/hooks/before-shell-mutate.js.map +1 -0
- package/dist/hooks/before-shell-skipped.d.ts +11 -0
- package/dist/hooks/before-shell-skipped.d.ts.map +1 -0
- package/dist/hooks/before-shell-skipped.js +49 -0
- package/dist/hooks/before-shell-skipped.js.map +1 -0
- package/dist/hooks/before-shell-types.d.ts +12 -0
- package/dist/hooks/before-shell-types.d.ts.map +1 -0
- package/dist/hooks/before-shell-types.js +2 -0
- package/dist/hooks/before-shell-types.js.map +1 -0
- package/dist/hooks/run-before-shell.d.ts +2 -10
- package/dist/hooks/run-before-shell.d.ts.map +1 -1
- package/dist/hooks/run-before-shell.js +63 -142
- package/dist/hooks/run-before-shell.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/evaluate-guard.d.ts.map +1 -1
- package/dist/mcp/evaluate-guard.js +20 -9
- package/dist/mcp/evaluate-guard.js.map +1 -1
- package/dist/mcp/guard-approval-block.d.ts +1 -0
- package/dist/mcp/guard-approval-block.d.ts.map +1 -1
- package/dist/mcp/guard-approval-block.js +1 -0
- package/dist/mcp/guard-approval-block.js.map +1 -1
- package/dist/policies.v1.json +4 -0
- package/dist/policy/index.d.ts +4 -0
- package/dist/policy/index.d.ts.map +1 -1
- package/dist/policy/index.js +6 -0
- package/dist/policy/index.js.map +1 -1
- package/dist/shell/analyze-command-aggregate.d.ts +16 -0
- package/dist/shell/analyze-command-aggregate.d.ts.map +1 -0
- package/dist/shell/analyze-command-aggregate.js +89 -0
- package/dist/shell/analyze-command-aggregate.js.map +1 -0
- package/dist/shell/analyze-command-invocations.d.ts +11 -0
- package/dist/shell/analyze-command-invocations.d.ts.map +1 -0
- package/dist/shell/analyze-command-invocations.js +113 -0
- package/dist/shell/analyze-command-invocations.js.map +1 -0
- package/dist/shell/analyze-command.d.ts +7 -0
- package/dist/shell/analyze-command.d.ts.map +1 -0
- package/dist/shell/analyze-command.js +46 -0
- package/dist/shell/analyze-command.js.map +1 -0
- package/dist/shell/analyze-command.types.d.ts +38 -0
- package/dist/shell/analyze-command.types.d.ts.map +1 -0
- package/dist/shell/analyze-command.types.js +2 -0
- package/dist/shell/analyze-command.types.js.map +1 -0
- package/dist/shell/evaluate.d.ts +15 -18
- package/dist/shell/evaluate.d.ts.map +1 -1
- package/dist/shell/evaluate.js +57 -47
- package/dist/shell/evaluate.js.map +1 -1
- package/dist/shell/governed-tools.d.ts +18 -1
- package/dist/shell/governed-tools.d.ts.map +1 -1
- package/dist/shell/governed-tools.js +60 -1
- package/dist/shell/governed-tools.js.map +1 -1
- package/dist/shell/guard-eval.d.ts +15 -0
- package/dist/shell/guard-eval.d.ts.map +1 -0
- package/dist/shell/guard-eval.js +35 -0
- package/dist/shell/guard-eval.js.map +1 -0
- package/dist/shell/parse-segments.d.ts +14 -0
- package/dist/shell/parse-segments.d.ts.map +1 -0
- package/dist/shell/parse-segments.js +41 -0
- package/dist/shell/parse-segments.js.map +1 -0
- package/package.json +1 -1
package/dist/shell/evaluate.d.ts
CHANGED
|
@@ -1,24 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type PoliciesV1 } from "../policy/index.js";
|
|
2
|
+
import { type ShellAnalysis } from "./analyze-command.js";
|
|
3
|
+
import { type GuardEvaluation } from "./guard-eval.js";
|
|
4
|
+
import { parseCommandToArgv } from "./parse.js";
|
|
2
5
|
export type { PoliciesV1, Tier } from "../policy/index.js";
|
|
6
|
+
export type { GuardEvaluation, GuardReason } from "./guard-eval.js";
|
|
7
|
+
export { evaluateArgv } from "./guard-eval.js";
|
|
3
8
|
export { parseCommandToArgv } from "./parse.js";
|
|
4
|
-
export {
|
|
5
|
-
export
|
|
6
|
-
code: string;
|
|
7
|
-
message: string;
|
|
8
|
-
details?: Record<string, unknown>;
|
|
9
|
-
};
|
|
10
|
-
export type GuardEvaluation = {
|
|
11
|
-
argv: string[];
|
|
12
|
-
tier: Tier;
|
|
13
|
-
reasons: GuardReason[];
|
|
14
|
-
classification: ReturnType<typeof classifyArgv>["classification"];
|
|
15
|
-
flags: ReturnType<typeof classifyArgv>["flags"];
|
|
16
|
-
};
|
|
9
|
+
export { analyzeShellCommand, listShellGovernedTools, type ShellAnalysis, type ShellApprovalFingerprintPayload, type ShellInvocation, } from "./analyze-command.js";
|
|
10
|
+
export { commandMayContainGovernedTool, DEFAULT_GOVERNED_SHELL_TOOLS, } from "./governed-tools.js";
|
|
17
11
|
export type ShellGateDecision = {
|
|
18
12
|
permission: "allow" | "deny" | "ask";
|
|
19
13
|
user_message?: string;
|
|
20
14
|
agent_message?: string;
|
|
21
15
|
evaluation: GuardEvaluation;
|
|
16
|
+
analysis?: ShellAnalysis;
|
|
22
17
|
};
|
|
23
18
|
/**
|
|
24
19
|
* MCP proposals (`beforeMCPExecution` hook, MCP `guard` with `kind: "mcp"`): if argv does not match any
|
|
@@ -29,16 +24,18 @@ export declare function evaluateMcpProposal(policy: PoliciesV1, argv: string[]):
|
|
|
29
24
|
evaluation: GuardEvaluation;
|
|
30
25
|
};
|
|
31
26
|
/**
|
|
32
|
-
* Shell proposals
|
|
27
|
+
* Shell proposals: analyze full command string for all governed invocations.
|
|
33
28
|
*/
|
|
34
|
-
export declare function evaluateShellProposal(policy: PoliciesV1,
|
|
29
|
+
export declare function evaluateShellProposal(policy: PoliciesV1, commandOrArgv: string | string[]): {
|
|
35
30
|
skipped: boolean;
|
|
36
31
|
evaluation: GuardEvaluation;
|
|
32
|
+
analysis: ShellAnalysis;
|
|
37
33
|
};
|
|
38
|
-
export declare function evaluateArgv(policy: PoliciesV1, argv: string[]): GuardEvaluation;
|
|
39
34
|
export declare function gateShellCommand(opts: {
|
|
40
35
|
policy: PoliciesV1;
|
|
41
36
|
command: string;
|
|
42
|
-
governedTools?: string[];
|
|
43
37
|
}): ShellGateDecision;
|
|
38
|
+
/** @deprecated Prefer `analyzeShellCommand` — kept for callers that only have flat argv. */
|
|
39
|
+
export declare function evaluateShellProposalFromArgv(policy: PoliciesV1, argv: string[]): ReturnType<typeof evaluateShellProposal>;
|
|
40
|
+
export { parseCommandToArgv as parseCommandToArgvLegacy };
|
|
44
41
|
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/shell/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/shell/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,UAAU,EAAa,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAgB,KAAK,eAAe,EAAoB,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,aAAa,EAClB,KAAK,+BAA+B,EACpC,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;IAC5B,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EAAE,GACb;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,CAoBnD;AA+BD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAC/B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,CAkC5E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,iBAAiB,CAkBpB;AAED,4FAA4F;AAC5F,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EAAE,GACb,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAE1C;AAED,OAAO,EAAE,kBAAkB,IAAI,wBAAwB,EAAE,CAAC"}
|
package/dist/shell/evaluate.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { classifyArgv } from "../policy/index.js";
|
|
2
|
+
import { analyzeShellCommand } from "./analyze-command.js";
|
|
3
|
+
import { evaluateArgv } from "./guard-eval.js";
|
|
2
4
|
import { parseCommandToArgv } from "./parse.js";
|
|
3
|
-
|
|
5
|
+
export { evaluateArgv } from "./guard-eval.js";
|
|
4
6
|
export { parseCommandToArgv } from "./parse.js";
|
|
5
|
-
export {
|
|
7
|
+
export { analyzeShellCommand, listShellGovernedTools, } from "./analyze-command.js";
|
|
8
|
+
export { commandMayContainGovernedTool, DEFAULT_GOVERNED_SHELL_TOOLS, } from "./governed-tools.js";
|
|
6
9
|
/**
|
|
7
10
|
* MCP proposals (`beforeMCPExecution` hook, MCP `guard` with `kind: "mcp"`): if argv does not match any
|
|
8
11
|
* row under `policies.mcp`, pass-through (same idea as ungoverned shell tools).
|
|
@@ -28,69 +31,70 @@ export function evaluateMcpProposal(policy, argv) {
|
|
|
28
31
|
}
|
|
29
32
|
return { skipped: false, evaluation: evaluateArgv(policy, argv) };
|
|
30
33
|
}
|
|
34
|
+
function analysisToEvaluation(analysis) {
|
|
35
|
+
const { primary, tier, raw_metacharacters, invocations } = analysis;
|
|
36
|
+
const evaluation = { ...primary.evaluation, tier };
|
|
37
|
+
if (raw_metacharacters && !evaluation.reasons.some((r) => r.code === "metacharacters")) {
|
|
38
|
+
evaluation.reasons = [
|
|
39
|
+
...evaluation.reasons,
|
|
40
|
+
{ code: "metacharacters", message: "Composition operators in raw command; treat as high-risk." },
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
if (analysis.fail_closed) {
|
|
44
|
+
return evaluation;
|
|
45
|
+
}
|
|
46
|
+
if (invocations.length > 1) {
|
|
47
|
+
evaluation.reasons = [
|
|
48
|
+
...evaluation.reasons,
|
|
49
|
+
{
|
|
50
|
+
code: "multiple_invocations",
|
|
51
|
+
message: `Found ${invocations.length} governed invocations; tier is max across all.`,
|
|
52
|
+
details: { invocation_count: invocations.length },
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
return evaluation;
|
|
57
|
+
}
|
|
31
58
|
/**
|
|
32
|
-
* Shell proposals
|
|
59
|
+
* Shell proposals: analyze full command string for all governed invocations.
|
|
33
60
|
*/
|
|
34
|
-
export function evaluateShellProposal(policy,
|
|
35
|
-
const
|
|
36
|
-
|
|
61
|
+
export function evaluateShellProposal(policy, commandOrArgv) {
|
|
62
|
+
const command = Array.isArray(commandOrArgv) ? commandOrArgv.join(" ") : commandOrArgv;
|
|
63
|
+
const analysis = analyzeShellCommand(command, policy);
|
|
64
|
+
if (analysis.skipped) {
|
|
37
65
|
return {
|
|
38
66
|
skipped: true,
|
|
67
|
+
analysis,
|
|
39
68
|
evaluation: {
|
|
40
|
-
argv,
|
|
69
|
+
argv: analysis.segments[0]?.argv ?? [],
|
|
41
70
|
tier: "READ",
|
|
42
71
|
reasons: [
|
|
43
72
|
{
|
|
44
73
|
code: "skipped",
|
|
45
|
-
message: "
|
|
74
|
+
message: "No governed invocation found in command; pass-through.",
|
|
46
75
|
},
|
|
47
76
|
],
|
|
48
|
-
classification: {
|
|
77
|
+
classification: {
|
|
78
|
+
tool: null,
|
|
79
|
+
command_path: null,
|
|
80
|
+
verb: null,
|
|
81
|
+
tier: "READ",
|
|
82
|
+
matched: false,
|
|
83
|
+
},
|
|
49
84
|
flags: { metacharacters: false, dangerous_flags: false },
|
|
50
85
|
},
|
|
51
86
|
};
|
|
52
87
|
}
|
|
53
|
-
return {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const reasons = [];
|
|
59
|
-
if (!classification.matched) {
|
|
60
|
-
reasons.push({
|
|
61
|
-
code: "unknown_command",
|
|
62
|
-
message: "Command did not match any policy entry; default-deny applies.",
|
|
63
|
-
details: { tool: classification.tool, command_path: classification.command_path, verb: classification.verb },
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
reasons.push({
|
|
68
|
-
code: "policy_match",
|
|
69
|
-
message: "Matched policy entry.",
|
|
70
|
-
details: { tool: classification.tool, command_path: classification.command_path, verb: classification.verb, tier },
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
if (flags.metacharacters) {
|
|
74
|
-
if (tier === "READ")
|
|
75
|
-
tier = "MUTATE";
|
|
76
|
-
reasons.push({ code: "metacharacters", message: "Metacharacters detected; treat as high-risk." });
|
|
77
|
-
}
|
|
78
|
-
if (flags.dangerous_flags && (tier === "MUTATE" || tier === "DESTRUCTIVE")) {
|
|
79
|
-
reasons.push({
|
|
80
|
-
code: "dangerous_flags",
|
|
81
|
-
message: "Dangerous flags detected for mutating/destructive action; rejected.",
|
|
82
|
-
details: { dangerous_flags: policy.dangerous_flags },
|
|
83
|
-
});
|
|
84
|
-
tier = "DESTRUCTIVE";
|
|
85
|
-
}
|
|
86
|
-
return { argv, tier, reasons, classification, flags };
|
|
88
|
+
return {
|
|
89
|
+
skipped: false,
|
|
90
|
+
analysis,
|
|
91
|
+
evaluation: analysisToEvaluation(analysis),
|
|
92
|
+
};
|
|
87
93
|
}
|
|
88
94
|
export function gateShellCommand(opts) {
|
|
89
|
-
const
|
|
90
|
-
const argv = parseCommandToArgv(opts.command);
|
|
91
|
-
const { skipped, evaluation } = evaluateShellProposal(opts.policy, argv, governedTools);
|
|
95
|
+
const { skipped, evaluation, analysis } = evaluateShellProposal(opts.policy, opts.command);
|
|
92
96
|
if (skipped) {
|
|
93
|
-
return { permission: "allow", evaluation };
|
|
97
|
+
return { permission: "allow", evaluation, analysis };
|
|
94
98
|
}
|
|
95
99
|
const permission = evaluation.tier === "READ" ? "allow" : "deny";
|
|
96
100
|
return {
|
|
@@ -100,6 +104,12 @@ export function gateShellCommand(opts) {
|
|
|
100
104
|
? `Blocked by guard. tier=${evaluation.tier}. argv=${JSON.stringify(evaluation.argv)}`
|
|
101
105
|
: undefined,
|
|
102
106
|
evaluation,
|
|
107
|
+
analysis,
|
|
103
108
|
};
|
|
104
109
|
}
|
|
110
|
+
/** @deprecated Prefer `analyzeShellCommand` — kept for callers that only have flat argv. */
|
|
111
|
+
export function evaluateShellProposalFromArgv(policy, argv) {
|
|
112
|
+
return evaluateShellProposal(policy, argv);
|
|
113
|
+
}
|
|
114
|
+
export { parseCommandToArgv as parseCommandToArgvLegacy };
|
|
105
115
|
//# sourceMappingURL=evaluate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/shell/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA8B,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/shell/evaluate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
import type { PoliciesV1 } from "../policy/index.js";
|
|
2
|
+
/** @deprecated Use `listShellGovernedTools(policy)` — policy keys are the source of truth. */
|
|
2
3
|
export declare const DEFAULT_GOVERNED_SHELL_TOOLS: string[];
|
|
4
|
+
declare const DEFAULT_PRELUDE_VERBS: readonly ["cd", "pushd", "popd"];
|
|
5
|
+
declare const DEFAULT_PRIVILEGE_VERBS: readonly ["sudo", "doas"];
|
|
6
|
+
export type ShellPolicyConfig = {
|
|
7
|
+
prelude_verbs: readonly string[];
|
|
8
|
+
privilege_verbs: readonly string[];
|
|
9
|
+
};
|
|
10
|
+
export declare function policyExcludeSet(): Set<string>;
|
|
11
|
+
export declare function listShellGovernedTools(policy: PoliciesV1): readonly string[];
|
|
12
|
+
export declare function resolveShellPolicyConfig(policy: PoliciesV1): ShellPolicyConfig;
|
|
13
|
+
export declare function normalizeExecutableToken(token: string, governedTools: readonly string[]): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Fast path: scan parsed tokens without loading policy. Used before `loadPoliciesV1()`.
|
|
16
|
+
* When `governedToolNames` is omitted, checks against bundled default tool names.
|
|
17
|
+
*/
|
|
18
|
+
export declare function commandMayContainGovernedTool(command: string, governedToolNames?: readonly string[]): boolean;
|
|
19
|
+
export { DEFAULT_PRELUDE_VERBS, DEFAULT_PRIVILEGE_VERBS };
|
|
3
20
|
//# sourceMappingURL=governed-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"governed-tools.d.ts","sourceRoot":"","sources":["../../src/shell/governed-tools.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"governed-tools.d.ts","sourceRoot":"","sources":["../../src/shell/governed-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,8FAA8F;AAC9F,eAAO,MAAM,4BAA4B,EAAE,MAAM,EAAwC,CAAC;AAI1F,QAAA,MAAM,qBAAqB,kCAAmC,CAAC;AAC/D,QAAA,MAAM,uBAAuB,2BAA4B,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,CAAC;AAEF,wBAAgB,gBAAgB,IAAI,GAAG,CAAC,MAAM,CAAC,CAI9C;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,MAAM,EAAE,CAG5E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CAM9E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAOvG;AAWD;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,EACf,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,GACpC,OAAO,CAUT;AAED,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,3 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
import { parseShellTokens } from "./parse-segments.js";
|
|
2
|
+
/** @deprecated Use `listShellGovernedTools(policy)` — policy keys are the source of truth. */
|
|
2
3
|
export const DEFAULT_GOVERNED_SHELL_TOOLS = ["gcloud", "firebase", "gh", "git"];
|
|
4
|
+
const DEFAULT_POLICY_EXCLUDE = new Set(["mcp"]);
|
|
5
|
+
const DEFAULT_PRELUDE_VERBS = ["cd", "pushd", "popd"];
|
|
6
|
+
const DEFAULT_PRIVILEGE_VERBS = ["sudo", "doas"];
|
|
7
|
+
export function policyExcludeSet() {
|
|
8
|
+
const fromEnv = process.env.PRAXIS_SHELL_POLICY_EXCLUDE?.trim();
|
|
9
|
+
if (!fromEnv)
|
|
10
|
+
return DEFAULT_POLICY_EXCLUDE;
|
|
11
|
+
return new Set(fromEnv.split(",").map((s) => s.trim()).filter(Boolean));
|
|
12
|
+
}
|
|
13
|
+
export function listShellGovernedTools(policy) {
|
|
14
|
+
const excluded = policyExcludeSet();
|
|
15
|
+
return Object.keys(policy.policies).filter((k) => !excluded.has(k));
|
|
16
|
+
}
|
|
17
|
+
export function resolveShellPolicyConfig(policy) {
|
|
18
|
+
const shell = policy.shell;
|
|
19
|
+
return {
|
|
20
|
+
prelude_verbs: shell?.prelude_verbs?.length ? shell.prelude_verbs : DEFAULT_PRELUDE_VERBS,
|
|
21
|
+
privilege_verbs: shell?.privilege_verbs?.length ? shell.privilege_verbs : DEFAULT_PRIVILEGE_VERBS,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function normalizeExecutableToken(token, governedTools) {
|
|
25
|
+
if (governedTools.includes(token))
|
|
26
|
+
return token;
|
|
27
|
+
const isPathLike = token.includes("/") || token.startsWith(".");
|
|
28
|
+
if (!isPathLike)
|
|
29
|
+
return null;
|
|
30
|
+
const base = token.split("/").pop();
|
|
31
|
+
if (!base)
|
|
32
|
+
return null;
|
|
33
|
+
return governedTools.includes(base) ? base : null;
|
|
34
|
+
}
|
|
35
|
+
function tokenMightBeGoverned(token, governedSet) {
|
|
36
|
+
if (governedSet.has(token))
|
|
37
|
+
return true;
|
|
38
|
+
if (token.includes("/") || token.startsWith(".")) {
|
|
39
|
+
const base = token.split("/").pop();
|
|
40
|
+
if (base && governedSet.has(base))
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Fast path: scan parsed tokens without loading policy. Used before `loadPoliciesV1()`.
|
|
47
|
+
* When `governedToolNames` is omitted, checks against bundled default tool names.
|
|
48
|
+
*/
|
|
49
|
+
export function commandMayContainGovernedTool(command, governedToolNames) {
|
|
50
|
+
const governedSet = new Set(governedToolNames ?? DEFAULT_GOVERNED_SHELL_TOOLS);
|
|
51
|
+
const tokens = parseShellTokens(command);
|
|
52
|
+
if (tokens[0] === "<unparseable>")
|
|
53
|
+
return true;
|
|
54
|
+
for (const token of tokens) {
|
|
55
|
+
if (typeof token === "string" && tokenMightBeGoverned(token, governedSet)) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
export { DEFAULT_PRELUDE_VERBS, DEFAULT_PRIVILEGE_VERBS };
|
|
3
62
|
//# sourceMappingURL=governed-tools.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"governed-tools.js","sourceRoot":"","sources":["../../src/shell/governed-tools.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"governed-tools.js","sourceRoot":"","sources":["../../src/shell/governed-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { classifyArgv, type PoliciesV1, type Tier } from "../policy/index.js";
|
|
2
|
+
export type GuardReason = {
|
|
3
|
+
code: string;
|
|
4
|
+
message: string;
|
|
5
|
+
details?: Record<string, unknown>;
|
|
6
|
+
};
|
|
7
|
+
export type GuardEvaluation = {
|
|
8
|
+
argv: string[];
|
|
9
|
+
tier: Tier;
|
|
10
|
+
reasons: GuardReason[];
|
|
11
|
+
classification: ReturnType<typeof classifyArgv>["classification"];
|
|
12
|
+
flags: ReturnType<typeof classifyArgv>["flags"];
|
|
13
|
+
};
|
|
14
|
+
export declare function evaluateArgv(policy: PoliciesV1, argv: string[]): GuardEvaluation;
|
|
15
|
+
//# sourceMappingURL=guard-eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard-eval.d.ts","sourceRoot":"","sources":["../../src/shell/guard-eval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE9E,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAE/F,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,cAAc,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAClE,KAAK,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC;CACjD,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAkChF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { classifyArgv } from "../policy/index.js";
|
|
2
|
+
export function evaluateArgv(policy, argv) {
|
|
3
|
+
const { classification, flags } = classifyArgv(policy, argv);
|
|
4
|
+
let tier = classification.tier;
|
|
5
|
+
const reasons = [];
|
|
6
|
+
if (!classification.matched) {
|
|
7
|
+
reasons.push({
|
|
8
|
+
code: "unknown_command",
|
|
9
|
+
message: "Command did not match any policy entry; default-deny applies.",
|
|
10
|
+
details: { tool: classification.tool, command_path: classification.command_path, verb: classification.verb },
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
reasons.push({
|
|
15
|
+
code: "policy_match",
|
|
16
|
+
message: "Matched policy entry.",
|
|
17
|
+
details: { tool: classification.tool, command_path: classification.command_path, verb: classification.verb, tier },
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (flags.metacharacters) {
|
|
21
|
+
if (tier === "READ")
|
|
22
|
+
tier = "MUTATE";
|
|
23
|
+
reasons.push({ code: "metacharacters", message: "Metacharacters detected; treat as high-risk." });
|
|
24
|
+
}
|
|
25
|
+
if (flags.dangerous_flags && (tier === "MUTATE" || tier === "DESTRUCTIVE")) {
|
|
26
|
+
reasons.push({
|
|
27
|
+
code: "dangerous_flags",
|
|
28
|
+
message: "Dangerous flags detected for mutating/destructive action; rejected.",
|
|
29
|
+
details: { dangerous_flags: policy.dangerous_flags },
|
|
30
|
+
});
|
|
31
|
+
tier = "DESTRUCTIVE";
|
|
32
|
+
}
|
|
33
|
+
return { argv, tier, reasons, classification, flags };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=guard-eval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard-eval.js","sourceRoot":"","sources":["../../src/shell/guard-eval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA8B,MAAM,oBAAoB,CAAC;AAY9E,MAAM,UAAU,YAAY,CAAC,MAAkB,EAAE,IAAc;IAC7D,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,IAAI,GAAS,cAAc,CAAC,IAAI,CAAC;IAErC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,+DAA+D;YACxE,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC,YAAY,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE;SAC7G,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC,YAAY,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;SACnH,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,MAAM;YAAE,IAAI,GAAG,QAAQ,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,aAAa,CAAC,EAAE,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,qEAAqE;YAC9E,OAAO,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE;SACrD,CAAC,CAAC;QACH,IAAI,GAAG,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ShellOperator = "&&" | "||" | ";" | "|";
|
|
2
|
+
export type ShellParseToken = string | {
|
|
3
|
+
op: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function parseShellTokens(command: string): ShellParseToken[];
|
|
6
|
+
export declare function isUnparseableTokens(tokens: ShellParseToken[]): boolean;
|
|
7
|
+
export declare function parseShellSegments(command: string): {
|
|
8
|
+
tokens: ShellParseToken[];
|
|
9
|
+
segments: {
|
|
10
|
+
argv: string[];
|
|
11
|
+
}[];
|
|
12
|
+
operators: ShellOperator[];
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=parse-segments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-segments.d.ts","sourceRoot":"","sources":["../../src/shell/parse-segments.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;AAIpD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAInE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,OAAO,CAEtE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IACnD,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAC/B,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B,CA+BA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { parse as shellParse } from "shell-quote";
|
|
2
|
+
const SEGMENT_OPERATORS = new Set(["&&", "||", ";", "|"]);
|
|
3
|
+
export function parseShellTokens(command) {
|
|
4
|
+
const parsed = shellParse(command);
|
|
5
|
+
if (parsed.length === 0)
|
|
6
|
+
return ["<unparseable>", command];
|
|
7
|
+
return parsed;
|
|
8
|
+
}
|
|
9
|
+
export function isUnparseableTokens(tokens) {
|
|
10
|
+
return tokens.length >= 1 && tokens[0] === "<unparseable>";
|
|
11
|
+
}
|
|
12
|
+
export function parseShellSegments(command) {
|
|
13
|
+
const tokens = parseShellTokens(command);
|
|
14
|
+
if (isUnparseableTokens(tokens)) {
|
|
15
|
+
return {
|
|
16
|
+
tokens,
|
|
17
|
+
segments: [{ argv: tokens }],
|
|
18
|
+
operators: [],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const segments = [];
|
|
22
|
+
const operators = [];
|
|
23
|
+
let current = [];
|
|
24
|
+
for (const token of tokens) {
|
|
25
|
+
if (typeof token === "object" && token !== null && "op" in token) {
|
|
26
|
+
const op = token.op;
|
|
27
|
+
if (SEGMENT_OPERATORS.has(op)) {
|
|
28
|
+
segments.push({ argv: current });
|
|
29
|
+
current = [];
|
|
30
|
+
operators.push(op);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
current.push(op);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
current.push(token);
|
|
37
|
+
}
|
|
38
|
+
segments.push({ argv: current });
|
|
39
|
+
return { tokens, segments, operators };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=parse-segments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-segments.js","sourceRoot":"","sources":["../../src/shell/parse-segments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAIlD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAIlE,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAC3D,OAAO,MAA2B,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAKhD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAkB,EAAE,CAAC;YACxC,SAAS,EAAE,EAAE;SACd,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAoB,EAAE,CAAC;IACtC,IAAI,OAAO,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YACjE,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;YACpB,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;gBACjC,OAAO,GAAG,EAAE,CAAC;gBACb,SAAS,CAAC,IAAI,CAAC,EAAmB,CAAC,CAAC;gBACpC,SAAS;YACX,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,SAAS;QACX,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAEjC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACzC,CAAC"}
|