@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.
- package/README.md +40 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/audit.test.d.ts +2 -0
- package/dist/__tests__/audit.test.d.ts.map +1 -0
- package/dist/__tests__/audit.test.js +96 -0
- package/dist/__tests__/audit.test.js.map +1 -0
- package/dist/__tests__/rate-limiter.test.js +26 -0
- package/dist/__tests__/rate-limiter.test.js.map +1 -1
- package/dist/__tests__/redactor.test.js +17 -0
- package/dist/__tests__/redactor.test.js.map +1 -1
- package/dist/__tests__/scope-guard.test.js +5 -6
- package/dist/__tests__/scope-guard.test.js.map +1 -1
- package/dist/__tests__/wrap.test.js +2 -2
- package/dist/__tests__/wrap.test.js.map +1 -1
- package/dist/audit.d.ts +27 -1
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +73 -5
- package/dist/audit.js.map +1 -1
- package/dist/hooks.d.ts +0 -6
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +4 -50
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/rate-limiter.d.ts +2 -1
- package/dist/rate-limiter.d.ts.map +1 -1
- package/dist/rate-limiter.js +9 -7
- package/dist/rate-limiter.js.map +1 -1
- package/dist/redactor.d.ts +2 -0
- package/dist/redactor.d.ts.map +1 -1
- package/dist/redactor.js +4 -0
- package/dist/redactor.js.map +1 -1
- package/dist/scope-guard.d.ts +1 -3
- package/dist/scope-guard.d.ts.map +1 -1
- package/dist/scope-guard.js +9 -11
- package/dist/scope-guard.js.map +1 -1
- package/dist/wrap.d.ts +1 -1
- package/dist/wrap.d.ts.map +1 -1
- package/dist/wrap.js +4 -8
- package/dist/wrap.js.map +1 -1
- 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 {
|
|
3
|
-
describe('
|
|
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(() =>
|
|
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(() =>
|
|
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
|
-
|
|
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,
|
|
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 } }] }
|
|
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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAExD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACpF,MAAM,IAAI,GAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAsB,CAAC,IAAI,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,
|
|
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
|
package/dist/audit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"
|
|
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
|
-
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
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 {
|
|
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
|
|
29
|
-
|
|
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":"AACA,OAAO,EAAE,
|
|
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
|
|
2
|
-
export {
|
|
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';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,
|
|
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
|
|
2
|
-
export {
|
|
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,
|
|
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"}
|
package/dist/rate-limiter.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare class RateLimiter {
|
|
|
7
7
|
private readonly perMinute;
|
|
8
8
|
private readonly maxConcurrent;
|
|
9
9
|
constructor(opts?: RateLimitOptions);
|
|
10
|
-
|
|
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;
|
|
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"}
|
package/dist/rate-limiter.js
CHANGED
|
@@ -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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
package/dist/rate-limiter.js.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/redactor.d.ts
CHANGED
|
@@ -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;
|
package/dist/redactor.d.ts.map
CHANGED
|
@@ -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"}
|