@dotsetlabs/tollgate 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +885 -0
- package/dist/analyzers/filesystem.d.ts +26 -0
- package/dist/analyzers/filesystem.d.ts.map +1 -0
- package/dist/analyzers/filesystem.js +284 -0
- package/dist/analyzers/filesystem.js.map +1 -0
- package/dist/analyzers/http.d.ts +90 -0
- package/dist/analyzers/http.d.ts.map +1 -0
- package/dist/analyzers/http.js +433 -0
- package/dist/analyzers/http.js.map +1 -0
- package/dist/analyzers/index.d.ts +101 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +342 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/loader.d.ts +114 -0
- package/dist/analyzers/loader.d.ts.map +1 -0
- package/dist/analyzers/loader.js +184 -0
- package/dist/analyzers/loader.js.map +1 -0
- package/dist/analyzers/prompt-injection.d.ts +95 -0
- package/dist/analyzers/prompt-injection.d.ts.map +1 -0
- package/dist/analyzers/prompt-injection.js +725 -0
- package/dist/analyzers/prompt-injection.js.map +1 -0
- package/dist/analyzers/sdk.d.ts +230 -0
- package/dist/analyzers/sdk.d.ts.map +1 -0
- package/dist/analyzers/sdk.js +283 -0
- package/dist/analyzers/sdk.js.map +1 -0
- package/dist/analyzers/shell.d.ts +20 -0
- package/dist/analyzers/shell.d.ts.map +1 -0
- package/dist/analyzers/shell.js +297 -0
- package/dist/analyzers/shell.js.map +1 -0
- package/dist/analyzers/sql.d.ts +37 -0
- package/dist/analyzers/sql.d.ts.map +1 -0
- package/dist/analyzers/sql.js +455 -0
- package/dist/analyzers/sql.js.map +1 -0
- package/dist/analyzers/types.d.ts +117 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +46 -0
- package/dist/analyzers/types.js.map +1 -0
- package/dist/approval/interactive.d.ts +72 -0
- package/dist/approval/interactive.d.ts.map +1 -0
- package/dist/approval/interactive.js +550 -0
- package/dist/approval/interactive.js.map +1 -0
- package/dist/approval/terminal.d.ts +59 -0
- package/dist/approval/terminal.d.ts.map +1 -0
- package/dist/approval/terminal.js +238 -0
- package/dist/approval/terminal.js.map +1 -0
- package/dist/approval/types.d.ts +66 -0
- package/dist/approval/types.d.ts.map +1 -0
- package/dist/approval/types.js +2 -0
- package/dist/approval/types.js.map +1 -0
- package/dist/audit/exporter.d.ts +138 -0
- package/dist/audit/exporter.d.ts.map +1 -0
- package/dist/audit/exporter.js +366 -0
- package/dist/audit/exporter.js.map +1 -0
- package/dist/audit/logger.d.ts +156 -0
- package/dist/audit/logger.d.ts.map +1 -0
- package/dist/audit/logger.js +406 -0
- package/dist/audit/logger.js.map +1 -0
- package/dist/audit/redaction.d.ts +110 -0
- package/dist/audit/redaction.d.ts.map +1 -0
- package/dist/audit/redaction.js +307 -0
- package/dist/audit/redaction.js.map +1 -0
- package/dist/audit/schema.d.ts +76 -0
- package/dist/audit/schema.d.ts.map +1 -0
- package/dist/audit/schema.js +122 -0
- package/dist/audit/schema.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +34 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +431 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export.d.ts +18 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +63 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/init.d.ts +12 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +102 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +11 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +60 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +29 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/scan.js +251 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +26 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +424 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/start.d.ts +20 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +82 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +10 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +42 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/templates.d.ts +26 -0
- package/dist/cli/commands/templates.d.ts.map +1 -0
- package/dist/cli/commands/templates.js +221 -0
- package/dist/cli/commands/templates.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +12 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +107 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/commands/wrap.d.ts +19 -0
- package/dist/cli/commands/wrap.d.ts.map +1 -0
- package/dist/cli/commands/wrap.js +59 -0
- package/dist/cli/commands/wrap.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +202 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui.d.ts +139 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +271 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/constants.d.ts +33 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +54 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +28 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +37 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/index.d.ts +11 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +10 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/manager.d.ts +127 -0
- package/dist/orchestrator/manager.d.ts.map +1 -0
- package/dist/orchestrator/manager.js +498 -0
- package/dist/orchestrator/manager.js.map +1 -0
- package/dist/orchestrator/types.d.ts +141 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +9 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/policy/engine.d.ts +55 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +288 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/natural-language.d.ts +141 -0
- package/dist/policy/natural-language.d.ts.map +1 -0
- package/dist/policy/natural-language.js +552 -0
- package/dist/policy/natural-language.js.map +1 -0
- package/dist/policy/parser.d.ts +141 -0
- package/dist/policy/parser.d.ts.map +1 -0
- package/dist/policy/parser.js +314 -0
- package/dist/policy/parser.js.map +1 -0
- package/dist/policy/types.d.ts +428 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +32 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/policy/validator.d.ts +72 -0
- package/dist/policy/validator.d.ts.map +1 -0
- package/dist/policy/validator.js +453 -0
- package/dist/policy/validator.js.map +1 -0
- package/dist/proxy/bridge.d.ts +84 -0
- package/dist/proxy/bridge.d.ts.map +1 -0
- package/dist/proxy/bridge.js +217 -0
- package/dist/proxy/bridge.js.map +1 -0
- package/dist/proxy/client.d.ts +130 -0
- package/dist/proxy/client.d.ts.map +1 -0
- package/dist/proxy/client.js +290 -0
- package/dist/proxy/client.js.map +1 -0
- package/dist/proxy/server.d.ts +111 -0
- package/dist/proxy/server.d.ts.map +1 -0
- package/dist/proxy/server.js +444 -0
- package/dist/proxy/server.js.map +1 -0
- package/dist/scanner.d.ts +91 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +373 -0
- package/dist/scanner.js.map +1 -0
- package/dist/session/index.d.ts +32 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +31 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/manager.d.ts +166 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +454 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/sqlite-store.d.ts +54 -0
- package/dist/session/sqlite-store.d.ts.map +1 -0
- package/dist/session/sqlite-store.js +209 -0
- package/dist/session/sqlite-store.js.map +1 -0
- package/dist/session/types.d.ts +179 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +38 -0
- package/dist/session/types.js.map +1 -0
- package/dist/templates.d.ts +64 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +451 -0
- package/dist/templates.js.map +1 -0
- package/dist/utils/config.d.ts +57 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +104 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/errors.d.ts +18 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +35 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +144 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +300 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/wizard.d.ts +68 -0
- package/dist/wizard.d.ts.map +1 -0
- package/dist/wizard.js +395 -0
- package/dist/wizard.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Manager for Tollgate
|
|
3
|
+
*
|
|
4
|
+
* Manages session-based approvals, allowing users to grant time-bounded
|
|
5
|
+
* permissions that reduce approval fatigue while maintaining security.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const manager = new SessionManager();
|
|
10
|
+
*
|
|
11
|
+
* // Create a grant when user approves with session option
|
|
12
|
+
* const grant = manager.createGrant({
|
|
13
|
+
* context: { server: 'postgres', tool: 'query', args: {}, timestamp: new Date() },
|
|
14
|
+
* scope: 'tool',
|
|
15
|
+
* duration: '5min',
|
|
16
|
+
* grantedBy: 'terminal',
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Check if a future call is covered
|
|
20
|
+
* const result = manager.checkGrant({
|
|
21
|
+
* server: 'postgres',
|
|
22
|
+
* tool: 'query',
|
|
23
|
+
* args: { sql: 'SELECT * FROM users' },
|
|
24
|
+
* timestamp: new Date(),
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* if (result.granted) {
|
|
28
|
+
* // Skip prompting, forward directly
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
import { minimatch } from 'minimatch';
|
|
33
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
34
|
+
import { sessionLogger as logger } from '../utils/logger.js';
|
|
35
|
+
import { durationToTtlSeconds } from './types.js';
|
|
36
|
+
/**
|
|
37
|
+
* Simple async mutex for thread-safety in async operations.
|
|
38
|
+
* Ensures only one operation can modify grants at a time.
|
|
39
|
+
*/
|
|
40
|
+
class AsyncMutex {
|
|
41
|
+
locked = false;
|
|
42
|
+
queue = [];
|
|
43
|
+
async acquire() {
|
|
44
|
+
if (!this.locked) {
|
|
45
|
+
this.locked = true;
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
this.queue.push(resolve);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
release() {
|
|
53
|
+
const next = this.queue.shift();
|
|
54
|
+
if (next) {
|
|
55
|
+
next();
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.locked = false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* In-memory session store implementation.
|
|
64
|
+
*
|
|
65
|
+
* Grants are stored in memory and lost on restart.
|
|
66
|
+
* For persistence, use SqliteSessionStore (see session/sqlite-store.ts).
|
|
67
|
+
*/
|
|
68
|
+
export class InMemorySessionStore {
|
|
69
|
+
grants = new Map();
|
|
70
|
+
set(grant) {
|
|
71
|
+
this.grants.set(grant.id, grant);
|
|
72
|
+
}
|
|
73
|
+
get(id) {
|
|
74
|
+
return this.grants.get(id);
|
|
75
|
+
}
|
|
76
|
+
findMatching(context) {
|
|
77
|
+
const now = new Date();
|
|
78
|
+
const matches = [];
|
|
79
|
+
for (const grant of this.grants.values()) {
|
|
80
|
+
// Skip expired grants
|
|
81
|
+
if (grant.expiresAt && grant.expiresAt < now) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
// Must match server
|
|
85
|
+
if (grant.server !== context.server) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
matches.push(grant);
|
|
89
|
+
}
|
|
90
|
+
return matches;
|
|
91
|
+
}
|
|
92
|
+
delete(id) {
|
|
93
|
+
return this.grants.delete(id);
|
|
94
|
+
}
|
|
95
|
+
pruneExpired() {
|
|
96
|
+
const now = new Date();
|
|
97
|
+
let pruned = 0;
|
|
98
|
+
for (const [id, grant] of this.grants) {
|
|
99
|
+
if (grant.expiresAt && grant.expiresAt < now) {
|
|
100
|
+
this.grants.delete(id);
|
|
101
|
+
pruned++;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return pruned;
|
|
105
|
+
}
|
|
106
|
+
getAll() {
|
|
107
|
+
return Array.from(this.grants.values());
|
|
108
|
+
}
|
|
109
|
+
clear() {
|
|
110
|
+
this.grants.clear();
|
|
111
|
+
}
|
|
112
|
+
getStats() {
|
|
113
|
+
const now = new Date();
|
|
114
|
+
const fiveMinutesFromNow = new Date(now.getTime() + 5 * 60 * 1000);
|
|
115
|
+
const stats = {
|
|
116
|
+
activeGrants: 0,
|
|
117
|
+
grantsByScope: { exact: 0, tool: 0, server: 0, pattern: 0 },
|
|
118
|
+
totalUsage: 0,
|
|
119
|
+
expiringSoon: 0,
|
|
120
|
+
};
|
|
121
|
+
for (const grant of this.grants.values()) {
|
|
122
|
+
// Skip expired
|
|
123
|
+
if (grant.expiresAt && grant.expiresAt < now) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
stats.activeGrants++;
|
|
127
|
+
stats.grantsByScope[grant.scope]++;
|
|
128
|
+
stats.totalUsage += grant.usageCount;
|
|
129
|
+
if (grant.expiresAt && grant.expiresAt < fiveMinutesFromNow) {
|
|
130
|
+
stats.expiringSoon++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return stats;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* SessionManager handles creation, checking, and lifecycle of session grants.
|
|
138
|
+
*
|
|
139
|
+
* Thread-safe and designed for concurrent access from the proxy server.
|
|
140
|
+
*/
|
|
141
|
+
export class SessionManager {
|
|
142
|
+
store;
|
|
143
|
+
pruneInterval = null;
|
|
144
|
+
mutex = new AsyncMutex();
|
|
145
|
+
/**
|
|
146
|
+
* Request deduplication cache to prevent double-counting for the same request.
|
|
147
|
+
* Maps requestId -> grantId for recently processed requests.
|
|
148
|
+
* Entries are cleared after 5 seconds to prevent memory leaks.
|
|
149
|
+
*/
|
|
150
|
+
recentRequests = new Map();
|
|
151
|
+
REQUEST_CACHE_TTL_MS = 5000;
|
|
152
|
+
/**
|
|
153
|
+
* Creates a new SessionManager.
|
|
154
|
+
*
|
|
155
|
+
* @param store - Session store backend (defaults to in-memory)
|
|
156
|
+
* @param autoPrune - Whether to automatically prune expired grants (default: true)
|
|
157
|
+
* @param pruneIntervalMs - How often to prune (default: 60 seconds)
|
|
158
|
+
*/
|
|
159
|
+
constructor(store, autoPrune = true, pruneIntervalMs = 60_000) {
|
|
160
|
+
this.store = store ?? new InMemorySessionStore();
|
|
161
|
+
if (autoPrune) {
|
|
162
|
+
this.pruneInterval = setInterval(() => {
|
|
163
|
+
try {
|
|
164
|
+
this.store.pruneExpired();
|
|
165
|
+
this.pruneRecentRequests();
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
// Log prune errors but don't crash
|
|
169
|
+
logger.error('Prune error', {
|
|
170
|
+
error: error instanceof Error ? error.message : String(error),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}, pruneIntervalMs);
|
|
174
|
+
// Don't keep the process alive just for pruning
|
|
175
|
+
this.pruneInterval.unref();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Clean up old entries from the request deduplication cache.
|
|
180
|
+
*/
|
|
181
|
+
pruneRecentRequests() {
|
|
182
|
+
const now = Date.now();
|
|
183
|
+
for (const [requestId, entry] of this.recentRequests) {
|
|
184
|
+
if (now - entry.timestamp > this.REQUEST_CACHE_TTL_MS) {
|
|
185
|
+
this.recentRequests.delete(requestId);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Creates a new session grant based on an approved tool call.
|
|
191
|
+
*
|
|
192
|
+
* @param input - Grant creation parameters
|
|
193
|
+
* @returns The created grant
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* const grant = manager.createGrant({
|
|
198
|
+
* context: { server: 'postgres', tool: 'query', args: {}, timestamp: new Date() },
|
|
199
|
+
* scope: 'tool',
|
|
200
|
+
* duration: '5min',
|
|
201
|
+
* grantedBy: 'terminal',
|
|
202
|
+
* });
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
createGrant(input) {
|
|
206
|
+
const { context, scope, duration, grantedBy, pattern, originalRequestId } = input;
|
|
207
|
+
const ttlSeconds = durationToTtlSeconds(duration);
|
|
208
|
+
const now = new Date();
|
|
209
|
+
// Calculate expiry
|
|
210
|
+
let expiresAt = null;
|
|
211
|
+
if (ttlSeconds > 0) {
|
|
212
|
+
expiresAt = new Date(now.getTime() + ttlSeconds * 1000);
|
|
213
|
+
}
|
|
214
|
+
else if (ttlSeconds === 0) {
|
|
215
|
+
// 'once' - grant expires immediately (used for audit only)
|
|
216
|
+
expiresAt = now;
|
|
217
|
+
}
|
|
218
|
+
// ttlSeconds === -1 means 'session' - no expiry
|
|
219
|
+
// Build scope value
|
|
220
|
+
let scopeValue;
|
|
221
|
+
let tool;
|
|
222
|
+
switch (scope) {
|
|
223
|
+
case 'exact':
|
|
224
|
+
scopeValue = JSON.stringify(context.args);
|
|
225
|
+
tool = context.tool;
|
|
226
|
+
break;
|
|
227
|
+
case 'tool':
|
|
228
|
+
tool = context.tool;
|
|
229
|
+
break;
|
|
230
|
+
case 'pattern':
|
|
231
|
+
scopeValue = pattern;
|
|
232
|
+
break;
|
|
233
|
+
case 'server':
|
|
234
|
+
// No additional value needed
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
const grant = {
|
|
238
|
+
id: uuidv4(),
|
|
239
|
+
createdAt: now,
|
|
240
|
+
expiresAt,
|
|
241
|
+
server: context.server,
|
|
242
|
+
scope,
|
|
243
|
+
scopeValue,
|
|
244
|
+
tool,
|
|
245
|
+
grantedBy,
|
|
246
|
+
usageCount: 0,
|
|
247
|
+
originalRequestId,
|
|
248
|
+
};
|
|
249
|
+
this.store.set(grant);
|
|
250
|
+
return grant;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Checks if a tool call is covered by an existing session grant.
|
|
254
|
+
*
|
|
255
|
+
* Returns the most specific matching grant if multiple exist.
|
|
256
|
+
* Order of specificity: exact > tool > pattern > server
|
|
257
|
+
*
|
|
258
|
+
* @param context - The tool call to check
|
|
259
|
+
* @param requestId - Optional request ID for deduplication (prevents double-counting on retry)
|
|
260
|
+
* @returns Check result with grant details if matched
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* const result = manager.checkGrant({
|
|
265
|
+
* server: 'postgres',
|
|
266
|
+
* tool: 'query',
|
|
267
|
+
* args: { sql: 'SELECT * FROM users' },
|
|
268
|
+
* timestamp: new Date(),
|
|
269
|
+
* }, 'req-123');
|
|
270
|
+
*
|
|
271
|
+
* if (result.granted) {
|
|
272
|
+
* console.log(`Authorized by session grant ${result.grant.id}`);
|
|
273
|
+
* }
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
checkGrant(context, requestId) {
|
|
277
|
+
// Check deduplication cache first - if this request was already processed,
|
|
278
|
+
// return the cached grant without incrementing usage count again
|
|
279
|
+
if (requestId) {
|
|
280
|
+
const cached = this.recentRequests.get(requestId);
|
|
281
|
+
if (cached) {
|
|
282
|
+
const grant = this.store.get(cached.grantId);
|
|
283
|
+
if (grant && (!grant.expiresAt || grant.expiresAt > new Date())) {
|
|
284
|
+
logger.debug('Returning cached grant for duplicate request', { requestId, grantId: cached.grantId });
|
|
285
|
+
return { granted: true, grant };
|
|
286
|
+
}
|
|
287
|
+
// Cached grant expired or deleted - remove from cache
|
|
288
|
+
this.recentRequests.delete(requestId);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const candidates = this.store.findMatching(context);
|
|
292
|
+
if (candidates.length === 0) {
|
|
293
|
+
return { granted: false, reason: 'no_grant' };
|
|
294
|
+
}
|
|
295
|
+
// Find the best matching grant (most specific first)
|
|
296
|
+
const scopePriority = {
|
|
297
|
+
exact: 4,
|
|
298
|
+
tool: 3,
|
|
299
|
+
pattern: 2,
|
|
300
|
+
server: 1,
|
|
301
|
+
};
|
|
302
|
+
// Sort by specificity (highest first)
|
|
303
|
+
const sorted = candidates.sort((a, b) => scopePriority[b.scope] - scopePriority[a.scope]);
|
|
304
|
+
for (const grant of sorted) {
|
|
305
|
+
if (this.grantMatchesContext(grant, context)) {
|
|
306
|
+
// Re-validate expiry right before granting to prevent race condition
|
|
307
|
+
// where grant expires between initial check and use
|
|
308
|
+
const now = new Date();
|
|
309
|
+
if (grant.expiresAt && grant.expiresAt <= now) {
|
|
310
|
+
// Grant expired during processing - skip it
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
// Increment usage count and persist the update
|
|
314
|
+
const updatedGrant = { ...grant, usageCount: grant.usageCount + 1 };
|
|
315
|
+
this.store.set(updatedGrant);
|
|
316
|
+
// Cache the request ID to prevent double-counting on retry
|
|
317
|
+
if (requestId) {
|
|
318
|
+
this.recentRequests.set(requestId, { grantId: grant.id, timestamp: Date.now() });
|
|
319
|
+
}
|
|
320
|
+
return { granted: true, grant: updatedGrant };
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return { granted: false, reason: 'scope_mismatch' };
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Checks if a specific grant matches a tool call context.
|
|
327
|
+
*/
|
|
328
|
+
grantMatchesContext(grant, context) {
|
|
329
|
+
// Server must always match (already filtered in findMatching)
|
|
330
|
+
if (grant.server !== context.server) {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
switch (grant.scope) {
|
|
334
|
+
case 'exact':
|
|
335
|
+
// Must match tool AND args exactly
|
|
336
|
+
return (grant.tool === context.tool &&
|
|
337
|
+
grant.scopeValue === JSON.stringify(context.args));
|
|
338
|
+
case 'tool':
|
|
339
|
+
// Must match tool name
|
|
340
|
+
return grant.tool === context.tool;
|
|
341
|
+
case 'pattern':
|
|
342
|
+
// Must match glob pattern
|
|
343
|
+
if (!grant.scopeValue)
|
|
344
|
+
return false;
|
|
345
|
+
return minimatch(context.tool, grant.scopeValue);
|
|
346
|
+
case 'server':
|
|
347
|
+
// Server already matches, any tool is covered
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Revokes a session grant by ID.
|
|
353
|
+
*
|
|
354
|
+
* @param id - Grant ID to revoke
|
|
355
|
+
* @returns true if grant was found and revoked
|
|
356
|
+
*/
|
|
357
|
+
revokeGrant(id) {
|
|
358
|
+
return this.store.delete(id);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Revokes all grants for a specific server.
|
|
362
|
+
*
|
|
363
|
+
* @param server - Server name
|
|
364
|
+
* @returns Number of grants revoked
|
|
365
|
+
*/
|
|
366
|
+
revokeByServer(server) {
|
|
367
|
+
const grants = this.store.getAll().filter((g) => g.server === server);
|
|
368
|
+
let revoked = 0;
|
|
369
|
+
for (const grant of grants) {
|
|
370
|
+
if (this.store.delete(grant.id)) {
|
|
371
|
+
revoked++;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return revoked;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Revokes all session grants.
|
|
378
|
+
*/
|
|
379
|
+
revokeAll() {
|
|
380
|
+
this.store.clear();
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Gets all active (non-expired) grants.
|
|
384
|
+
*/
|
|
385
|
+
getActiveGrants() {
|
|
386
|
+
const now = new Date();
|
|
387
|
+
return this.store.getAll().filter((g) => !g.expiresAt || g.expiresAt > now);
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Gets session statistics.
|
|
391
|
+
*/
|
|
392
|
+
getStats() {
|
|
393
|
+
return this.store.getStats();
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Manually trigger expired grant cleanup.
|
|
397
|
+
*
|
|
398
|
+
* @returns Number of grants pruned
|
|
399
|
+
*/
|
|
400
|
+
pruneExpired() {
|
|
401
|
+
return this.store.pruneExpired();
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Formats a grant for display in terminal or logs.
|
|
405
|
+
*/
|
|
406
|
+
formatGrant(grant) {
|
|
407
|
+
const parts = [];
|
|
408
|
+
// Server and scope
|
|
409
|
+
parts.push(`${grant.server}`);
|
|
410
|
+
switch (grant.scope) {
|
|
411
|
+
case 'exact':
|
|
412
|
+
parts.push(`:${grant.tool}[exact]`);
|
|
413
|
+
break;
|
|
414
|
+
case 'tool':
|
|
415
|
+
parts.push(`:${grant.tool}`);
|
|
416
|
+
break;
|
|
417
|
+
case 'pattern':
|
|
418
|
+
parts.push(`:${grant.scopeValue}`);
|
|
419
|
+
break;
|
|
420
|
+
case 'server':
|
|
421
|
+
parts.push(':*');
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
// Expiry
|
|
425
|
+
if (grant.expiresAt) {
|
|
426
|
+
const remaining = grant.expiresAt.getTime() - Date.now();
|
|
427
|
+
if (remaining > 0) {
|
|
428
|
+
const minutes = Math.ceil(remaining / 60000);
|
|
429
|
+
parts.push(` (${minutes}m remaining)`);
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
parts.push(' (expired)');
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
parts.push(' (session)');
|
|
437
|
+
}
|
|
438
|
+
// Usage
|
|
439
|
+
if (grant.usageCount > 0) {
|
|
440
|
+
parts.push(` [used ${grant.usageCount}x]`);
|
|
441
|
+
}
|
|
442
|
+
return parts.join('');
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Cleans up resources. Call when shutting down.
|
|
446
|
+
*/
|
|
447
|
+
close() {
|
|
448
|
+
if (this.pruneInterval) {
|
|
449
|
+
clearInterval(this.pruneInterval);
|
|
450
|
+
this.pruneInterval = null;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/session/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed Session Store for Tollgate
|
|
3
|
+
*
|
|
4
|
+
* Provides persistent session storage that survives process restarts.
|
|
5
|
+
* Uses the same database as the audit logger for consistency.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { SqliteSessionStore } from './sqlite-store.js';
|
|
10
|
+
* import { SessionManager } from './manager.js';
|
|
11
|
+
*
|
|
12
|
+
* const store = new SqliteSessionStore('./data/sessions.db');
|
|
13
|
+
* const manager = new SessionManager(store);
|
|
14
|
+
*
|
|
15
|
+
* // Sessions now persist across restarts
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import type { ToolCallContext } from '../policy/types.js';
|
|
19
|
+
import type { SessionGrant, SessionStats, SessionStore } from './types.js';
|
|
20
|
+
/**
|
|
21
|
+
* SQLite-backed session store for persistent session grants.
|
|
22
|
+
*
|
|
23
|
+
* Features:
|
|
24
|
+
* - Sessions survive process restarts
|
|
25
|
+
* - Automatic cleanup of expired grants
|
|
26
|
+
* - Thread-safe via SQLite's locking
|
|
27
|
+
*/
|
|
28
|
+
export declare class SqliteSessionStore implements SessionStore {
|
|
29
|
+
private db;
|
|
30
|
+
private insertStmt;
|
|
31
|
+
private getStmt;
|
|
32
|
+
private deleteStmt;
|
|
33
|
+
private updateUsageStmt;
|
|
34
|
+
constructor(dbPath: string);
|
|
35
|
+
set(grant: SessionGrant): void;
|
|
36
|
+
get(id: string): SessionGrant | undefined;
|
|
37
|
+
findMatching(context: ToolCallContext): SessionGrant[];
|
|
38
|
+
delete(id: string): boolean;
|
|
39
|
+
pruneExpired(): number;
|
|
40
|
+
getAll(): SessionGrant[];
|
|
41
|
+
clear(): void;
|
|
42
|
+
getStats(): SessionStats;
|
|
43
|
+
/**
|
|
44
|
+
* Increment usage count for a grant.
|
|
45
|
+
* Called when a grant is used to authorize a tool call.
|
|
46
|
+
*/
|
|
47
|
+
incrementUsage(id: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Close the database connection.
|
|
50
|
+
*/
|
|
51
|
+
close(): void;
|
|
52
|
+
private rowToGrant;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=sqlite-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../src/session/sqlite-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAgB,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA6BzF;;;;;;;GAOG;AACH,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,eAAe,CAAqB;gBAEhC,MAAM,EAAE,MAAM;IAqC1B,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAe9B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAczC,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,YAAY,EAAE;IAsBtD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK3B,YAAY,IAAI,MAAM;IAUtB,MAAM,IAAI,YAAY,EAAE;IAMxB,KAAK,IAAI,IAAI;IAIb,QAAQ,IAAI,YAAY;IA4CxB;;;OAGG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,UAAU;CAcnB"}
|