@provos/ironcurtain 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.
Files changed (160) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +311 -0
  3. package/dist/agent/index.d.ts +10 -0
  4. package/dist/agent/index.js +71 -0
  5. package/dist/agent/index.js.map +1 -0
  6. package/dist/agent/prompts.d.ts +5 -0
  7. package/dist/agent/prompts.js +26 -0
  8. package/dist/agent/prompts.js.map +1 -0
  9. package/dist/agent/tools.d.ts +13 -0
  10. package/dist/agent/tools.js +51 -0
  11. package/dist/agent/tools.js.map +1 -0
  12. package/dist/cli.d.ts +2 -0
  13. package/dist/cli.js +78 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config/constitution.md +16 -0
  16. package/dist/config/generated/compiled-policy.json +236 -0
  17. package/dist/config/generated/test-scenarios.json +765 -0
  18. package/dist/config/generated/tool-annotations.json +955 -0
  19. package/dist/config/index.d.ts +25 -0
  20. package/dist/config/index.js +151 -0
  21. package/dist/config/index.js.map +1 -0
  22. package/dist/config/mcp-servers.json +22 -0
  23. package/dist/config/model-provider.d.ts +49 -0
  24. package/dist/config/model-provider.js +78 -0
  25. package/dist/config/model-provider.js.map +1 -0
  26. package/dist/config/paths.d.ts +59 -0
  27. package/dist/config/paths.js +96 -0
  28. package/dist/config/paths.js.map +1 -0
  29. package/dist/config/types.d.ts +89 -0
  30. package/dist/config/types.js +2 -0
  31. package/dist/config/types.js.map +1 -0
  32. package/dist/config/user-config.d.ts +93 -0
  33. package/dist/config/user-config.js +309 -0
  34. package/dist/config/user-config.js.map +1 -0
  35. package/dist/hash.d.ts +17 -0
  36. package/dist/hash.js +34 -0
  37. package/dist/hash.js.map +1 -0
  38. package/dist/index.d.ts +1 -0
  39. package/dist/index.js +61 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/logger.d.ts +11 -0
  42. package/dist/logger.js +93 -0
  43. package/dist/logger.js.map +1 -0
  44. package/dist/pipeline/annotate.d.ts +9 -0
  45. package/dist/pipeline/annotate.js +136 -0
  46. package/dist/pipeline/annotate.js.map +1 -0
  47. package/dist/pipeline/compile.d.ts +23 -0
  48. package/dist/pipeline/compile.js +386 -0
  49. package/dist/pipeline/compile.js.map +1 -0
  50. package/dist/pipeline/constitution-compiler.d.ts +22 -0
  51. package/dist/pipeline/constitution-compiler.js +197 -0
  52. package/dist/pipeline/constitution-compiler.js.map +1 -0
  53. package/dist/pipeline/generate-with-repair.d.ts +22 -0
  54. package/dist/pipeline/generate-with-repair.js +64 -0
  55. package/dist/pipeline/generate-with-repair.js.map +1 -0
  56. package/dist/pipeline/handwritten-scenarios.d.ts +9 -0
  57. package/dist/pipeline/handwritten-scenarios.js +321 -0
  58. package/dist/pipeline/handwritten-scenarios.js.map +1 -0
  59. package/dist/pipeline/llm-logger.d.ts +42 -0
  60. package/dist/pipeline/llm-logger.js +78 -0
  61. package/dist/pipeline/llm-logger.js.map +1 -0
  62. package/dist/pipeline/pipeline-shared.d.ts +47 -0
  63. package/dist/pipeline/pipeline-shared.js +145 -0
  64. package/dist/pipeline/pipeline-shared.js.map +1 -0
  65. package/dist/pipeline/policy-verifier.d.ts +46 -0
  66. package/dist/pipeline/policy-verifier.js +277 -0
  67. package/dist/pipeline/policy-verifier.js.map +1 -0
  68. package/dist/pipeline/scenario-generator.d.ts +11 -0
  69. package/dist/pipeline/scenario-generator.js +128 -0
  70. package/dist/pipeline/scenario-generator.js.map +1 -0
  71. package/dist/pipeline/tool-annotator.d.ts +24 -0
  72. package/dist/pipeline/tool-annotator.js +201 -0
  73. package/dist/pipeline/tool-annotator.js.map +1 -0
  74. package/dist/pipeline/types.d.ts +122 -0
  75. package/dist/pipeline/types.js +10 -0
  76. package/dist/pipeline/types.js.map +1 -0
  77. package/dist/sandbox/index.d.ts +39 -0
  78. package/dist/sandbox/index.js +178 -0
  79. package/dist/sandbox/index.js.map +1 -0
  80. package/dist/session/agent-session.d.ts +83 -0
  81. package/dist/session/agent-session.js +382 -0
  82. package/dist/session/agent-session.js.map +1 -0
  83. package/dist/session/cli-transport.d.ts +61 -0
  84. package/dist/session/cli-transport.js +320 -0
  85. package/dist/session/cli-transport.js.map +1 -0
  86. package/dist/session/errors.d.ts +19 -0
  87. package/dist/session/errors.js +33 -0
  88. package/dist/session/errors.js.map +1 -0
  89. package/dist/session/index.d.ts +29 -0
  90. package/dist/session/index.js +104 -0
  91. package/dist/session/index.js.map +1 -0
  92. package/dist/session/message-compactor.d.ts +32 -0
  93. package/dist/session/message-compactor.js +81 -0
  94. package/dist/session/message-compactor.js.map +1 -0
  95. package/dist/session/prompts.d.ts +5 -0
  96. package/dist/session/prompts.js +62 -0
  97. package/dist/session/prompts.js.map +1 -0
  98. package/dist/session/resource-budget-tracker.d.ts +124 -0
  99. package/dist/session/resource-budget-tracker.js +327 -0
  100. package/dist/session/resource-budget-tracker.js.map +1 -0
  101. package/dist/session/step-loop-detector.d.ts +63 -0
  102. package/dist/session/step-loop-detector.js +136 -0
  103. package/dist/session/step-loop-detector.js.map +1 -0
  104. package/dist/session/transport.d.ts +24 -0
  105. package/dist/session/transport.js +2 -0
  106. package/dist/session/transport.js.map +1 -0
  107. package/dist/session/truncate-result.d.ts +35 -0
  108. package/dist/session/truncate-result.js +71 -0
  109. package/dist/session/truncate-result.js.map +1 -0
  110. package/dist/session/types.d.ts +220 -0
  111. package/dist/session/types.js +6 -0
  112. package/dist/session/types.js.map +1 -0
  113. package/dist/trusted-process/audit-log.d.ts +7 -0
  114. package/dist/trusted-process/audit-log.js +21 -0
  115. package/dist/trusted-process/audit-log.js.map +1 -0
  116. package/dist/trusted-process/call-circuit-breaker.d.ts +33 -0
  117. package/dist/trusted-process/call-circuit-breaker.js +61 -0
  118. package/dist/trusted-process/call-circuit-breaker.js.map +1 -0
  119. package/dist/trusted-process/escalation.d.ts +7 -0
  120. package/dist/trusted-process/escalation.js +38 -0
  121. package/dist/trusted-process/escalation.js.map +1 -0
  122. package/dist/trusted-process/index.d.ts +32 -0
  123. package/dist/trusted-process/index.js +151 -0
  124. package/dist/trusted-process/index.js.map +1 -0
  125. package/dist/trusted-process/mcp-client-manager.d.ts +25 -0
  126. package/dist/trusted-process/mcp-client-manager.js +90 -0
  127. package/dist/trusted-process/mcp-client-manager.js.map +1 -0
  128. package/dist/trusted-process/mcp-proxy-server.d.ts +24 -0
  129. package/dist/trusted-process/mcp-proxy-server.js +451 -0
  130. package/dist/trusted-process/mcp-proxy-server.js.map +1 -0
  131. package/dist/trusted-process/path-utils.d.ts +50 -0
  132. package/dist/trusted-process/path-utils.js +158 -0
  133. package/dist/trusted-process/path-utils.js.map +1 -0
  134. package/dist/trusted-process/policy-engine.d.ts +88 -0
  135. package/dist/trusted-process/policy-engine.js +523 -0
  136. package/dist/trusted-process/policy-engine.js.map +1 -0
  137. package/dist/trusted-process/policy-roots.d.ts +50 -0
  138. package/dist/trusted-process/policy-roots.js +67 -0
  139. package/dist/trusted-process/policy-roots.js.map +1 -0
  140. package/dist/trusted-process/policy-types.d.ts +6 -0
  141. package/dist/trusted-process/policy-types.js +2 -0
  142. package/dist/trusted-process/policy-types.js.map +1 -0
  143. package/dist/trusted-process/sandbox-integration.d.ts +92 -0
  144. package/dist/trusted-process/sandbox-integration.js +184 -0
  145. package/dist/trusted-process/sandbox-integration.js.map +1 -0
  146. package/dist/types/argument-roles.d.ts +112 -0
  147. package/dist/types/argument-roles.js +344 -0
  148. package/dist/types/argument-roles.js.map +1 -0
  149. package/dist/types/audit.d.ts +18 -0
  150. package/dist/types/audit.js +2 -0
  151. package/dist/types/audit.js.map +1 -0
  152. package/dist/types/mcp.d.ts +20 -0
  153. package/dist/types/mcp.js +2 -0
  154. package/dist/types/mcp.js.map +1 -0
  155. package/package.json +83 -0
  156. package/src/config/constitution.md +16 -0
  157. package/src/config/generated/compiled-policy.json +236 -0
  158. package/src/config/generated/test-scenarios.json +765 -0
  159. package/src/config/generated/tool-annotations.json +955 -0
  160. package/src/config/mcp-servers.json +22 -0
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Path normalization utilities for the trusted process security boundary.
3
+ *
4
+ * Provides annotation-driven normalization via `prepareToolArgs()` and a
5
+ * legacy heuristic fallback via `normalizeToolArgPaths()`. The heuristic
6
+ * is retained for defense-in-depth and as a fallback when annotations are
7
+ * unavailable.
8
+ */
9
+ import { resolve } from 'node:path';
10
+ import { getRoleDefinition, resolveRealPath, expandTilde } from '../types/argument-roles.js';
11
+ export { expandTilde } from '../types/argument-roles.js';
12
+ /** Returns true if the string looks like a filesystem path. */
13
+ function looksLikePath(value) {
14
+ return value.startsWith('/') || value.startsWith('.') || value.startsWith('~');
15
+ }
16
+ /** Resolves a path-like string to its canonical real path, following symlinks. */
17
+ function normalizePath(value) {
18
+ return resolveRealPath(expandTilde(value));
19
+ }
20
+ /**
21
+ * Returns a new arguments object with all path-like string values
22
+ * fully resolved (tilde expanded, relative resolved, traversals collapsed).
23
+ *
24
+ * A string value is considered path-like if it starts with `/`, `.`, or `~`.
25
+ * Array values have each string element checked individually.
26
+ * Non-string and non-path values pass through unchanged.
27
+ *
28
+ * The input object is never mutated.
29
+ *
30
+ * @deprecated Use `prepareToolArgs()` with annotation-driven normalization.
31
+ * Retained as a fallback when annotations are unavailable.
32
+ */
33
+ export function normalizeToolArgPaths(args) {
34
+ const result = {};
35
+ for (const [key, value] of Object.entries(args)) {
36
+ if (typeof value === 'string' && looksLikePath(value)) {
37
+ result[key] = normalizePath(value);
38
+ }
39
+ else if (Array.isArray(value)) {
40
+ result[key] = value.map(item => typeof item === 'string' && looksLikePath(item)
41
+ ? normalizePath(item)
42
+ : item);
43
+ }
44
+ else {
45
+ result[key] = value;
46
+ }
47
+ }
48
+ return result;
49
+ }
50
+ // ---------------------------------------------------------------------------
51
+ // Absolute vs relative path detection
52
+ // ---------------------------------------------------------------------------
53
+ /** Returns true if the path is absolute (starts with `/` or `~`). */
54
+ function isAbsolutePath(value) {
55
+ return value.startsWith('/') || value.startsWith('~');
56
+ }
57
+ /**
58
+ * Resolves a relative path against the sandbox directory for policy evaluation.
59
+ * Applies tilde expansion first, then resolves against the sandbox base,
60
+ * then follows symlinks via resolveRealPath.
61
+ */
62
+ function resolveAgainstSandbox(value, sandboxDir) {
63
+ const expanded = expandTilde(value);
64
+ const absolute = resolve(sandboxDir, expanded);
65
+ return resolveRealPath(absolute);
66
+ }
67
+ /**
68
+ * Finds the first resource-identifier role in a role array, or undefined
69
+ * if all roles are non-resource (e.g., 'none').
70
+ */
71
+ function findResourceRole(roles) {
72
+ return roles.find(r => getRoleDefinition(r).isResourceIdentifier);
73
+ }
74
+ /**
75
+ * Normalizes a single argument value using a role's normalizer.
76
+ * Handles both string and string-array values. Non-string values
77
+ * pass through unchanged.
78
+ */
79
+ function normalizeArgValue(value, normalize) {
80
+ if (typeof value === 'string') {
81
+ return normalize(value);
82
+ }
83
+ if (Array.isArray(value)) {
84
+ return value.map(item => typeof item === 'string' ? normalize(item) : item);
85
+ }
86
+ return value;
87
+ }
88
+ /**
89
+ * Normalizes a single path argument for transport, handling the
90
+ * absolute/relative split. Absolute paths get full normalization;
91
+ * relative paths pass through unchanged (the MCP server resolves
92
+ * them against its own CWD, which is the sandbox directory).
93
+ */
94
+ function normalizePathForTransport(value, def) {
95
+ return normalizeArgValue(value, v => isAbsolutePath(v) ? def.normalize(v) : v);
96
+ }
97
+ /**
98
+ * Normalizes a single path argument for policy evaluation. Absolute
99
+ * paths get full normalization; relative paths are resolved against
100
+ * the sandbox (allowedDirectory) so the policy engine can perform
101
+ * containment checks with absolute canonical paths.
102
+ */
103
+ function normalizePathForPolicy(value, def, allowedDirectory) {
104
+ return normalizeArgValue(value, v => isAbsolutePath(v) ? def.normalize(v) : resolveAgainstSandbox(v, allowedDirectory));
105
+ }
106
+ /**
107
+ * Annotation-driven normalization of tool call arguments.
108
+ *
109
+ * For each argument, looks up its annotated roles and applies the
110
+ * corresponding normalizer from the registry. Returns two argument
111
+ * objects: one for transport (MCP server) and one for policy evaluation.
112
+ *
113
+ * For path-category roles, relative paths (not starting with `/` or `~`)
114
+ * are treated differently:
115
+ * - Transport: passed through unchanged (the MCP server resolves them
116
+ * against its own sandbox CWD)
117
+ * - Policy: resolved against `allowedDirectory` so the policy engine
118
+ * has absolute canonical paths for containment checks
119
+ *
120
+ * When `annotation` is undefined (unknown tool), falls back to the
121
+ * heuristic `normalizeToolArgPaths()` for both outputs.
122
+ *
123
+ * The input object is never mutated.
124
+ */
125
+ export function prepareToolArgs(args, annotation, allowedDirectory) {
126
+ if (!annotation) {
127
+ const fallback = normalizeToolArgPaths(args);
128
+ return { argsForTransport: fallback, argsForPolicy: fallback };
129
+ }
130
+ const argsForTransport = {};
131
+ const argsForPolicy = {};
132
+ for (const [key, value] of Object.entries(args)) {
133
+ const roles = annotation.args[key];
134
+ const resourceRole = roles ? findResourceRole(roles) : undefined;
135
+ if (resourceRole) {
136
+ const def = getRoleDefinition(resourceRole);
137
+ if (def.category === 'path' && allowedDirectory) {
138
+ // Path roles with sandbox context: split relative vs absolute
139
+ argsForTransport[key] = normalizePathForTransport(value, def);
140
+ argsForPolicy[key] = normalizePathForPolicy(value, def, allowedDirectory);
141
+ }
142
+ else {
143
+ // Non-path roles (URLs, opaque) or no sandbox: normalize for both
144
+ const transportValue = normalizeArgValue(value, def.normalize);
145
+ argsForTransport[key] = transportValue;
146
+ // Domain extraction (prepareForPolicy) is handled later by
147
+ // the policy engine's resolveUrlForDomainCheck().
148
+ argsForPolicy[key] = transportValue;
149
+ }
150
+ }
151
+ else {
152
+ argsForTransport[key] = value;
153
+ argsForPolicy[key] = value;
154
+ }
155
+ }
156
+ return { argsForTransport, argsForPolicy };
157
+ }
158
+ //# sourceMappingURL=path-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../../src/trusted-process/path-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * PolicyEngine -- Two-phase declarative policy evaluation.
3
+ *
4
+ * Phase 1: Hardcoded structural invariants (protected paths, unknown tools).
5
+ * These are never overridden by compiled rules. Sandbox containment
6
+ * is checked per-role: roles whose paths are all within the sandbox
7
+ * are resolved here and skipped in Phase 2.
8
+ *
9
+ * Phase 2: Compiled declarative rules loaded from compiled-policy.json.
10
+ * Each distinct role from the tool's annotation is evaluated
11
+ * independently through the rule chain (first-match-wins per role).
12
+ * The most restrictive result wins: deny > escalate > allow.
13
+ * Roles already resolved by Phase 1 sandbox containment are skipped.
14
+ */
15
+ import type { ToolCallRequest } from '../types/mcp.js';
16
+ import type { EvaluationResult } from './policy-types.js';
17
+ import type { CompiledPolicyFile, ToolAnnotationsFile, ToolAnnotation } from '../pipeline/types.js';
18
+ /**
19
+ * Checks whether a domain matches any pattern in an allowlist.
20
+ * Supports exact match, `*` wildcard (matches everything),
21
+ * and `*.example.com` prefix wildcards (matches example.com and *.example.com).
22
+ */
23
+ export declare function domainMatchesAllowlist(domain: string, allowedDomains: readonly string[]): boolean;
24
+ export declare class PolicyEngine {
25
+ private annotationMap;
26
+ private compiledPolicy;
27
+ private protectedPaths;
28
+ private allowedDirectory?;
29
+ private serverDomainAllowlists;
30
+ constructor(compiledPolicy: CompiledPolicyFile, toolAnnotations: ToolAnnotationsFile, protectedPaths: string[], allowedDirectory?: string, serverDomainAllowlists?: ReadonlyMap<string, readonly string[]>);
31
+ private buildAnnotationMap;
32
+ /** Returns the annotation for a tool, or undefined if unknown. */
33
+ getAnnotation(serverName: string, toolName: string): ToolAnnotation | undefined;
34
+ evaluate(request: ToolCallRequest): EvaluationResult;
35
+ /**
36
+ * Phase 1: Hardcoded structural invariants.
37
+ *
38
+ * 1a. Protected path check (deny)
39
+ * 1b. Sandbox containment for path-category roles (allow/partial)
40
+ * 1c. Domain allowlist for url-category roles (escalate)
41
+ * 1d. Unknown tool denial (deny)
42
+ *
43
+ * Uses the union of heuristic and annotation-based path extraction
44
+ * for defense-in-depth. Returns a StructuralResult with either a
45
+ * final decision or a set of roles resolved by sandbox containment.
46
+ */
47
+ private evaluateStructuralInvariants;
48
+ /**
49
+ * Phase 2: Evaluate compiled declarative rules.
50
+ *
51
+ * For tools with multiple roles (e.g., edit_file has read-path + write-path),
52
+ * each role is evaluated independently through the rule chain. The most
53
+ * restrictive result across all roles wins (deny > escalate > allow).
54
+ * Roles already resolved by Phase 1 sandbox containment are skipped.
55
+ *
56
+ * For tools with no roles (e.g., list_allowed_directories), the chain is
57
+ * evaluated once without role filtering.
58
+ */
59
+ private evaluateCompiledRules;
60
+ /**
61
+ * Evaluates the rule chain for a single role (or all roles if undefined).
62
+ *
63
+ * When evaluatingRole is set, only rules that are either role-agnostic
64
+ * (no roles/paths conditions) or relevant to the specified role are
65
+ * considered. First matching rule wins; default deny if none match.
66
+ *
67
+ * For roles with multiple extracted paths, delegates to
68
+ * evaluateRulesForMultiPaths for per-element evaluation.
69
+ */
70
+ private evaluateRulesForRole;
71
+ /**
72
+ * Per-element path evaluation for roles with multiple paths.
73
+ *
74
+ * Each path is independently "discharged" by the first rule whose
75
+ * paths.within contains it. Rules without path conditions match all
76
+ * remaining paths. The most restrictive decision across all discharged
77
+ * paths wins (deny > escalate > allow). Undischarged paths default-deny.
78
+ */
79
+ private evaluateRulesForMultiPaths;
80
+ /**
81
+ * Checks non-path conditions in a rule's `if` block: roles, server, tool, sideEffects.
82
+ */
83
+ private ruleMatchesNonPathConditions;
84
+ /**
85
+ * Checks whether all conditions in a rule's `if` block are satisfied.
86
+ */
87
+ private ruleMatches;
88
+ }