@intutic/mcp-governance-proxy 2.2.0 → 2.4.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 (137) hide show
  1. package/README.md +8 -7
  2. package/dist/agentTools.d.ts +83 -0
  3. package/dist/agentTools.d.ts.map +1 -0
  4. package/dist/agentTools.js +170 -0
  5. package/dist/agentTools.js.map +1 -0
  6. package/dist/anomaly/detectors.js +1 -1
  7. package/dist/anomaly/detectors.js.map +1 -1
  8. package/dist/approvalHold.d.ts +8 -7
  9. package/dist/approvalHold.d.ts.map +1 -1
  10. package/dist/approvalHold.js +7 -6
  11. package/dist/approvalHold.js.map +1 -1
  12. package/dist/budget.d.ts +133 -0
  13. package/dist/budget.d.ts.map +1 -0
  14. package/dist/budget.js +191 -0
  15. package/dist/budget.js.map +1 -0
  16. package/dist/config.d.ts +1 -1
  17. package/dist/config.js +1 -1
  18. package/dist/config.js.map +1 -1
  19. package/dist/daemon/healthMonitor.d.ts.map +1 -1
  20. package/dist/daemon/healthMonitor.js +0 -1
  21. package/dist/daemon/healthMonitor.js.map +1 -1
  22. package/dist/daemon/index.d.ts +0 -2
  23. package/dist/daemon/index.d.ts.map +1 -1
  24. package/dist/daemon/index.js +0 -2
  25. package/dist/daemon/index.js.map +1 -1
  26. package/dist/daemon/policyCache.d.ts +22 -3
  27. package/dist/daemon/policyCache.d.ts.map +1 -1
  28. package/dist/daemon/policyCache.js +38 -15
  29. package/dist/daemon/policyCache.js.map +1 -1
  30. package/dist/daemon/socketServer.d.ts +0 -1
  31. package/dist/daemon/socketServer.d.ts.map +1 -1
  32. package/dist/daemon/socketServer.js +0 -1
  33. package/dist/daemon/socketServer.js.map +1 -1
  34. package/dist/daemon/statusReporter.d.ts.map +1 -1
  35. package/dist/daemon/statusReporter.js +0 -1
  36. package/dist/daemon/statusReporter.js.map +1 -1
  37. package/dist/daemon/telemetryBatcher.d.ts.map +1 -1
  38. package/dist/daemon/telemetryBatcher.js +0 -1
  39. package/dist/daemon/telemetryBatcher.js.map +1 -1
  40. package/dist/daemonClient.d.ts.map +1 -1
  41. package/dist/daemonClient.js +0 -1
  42. package/dist/daemonClient.js.map +1 -1
  43. package/dist/dlp.d.ts +32 -3
  44. package/dist/dlp.d.ts.map +1 -1
  45. package/dist/dlp.js +116 -18
  46. package/dist/dlp.js.map +1 -1
  47. package/dist/dlpPii.d.ts +66 -0
  48. package/dist/dlpPii.d.ts.map +1 -0
  49. package/dist/dlpPii.js +235 -0
  50. package/dist/dlpPii.js.map +1 -0
  51. package/dist/emitter.d.ts +65 -3
  52. package/dist/emitter.d.ts.map +1 -1
  53. package/dist/emitter.js +13 -1
  54. package/dist/emitter.js.map +1 -1
  55. package/dist/guardedValkey.d.ts +40 -0
  56. package/dist/guardedValkey.d.ts.map +1 -0
  57. package/dist/guardedValkey.js +84 -0
  58. package/dist/guardedValkey.js.map +1 -0
  59. package/dist/httpJson.d.ts +7 -0
  60. package/dist/httpJson.d.ts.map +1 -1
  61. package/dist/httpJson.js +39 -0
  62. package/dist/httpJson.js.map +1 -1
  63. package/dist/injection.js +1 -1
  64. package/dist/interceptor.d.ts +65 -10
  65. package/dist/interceptor.d.ts.map +1 -1
  66. package/dist/interceptor.js +190 -69
  67. package/dist/interceptor.js.map +1 -1
  68. package/dist/policy.d.ts +37 -1
  69. package/dist/policy.d.ts.map +1 -1
  70. package/dist/policy.js +62 -3
  71. package/dist/policy.js.map +1 -1
  72. package/dist/proxy.d.ts +30 -9
  73. package/dist/proxy.d.ts.map +1 -1
  74. package/dist/proxy.js +127 -57
  75. package/dist/proxy.js.map +1 -1
  76. package/dist/refusals.d.ts +26 -0
  77. package/dist/refusals.d.ts.map +1 -0
  78. package/dist/refusals.js +43 -0
  79. package/dist/refusals.js.map +1 -0
  80. package/dist/registryObserver.d.ts +9 -5
  81. package/dist/registryObserver.d.ts.map +1 -1
  82. package/dist/registryObserver.js +19 -8
  83. package/dist/registryObserver.js.map +1 -1
  84. package/dist/session.d.ts +1 -1
  85. package/dist/session.js +1 -1
  86. package/dist/sessionScope.d.ts +1 -1
  87. package/dist/sessionScope.js +1 -1
  88. package/dist/sessionStore.d.ts +10 -23
  89. package/dist/sessionStore.d.ts.map +1 -1
  90. package/dist/sessionStore.js +17 -76
  91. package/dist/sessionStore.js.map +1 -1
  92. package/dist/wasm/cloudRules.d.ts +138 -0
  93. package/dist/wasm/cloudRules.d.ts.map +1 -0
  94. package/dist/wasm/cloudRules.js +242 -0
  95. package/dist/wasm/cloudRules.js.map +1 -0
  96. package/dist/wasm/context.d.ts +10 -0
  97. package/dist/wasm/context.d.ts.map +1 -1
  98. package/dist/wasm/context.js +27 -0
  99. package/dist/wasm/context.js.map +1 -1
  100. package/dist/wasm/hostImports.d.ts +3 -3
  101. package/dist/wasm/hostImports.d.ts.map +1 -1
  102. package/dist/wasm/hostImports.js +8 -7
  103. package/dist/wasm/hostImports.js.map +1 -1
  104. package/dist/wasm/loader.d.ts +10 -1
  105. package/dist/wasm/loader.d.ts.map +1 -1
  106. package/dist/wasm/loader.js +2 -0
  107. package/dist/wasm/loader.js.map +1 -1
  108. package/dist/wasm/referencedFiles.d.ts +29 -4
  109. package/dist/wasm/referencedFiles.d.ts.map +1 -1
  110. package/dist/wasm/referencedFiles.js +48 -21
  111. package/dist/wasm/referencedFiles.js.map +1 -1
  112. package/dist/wasm/runner.d.ts +169 -31
  113. package/dist/wasm/runner.d.ts.map +1 -1
  114. package/dist/wasm/runner.js +298 -83
  115. package/dist/wasm/runner.js.map +1 -1
  116. package/dist/wasm/watch.js +1 -1
  117. package/dist/wasm/worker.d.ts +10 -6
  118. package/dist/wasm/worker.d.ts.map +1 -1
  119. package/dist/wasm/worker.js +93 -9
  120. package/dist/wasm/worker.js.map +1 -1
  121. package/package.json +5 -4
  122. package/dist/toolPoison.d.ts +0 -32
  123. package/dist/toolPoison.d.ts.map +0 -1
  124. package/dist/toolPoison.js +0 -81
  125. package/dist/toolPoison.js.map +0 -1
  126. package/dist/wasm/fuel.d.ts +0 -35
  127. package/dist/wasm/fuel.d.ts.map +0 -1
  128. package/dist/wasm/fuel.js +0 -299
  129. package/dist/wasm/fuel.js.map +0 -1
  130. package/dist/wasm/memoryCap.d.ts +0 -21
  131. package/dist/wasm/memoryCap.d.ts.map +0 -1
  132. package/dist/wasm/memoryCap.js +0 -54
  133. package/dist/wasm/memoryCap.js.map +0 -1
  134. package/dist/wasm/wasmBinary.d.ts +0 -25
  135. package/dist/wasm/wasmBinary.d.ts.map +0 -1
  136. package/dist/wasm/wasmBinary.js +0 -100
  137. package/dist/wasm/wasmBinary.js.map +0 -1
