@mcpolyglot/security 0.0.3 → 0.2.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 (43) hide show
  1. package/README.md +40 -3
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/audit.test.d.ts +2 -0
  4. package/dist/__tests__/audit.test.d.ts.map +1 -0
  5. package/dist/__tests__/audit.test.js +96 -0
  6. package/dist/__tests__/audit.test.js.map +1 -0
  7. package/dist/__tests__/rate-limiter.test.js +26 -0
  8. package/dist/__tests__/rate-limiter.test.js.map +1 -1
  9. package/dist/__tests__/redactor.test.js +17 -0
  10. package/dist/__tests__/redactor.test.js.map +1 -1
  11. package/dist/__tests__/scope-guard.test.js +5 -6
  12. package/dist/__tests__/scope-guard.test.js.map +1 -1
  13. package/dist/__tests__/wrap.test.js +2 -2
  14. package/dist/__tests__/wrap.test.js.map +1 -1
  15. package/dist/audit.d.ts +27 -1
  16. package/dist/audit.d.ts.map +1 -1
  17. package/dist/audit.js +73 -5
  18. package/dist/audit.js.map +1 -1
  19. package/dist/hooks.d.ts +0 -6
  20. package/dist/hooks.d.ts.map +1 -1
  21. package/dist/hooks.js +4 -50
  22. package/dist/hooks.js.map +1 -1
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/rate-limiter.d.ts +2 -1
  28. package/dist/rate-limiter.d.ts.map +1 -1
  29. package/dist/rate-limiter.js +9 -7
  30. package/dist/rate-limiter.js.map +1 -1
  31. package/dist/redactor.d.ts +2 -0
  32. package/dist/redactor.d.ts.map +1 -1
  33. package/dist/redactor.js +4 -0
  34. package/dist/redactor.js.map +1 -1
  35. package/dist/scope-guard.d.ts +1 -3
  36. package/dist/scope-guard.d.ts.map +1 -1
  37. package/dist/scope-guard.js +9 -11
  38. package/dist/scope-guard.js.map +1 -1
  39. package/dist/wrap.d.ts +1 -1
  40. package/dist/wrap.d.ts.map +1 -1
  41. package/dist/wrap.js +4 -8
  42. package/dist/wrap.js.map +1 -1
  43. package/package.json +2 -2
