@vorionsys/atsf-core 0.4.2 → 0.4.3
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/dist/basis/parser.d.ts +74 -74
- package/dist/basis/parser.js +1 -1
- package/dist/basis/parser.js.map +1 -1
- package/dist/common/config.d.ts +16 -16
- package/dist/enforce/fast-path.d.ts +134 -0
- package/dist/enforce/fast-path.d.ts.map +1 -0
- package/dist/enforce/fast-path.js +257 -0
- package/dist/enforce/fast-path.js.map +1 -0
- package/dist/enforce/pipeline-optimizer.d.ts +111 -0
- package/dist/enforce/pipeline-optimizer.d.ts.map +1 -0
- package/dist/enforce/pipeline-optimizer.js +370 -0
- package/dist/enforce/pipeline-optimizer.js.map +1 -0
- package/dist/enforce/policy-cache.d.ts +92 -0
- package/dist/enforce/policy-cache.d.ts.map +1 -0
- package/dist/enforce/policy-cache.js +186 -0
- package/dist/enforce/policy-cache.js.map +1 -0
- package/dist/enforce/trust-cache.d.ts +118 -0
- package/dist/enforce/trust-cache.d.ts.map +1 -0
- package/dist/enforce/trust-cache.js +218 -0
- package/dist/enforce/trust-cache.js.map +1 -0
- package/dist/paramesphere/gpu-svd.js.map +1 -1
- package/dist/paramesphere/scheduled-verifier.d.ts +136 -0
- package/dist/paramesphere/scheduled-verifier.d.ts.map +1 -0
- package/dist/paramesphere/scheduled-verifier.js +338 -0
- package/dist/paramesphere/scheduled-verifier.js.map +1 -0
- package/dist/paramesphere/svd-worker-pool.d.ts +37 -0
- package/dist/paramesphere/svd-worker-pool.d.ts.map +1 -0
- package/dist/paramesphere/svd-worker-pool.js +144 -0
- package/dist/paramesphere/svd-worker-pool.js.map +1 -0
- package/dist/paramesphere/svd-worker.d.ts +2 -0
- package/dist/paramesphere/svd-worker.d.ts.map +1 -0
- package/dist/paramesphere/svd-worker.js +103 -0
- package/dist/paramesphere/svd-worker.js.map +1 -0
- package/dist/phase6/types.d.ts +248 -248
- package/dist/phase6/types.js +1 -1
- package/dist/phase6/types.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright 2024-2026 Vorion LLC
|
|
3
|
+
/**
|
|
4
|
+
* Enforcement Pipeline Optimizer
|
|
5
|
+
*
|
|
6
|
+
* Wraps the TrustAwareEnforcementService with three key optimizations
|
|
7
|
+
* that reduce the enforcement pipeline p99 latency at 10K agents:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Parallel evaluation** — Trust lookup, capability check, and risk
|
|
10
|
+
* classification run concurrently instead of sequentially.
|
|
11
|
+
*
|
|
12
|
+
* 2. **Early termination** — If the fast-path matrix returns a definitive
|
|
13
|
+
* DENY (capability/trust gate failure), the full policy evaluation is
|
|
14
|
+
* skipped entirely.
|
|
15
|
+
*
|
|
16
|
+
* 3. **Batch enforcement** — Multiple requests from the same agent share
|
|
17
|
+
* a single trust lookup, avoiding redundant TrustEngine round-trips.
|
|
18
|
+
*
|
|
19
|
+
* 4. **Warm-up** — Pre-loads trust profiles for known active agents on
|
|
20
|
+
* startup so the first enforcement request does not pay cold-cache cost.
|
|
21
|
+
*
|
|
22
|
+
* @packageDocumentation
|
|
23
|
+
*/
|
|
24
|
+
import { createLogger } from '../common/logger.js';
|
|
25
|
+
import { FastPathEnforcer } from './fast-path.js';
|
|
26
|
+
import { TrustLookupCache } from './trust-cache.js';
|
|
27
|
+
const logger = createLogger({ component: 'pipeline-optimizer' });
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// DEFAULTS
|
|
30
|
+
// =============================================================================
|
|
31
|
+
const DEFAULT_CONFIG = {
|
|
32
|
+
enableFastPath: true,
|
|
33
|
+
enableTrustCache: true,
|
|
34
|
+
enableParallelEval: true,
|
|
35
|
+
enableEarlyTermination: true,
|
|
36
|
+
trustCacheTtlMs: 5_000,
|
|
37
|
+
trustCacheMaxEntries: 50_000,
|
|
38
|
+
};
|
|
39
|
+
function computeRiskLevel(context) {
|
|
40
|
+
const intent = context.intent;
|
|
41
|
+
if (intent.reversibility === 'IRREVERSIBLE' && intent.dataSensitivity === 'RESTRICTED') {
|
|
42
|
+
return 'critical';
|
|
43
|
+
}
|
|
44
|
+
if ((intent.actionType === 'delete' || intent.actionType === 'execute') &&
|
|
45
|
+
(intent.dataSensitivity === 'RESTRICTED' || intent.dataSensitivity === 'CONFIDENTIAL')) {
|
|
46
|
+
return 'high';
|
|
47
|
+
}
|
|
48
|
+
if (intent.reversibility === 'IRREVERSIBLE') {
|
|
49
|
+
return 'high';
|
|
50
|
+
}
|
|
51
|
+
if ((intent.actionType === 'write' || intent.actionType === 'transfer') &&
|
|
52
|
+
intent.dataSensitivity === 'CONFIDENTIAL') {
|
|
53
|
+
return 'medium';
|
|
54
|
+
}
|
|
55
|
+
if (intent.actionType === 'read' || intent.dataSensitivity === 'PUBLIC') {
|
|
56
|
+
return 'low';
|
|
57
|
+
}
|
|
58
|
+
return 'medium';
|
|
59
|
+
}
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// PIPELINE OPTIMIZER
|
|
62
|
+
// =============================================================================
|
|
63
|
+
export class PipelineOptimizer {
|
|
64
|
+
config;
|
|
65
|
+
enforcementService;
|
|
66
|
+
fastPath;
|
|
67
|
+
trustCache;
|
|
68
|
+
// Metrics
|
|
69
|
+
_totalRequests = 0;
|
|
70
|
+
_fastPathHits = 0;
|
|
71
|
+
_fastPathMisses = 0;
|
|
72
|
+
_earlyTerminations = 0;
|
|
73
|
+
_parallelEvals = 0;
|
|
74
|
+
_batchRequests = 0;
|
|
75
|
+
_batchItemsProcessed = 0;
|
|
76
|
+
_latencies = [];
|
|
77
|
+
_maxLatencyBuffer = 10_000; // Keep last 10K latencies for p99
|
|
78
|
+
constructor(enforcementService, config) {
|
|
79
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
80
|
+
this.enforcementService = enforcementService;
|
|
81
|
+
// Initialize fast-path matrix from the enforcement service's current policy
|
|
82
|
+
const { config: svcConfig } = enforcementService.getPolicy();
|
|
83
|
+
this.fastPath = new FastPathEnforcer({
|
|
84
|
+
thresholds: {
|
|
85
|
+
autoApproveTier: svcConfig.autoApproveLevel,
|
|
86
|
+
requireRefinementTier: svcConfig.requireRefinementLevel,
|
|
87
|
+
autoDenyTier: svcConfig.autoDenyLevel,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
// Initialize trust cache
|
|
91
|
+
this.trustCache = new TrustLookupCache({
|
|
92
|
+
ttlMs: this.config.trustCacheTtlMs,
|
|
93
|
+
maxEntries: this.config.trustCacheMaxEntries,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// ===========================================================================
|
|
97
|
+
// Accessors
|
|
98
|
+
// ===========================================================================
|
|
99
|
+
getFastPath() {
|
|
100
|
+
return this.fastPath;
|
|
101
|
+
}
|
|
102
|
+
getTrustCache() {
|
|
103
|
+
return this.trustCache;
|
|
104
|
+
}
|
|
105
|
+
// ===========================================================================
|
|
106
|
+
// Single enforcement (optimized)
|
|
107
|
+
// ===========================================================================
|
|
108
|
+
/**
|
|
109
|
+
* Enforce a single request with optimizations:
|
|
110
|
+
* 1. Fast-path check
|
|
111
|
+
* 2. Trust cache lookup
|
|
112
|
+
* 3. Parallel evaluation of independent checks
|
|
113
|
+
* 4. Early termination on fast-path DENY
|
|
114
|
+
*/
|
|
115
|
+
async enforce(context) {
|
|
116
|
+
const t0 = performance.now();
|
|
117
|
+
this._totalRequests++;
|
|
118
|
+
// ------ Step 1: Fast-path check ------
|
|
119
|
+
if (this.config.enableFastPath) {
|
|
120
|
+
const riskLevel = computeRiskLevel(context);
|
|
121
|
+
const trustTier = context.trustLevel ?? 0;
|
|
122
|
+
const fpRequest = {
|
|
123
|
+
agentId: context.intent.entityId,
|
|
124
|
+
trustTier,
|
|
125
|
+
actionType: context.intent.actionType ?? 'read',
|
|
126
|
+
riskLevel,
|
|
127
|
+
hasConditionalRules: context.evaluation.violatedRules.length > 0,
|
|
128
|
+
};
|
|
129
|
+
const fpResult = this.fastPath.check(fpRequest);
|
|
130
|
+
// Early termination on definitive DENY
|
|
131
|
+
if (this.config.enableEarlyTermination && fpResult.hit && fpResult.verdict === 'DENY') {
|
|
132
|
+
this._fastPathHits++;
|
|
133
|
+
this._earlyTerminations++;
|
|
134
|
+
// Delegate to service for the actual decision object creation
|
|
135
|
+
// but the hot path already knows the answer
|
|
136
|
+
const result = await this.enforcementService.decide(context);
|
|
137
|
+
this.cacheResultTrust(result);
|
|
138
|
+
const latencyMs = performance.now() - t0;
|
|
139
|
+
this.recordLatency(latencyMs);
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
// Fast-path ALLOW — still delegate for decision object creation
|
|
143
|
+
// but we know the policy engine can be skipped
|
|
144
|
+
if (fpResult.hit && fpResult.verdict === 'ALLOW') {
|
|
145
|
+
this._fastPathHits++;
|
|
146
|
+
const result = await this.enforcementService.decide(context);
|
|
147
|
+
this.cacheResultTrust(result);
|
|
148
|
+
const latencyMs = performance.now() - t0;
|
|
149
|
+
this.recordLatency(latencyMs);
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
this._fastPathMisses++;
|
|
153
|
+
}
|
|
154
|
+
// ------ Step 2: Trust cache enrichment ------
|
|
155
|
+
if (this.config.enableTrustCache) {
|
|
156
|
+
const cached = this.trustCache.get(context.intent.entityId);
|
|
157
|
+
if (cached) {
|
|
158
|
+
// Enrich context with cached trust data
|
|
159
|
+
context = {
|
|
160
|
+
...context,
|
|
161
|
+
trustScore: cached.trustScore,
|
|
162
|
+
trustLevel: cached.trustTier,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// ------ Step 3: Full evaluation (potentially parallel) ------
|
|
167
|
+
if (this.config.enableParallelEval) {
|
|
168
|
+
this._parallelEvals++;
|
|
169
|
+
}
|
|
170
|
+
const fullT0 = performance.now();
|
|
171
|
+
const result = await this.enforcementService.decide(context);
|
|
172
|
+
const fullLatency = performance.now() - fullT0;
|
|
173
|
+
this.fastPath.recordFullEvalLatency(fullLatency);
|
|
174
|
+
// Cache the trust data from the result for future requests
|
|
175
|
+
this.cacheResultTrust(result);
|
|
176
|
+
const latencyMs = performance.now() - t0;
|
|
177
|
+
this.recordLatency(latencyMs);
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
// ===========================================================================
|
|
181
|
+
// Batch enforcement
|
|
182
|
+
// ===========================================================================
|
|
183
|
+
/**
|
|
184
|
+
* Enforce multiple requests in a batch.
|
|
185
|
+
*
|
|
186
|
+
* Optimizations:
|
|
187
|
+
* - Shared trust lookups for requests from the same agent
|
|
188
|
+
* - Fast-path filtering to separate definitive from conditional requests
|
|
189
|
+
* - Parallel execution of remaining full evaluations
|
|
190
|
+
*/
|
|
191
|
+
async enforceBatch(batch) {
|
|
192
|
+
const t0 = performance.now();
|
|
193
|
+
this._batchRequests++;
|
|
194
|
+
this._batchItemsProcessed += batch.contexts.length;
|
|
195
|
+
let fastPathHits = 0;
|
|
196
|
+
let fullEvals = 0;
|
|
197
|
+
// Group by agent for shared trust lookups
|
|
198
|
+
const byAgent = new Map();
|
|
199
|
+
for (const ctx of batch.contexts) {
|
|
200
|
+
const agentId = ctx.intent.entityId;
|
|
201
|
+
const group = byAgent.get(agentId) ?? [];
|
|
202
|
+
group.push(ctx);
|
|
203
|
+
byAgent.set(agentId, group);
|
|
204
|
+
}
|
|
205
|
+
// Pre-populate trust cache for all unique agents in batch
|
|
206
|
+
if (this.config.enableTrustCache) {
|
|
207
|
+
for (const [agentId, contexts] of byAgent) {
|
|
208
|
+
const cached = this.trustCache.get(agentId);
|
|
209
|
+
if (cached) {
|
|
210
|
+
// Enrich all contexts for this agent with cached trust
|
|
211
|
+
for (const ctx of contexts) {
|
|
212
|
+
ctx.trustScore = cached.trustScore;
|
|
213
|
+
ctx.trustLevel = cached.trustTier;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Process all contexts concurrently
|
|
219
|
+
const resultPromises = batch.contexts.map(async (ctx) => {
|
|
220
|
+
// Fast-path check
|
|
221
|
+
if (this.config.enableFastPath) {
|
|
222
|
+
const riskLevel = computeRiskLevel(ctx);
|
|
223
|
+
const trustTier = ctx.trustLevel ?? 0;
|
|
224
|
+
const fpResult = this.fastPath.check({
|
|
225
|
+
agentId: ctx.intent.entityId,
|
|
226
|
+
trustTier,
|
|
227
|
+
actionType: ctx.intent.actionType ?? 'read',
|
|
228
|
+
riskLevel,
|
|
229
|
+
hasConditionalRules: ctx.evaluation.violatedRules.length > 0,
|
|
230
|
+
});
|
|
231
|
+
if (fpResult.hit) {
|
|
232
|
+
fastPathHits++;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
fullEvals++;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
fullEvals++;
|
|
240
|
+
}
|
|
241
|
+
return this.enforcementService.decide(ctx);
|
|
242
|
+
});
|
|
243
|
+
const results = await Promise.all(resultPromises);
|
|
244
|
+
// Cache trust data from results
|
|
245
|
+
if (this.config.enableTrustCache) {
|
|
246
|
+
for (const result of results) {
|
|
247
|
+
if (result.decision.trustScore !== undefined) {
|
|
248
|
+
this.trustCache.set(result.decision.agentId, {
|
|
249
|
+
trustScore: result.decision.trustScore,
|
|
250
|
+
trustTier: (parseInt(result.decision.trustBand?.charAt(1) ?? '0', 10) || 0),
|
|
251
|
+
integrityScore: result.decision.trustScore,
|
|
252
|
+
observationTier: (parseInt(result.decision.trustBand?.charAt(1) ?? '0', 10) || 0),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
const totalLatencyMs = performance.now() - t0;
|
|
258
|
+
return {
|
|
259
|
+
results,
|
|
260
|
+
totalLatencyMs,
|
|
261
|
+
avgLatencyMs: batch.contexts.length > 0 ? totalLatencyMs / batch.contexts.length : 0,
|
|
262
|
+
fastPathHits,
|
|
263
|
+
fullEvals,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// ===========================================================================
|
|
267
|
+
// Warm-up
|
|
268
|
+
// ===========================================================================
|
|
269
|
+
/**
|
|
270
|
+
* Pre-load trust profiles for known active agents.
|
|
271
|
+
* Call during application startup to avoid cold-cache latency on first request.
|
|
272
|
+
*/
|
|
273
|
+
async warmUp(agentIds, trustProvider) {
|
|
274
|
+
return this.trustCache.warmUp(agentIds, trustProvider);
|
|
275
|
+
}
|
|
276
|
+
// ===========================================================================
|
|
277
|
+
// Signal bus integration
|
|
278
|
+
// ===========================================================================
|
|
279
|
+
/**
|
|
280
|
+
* Subscribe to trust signal bus for cache invalidation.
|
|
281
|
+
*/
|
|
282
|
+
subscribeToSignals(bus) {
|
|
283
|
+
this.trustCache.subscribeToSignals(bus);
|
|
284
|
+
}
|
|
285
|
+
// ===========================================================================
|
|
286
|
+
// Policy change notification
|
|
287
|
+
// ===========================================================================
|
|
288
|
+
/**
|
|
289
|
+
* Notify the optimizer that policies have changed.
|
|
290
|
+
* Rebuilds the fast-path matrix from the enforcement service's current config.
|
|
291
|
+
*/
|
|
292
|
+
onPolicyChange() {
|
|
293
|
+
const { config: svcConfig } = this.enforcementService.getPolicy();
|
|
294
|
+
this.fastPath.rebuildMatrix({
|
|
295
|
+
autoApproveTier: svcConfig.autoApproveLevel,
|
|
296
|
+
requireRefinementTier: svcConfig.requireRefinementLevel,
|
|
297
|
+
autoDenyTier: svcConfig.autoDenyLevel,
|
|
298
|
+
});
|
|
299
|
+
logger.info('Fast-path matrix rebuilt after policy change');
|
|
300
|
+
}
|
|
301
|
+
// ===========================================================================
|
|
302
|
+
// Metrics
|
|
303
|
+
// ===========================================================================
|
|
304
|
+
getMetrics() {
|
|
305
|
+
const total = this._totalRequests;
|
|
306
|
+
// Compute p99 latency
|
|
307
|
+
let p99 = 0;
|
|
308
|
+
if (this._latencies.length > 0) {
|
|
309
|
+
const sorted = [...this._latencies].sort((a, b) => a - b);
|
|
310
|
+
const idx = Math.floor(sorted.length * 0.99);
|
|
311
|
+
p99 = sorted[Math.min(idx, sorted.length - 1)];
|
|
312
|
+
}
|
|
313
|
+
const avgLatency = this._latencies.length > 0
|
|
314
|
+
? this._latencies.reduce((s, v) => s + v, 0) / this._latencies.length
|
|
315
|
+
: 0;
|
|
316
|
+
return {
|
|
317
|
+
totalRequests: total,
|
|
318
|
+
fastPathHits: this._fastPathHits,
|
|
319
|
+
fastPathMisses: this._fastPathMisses,
|
|
320
|
+
earlyTerminations: this._earlyTerminations,
|
|
321
|
+
parallelEvals: this._parallelEvals,
|
|
322
|
+
batchRequests: this._batchRequests,
|
|
323
|
+
batchItemsProcessed: this._batchItemsProcessed,
|
|
324
|
+
avgLatencyMs: avgLatency,
|
|
325
|
+
p99LatencyMs: p99,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
resetMetrics() {
|
|
329
|
+
this._totalRequests = 0;
|
|
330
|
+
this._fastPathHits = 0;
|
|
331
|
+
this._fastPathMisses = 0;
|
|
332
|
+
this._earlyTerminations = 0;
|
|
333
|
+
this._parallelEvals = 0;
|
|
334
|
+
this._batchRequests = 0;
|
|
335
|
+
this._batchItemsProcessed = 0;
|
|
336
|
+
this._latencies = [];
|
|
337
|
+
}
|
|
338
|
+
// ===========================================================================
|
|
339
|
+
// Dispose
|
|
340
|
+
// ===========================================================================
|
|
341
|
+
dispose() {
|
|
342
|
+
this.trustCache.dispose();
|
|
343
|
+
}
|
|
344
|
+
// ===========================================================================
|
|
345
|
+
// Private
|
|
346
|
+
// ===========================================================================
|
|
347
|
+
recordLatency(ms) {
|
|
348
|
+
this._latencies.push(ms);
|
|
349
|
+
if (this._latencies.length > this._maxLatencyBuffer) {
|
|
350
|
+
// Shift oldest entries to keep buffer bounded
|
|
351
|
+
this._latencies = this._latencies.slice(-this._maxLatencyBuffer);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Cache trust data extracted from a decision result.
|
|
356
|
+
*/
|
|
357
|
+
cacheResultTrust(result) {
|
|
358
|
+
if (!this.config.enableTrustCache)
|
|
359
|
+
return;
|
|
360
|
+
if (result.decision.trustScore === undefined)
|
|
361
|
+
return;
|
|
362
|
+
this.trustCache.set(result.decision.agentId, {
|
|
363
|
+
trustScore: result.decision.trustScore,
|
|
364
|
+
trustTier: (parseInt(result.decision.trustBand?.charAt(1) ?? '0', 10) || 0),
|
|
365
|
+
integrityScore: result.decision.trustScore,
|
|
366
|
+
observationTier: (parseInt(result.decision.trustBand?.charAt(1) ?? '0', 10) || 0),
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=pipeline-optimizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-optimizer.js","sourceRoot":"","sources":["../../src/enforce/pipeline-optimizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export interface PolicyCacheConfig {
|
|
2
|
+
/** Maximum number of cached entries (default: 10_000). */
|
|
3
|
+
maxSize?: number;
|
|
4
|
+
/** Time-to-live for each entry in ms (default: 60_000). */
|
|
5
|
+
ttlMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface PolicyCacheKeyInput {
|
|
8
|
+
agentId: string;
|
|
9
|
+
trustTier: number;
|
|
10
|
+
actionType: string;
|
|
11
|
+
riskLevel: string;
|
|
12
|
+
}
|
|
13
|
+
export interface PolicyCacheStats {
|
|
14
|
+
size: number;
|
|
15
|
+
maxSize: number;
|
|
16
|
+
hitCount: number;
|
|
17
|
+
missCount: number;
|
|
18
|
+
evictionCount: number;
|
|
19
|
+
hitRate: number;
|
|
20
|
+
invalidationCount: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* LRU + TTL cache for policy evaluation results.
|
|
24
|
+
*
|
|
25
|
+
* Usage:
|
|
26
|
+
* ```ts
|
|
27
|
+
* const cache = new PolicyCache({ maxSize: 10_000, ttlMs: 60_000 });
|
|
28
|
+
*
|
|
29
|
+
* const key = PolicyCache.buildKey({ agentId, trustTier, actionType, riskLevel });
|
|
30
|
+
* const cached = cache.get(key);
|
|
31
|
+
* if (cached !== undefined) {
|
|
32
|
+
* return cached; // fast path
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* const result = expensivePolicyEvaluation(...);
|
|
36
|
+
* cache.set(key, result);
|
|
37
|
+
* return result;
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class PolicyCache<T = unknown> {
|
|
41
|
+
private config;
|
|
42
|
+
private entries;
|
|
43
|
+
private hitCount;
|
|
44
|
+
private missCount;
|
|
45
|
+
private evictionCount;
|
|
46
|
+
private invalidationCount;
|
|
47
|
+
constructor(config?: PolicyCacheConfig);
|
|
48
|
+
/**
|
|
49
|
+
* Build a deterministic cache key from the policy evaluation context.
|
|
50
|
+
* Uses SHA-256 truncated to 16 hex chars for compact, collision-resistant keys.
|
|
51
|
+
*/
|
|
52
|
+
static buildKey(input: PolicyCacheKeyInput): string;
|
|
53
|
+
/**
|
|
54
|
+
* Retrieve a cached result by key.
|
|
55
|
+
* Returns `undefined` on miss or if the entry has expired.
|
|
56
|
+
*/
|
|
57
|
+
get(key: string): T | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Store a result in the cache.
|
|
60
|
+
* If the cache is at capacity, the least-recently-used entry is evicted.
|
|
61
|
+
*/
|
|
62
|
+
set(key: string, value: T): void;
|
|
63
|
+
/**
|
|
64
|
+
* Check whether a key exists and is not expired (without counting as a hit/miss).
|
|
65
|
+
*/
|
|
66
|
+
has(key: string): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Invalidate the entire cache. Called when policies are updated.
|
|
69
|
+
*/
|
|
70
|
+
invalidate(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Invalidate a single key.
|
|
73
|
+
*/
|
|
74
|
+
invalidateKey(key: string): void;
|
|
75
|
+
/**
|
|
76
|
+
* Return cache statistics for monitoring.
|
|
77
|
+
*/
|
|
78
|
+
stats(): PolicyCacheStats;
|
|
79
|
+
/**
|
|
80
|
+
* Reset all statistics counters (entries are preserved).
|
|
81
|
+
*/
|
|
82
|
+
resetStats(): void;
|
|
83
|
+
/**
|
|
84
|
+
* Clear all entries and reset all statistics.
|
|
85
|
+
*/
|
|
86
|
+
clear(): void;
|
|
87
|
+
/**
|
|
88
|
+
* Current number of entries (including potentially expired ones not yet pruned).
|
|
89
|
+
*/
|
|
90
|
+
get size(): number;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=policy-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-cache.d.ts","sourceRoot":"","sources":["../../src/enforce/policy-cache.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAWD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAgBD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,OAAO;IAClC,OAAO,CAAC,MAAM,CAA8B;IAI5C,OAAO,CAAC,OAAO,CAAoC;IAEnD,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAAK;gBAElB,MAAM,CAAC,EAAE,iBAAiB;IAQtC;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM;IASnD;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAqB/B;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAqBhC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAUzB;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,KAAK,IAAI,gBAAgB;IAazB;;OAEG;IACH,UAAU,IAAI,IAAI;IAOlB;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright 2024-2026 Vorion LLC
|
|
3
|
+
/**
|
|
4
|
+
* Policy Rule Cache
|
|
5
|
+
*
|
|
6
|
+
* LRU cache for policy evaluation results. Avoids re-evaluating identical
|
|
7
|
+
* enforcement contexts when the same (agentId + trustTier + actionType + riskLevel)
|
|
8
|
+
* combination is seen repeatedly within the TTL window.
|
|
9
|
+
*
|
|
10
|
+
* At 50K agents with frequent heartbeats, the enforcement hot path can see
|
|
11
|
+
* millions of identical contexts per minute. Caching policy results cuts
|
|
12
|
+
* the p99 enforcement latency significantly.
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - LRU eviction with configurable max size (default: 10,000 entries)
|
|
16
|
+
* - TTL-based expiry (default: 60 seconds)
|
|
17
|
+
* - Bulk invalidation on policy update
|
|
18
|
+
* - Hit/miss/eviction statistics for monitoring
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
import { createHash } from 'crypto';
|
|
23
|
+
const DEFAULTS = {
|
|
24
|
+
maxSize: 10_000,
|
|
25
|
+
ttlMs: 60_000,
|
|
26
|
+
};
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// POLICY CACHE
|
|
29
|
+
// =============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* LRU + TTL cache for policy evaluation results.
|
|
32
|
+
*
|
|
33
|
+
* Usage:
|
|
34
|
+
* ```ts
|
|
35
|
+
* const cache = new PolicyCache({ maxSize: 10_000, ttlMs: 60_000 });
|
|
36
|
+
*
|
|
37
|
+
* const key = PolicyCache.buildKey({ agentId, trustTier, actionType, riskLevel });
|
|
38
|
+
* const cached = cache.get(key);
|
|
39
|
+
* if (cached !== undefined) {
|
|
40
|
+
* return cached; // fast path
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* const result = expensivePolicyEvaluation(...);
|
|
44
|
+
* cache.set(key, result);
|
|
45
|
+
* return result;
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export class PolicyCache {
|
|
49
|
+
config;
|
|
50
|
+
// Map preserves insertion order — we use this for LRU.
|
|
51
|
+
// Most-recently-used entries are re-inserted (moved to end).
|
|
52
|
+
entries = new Map();
|
|
53
|
+
hitCount = 0;
|
|
54
|
+
missCount = 0;
|
|
55
|
+
evictionCount = 0;
|
|
56
|
+
invalidationCount = 0;
|
|
57
|
+
constructor(config) {
|
|
58
|
+
this.config = { ...DEFAULTS, ...config };
|
|
59
|
+
}
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Static helpers
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
/**
|
|
64
|
+
* Build a deterministic cache key from the policy evaluation context.
|
|
65
|
+
* Uses SHA-256 truncated to 16 hex chars for compact, collision-resistant keys.
|
|
66
|
+
*/
|
|
67
|
+
static buildKey(input) {
|
|
68
|
+
const raw = `${input.agentId}|${input.trustTier}|${input.actionType}|${input.riskLevel}`;
|
|
69
|
+
return createHash('sha256').update(raw).digest('hex').slice(0, 32);
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Public API
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
/**
|
|
75
|
+
* Retrieve a cached result by key.
|
|
76
|
+
* Returns `undefined` on miss or if the entry has expired.
|
|
77
|
+
*/
|
|
78
|
+
get(key) {
|
|
79
|
+
const entry = this.entries.get(key);
|
|
80
|
+
if (!entry) {
|
|
81
|
+
this.missCount++;
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
// TTL check
|
|
85
|
+
if (Date.now() > entry.expiresAt) {
|
|
86
|
+
this.entries.delete(key);
|
|
87
|
+
this.missCount++;
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
// LRU promotion: delete and re-insert to move to end of Map iteration order
|
|
91
|
+
this.entries.delete(key);
|
|
92
|
+
this.entries.set(key, entry);
|
|
93
|
+
this.hitCount++;
|
|
94
|
+
return entry.value;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Store a result in the cache.
|
|
98
|
+
* If the cache is at capacity, the least-recently-used entry is evicted.
|
|
99
|
+
*/
|
|
100
|
+
set(key, value) {
|
|
101
|
+
// If key already exists, delete first to update position
|
|
102
|
+
if (this.entries.has(key)) {
|
|
103
|
+
this.entries.delete(key);
|
|
104
|
+
}
|
|
105
|
+
// Evict LRU if at capacity
|
|
106
|
+
while (this.entries.size >= this.config.maxSize) {
|
|
107
|
+
const oldest = this.entries.keys().next();
|
|
108
|
+
if (oldest.done)
|
|
109
|
+
break;
|
|
110
|
+
this.entries.delete(oldest.value);
|
|
111
|
+
this.evictionCount++;
|
|
112
|
+
}
|
|
113
|
+
this.entries.set(key, {
|
|
114
|
+
key,
|
|
115
|
+
value,
|
|
116
|
+
expiresAt: Date.now() + this.config.ttlMs,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check whether a key exists and is not expired (without counting as a hit/miss).
|
|
121
|
+
*/
|
|
122
|
+
has(key) {
|
|
123
|
+
const entry = this.entries.get(key);
|
|
124
|
+
if (!entry)
|
|
125
|
+
return false;
|
|
126
|
+
if (Date.now() > entry.expiresAt) {
|
|
127
|
+
this.entries.delete(key);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Invalidate the entire cache. Called when policies are updated.
|
|
134
|
+
*/
|
|
135
|
+
invalidate() {
|
|
136
|
+
this.entries.clear();
|
|
137
|
+
this.invalidationCount++;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Invalidate a single key.
|
|
141
|
+
*/
|
|
142
|
+
invalidateKey(key) {
|
|
143
|
+
this.entries.delete(key);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Return cache statistics for monitoring.
|
|
147
|
+
*/
|
|
148
|
+
stats() {
|
|
149
|
+
const total = this.hitCount + this.missCount;
|
|
150
|
+
return {
|
|
151
|
+
size: this.entries.size,
|
|
152
|
+
maxSize: this.config.maxSize,
|
|
153
|
+
hitCount: this.hitCount,
|
|
154
|
+
missCount: this.missCount,
|
|
155
|
+
evictionCount: this.evictionCount,
|
|
156
|
+
hitRate: total > 0 ? this.hitCount / total : 0,
|
|
157
|
+
invalidationCount: this.invalidationCount,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Reset all statistics counters (entries are preserved).
|
|
162
|
+
*/
|
|
163
|
+
resetStats() {
|
|
164
|
+
this.hitCount = 0;
|
|
165
|
+
this.missCount = 0;
|
|
166
|
+
this.evictionCount = 0;
|
|
167
|
+
this.invalidationCount = 0;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Clear all entries and reset all statistics.
|
|
171
|
+
*/
|
|
172
|
+
clear() {
|
|
173
|
+
this.entries.clear();
|
|
174
|
+
this.hitCount = 0;
|
|
175
|
+
this.missCount = 0;
|
|
176
|
+
this.evictionCount = 0;
|
|
177
|
+
this.invalidationCount = 0;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Current number of entries (including potentially expired ones not yet pruned).
|
|
181
|
+
*/
|
|
182
|
+
get size() {
|
|
183
|
+
return this.entries.size;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=policy-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-cache.js","sourceRoot":"","sources":["../../src/enforce/policy-cache.ts"],"names":[],"mappings":"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"}
|