package/dist/dlpPii.js ADDED
@@ -0,0 +1,235 @@
1
+ /**
2
+ * dlpPii.ts — validated PII detectors (card and IBAN checksums, SSN issued ranges).
3
+ *
4
+ * The TypeScript twin of the Rust proxy's `packages/proxy/src/dlp/pii.rs`.
5
+ * Both read the same definition (`PII_DEFINITION` from
6
+ * `@intutic/shared-types`, a byte-identical copy of the proxy's
7
+ * `pii_detectors.json`) and implement its validators and boundary rule the
8
+ * same way; `packages/shared-types/fixtures/pii-detector-vectors.json` runs
9
+ * through both (`__tests__/dlpPii.test.ts`, `tests/pii_conformance_test.rs`).
10
+ * A change to a rule here needs the same change there, or the vectors fail on
11
+ * one side.
12
+ *
13
+ * The regex finds a candidate; the validator decides. Luhn plus the IIN table
14
+ * for cards, the country length table plus mod-97 for IBANs, the never-issued
15
+ * ranges for SSNs, structure for email, digit count for phone numbers.
16
+ *
17
+ * The boundary rule replaces `\b`, which means different things in the two
18
+ * engines. Neighbouring characters must not be ASCII letters, digits or `_`,
19
+ * except that a match right after a JSON escape (`\n`, `\r`, `\t`) counts as
20
+ * bounded — both scanners read JSON as sent. A match starting right after a
21
+ * backslash starts inside an escape and is rejected. `numeric` detectors
22
+ * also reject a match glued to more digits by `.` or `-` (a decimal fraction,
23
+ * a five-group serial). A rejected candidate resumes the search one character
24
+ * after its start, so a card number right after `12 ` is still found.
25
+ *
26
+ * @module
27
+ */
28
+ import { PII_DEFINITION, PII_DETECTOR_IDS } from '@intutic/shared-types';
29
+ const CARD_BRANDS = PII_DEFINITION.card_brands;
30
+ const IBAN_LENGTHS = PII_DEFINITION.iban_lengths;
31
+ const isDigit = (c) => c >= 48 && c <= 57;
32
+ const isWord = (c) => isDigit(c) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122) || c === 95;
33
+ const BACKSLASH = 92;
34
+ const DOT = 46;
35
+ const DASH = 45;
36
+ function luhn(digits) {
37
+ let sum = 0;
38
+ for (let i = 0; i < digits.length; i++) {
39
+ let d = digits.charCodeAt(digits.length - 1 - i) - 48;
40
+ if (i % 2 === 1) {
41
+ d *= 2;
42
+ if (d > 9)
43
+ d -= 9;
44
+ }
45
+ sum += d;
46
+ }
47
+ return sum % 10 === 0;
48
+ }
49
+ function card(span) {
50
+ const digits = span.replace(/[^0-9]/g, '');
51
+ const n = digits.length;
52
+ const known = CARD_BRANDS.some((b) => b.lengths.includes(n) &&
53
+ b.prefixes.some(([lo, hi]) => {
54
+ const head = digits.slice(0, lo.length);
55
+ return head >= lo && head <= hi;
56
+ }));
57
+ return known && luhn(digits);
58
+ }
59
+ /** Truncates to the country's length: the regex is greedy and runs on into `EUR`. */
60
+ function iban(span) {
61
+ const want = IBAN_LENGTHS[span.slice(0, 2)];
62
+ if (want === undefined)
63
+ return null;
64
+ let chars = '';
65
+ let end = span.length;
66
+ for (let i = 0; i < span.length; i++) {
67
+ const c = span[i];
68
+ if (c === ' ')
69
+ continue;
70
+ if (chars.length === want) {
71
+ // A further character glued on (no space) makes it longer than any
72
+ // IBAN of this country.
73
+ if (span[i - 1] !== ' ')
74
+ return null;
75
+ break;
76
+ }
77
+ chars += c;
78
+ end = i + 1;
79
+ }
80
+ if (chars.length !== want)
81
+ return null;
82
+ const rotated = chars.slice(4) + chars.slice(0, 4);
83
+ let rem = 0;
84
+ for (const c of rotated) {
85
+ const code = c.charCodeAt(0);
86
+ const v = isDigit(code) ? code - 48 : code - 65 + 10;
87
+ rem = v >= 10 ? (rem * 100 + v) % 97 : (rem * 10 + v) % 97;
88
+ }
89
+ return rem === 1 ? end : null;
90
+ }
91
+ /** Never issued: area 000, 666 or 9xx; group 00; serial 0000. */
92
+ function ssn(span) {
93
+ const area = span.slice(0, 3);
94
+ const group = span.slice(4, 6);
95
+ const serial = span.slice(7, 11);
96
+ return area !== '000' && area !== '666' && area[0] !== '9' && group !== '00' && serial !== '0000';
97
+ }
98
+ function email(span) {
99
+ const at = span.indexOf('@');
100
+ if (at < 0)
101
+ return false;
102
+ const local = span.slice(0, at);
103
+ const domain = span.slice(at + 1);
104
+ if (local.startsWith('.') || local.endsWith('.') || local.includes('..'))
105
+ return false;
106
+ const labels = domain.split('.');
107
+ if (labels.some((l) => l === '' || l.startsWith('-') || l.endsWith('-')))
108
+ return false;
109
+ const tld = labels[labels.length - 1];
110
+ if (tld.length < 2 || !/^[A-Za-z]+$/.test(tld))
111
+ return false;
112
+ // `icon@2x.png`: an asset scale suffix, not an address.
113
+ const first = labels[0];
114
+ return !/^[0-9]+x$/.test(first);
115
+ }
116
+ function phone(span) {
117
+ const n = span.replace(/[^0-9]/g, '').length;
118
+ return n >= 10 && n <= 15;
119
+ }
120
+ const whole = (check) => (span) => check(span) ? span.length : null;
121
+ const VALIDATORS = {
122
+ card_luhn: whole(card),
123
+ iban_mod97: iban,
124
+ ssn_ranges: whole(ssn),
125
+ email_shape: whole(email),
126
+ phone_digits: whole(phone),
127
+ };
128
+ /** Every PII detector, in definition order, whatever its configured action. */
129
+ export const PII_DETECTORS = PII_DEFINITION.detectors.map((d) => {
130
+ const validate = VALIDATORS[d.validator];
131
+ if (!validate)
132
+ throw new Error(`pii detector ${d.id} names unknown validator ${d.validator}`);
133
+ return {
134
+ id: d.id,
135
+ category: d.category,
136
+ description: d.description,
137
+ regex: new RegExp(d.regex, 'g'),
138
+ numeric: d.boundary === 'numeric',
139
+ validate,
140
+ };
141
+ });
142
+ function bounded(text, start, end, numeric) {
143
+ if (start > 0) {
144
+ const p = text.charCodeAt(start - 1);
145
+ if (p === BACKSLASH)
146
+ return false;
147
+ const escaped = (p === 110 || p === 114 || p === 116) && start >= 2 && text.charCodeAt(start - 2) === BACKSLASH;
148
+ if (isWord(p) && !escaped)
149
+ return false;
150
+ if (numeric && (p === DOT || p === DASH) && start >= 2 && isDigit(text.charCodeAt(start - 2)))
151
+ return false;
152
+ }
153
+ if (end < text.length) {
154
+ const q = text.charCodeAt(end);
155
+ if (isWord(q))
156
+ return false;
157
+ if (numeric && (q === DOT || q === DASH) && end + 1 < text.length && isDigit(text.charCodeAt(end + 1))) {
158
+ return false;
159
+ }
160
+ }
161
+ return true;
162
+ }
163
+ /** Validated matches of one detector, as `[start, end)` UTF-16 ranges, in text order. */
164
+ export function findPii(det, text) {
165
+ const out = [];
166
+ const re = det.regex;
167
+ let pos = 0;
168
+ while (pos < text.length) {
169
+ re.lastIndex = pos;
170
+ const m = re.exec(text);
171
+ if (!m)
172
+ break;
173
+ const start = m.index;
174
+ const len = det.validate(m[0]);
175
+ const end = len === null ? null : start + len;
176
+ if (end !== null && bounded(text, start, end, det.numeric)) {
177
+ out.push([start, end]);
178
+ pos = end;
179
+ }
180
+ else {
181
+ pos = start + 1;
182
+ }
183
+ }
184
+ return out;
185
+ }
186
+ /**
187
+ * Every detector over `text`, actions ignored, in definition order then text
188
+ * order — what the conformance vectors measure.
189
+ */
190
+ export function detectPii(text) {
191
+ const out = [];
192
+ for (const det of PII_DETECTORS) {
193
+ for (const [start, end] of findPii(det, text))
194
+ out.push({ id: det.id, start, end });
195
+ }
196
+ return out;
197
+ }
198
+ /**
199
+ * The detectors an `INTUTIC_MCP_DLP_DETECTORS` value names — a JSON object of
200
+ * detector id → `off` | `redact` | `block` — with their actions. Detectors it
201
+ * leaves out are not listed: they keep their defaults, or the workspace's
202
+ * action (`effectivePiiActions` in `@intutic/shared-types`). Never throws,
203
+ * like the other `INTUTIC_MCP_*` JSON settings: an unparseable value, an
204
+ * unknown id or an unknown action is reported in `problems` and that entry is
205
+ * left out, so it keeps its default, which for card, IBAN and SSN is on.
206
+ */
207
+ export function parseLocalPiiActions(raw) {
208
+ const configured = {};
209
+ if (!raw)
210
+ return { configured, problems: [] };
211
+ let parsed;
212
+ try {
213
+ parsed = JSON.parse(raw);
214
+ }
215
+ catch {
216
+ return { configured, problems: ['INTUTIC_MCP_DLP_DETECTORS is not valid JSON; using the defaults'] };
217
+ }
218
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
219
+ return { configured, problems: ['INTUTIC_MCP_DLP_DETECTORS is not a JSON object; using the defaults'] };
220
+ }
221
+ const problems = [];
222
+ for (const [id, action] of Object.entries(parsed)) {
223
+ if (!PII_DETECTOR_IDS.includes(id)) {
224
+ problems.push(`INTUTIC_MCP_DLP_DETECTORS names unknown detector ${id}; known: ${PII_DETECTOR_IDS.join(', ')}`);
225
+ }
226
+ else if (action !== 'off' && action !== 'redact' && action !== 'block') {
227
+ problems.push(`INTUTIC_MCP_DLP_DETECTORS sets ${id} to ${String(action)}; only off, redact and block exist`);
228
+ }
229
+ else {
230
+ configured[id] = action;
231
+ }
232
+ }
233
+ return { configured, problems };
234
+ }
235
+ //# sourceMappingURL=dlpPii.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlpPii.js","sourceRoot":"","sources":["../src/dlpPii.ts"],"names":[],"mappings":"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"}
package/dist/emitter.d.ts CHANGED
@@ -10,9 +10,12 @@
10
10
  */