@@ -0,0 +1,96 @@
1
+ import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
2
+ import { createServer } from 'node:http';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { afterEach, describe, expect, it, vi } from 'vitest';
6
+ import { AuditLogger } from '../audit.js';
7
+ const base = { ts: '2026-01-01T00:00:00.000Z', tool: 't', decision: 'deny', argsHash: 'abc' };
8
+ let dir;
9
+ afterEach(() => {
10
+ vi.restoreAllMocks();
11
+ if (dir)
12
+ rmSync(dir, { recursive: true, force: true });
13
+ dir = undefined;
14
+ });
15
+ function tmpFile() {
16
+ dir = mkdtempSync(join(tmpdir(), 'mcpolyglot-audit-'));
17
+ return join(dir, 'nested', 'audit.log');
18
+ }
19
+ describe('AuditLogger', () => {
20
+ it('writes JSONL to stdout by default', async () => {
21
+ const spy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
22
+ await new AuditLogger().append(base);
23
+ expect(JSON.parse(String(spy.mock.calls[0][0]))).toMatchObject(base);
24
+ });
25
+ it('can target stderr or be silenced', async () => {
26
+ const out = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
27
+ const err = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
28
+ await new AuditLogger({ console: 'stderr' }).append(base);
29
+ await new AuditLogger({ console: false }).append(base);
30
+ expect(out).not.toHaveBeenCalled();
31
+ expect(err).toHaveBeenCalledTimes(1);
32
+ });
33
+ it('file sink appends and never truncates, across logger instances', async () => {
34
+ const path = tmpFile();
35
+ await new AuditLogger({ console: false, path }).append({ ...base, n: 1 });
36
+ await new AuditLogger({ console: false, path }).append({ ...base, n: 2 });
37
+ const lines = readFileSync(path, 'utf8')
38
+ .trim()
39
+ .split('\n')
40
+ .map((l) => JSON.parse(l));
41
+ expect(lines.map((l) => l.n)).toEqual([1, 2]);
42
+ });
43
+ it('scrubs credentials and PII from reason and error text, and truncates', async () => {
44
+ const path = tmpFile();
45
+ await new AuditLogger({ console: false, path }).append({
46
+ ...base,
47
+ reason: 'connect postgres://admin:hunter2@db:5432/x failed for alice@example.com',
48
+ error: {
49
+ code: 'x',
50
+ message: 'token eyJhbGciOi.eyJzdWIiOiIx.c2lnbmF0dXJl ' + 'z'.repeat(1000),
51
+ },
52
+ });
53
+ const raw = readFileSync(path, 'utf8');
54
+ expect(raw).not.toContain('hunter2');
55
+ expect(raw).not.toContain('admin:');
56
+ expect(raw).not.toContain('alice@example.com');
57
+ expect(raw).not.toContain('eyJhbGciOi');
58
+ const e = JSON.parse(raw);
59
+ expect(e.error.message.length).toBeLessThanOrEqual(501);
60
+ });
61
+ it('webhook receives each entry as JSON', async () => {
62
+ const received = [];
63
+ const srv = createServer((req, res) => {
64
+ let body = '';
65
+ req.on('data', (c) => (body += c));
66
+ req.on('end', () => {
67
+ received.push(JSON.parse(body));
68
+ res.end();
69
+ });
70
+ });
71
+ await new Promise((r) => srv.listen(0, '127.0.0.1', r));
72
+ const port = srv.address().port;
73
+ try {
74
+ const log = new AuditLogger({
75
+ console: false,
76
+ webhook: { url: `http://127.0.0.1:${port}/` },
77
+ });
78
+ await log.append(base);
79
+ await log.flush();
80
+ expect(received).toEqual([base]);
81
+ }
82
+ finally {
83
+ srv.close();
84
+ }
85
+ });
86
+ it('webhook failure never throws and never logs the URL', async () => {
87
+ const err = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
88
+ const url = 'http://127.0.0.1:1/?token=sekret';
89
+ const log = new AuditLogger({ console: false, webhook: { url, timeoutMs: 500 } });
90
+ await expect(log.append(base)).resolves.toBeUndefined();
91
+ await log.flush();
92
+ expect(err).toHaveBeenCalled();
93
+ expect(String(err.mock.calls.at(-1)[0])).not.toContain('sekret');
94
+ });
95
+ });
96
+ //# sourceMappingURL=audit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.test.js","sourceRoot":"","sources":["../../src/__tests__/audit.test.ts"],"names":[],"mappings":"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"}
@@ -18,4 +18,30 @@ describe('RateLimiter', () => {
18
18
  await expect(rl.check('demo.list_tables', 'session-a')).resolves.not.toThrow();
19
19
  });
20
20
  });
21
+ describe('RateLimiter concurrency', () => {
22
+ it('caps concurrent calls, and frees the slot when a call finishes', async () => {
23
+ const rl = new RateLimiter({ perMinute: 100, maxConcurrent: 2 });
24
+ const a = await rl.check('t', 's');
25
+ const b = await rl.check('t', 's');
26
+ await expect(rl.check('t', 's')).rejects.toMatchObject({ code: 'rate_limited' });
27
+ a();
28
+ const c = await rl.check('t', 's');
29
+ b();
30
+ c();
31
+ });
32
+ it('sequential calls never hit the concurrency cap', async () => {
33
+ const rl = new RateLimiter({ perMinute: 100, maxConcurrent: 1 });
34
+ for (let i = 0; i < 10; i++)
35
+ (await rl.check('t', 's'))();
36
+ });
37
+ it('release is idempotent', async () => {
38
+ const rl = new RateLimiter({ perMinute: 100, maxConcurrent: 1 });
39
+ const r = await rl.check('t', 's');
40
+ r();
41
+ r();
42
+ const r2 = await rl.check('t', 's');
43
+ await expect(rl.check('t', 's')).rejects.toMatchObject({ code: 'rate_limited' });
44
+ r2();
45
+ });
46
+ });
21
47
  //# sourceMappingURL=rate-limiter.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter.test.js","sourceRoot":"","sources":["../../src/__tests__/rate-limiter.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC;QAChE,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC;QAChE,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC1C,kCAAkC;QAClC,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACzE,6CAA6C;QAC7C,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"rate-limiter.test.js","sourceRoot":"","sources":["../../src/__tests__/rate-limiter.test.ts"],"names":[],"mappings":"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"}
@@ -55,4 +55,21 @@ describe('Redactor', () => {
55
55
  expect(out.result.content[0].text).toContain('[REDACTED:iid]');
56
56
  });
57
57
  });
58
+ describe('Redactor built-in patterns', () => {
59
+ it.each([
60
+ ['email', 'alice@example.com'],
61
+ ['jwt', 'eyJhbGciOi.eyJzdWIiOi.signaturepart'],
62
+ ['aws-access-key', 'AKIAIOSFODNN7EXAMPLE'],
63
+ ['github-token', 'ghp_' + 'a'.repeat(36)],
64
+ ['us-ssn', '123-45-6789'],
65
+ ['credit-card', '4111 1111 1111 1111'],
66
+ ])('%s', (name, secret) => {
67
+ const out = new Redactor().apply('demo', {
68
+ content: [{ type: 'json', data: { rows: [{ note: `value: ${secret}` }] } }],
69
+ });
70
+ const text = JSON.stringify(out.result.content);
71
+ expect(text).not.toContain(secret);
72
+ expect(text).toContain(`[REDACTED:${name}]`);
73
+ });
74
+ });
58
75
  //# sourceMappingURL=redactor.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redactor.test.js","sourceRoot":"","sources":["../../src/__tests__/redactor.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redactor.test.js","sourceRoot":"","sources":["../../src/__tests__/redactor.test.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,16 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { ScopeGuard } from '../scope-guard.js';