11
11
  import type { CallerIdentity } from './identity.js';
12
12
  import type { AnomalyFinding } from './anomaly/index.js';
13
+ import type { BudgetEventDetail } from './budget.js';
14
+ import type { ShadowReport } from './wasm/runner.js';
15
+ import type { RuleLoadFailureReason } from '@intutic/shared-types';
13
16
  export type EventKind = 'tool_allowed' | 'tool_blocked' | 'tool_redacted'
14
17
  /**
15
- * A `warn` SOP rule matched and the call was allowed (LLD #71): the same
18
+ * A `warn` SOP rule matched and the call was allowed: the same
16
19
  * event the harness gates log for a warn-severity rule, carrying the rule
17
20
  * id as `[<id>]` in `reason`, so a SHADOW guardrail seen through this
18
21
  * proxy counts toward its evidence like one seen through a gate.
@@ -49,7 +52,50 @@ export type EventKind = 'tool_allowed' | 'tool_blocked' | 'tool_redacted'
49
52
  */
50
53
  | 'tool_held'
51
54
  /** An approved, unexpired, exact-match bypass let a held call through. */
52
- | 'hold_approved_bypass_used';
55
+ | 'hold_approved_bypass_used'
56
+ /**
57
+ * An MCP call budget (budget.ts) reached its warning threshold. Once per
58
+ * budget per period, across every proxy sharing the Valkey; carries
59
+ * `budget` and a finding. The call itself was allowed.
60
+ */
61
+ | 'mcp_budget_threshold'
62
+ /**
63
+ * An MCP call budget is used up. Once per budget per period, on the first
64
+ * refusal; every refusal also sends its own `tool_blocked`.
65
+ */
66
+ | 'mcp_budget_exceeded'
67
+ /**
68
+ * A version of one of the workspace's control-plane rules was refused
69
+ * (wasm/cloudRules.ts): its binary is missing, does not hash to what its
70
+ * descriptor names, or cannot load. Sent once per hash and reason, with
71
+ * `toolName` carrying the rule id and `wasmRule` the detail; the control
72
+ * plane files one incident per version, as for the LLM proxy's refusals.
73
+ */
74
+ | 'wasm_rule_refused'
75
+ /**
76
+ * The call was evaluated against custom rules in `SHADOW` mode: what each
77
+ * would have done, bypasses included, in `wasmShadowReports`. The same
78
+ * report the LLM proxy carries on a trace (`wasm_shadow_reports`); the
79
+ * control plane counts both toward the rule's promotion evidence.
80
+ */
81
+ | 'wasm_shadow_evaluated';
82
+ /** What a custom-rule event carries: `wasmRule` on `wasm_rule_refused`, `wasmShadowReports` on `wasm_shadow_evaluated`. */
83
+ export interface RuleEventDetail {
84
+ wasmRule?: WasmRuleRefusalDetail;
85
+ wasmShadowReports?: ShadowReport[];
86
+ }
87
+ /** Which rule version a `wasm_rule_refused` event is about, and why it was refused. */
88
+ export interface WasmRuleRefusalDetail {
89
+ ruleId: string;
90
+ name: string;
91
+ sha256: string;
92
+ /** One of `RULE_LOAD_FAILURE_REASONS`, as the Rust proxy reports it too. */
93
+ refusal: RuleLoadFailureReason;
94
+ /** What the binary hashed to, on a hash mismatch. */
95
+ actualSha256?: string;
96
+ /** Whether an earlier version of the rule stays in force on this proxy. */
97
+ previousInForce: boolean;
98
+ }
53
99
  /**
54
100
  * What a detection-style event found, so the control plane can file it as a
55
101
  * detector finding (adjudicable on the Findings page, routed as
@@ -72,6 +118,13 @@ export interface DetectionFinding {
72
118
  export declare function detectionFinding(finding: AnomalyFinding, disposition: DetectionFinding['disposition'], severity: DetectionFinding['severity']): DetectionFinding;
73
119
  export interface GovernanceEvent {
74
120
  incidentId: string;
121
+ /**
122
+ * This event's id, made once in {@link GovernanceEmitter.emit} and carried
123
+ * on every path it is delivered by — the daemon socket, the direct post and
124
+ * the event file — so the control plane processes it once however many of
125
+ * them, and their retries, arrive.
126
+ */
127
+ eventId: string;
75
128
  kind: EventKind;