3
- describe('ScopeGuard', () => {
4
- const guard = new ScopeGuard();
2
+ import { checkScopes } from '../scope-guard.js';
3
+ describe('checkScopes', () => {
5
4
  it('passes when granted is a superset of required', () => {
6
- expect(() => guard.check('demo.query', ['tables:read'], new Set(['tables:read', 'schema:read']))).not.toThrow();
5
+ expect(() => checkScopes('demo.query', ['tables:read'], new Set(['tables:read', 'schema:read']))).not.toThrow();
7
6
  });
8
7
  it('throws ScopeError when a required scope is missing', () => {
9
- expect(() => guard.check('demo.query', ['tables:write'], new Set(['tables:read']))).toThrow(/tables:write/);
8
+ expect(() => checkScopes('demo.query', ['tables:write'], new Set(['tables:read']))).toThrow(/tables:write/);
10
9
  });
11
10
  it('reports every missing scope', () => {
12
11
  let caught;
13
12
  try {
14
- guard.check('demo.query', ['tables:write', 'query:raw'], new Set([]));
13
+ checkScopes('demo.query', ['tables:write', 'query:raw'], new Set([]));
15
14
  }
16
15
  catch (e) {
17
16
  caught = e;
@@ -1 +1 @@
1
- {"version":3,"file":"scope-guard.test.js","sourceRoot":"","sources":["../../src/__tests__/scope-guard.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;IAE/B,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,GAAG,EAAE,CACV,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,aAAa,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,CACpF,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CACzF,cAAc,CACf,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,IAAI,MAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,CAAU,CAAC;QACtB,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChD,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"scope-guard.test.js","sourceRoot":"","sources":["../../src/__tests__/scope-guard.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,GAAG,EAAE,CACV,WAAW,CAAC,YAAY,EAAE,CAAC,aAAa,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,CACpF,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CACzF,cAAc,CACf,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,IAAI,MAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,WAAW,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,CAAU,CAAC;QACtB,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChD,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -10,10 +10,10 @@ describe('wrapUntrusted', () => {
10
10
  expect(text).toContain('hello');
11
11
  });
12
12
  it('serializes json content into a wrapped text block', () => {
13
- const out = wrapUntrusted({ content: [{ type: 'json', data: { x: 1 } }] }, 'minimal');
13
+ const out = wrapUntrusted({ content: [{ type: 'json', data: { x: 1 } }] });
14
14
  expect(out.content[0]?.type).toBe('text');
15
15
  expect(out.content[0].text).toContain('"x": 1');
16
- expect(out.content[0].text).toContain('<mcpolyglot-data>');
16
+ expect(out.content[0].text).toContain('<mcpolyglot-data trusted="false">');
17
17
  });
18
18
  it('does not wrap when mode is off', () => {
19
19
  const out = wrapUntrusted({ content: [{ type: 'text', text: 'hi' }] }, 'off');
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.test.js","sourceRoot":"","sources":["../../src/__tests__/wrap.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrap.test.js","sourceRoot":"","sources":["../../src/__tests__/wrap.test.ts"],"names":[],"mappings":"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"}
package/dist/audit.d.ts CHANGED
@@ -1,10 +1,36 @@
1
1
  export interface AuditLoggerOptions {
2
+ /**
3
+ * JSONL to a console stream. Defaults to `'stdout'`. Use `'stderr'` under the stdio
4
+ * transport, where stdout carries the MCP protocol.
5
+ */
6
+ console?: 'stdout' | 'stderr' | false;
7
+ /** Also append JSONL to this file. */
2
8
  path?: string;
9
+ /** Also POST each entry as JSON. Best-effort: failures are reported, never fail the call. */
10
+ webhook?: {
11
+ url: string;
12
+ timeoutMs?: number;
13
+ };
3
14
  }
15
+ /**
16
+ * Append-only audit sink. Entries are sanitized before any sink sees them: free-text
17
+ * fields are scrubbed of credentials and PII and truncated. Callers never pass rows or raw
18
+ * args (the server logs an args hash), so this only has to guard error text.
19
+ */
4
20
  export declare class AuditLogger {
5
- private readonly path;
21
+ private readonly path?;
22
+ private readonly stream?;
23
+ private readonly webhook?;
24
+ private readonly redactor;
25
+ private readonly pending;
6
26
  private dirEnsured;
7
27
  constructor(opts?: AuditLoggerOptions);
8
28
  append(entry: Record<string, unknown>): Promise<void>;
29
+ /** Wait for in-flight webhook posts. Call on shutdown. */
30
+ flush(): Promise<void>;
31
+ private sanitize;
32
+ private scrub;
33
+ private post;
34
+ private track;
9
35
  }
10
36
  //# sourceMappingURL=audit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,UAAU,CAAS;gBAEf,IAAI,GAAE,kBAAuB;IAInC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAO5D"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6FAA6F;IAC7F,OAAO,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAMD;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;gBAEf,IAAI,GAAE,kBAAuB;IAOnC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3D,0DAA0D;IACpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,KAAK;YAKC,IAAI;IAsBlB,OAAO,CAAC,KAAK;CAId"}
package/dist/audit.js CHANGED
@@ -1,18 +1,86 @@
1
1
  import { mkdir, appendFile } from 'node:fs/promises';
2
2
  import { dirname } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
+ import { Redactor } from './redactor.js';
5
+ const MAX_TEXT = 500;
6
+ // `scheme://user:password@host` — connection strings in driver error messages.
7
+ const URL_CREDENTIALS = /(\b[a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi;
8
+ /**
9
+ * Append-only audit sink. Entries are sanitized before any sink sees them: free-text
10
+ * fields are scrubbed of credentials and PII and truncated. Callers never pass rows or raw
11
+ * args (the server logs an args hash), so this only has to guard error text.
12
+ */
4
13
  export class AuditLogger {
5
14
  path;
15
+ stream;
16
+ webhook;
17
+ redactor = new Redactor();
18
+ pending = new Set();
6
19
  dirEnsured = false;
7
20
  constructor(opts = {}) {
8
- this.path = expandHome(opts.path ?? '~/.mcpolyglot/audit.log');
21
+ const target = opts.console ?? 'stdout';
22
+ if (target)
23
+ this.stream = target === 'stdout' ? process.stdout : process.stderr;
24
+ if (opts.path)
25
+ this.path = expandHome(opts.path);
26
+ if (opts.webhook)
27
+ this.webhook = { timeoutMs: 2_000, ...opts.webhook };
9
28
  }
10
29
  async append(entry) {
11
- if (!this.dirEnsured) {
12
- await mkdir(dirname(this.path), { recursive: true });
13
- this.dirEnsured = true;
30
+ const line = JSON.stringify(this.sanitize(entry)) + '\n';
31
+ this.stream?.write(line);
32
+ if (this.path) {
33
+ if (!this.dirEnsured) {
34
+ await mkdir(dirname(this.path), { recursive: true });
35
+ this.dirEnsured = true;
36
+ }
37
+ // 'a' flag: O_APPEND, never truncates or seeks.
38
+ await appendFile(this.path, line, { encoding: 'utf8', flag: 'a' });
14
39
  }
15
- await appendFile(this.path, JSON.stringify(entry) + '\n', 'utf8');
40
+ if (this.webhook)
41
+ this.track(this.post(line));
42
+ }
43
+ /** Wait for in-flight webhook posts. Call on shutdown. */
44
+ async flush() {
45
+ await Promise.all(this.pending);
46
+ }
47
+ sanitize(entry) {
48
+ const out = { ...entry };
49
+ if (typeof out.reason === 'string')
50
+ out.reason = this.scrub(out.reason);
51
+ const err = out.error;
52
+ if (err)
53
+ out.error = { ...err, message: this.scrub(err.message) };
54
+ return out;
55
+ }
56
+ scrub(s) {
57
+ const text = this.redactor.redactText(s.replace(URL_CREDENTIALS, '$1[REDACTED]@'));
58
+ return text.length > MAX_TEXT ? text.slice(0, MAX_TEXT) + '…' : text;
59
+ }
60
+ async post(line) {
61
+ const { url, timeoutMs } = this.webhook;
62
+ try {
63
+ const res = await fetch(url, {
64
+ method: 'POST',
65
+ headers: { 'content-type': 'application/json' },
66
+ body: line,
67
+ signal: AbortSignal.timeout(timeoutMs),
68
+ });
69
+ if (!res.ok)
70
+ throw new Error(`HTTP ${res.status}`);
71
+ }
72
+ catch (err) {
73
+ // Never echo the URL: it may carry a token.
74
+ process.stderr.write(JSON.stringify({
75
+ level: 'warn',
76
+ msg: 'audit.webhook_failed',
77
+ error: err.message,
78
+ }) + '\n');
79
+ }
80
+ }
81
+ track(p) {
82
+ this.pending.add(p);
83
+ void p.finally(() => this.pending.delete(p));
16
84
  }
17
85
  }
18
86
  function expandHome(p) {
package/dist/audit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAMlC,MAAM,OAAO,WAAW;IACL,IAAI,CAAS;IACtB,UAAU,GAAG,KAAK,CAAC;IAE3B,YAAY,OAA2B,EAAE;QACvC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,yBAAyB,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAA8B;QACzC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IACpE,CAAC;CACF;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
package/dist/hooks.d.ts CHANGED
@@ -31,10 +31,4 @@ export interface DefaultHookOptions {
31
31
  * ```
32
32
  */
33
33
  export declare function defaultSecurityHooks(opts?: DefaultHookOptions): SecurityHooks;
34
- /**
35
- * Compose multiple `SecurityHooks` objects into one. Each phase runs through the
36
- * provided hooks in order — useful for adding custom audit sinks or extra redaction
37
- * passes alongside the defaults.
38
- */
39
- export declare function composeHooks(...hooks: SecurityHooks[]): SecurityHooks;
40
34
  //# sourceMappingURL=hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,EAAY,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAA8B,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEtE,6FAA6F;AAC7F,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,gFAAgF;IAChF,QAAQ,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;IAC9E,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,kBAAuB,GAAG,aAAa,CA2BjF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAgCrE"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,EAAY,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAA8B,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEtE,6FAA6F;AAC7F,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,gFAAgF;IAChF,QAAQ,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;IAC9E,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,kBAAuB,GAAG,aAAa,CAwBjF"}
package/dist/hooks.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ScopeGuard } from './scope-guard.js';
1
+ import { checkScopes } from './scope-guard.js';
2
2
  import { Redactor } from './redactor.js';
3
3
  import { RateLimiter } from './rate-limiter.js';
4
4
  import { AuditLogger } from './audit.js';
@@ -19,17 +19,14 @@ import { wrapUntrusted, enforceSize } from './wrap.js';
19
19
  * ```
20
20
  */
21
21
  export function defaultSecurityHooks(opts = {}) {
22
- const guard = new ScopeGuard();
23
22
  const limiter = new RateLimiter(opts.rateLimit);
24
23
  const redactor = new Redactor(opts.redactor);
25
24
  const audit = new AuditLogger(opts.audit);
26
25
  const wrapMode = opts.wrapMode ?? 'strict';
27
26
  return {
28
- checkScopes(toolName, required, granted) {
29
- guard.check(toolName, required, granted);
30
- },
31
- async checkRateLimit(toolName, sessionId) {
32
- await limiter.check(toolName, sessionId);
27
+ checkScopes,
28
+ checkRateLimit(toolName, sessionId) {
29
+ return limiter.check(toolName, sessionId);
33
30
  },
34
31
  redact(toolName, result) {
35
32
  return redactor.apply(toolName, result);
@@ -45,47 +42,4 @@ export function defaultSecurityHooks(opts = {}) {
45
42
  },
46
43
  };
47
44
  }
48
- /**
49
- * Compose multiple `SecurityHooks` objects into one. Each phase runs through the
50
- * provided hooks in order — useful for adding custom audit sinks or extra redaction
51
- * passes alongside the defaults.
52
- */
53
- export function composeHooks(...hooks) {
54
- return {
55
- checkScopes(toolName, required, granted) {
56
- for (const h of hooks)
57
- h.checkScopes(toolName, required, granted);
58
- },
59
- async checkRateLimit(toolName, sessionId) {
60
- for (const h of hooks)
61
- await h.checkRateLimit(toolName, sessionId);
62
- },
63
- redact(toolName, result) {
64
- let acc = result;
65
- let count = 0;
66
- for (const h of hooks) {
67
- const r = h.redact(toolName, acc);
68
- acc = r.result;
69
- count += r.redactionsApplied;
70
- }
71
- return { result: acc, redactionsApplied: count };
72
- },
73
- enforceSize(toolName, result, maxBytes) {
74
- let acc = result;
75
- for (const h of hooks)
76
- acc = h.enforceSize(toolName, acc, maxBytes);
77
- return acc;
78
- },
79
- wrapUntrusted(result) {
80
- let acc = result;
81
- for (const h of hooks)
82
- acc = h.wrapUntrusted(acc);
83
- return acc;
84
- },
85
- async audit(entry) {
86
- for (const h of hooks)
87
- await h.audit(entry);
88
- },
89
- };
90
- }
91
45
  //# sourceMappingURL=hooks.js.map
package/dist/hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAA4C,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,WAAW,EAAyB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAA2B,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAiB,MAAM,WAAW,CAAC;AAYtE;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA2B,EAAE;IAChE,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAa,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAErD,OAAO;QACL,WAAW;QACX,cAAc,CAAC,QAAgB,EAAE,SAAiB;YAChD,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,CAAC,QAAgB,EAAE,MAAkB;YACzC,OAAO,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;QACD,WAAW,CAAC,QAAgB,EAAE,MAAkB,EAAE,QAAgB;YAChE,OAAO,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QACD,aAAa,CAAC,MAAkB;YAC9B,OAAO,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,KAAK;YACf,MAAM,KAAK,CAAC,MAAM,CAAC,KAA2C,CAAC,CAAC;QAClE,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { defaultSecurityHooks, composeHooks } from './hooks.js';
2
- export { ScopeGuard } from './scope-guard.js';
1
+ export { defaultSecurityHooks } from './hooks.js';
2
+ export { checkScopes } from './scope-guard.js';
3
3
  export { Redactor, type RedactionRule, type ColumnDenyEntry } from './redactor.js';
4
4
  export { RateLimiter, type RateLimitOptions } from './rate-limiter.js';
5
5
  export { AuditLogger, type AuditLoggerOptions } from './audit.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { defaultSecurityHooks, composeHooks } from './hooks.js';
2
- export { ScopeGuard } from './scope-guard.js';
1
+ export { defaultSecurityHooks } from './hooks.js';
2
+ export { checkScopes } from './scope-guard.js';
3
3
  export { Redactor } from './redactor.js';
4
4
  export { RateLimiter } from './rate-limiter.js';
5
5
  export { AuditLogger } from './audit.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAA4C,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,WAAW,EAAyB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAA2B,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAiB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAA4C,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,WAAW,EAAyB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAA2B,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAiB,MAAM,WAAW,CAAC"}
@@ -7,6 +7,7 @@ export declare class RateLimiter {
7
7
  private readonly perMinute;
8
8
  private readonly maxConcurrent;
9
9
  constructor(opts?: RateLimitOptions);
10
- check(toolName: string, sessionId: string): Promise<void>;
10
+ /** Take a token and a concurrency slot. Call the returned function when the call ends. */
11
+ check(toolName: string, sessionId: string): Promise<() => void>;
11
12
  }
12
13
  //# sourceMappingURL=rate-limiter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAQD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAE3B,IAAI,GAAE,gBAAqB;IAKjC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAkChE"}
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAQD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAE3B,IAAI,GAAE,gBAAqB;IAKvC,0FAA0F;IACpF,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;CAmCtE"}
@@ -7,6 +7,7 @@ export class RateLimiter {
7
7
  this.perMinute = opts.perMinute ?? 30;
8
8
  this.maxConcurrent = opts.maxConcurrent ?? 5;
9
9
  }
10
+ /** Take a token and a concurrency slot. Call the returned function when the call ends. */
10
11
  async check(toolName, sessionId) {
11
12
  const key = `${sessionId}::${toolName}`;
12
13
  const now = Date.now();
@@ -32,13 +33,14 @@ export class RateLimiter {
32
33
  }
33
34
  bucket.tokens -= 1;
34
35
  bucket.inFlight += 1;
35
- // best-effort release; the server pipeline currently does not signal completion,
36
- // so we time-release each in-flight slot after the typical timeout window.
37
- setTimeout(() => {
38
- const b = this.buckets.get(key);
39
- if (b && b.inFlight > 0)
40
- b.inFlight -= 1;
41
- }, 30_000).unref?.();
36
+ let released = false;
37
+ const b = bucket;
38
+ return () => {
39
+ if (released)
40
+ return;
41
+ released = true;
42
+ b.inFlight -= 1;
43
+ };
42
44
  }
43
45
  }
44
46
  //# sourceMappingURL=rate-limiter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAalD,MAAM,OAAO,WAAW;IACL,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IACzC,SAAS,CAAS;IAClB,aAAa,CAAS;IAEvC,YAAY,OAAyB,EAAE;QACrC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,SAAiB;QAC7C,MAAM,GAAG,GAAG,GAAG,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YACpE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC;QACrD,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACnF,MAAM,CAAC,YAAY,GAAG,GAAG,CAAC;QAE1B,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1C,MAAM,IAAI,cAAc,CAAC,gCAAgC,QAAQ,EAAE,EAAE;gBACnE,QAAQ;gBACR,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,cAAc,CAAC,2BAA2B,QAAQ,EAAE,EAAE;gBAC9D,QAAQ;gBACR,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;QACL,CAAC;QACD,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;QACnB,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;QAErB,iFAAiF;QACjF,2EAA2E;QAC3E,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;gBAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;QAC3C,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;IACvB,CAAC;CACF"}
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAalD,MAAM,OAAO,WAAW;IACL,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IACzC,SAAS,CAAS;IAClB,aAAa,CAAS;IAEvC,YAAY,OAAyB,EAAE;QACrC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,0FAA0F;IAC1F,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,SAAiB;QAC7C,MAAM,GAAG,GAAG,GAAG,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YACpE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC;QACrD,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACnF,MAAM,CAAC,YAAY,GAAG,GAAG,CAAC;QAE1B,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1C,MAAM,IAAI,cAAc,CAAC,gCAAgC,QAAQ,EAAE,EAAE;gBACnE,QAAQ;gBACR,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,cAAc,CAAC,2BAA2B,QAAQ,EAAE,EAAE;gBAC9D,QAAQ;gBACR,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;QACL,CAAC;QACD,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;QACnB,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;QAErB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,CAAC,GAAG,MAAM,CAAC;QACjB,OAAO,GAAG,EAAE;YACV,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC;CACF"}
@@ -19,6 +19,8 @@ export declare class Redactor {
19
19
  result: ToolResult;
20
20
  redactionsApplied: number;
21
21
  };
22
+ /** Apply the text rules (no column denies) to one string. */
23
+ redactText(input: string): string;
22
24
  private redactString;
23
25
  private redactJson;
24
26
  private isDenied;
@@ -1 +1 @@
1
- {"version":3,"file":"redactor.d.ts","sourceRoot":"","sources":["../src/redactor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;CACd;AA6BD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAE9B,IAAI,GAAE;QAAE,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAA;KAAO;IAKzF,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE;IAqB/F,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,UAAU;IAgClB,OAAO,CAAC,QAAQ;CAOjB"}
1
+ {"version":3,"file":"redactor.d.ts","sourceRoot":"","sources":["../src/redactor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;CACd;AA6BD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAE9B,IAAI,GAAE;QAAE,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAA;KAAO;IAKzF,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE;IAqB/F,6DAA6D;IAC7D,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIjC,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,UAAU;IAgClB,OAAO,CAAC,QAAQ;CAOjB"}