76
129
  toolName: string;
77
130
  toolInput: unknown;
@@ -88,6 +141,15 @@ export interface GovernanceEvent {
88
141
  * Absent only for an emitter constructed without one.
89
142
  */
90
143
  principal?: CallerIdentity;
144
+ /**
145
+ * Set on the budget events, and on the `tool_blocked` of a call a used-up
146
+ * budget refused: which budget, its limit, the calls made, when it resets.
147
+ */
148
+ budget?: BudgetEventDetail;
149
+ /** Set on `wasm_rule_refused`. */
150
+ wasmRule?: WasmRuleRefusalDetail;
151
+ /** Set on `wasm_shadow_evaluated`. */
152
+ wasmShadowReports?: ShadowReport[];
91
153
  timestamp: string;
92
154
  }
93
155
  export declare class GovernanceEmitter {
@@ -98,7 +160,7 @@ export declare class GovernanceEmitter {
98
160
  private readonly mcpProxyMode;
99
161
  private readonly identity;
100
162
  constructor(controlPlaneUrl: string, apiKey: string, eventsFilePath: string, workspaceId: string, mcpProxyMode?: string, identity?: CallerIdentity | undefined);
101
- emit(kind: EventKind, toolName: string, toolInput: unknown, reason?: string, finding?: DetectionFinding): void;
163
+ emit(kind: EventKind, toolName: string, toolInput: unknown, reason?: string, finding?: DetectionFinding, budget?: BudgetEventDetail, rule?: RuleEventDetail): void;
102
164
  private runDualPath;
103
165
  private postToControlPlane;
104
166
  private appendToFile;
@@ -1 +1 @@
1
- {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAIxD,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,cAAc,GACd,eAAe;AACjB;;;;;GAKG;GACD,cAAc;AAChB;;;;;;GAMG;GACD,+BAA+B;AACjC;;;;;;;GAOG;GACD,oBAAoB;AACtB;;;;;GAKG;GACD,kBAAkB;AACpB;;;;GAIG;GACD,WAAW;AACb,0EAA0E;GACxE,2BAA2B,CAAA;AAE/B;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,UAAU,EAAE,MAAM,CAAA;IAClB,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAA;IACZ,kDAAkD;IAClD,WAAW,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAA;IACvC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;IACnC,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,gBAAgB,CAAC,aAAa,CAAC,EAC5C,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC,GACrC,gBAAgB,CAElB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,cAAc,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBALR,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAsB,EACpC,QAAQ,GAAE,cAAc,GAAG,SAAqB;IAGnE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI;IA4C9G,OAAO,CAAC,WAAW;YAYL,kBAAkB;YA8BlB,YAAY;CAM3B"}
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"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"}
package/dist/emitter.js CHANGED
@@ -34,9 +34,10 @@ export class GovernanceEmitter {
34
34
  this.mcpProxyMode = mcpProxyMode;
35
35
  this.identity = identity;
36
36
  }
37
- emit(kind, toolName, toolInput, reason, finding) {
37
+ emit(kind, toolName, toolInput, reason, finding, budget, rule) {
38
38
  const event = {
39
39
  incidentId: node_crypto.randomUUID(),
40
+ eventId: node_crypto.randomUUID(),
40
41
  kind,
41
42
  toolName,
42
43
  toolInput,
@@ -46,6 +47,9 @@ export class GovernanceEmitter {
46
47
  severity: finding?.severity,
47
48
  finding,
48
49
  principal: this.identity,
50
+ budget,
51
+ wasmRule: rule?.wasmRule,
52
+ wasmShadowReports: rule?.wasmShadowReports,
49
53
  timestamp: new Date().toISOString(),
50
54
  };
51
55
  if (this.mcpProxyMode === 'daemon') {
@@ -58,12 +62,16 @@ export class GovernanceEmitter {
58
62
  workspaceId: this.workspaceId,
59
63
  harnessType: 'mcp-governance-proxy',
60
64
  incidentId: event.incidentId,
65
+ eventId: event.eventId,
61
66
  timestamp: event.timestamp,
62
67
  reason,
63
68
  severity: event.severity,
64
69
  finding,
65
70
  toolInput,
66
71
  principal: event.principal,
72
+ budget,
73
+ wasmRule: event.wasmRule,
74
+ wasmShadowReports: event.wasmShadowReports,
67
75
  };
68
76
  callDaemonSocket('telemetry.enqueue', eventPayload).then(() => {
69
77
  log.debug({ action: 'telemetry_enqueued' }, 'Telemetry successfully enqueued to daemon');
@@ -96,10 +104,14 @@ export class GovernanceEmitter {
96
104
  workspaceId: event.workspaceId,
97
105
  harnessType: event.harnessType,
98
106
  incidentId: event.incidentId,
107
+ eventId: event.eventId,
99
108
  reason: event.reason,
100
109
  severity: event.severity,
101
110
  finding: event.finding,
102
111
  principal: event.principal,
112
+ budget: event.budget,
113
+ wasmRule: event.wasmRule,
114
+ wasmShadowReports: event.wasmShadowReports,
103
115
  timestamp: event.timestamp,
104
116
  },
105
117
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * guardedValkey.ts — the one Valkey connection a proxy process holds, and the
3
+ * guard every command on it goes through.
4
+ *
5
+ * Two things in a proxy read and write Valkey: the shared session window
6
+ * (sessionStore.ts) and the MCP call budgets (budget.ts). They share this
7
+ * connection, and they share its rule: a command runs only on a connected
8
+ * client, never waits longer than a short timeout, and any failure comes back
9
+ * as `undefined`. What `undefined` means is each caller's business — the
10
+ * session window falls back to its per-process copy; a budget follows the
11
+ * proxy's fail setting.
12
+ *
13
+ * @module
14
+ */
15
+ import { Redis } from 'ioredis';
16
+ /** A command that takes longer than this is treated as Valkey being unavailable. */
17
+ export declare const VALKEY_COMMAND_TIMEOUT_MS = 200;
18
+ export interface GuardedValkeyOptions {
19
+ timeoutMs?: number;
20
+ }
21
+ export interface GuardedRunOptions {
22
+ /**
23
+ * Wait (within the timeout) for a connection that is still being set up,
24
+ * instead of answering `undefined` straight away. For a check whose
25
+ * `undefined` can refuse a call: the first call after the proxy starts
26
+ * must not be refused because the connection was a few milliseconds old.
27
+ */
28
+ awaitConnect?: boolean;
29
+ }
30
+ export declare class GuardedValkey {
31
+ readonly client: Redis;
32
+ private readonly timeoutMs;
33
+ private warned;
34
+ constructor(url: string, opts?: GuardedValkeyOptions);
35
+ /** Runs `op`, or answers `undefined` when Valkey is not connected, too slow, or fails. */
36
+ run<T>(op: (client: Redis) => Promise<T>, opts?: GuardedRunOptions): Promise<T | undefined>;
37
+ close(): Promise<void>;
38
+ private warnOnce;
39
+ }
40
+ //# sourceMappingURL=guardedValkey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardedValkey.d.ts","sourceRoot":"","sources":["../src/guardedValkey.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAM/B,oFAAoF;AACpF,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAE5C,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,qBAAa,aAAa;IACxB,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAA;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,MAAM,CAAQ;gBAEV,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB;IAexD,0FAA0F;IACpF,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAsB/F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,OAAO,CAAC,QAAQ;CAYjB"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * guardedValkey.ts — the one Valkey connection a proxy process holds, and the
3
+ * guard every command on it goes through.
4
+ *
5
+ * Two things in a proxy read and write Valkey: the shared session window
6
+ * (sessionStore.ts) and the MCP call budgets (budget.ts). They share this
7
+ * connection, and they share its rule: a command runs only on a connected
8
+ * client, never waits longer than a short timeout, and any failure comes back
9
+ * as `undefined`. What `undefined` means is each caller's business — the
10
+ * session window falls back to its per-process copy; a budget follows the
11
+ * proxy's fail setting.
12
+ *
13
+ * @module
14
+ */
15
+ import { Redis } from 'ioredis';
16
+ import { createStderrLogger } from './stderrLog.js';
17
+ import { describeConnectionError } from './valkeyErrors.js';
18
+ const log = createStderrLogger('mcp-proxy.valkey');
19
+ /** A command that takes longer than this is treated as Valkey being unavailable. */
20
+ export const VALKEY_COMMAND_TIMEOUT_MS = 200;
21
+ export class GuardedValkey {
22
+ client;
23
+ timeoutMs;
24
+ warned = false;
25
+ constructor(url, opts = {}) {
26
+ this.timeoutMs = opts.timeoutMs ?? VALKEY_COMMAND_TIMEOUT_MS;
27
+ this.client = new Redis(url, {
28
+ lazyConnect: true,
29
+ // No offline queue: a command issued before the connection is up must
30
+ // fail now, not wait for a Valkey that may never answer.
31
+ enableOfflineQueue: false,
32
+ maxRetriesPerRequest: 1,
33
+ connectTimeout: 1000,
34
+ retryStrategy: (times) => Math.min(1000 * 2 ** Math.min(times, 5), 30_000),
35
+ });
36
+ this.client.on('error', (err) => this.warnOnce('Valkey unreachable', err));
37
+ void this.client.connect().catch((err) => this.warnOnce('Valkey connect failed', err));
38
+ }
39
+ /** Runs `op`, or answers `undefined` when Valkey is not connected, too slow, or fails. */
40
+ async run(op, opts = {}) {
41
+ let timer;
42
+ const timeout = new Promise((resolve) => {
43
+ timer = setTimeout(() => resolve(undefined), this.timeoutMs);
44
+ timer.unref();
45
+ });
46
+ try {
47
+ if (this.client.status !== 'ready') {
48
+ const settingUp = this.client.status === 'connecting' || this.client.status === 'connect';
49
+ if (!opts.awaitConnect || !settingUp)
50
+ return undefined;
51
+ const ready = new Promise((resolve) => this.client.once('ready', () => resolve(true)));
52
+ if ((await Promise.race([ready, timeout])) !== true)
53
+ return undefined;
54
+ }
55
+ return await Promise.race([op(this.client), timeout]);
56
+ }
57
+ catch (err) {
58
+ this.warnOnce('Valkey command failed', err);
59
+ return undefined;
60
+ }
61
+ finally {
62
+ if (timer)
63
+ clearTimeout(timer);
64
+ }
65
+ }
66
+ async close() {
67
+ try {
68
+ await this.client.quit();
69
+ }
70
+ catch {
71
+ this.client.disconnect();
72
+ }
73
+ }
74
+ warnOnce(msg, err) {
75
+ const detail = { err: describeConnectionError(err) };
76
+ if (this.warned) {
77
+ log.debug(detail, msg);
78
+ return;
79
+ }
80
+ this.warned = true;
81
+ log.warn(detail, `${msg} — the anomaly session window falls back to this process, and MCP call budgets follow the fail setting`);
82
+ }
83
+ }
84
+ //# sourceMappingURL=guardedValkey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardedValkey.js","sourceRoot":"","sources":["../src/guardedValkey.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,13 @@ export declare class HttpStatusError extends Error {
14
14
  constructor(status: number, message: string);
15
15
  }
16
16
  export declare function httpRequest(method: 'GET' | 'POST', url: string, apiKey: string, body?: string, timeoutMs?: number): Promise<string>;
17
+ /**
18
+ * GETs a binary body, refusing one larger than `maxBytes` as soon as it is:
19
+ * the custom-rule binaries (`wasm/cloudRules.ts`) are the one non-JSON body
20
+ * this package reads, and their size is the control plane's to promise, not
21
+ * this process's to trust.
22
+ */
23
+ export declare function getBytes(url: string, apiKey: string, maxBytes: number, timeoutMs?: number): Promise<Buffer>;
17
24
  export declare function getJson(url: string, apiKey: string, timeoutMs?: number): Promise<unknown>;
18
25
  export declare function postJson(url: string, apiKey: string, payload: unknown, timeoutMs?: number): Promise<unknown>;
19
26
  //# sourceMappingURL=httpJson.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"httpJson.d.ts","sourceRoot":"","sources":["../src/httpJson.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,yFAAyF;AACzF,qBAAa,eAAgB,SAAQ,KAAK;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIrD;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,SAAO,GACf,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAED,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE/F;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlH"}
1
+ {"version":3,"file":"httpJson.d.ts","sourceRoot":"","sources":["../src/httpJson.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,yFAAyF;AACzF,qBAAa,eAAgB,SAAQ,KAAK;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIrD;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,SAAO,GACf,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BzG;AAED,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE/F;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlH"}
package/dist/httpJson.js CHANGED
@@ -52,6 +52,45 @@ export function httpRequest(method, url, apiKey, body, timeoutMs = 5000) {
52
52
  req.end();
53
53
  });
54
54
  }
55
+ /**
56
+ * GETs a binary body, refusing one larger than `maxBytes` as soon as it is:
57
+ * the custom-rule binaries (`wasm/cloudRules.ts`) are the one non-JSON body
58
+ * this package reads, and their size is the control plane's to promise, not
59
+ * this process's to trust.
60
+ */
61
+ export function getBytes(url, apiKey, maxBytes, timeoutMs = 5000) {
62
+ return new Promise((resolve, reject) => {
63
+ const lib = new URL(url).protocol === 'https:' ? node_https : node_http;
64
+ const headers = { Authorization: `Bearer ${apiKey}`, Accept: 'application/wasm' };
65
+ const req = lib.request(url, { method: 'GET', headers, timeout: timeoutMs }, (res) => {
66
+ const status = res.statusCode ?? 0;
67
+ const chunks = [];
68
+ let size = 0;
69
+ res.on('data', (c) => {
70
+ size += c.length;
71
+ if (size > maxBytes) {
72
+ req.destroy();
73
+ reject(new Error(`HTTP GET ${url} returned more than ${maxBytes} bytes`));
74
+ return;
75
+ }
76
+ chunks.push(c);
77
+ });
78
+ res.on('end', () => {
79
+ const body = Buffer.concat(chunks);
80
+ if (status >= 400)
81
+ reject(new HttpStatusError(status, `HTTP GET ${url} returned ${status}: ${body.toString('utf-8').slice(0, 200)}`));
82
+ else
83
+ resolve(body);
84
+ });
85
+ });
86
+ req.on('error', reject);
87
+ req.on('timeout', () => {
88
+ req.destroy();
89
+ reject(new Error(`HTTP GET ${url} timed out`));
90
+ });
91
+ req.end();
92
+ });
93
+ }
55
94
  export async function getJson(url, apiKey, timeoutMs) {
56
95
  return JSON.parse(await httpRequest('GET', url, apiKey, undefined, timeoutMs));
57
96
  }