ai-shield-core 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/dist/audit/logger.d.ts +40 -0
- package/dist/audit/logger.d.ts.map +1 -0
- package/dist/audit/logger.js +100 -0
- package/dist/audit/logger.js.map +1 -0
- package/dist/audit/types.d.ts +12 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +3 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cache/lru.d.ts +27 -0
- package/dist/cache/lru.d.ts.map +1 -0
- package/dist/cache/lru.js +74 -0
- package/dist/cache/lru.js.map +1 -0
- package/dist/cost/anomaly.d.ts +10 -0
- package/dist/cost/anomaly.d.ts.map +1 -0
- package/dist/cost/anomaly.js +42 -0
- package/dist/cost/anomaly.js.map +1 -0
- package/dist/cost/pricing.d.ts +7 -0
- package/dist/cost/pricing.d.ts.map +1 -0
- package/dist/cost/pricing.js +51 -0
- package/dist/cost/pricing.js.map +1 -0
- package/dist/cost/tracker.d.ts +24 -0
- package/dist/cost/tracker.d.ts.map +1 -0
- package/dist/cost/tracker.js +136 -0
- package/dist/cost/tracker.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/engine.d.ts +36 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +127 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/tools.d.ts +25 -0
- package/dist/policy/tools.d.ts.map +1 -0
- package/dist/policy/tools.js +158 -0
- package/dist/policy/tools.js.map +1 -0
- package/dist/scanner/canary.d.ts +9 -0
- package/dist/scanner/canary.d.ts.map +1 -0
- package/dist/scanner/canary.js +19 -0
- package/dist/scanner/canary.js.map +1 -0
- package/dist/scanner/chain.d.ts +17 -0
- package/dist/scanner/chain.d.ts.map +1 -0
- package/dist/scanner/chain.js +69 -0
- package/dist/scanner/chain.js.map +1 -0
- package/dist/scanner/heuristic.d.ts +28 -0
- package/dist/scanner/heuristic.d.ts.map +1 -0
- package/dist/scanner/heuristic.js +375 -0
- package/dist/scanner/heuristic.js.map +1 -0
- package/dist/scanner/pii.d.ts +17 -0
- package/dist/scanner/pii.d.ts.map +1 -0
- package/dist/scanner/pii.js +255 -0
- package/dist/scanner/pii.js.map +1 -0
- package/dist/shield.d.ts +31 -0
- package/dist/shield.d.ts.map +1 -0
- package/dist/shield.js +184 -0
- package/dist/shield.js.map +1 -0
- package/dist/types.d.ts +182 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +27 -0
- package/src/audit/logger.ts +135 -0
- package/src/audit/schema.sql +51 -0
- package/src/audit/types.ts +16 -0
- package/src/cache/lru.ts +93 -0
- package/src/cost/anomaly.ts +57 -0
- package/src/cost/pricing.ts +58 -0
- package/src/cost/tracker.ts +182 -0
- package/src/index.ts +91 -0
- package/src/policy/engine.ts +163 -0
- package/src/policy/tools.ts +189 -0
- package/src/scanner/canary.ts +30 -0
- package/src/scanner/chain.ts +88 -0
- package/src/scanner/heuristic.ts +427 -0
- package/src/scanner/pii.ts +313 -0
- package/src/shield.ts +228 -0
- package/src/types.ts +242 -0
- package/tsconfig.json +8 -0
package/dist/shield.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ShieldConfig, ScanResult, ScanContext } from "./types.js";
|
|
2
|
+
import { PolicyEngine } from "./policy/engine.js";
|
|
3
|
+
export declare class AIShield {
|
|
4
|
+
private chain;
|
|
5
|
+
private policyEngine;
|
|
6
|
+
private costTracker;
|
|
7
|
+
private auditLogger;
|
|
8
|
+
private scanCache;
|
|
9
|
+
private config;
|
|
10
|
+
constructor(config?: ShieldConfig);
|
|
11
|
+
/** Scan input text — the main API */
|
|
12
|
+
scan(input: string, context?: ScanContext): Promise<ScanResult>;
|
|
13
|
+
/** Check cost budget before making an LLM call */
|
|
14
|
+
checkBudget(entityId: string, model: string, estimatedInputTokens: number, estimatedOutputTokens?: number): Promise<import("./types.js").BudgetCheckResult>;
|
|
15
|
+
/** Record cost after receiving LLM response */
|
|
16
|
+
recordCost(entityId: string, model: string, inputTokens: number, outputTokens: number): Promise<import("./types.js").CostRecord | null>;
|
|
17
|
+
/** Get current spend for an entity */
|
|
18
|
+
getCurrentSpend(entityId: string): Promise<number>;
|
|
19
|
+
/** Get the policy engine */
|
|
20
|
+
getPolicy(): PolicyEngine;
|
|
21
|
+
/** Clear the scan cache */
|
|
22
|
+
clearCache(): void;
|
|
23
|
+
/** Get cache stats */
|
|
24
|
+
get cacheSize(): number;
|
|
25
|
+
/** Graceful shutdown */
|
|
26
|
+
close(): Promise<void>;
|
|
27
|
+
private buildCacheKey;
|
|
28
|
+
private setupScanners;
|
|
29
|
+
private setupAudit;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=shield.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shield.d.ts","sourceRoot":"","sources":["../src/shield.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAKpF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAUlD,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,GAAE,YAAiB;IAyBrC,qCAAqC;IAC/B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IA+BzE,kDAAkD;IAC5C,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,oBAAoB,EAAE,MAAM,EAC5B,qBAAqB,CAAC,EAAE,MAAM;IAahC,+CAA+C;IACzC,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM;IAMtB,sCAAsC;IAChC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKxD,4BAA4B;IAC5B,SAAS,IAAI,YAAY;IAIzB,2BAA2B;IAC3B,UAAU,IAAI,IAAI;IAIlB,sBAAsB;IACtB,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,wBAAwB;IAClB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;IAkDrB,OAAO,CAAC,UAAU;CA2BnB"}
|
package/dist/shield.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AIShield = void 0;
|
|
4
|
+
const chain_js_1 = require("./scanner/chain.js");
|
|
5
|
+
const heuristic_js_1 = require("./scanner/heuristic.js");
|
|
6
|
+
const pii_js_1 = require("./scanner/pii.js");
|
|
7
|
+
const tools_js_1 = require("./policy/tools.js");
|
|
8
|
+
const engine_js_1 = require("./policy/engine.js");
|
|
9
|
+
const tracker_js_1 = require("./cost/tracker.js");
|
|
10
|
+
const logger_js_1 = require("./audit/logger.js");
|
|
11
|
+
const lru_js_1 = require("./cache/lru.js");
|
|
12
|
+
// ============================================================
|
|
13
|
+
// AIShield — Main class, single entry point
|
|
14
|
+
// ============================================================
|
|
15
|
+
class AIShield {
|
|
16
|
+
chain;
|
|
17
|
+
policyEngine;
|
|
18
|
+
costTracker;
|
|
19
|
+
auditLogger;
|
|
20
|
+
scanCache;
|
|
21
|
+
config;
|
|
22
|
+
constructor(config = {}) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
this.policyEngine = new engine_js_1.PolicyEngine(config.preset ?? "public_website");
|
|
25
|
+
this.chain = new chain_js_1.ScannerChain({ earlyExit: true });
|
|
26
|
+
// Build scanner chain based on config
|
|
27
|
+
this.setupScanners(config);
|
|
28
|
+
// Cost tracker (optional, needs Redis for distributed use)
|
|
29
|
+
this.costTracker = config.cost?.enabled !== false && config.cost?.budgets
|
|
30
|
+
? new tracker_js_1.CostTracker(config.cost.budgets)
|
|
31
|
+
: null;
|
|
32
|
+
// Audit logger (optional)
|
|
33
|
+
this.auditLogger = this.setupAudit(config);
|
|
34
|
+
// Scan cache (enabled when cache config is provided)
|
|
35
|
+
this.scanCache = config.cache && config.cache.enabled !== false
|
|
36
|
+
? new lru_js_1.ScanLRUCache({
|
|
37
|
+
maxSize: config.cache.maxSize,
|
|
38
|
+
ttlMs: config.cache.ttlMs,
|
|
39
|
+
})
|
|
40
|
+
: null;
|
|
41
|
+
}
|
|
42
|
+
/** Scan input text — the main API */
|
|
43
|
+
async scan(input, context = {}) {
|
|
44
|
+
// Apply preset if not set in context
|
|
45
|
+
if (!context.preset) {
|
|
46
|
+
context.preset = this.config.preset ?? "public_website";
|
|
47
|
+
}
|
|
48
|
+
// Check cache
|
|
49
|
+
if (this.scanCache) {
|
|
50
|
+
const cacheKey = this.buildCacheKey(input, context);
|
|
51
|
+
const cached = this.scanCache.get(cacheKey);
|
|
52
|
+
if (cached) {
|
|
53
|
+
return { ...cached, meta: { ...cached.meta, cached: true } };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const result = await this.chain.run(input, context);
|
|
57
|
+
// Store in cache
|
|
58
|
+
if (this.scanCache) {
|
|
59
|
+
const cacheKey = this.buildCacheKey(input, context);
|
|
60
|
+
this.scanCache.set(cacheKey, result);
|
|
61
|
+
}
|
|
62
|
+
// Log to audit if enabled
|
|
63
|
+
if (this.auditLogger) {
|
|
64
|
+
void this.auditLogger.log(input, result, context);
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
/** Check cost budget before making an LLM call */
|
|
69
|
+
async checkBudget(entityId, model, estimatedInputTokens, estimatedOutputTokens) {
|
|
70
|
+
if (!this.costTracker) {
|
|
71
|
+
return { allowed: true, currentSpend: 0, remainingBudget: Infinity };
|
|
72
|
+
}
|
|
73
|
+
return this.costTracker.checkBudget(entityId, model, estimatedInputTokens, estimatedOutputTokens);
|
|
74
|
+
}
|
|
75
|
+
/** Record cost after receiving LLM response */
|
|
76
|
+
async recordCost(entityId, model, inputTokens, outputTokens) {
|
|
77
|
+
if (!this.costTracker)
|
|
78
|
+
return null;
|
|
79
|
+
return this.costTracker.recordCost(entityId, model, inputTokens, outputTokens);
|
|
80
|
+
}
|
|
81
|
+
/** Get current spend for an entity */
|
|
82
|
+
async getCurrentSpend(entityId) {
|
|
83
|
+
if (!this.costTracker)
|
|
84
|
+
return 0;
|
|
85
|
+
return this.costTracker.getCurrentSpend(entityId);
|
|
86
|
+
}
|
|
87
|
+
/** Get the policy engine */
|
|
88
|
+
getPolicy() {
|
|
89
|
+
return this.policyEngine;
|
|
90
|
+
}
|
|
91
|
+
/** Clear the scan cache */
|
|
92
|
+
clearCache() {
|
|
93
|
+
this.scanCache?.clear();
|
|
94
|
+
}
|
|
95
|
+
/** Get cache stats */
|
|
96
|
+
get cacheSize() {
|
|
97
|
+
return this.scanCache?.size ?? 0;
|
|
98
|
+
}
|
|
99
|
+
/** Graceful shutdown */
|
|
100
|
+
async close() {
|
|
101
|
+
this.scanCache?.clear();
|
|
102
|
+
if (this.auditLogger) {
|
|
103
|
+
await this.auditLogger.close();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// --- Private setup ---
|
|
107
|
+
buildCacheKey(input, context) {
|
|
108
|
+
// Include preset + tool names in key since they affect scan results
|
|
109
|
+
const parts = [context.preset ?? "default"];
|
|
110
|
+
if (context.tools?.length) {
|
|
111
|
+
parts.push(context.tools.map((t) => t.name).sort().join(","));
|
|
112
|
+
}
|
|
113
|
+
parts.push(input);
|
|
114
|
+
return parts.join("\x00");
|
|
115
|
+
}
|
|
116
|
+
setupScanners(config) {
|
|
117
|
+
// 1. Heuristic injection scanner (always on unless explicitly disabled)
|
|
118
|
+
if (config.injection?.enabled !== false) {
|
|
119
|
+
const preset = this.policyEngine.getPreset();
|
|
120
|
+
this.chain.add(new heuristic_js_1.HeuristicScanner({
|
|
121
|
+
strictness: config.injection?.strictness ?? "medium",
|
|
122
|
+
threshold: config.injection?.threshold ?? preset.injection.threshold,
|
|
123
|
+
customPatterns: config.injection?.customPatterns?.map((pattern, i) => ({
|
|
124
|
+
id: `CUSTOM-${i + 1}`,
|
|
125
|
+
category: "instruction_override",
|
|
126
|
+
pattern,
|
|
127
|
+
weight: 0.25,
|
|
128
|
+
description: `Custom pattern #${i + 1}`,
|
|
129
|
+
})),
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
// 2. PII scanner
|
|
133
|
+
if (config.pii?.enabled !== false) {
|
|
134
|
+
this.chain.add(new pii_js_1.PIIScanner({
|
|
135
|
+
action: config.pii?.action ?? this.policyEngine.getPIIAction(),
|
|
136
|
+
locale: config.pii?.locale,
|
|
137
|
+
types: config.pii?.types,
|
|
138
|
+
allowedTypes: config.pii?.allowedTypes,
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
// 3. Tool policy scanner
|
|
142
|
+
if (config.tools?.enabled !== false && config.tools?.policies) {
|
|
143
|
+
const toolPolicy = {
|
|
144
|
+
permissions: config.tools.policies,
|
|
145
|
+
global: {
|
|
146
|
+
dangerousPatterns: config.tools.globalDangerousPatterns ??
|
|
147
|
+
this.policyEngine.getDangerousToolPatterns(),
|
|
148
|
+
maxToolChainDepth: config.tools.maxToolChainDepth ??
|
|
149
|
+
this.policyEngine.getMaxToolChainDepth(),
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
this.chain.add(new tools_js_1.ToolPolicyScanner(toolPolicy, config.tools.manifestPins));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
setupAudit(config) {
|
|
156
|
+
if (config.audit?.enabled === false)
|
|
157
|
+
return null;
|
|
158
|
+
let store;
|
|
159
|
+
switch (config.audit?.store) {
|
|
160
|
+
case "console":
|
|
161
|
+
store = new logger_js_1.ConsoleAuditStore();
|
|
162
|
+
break;
|
|
163
|
+
case "postgresql":
|
|
164
|
+
// PostgreSQL store would be imported separately to keep core lightweight
|
|
165
|
+
// For now, fall through to console
|
|
166
|
+
store = new logger_js_1.ConsoleAuditStore();
|
|
167
|
+
break;
|
|
168
|
+
case "memory":
|
|
169
|
+
default:
|
|
170
|
+
// If no store configured and audit not explicitly enabled, skip
|
|
171
|
+
if (!config.audit?.store && config.audit?.enabled !== true)
|
|
172
|
+
return null;
|
|
173
|
+
store = new logger_js_1.ConsoleAuditStore();
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
return new logger_js_1.AuditLogger({
|
|
177
|
+
store,
|
|
178
|
+
batchSize: config.audit?.batchSize,
|
|
179
|
+
flushIntervalMs: config.audit?.flushIntervalMs,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.AIShield = AIShield;
|
|
184
|
+
//# sourceMappingURL=shield.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shield.js","sourceRoot":"","sources":["../src/shield.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
export type ScanDecision = "allow" | "warn" | "block";
|
|
2
|
+
export type ViolationType = "prompt_injection" | "pii_detected" | "tool_denied" | "tool_rate_limit" | "budget_exceeded" | "content_policy" | "manifest_drift";
|
|
3
|
+
export interface Violation {
|
|
4
|
+
type: ViolationType;
|
|
5
|
+
scanner: string;
|
|
6
|
+
score: number;
|
|
7
|
+
threshold: number;
|
|
8
|
+
message: string;
|
|
9
|
+
detail?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ScanResult {
|
|
12
|
+
safe: boolean;
|
|
13
|
+
decision: ScanDecision;
|
|
14
|
+
sanitized: string;
|
|
15
|
+
violations: Violation[];
|
|
16
|
+
meta: {
|
|
17
|
+
scanDurationMs: number;
|
|
18
|
+
scannersRun: string[];
|
|
19
|
+
cached: boolean;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface ScannerResult {
|
|
23
|
+
decision: ScanDecision;
|
|
24
|
+
violations: Violation[];
|
|
25
|
+
sanitized?: string;
|
|
26
|
+
durationMs: number;
|
|
27
|
+
}
|
|
28
|
+
export interface Scanner {
|
|
29
|
+
name: string;
|
|
30
|
+
scan(input: string, context: ScanContext): Promise<ScannerResult>;
|
|
31
|
+
}
|
|
32
|
+
export interface ScanContext {
|
|
33
|
+
agentId?: string;
|
|
34
|
+
sessionId?: string;
|
|
35
|
+
userId?: string;
|
|
36
|
+
userType?: "lead" | "agency" | "customer" | "internal";
|
|
37
|
+
locale?: string;
|
|
38
|
+
preset?: PresetName;
|
|
39
|
+
tools?: ToolCall[];
|
|
40
|
+
}
|
|
41
|
+
export type PresetName = "public_website" | "internal_support" | "ops_agent";
|
|
42
|
+
export type PIIType = "email" | "phone" | "iban" | "credit_card" | "german_tax_id" | "german_personal_id" | "german_social_security" | "ip_address" | "url_with_credentials";
|
|
43
|
+
export type PIIAction = "block" | "mask" | "tokenize" | "allow";
|
|
44
|
+
export interface PIIEntity {
|
|
45
|
+
type: PIIType;
|
|
46
|
+
value: string;
|
|
47
|
+
start: number;
|
|
48
|
+
end: number;
|
|
49
|
+
confidence: number;
|
|
50
|
+
}
|
|
51
|
+
export interface ToolCall {
|
|
52
|
+
name: string;
|
|
53
|
+
arguments?: Record<string, unknown>;
|
|
54
|
+
serverId?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface ToolPermissions {
|
|
57
|
+
allowed: string[];
|
|
58
|
+
denied?: string[];
|
|
59
|
+
maxCallsPerMinute?: number;
|
|
60
|
+
maxCallsPerSession?: number;
|
|
61
|
+
requireApproval?: string[];
|
|
62
|
+
}
|
|
63
|
+
export interface ToolPolicy {
|
|
64
|
+
permissions: Record<string, ToolPermissions>;
|
|
65
|
+
global?: {
|
|
66
|
+
dangerousPatterns?: string[];
|
|
67
|
+
readOnlyMode?: boolean;
|
|
68
|
+
maxToolChainDepth?: number;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export interface ToolManifestPin {
|
|
72
|
+
serverId: string;
|
|
73
|
+
toolsHash: string;
|
|
74
|
+
toolCount: number;
|
|
75
|
+
knownTools: string[];
|
|
76
|
+
pinnedAt: Date;
|
|
77
|
+
}
|
|
78
|
+
export type BudgetPeriod = "hourly" | "daily" | "monthly";
|
|
79
|
+
export interface BudgetConfig {
|
|
80
|
+
softLimit: number;
|
|
81
|
+
hardLimit: number;
|
|
82
|
+
period: BudgetPeriod;
|
|
83
|
+
}
|
|
84
|
+
export interface CostEstimate {
|
|
85
|
+
inputTokens: number;
|
|
86
|
+
outputTokens: number;
|
|
87
|
+
estimatedCost: number;
|
|
88
|
+
model: string;
|
|
89
|
+
}
|
|
90
|
+
export interface CostRecord {
|
|
91
|
+
entityId: string;
|
|
92
|
+
model: string;
|
|
93
|
+
inputTokens: number;
|
|
94
|
+
outputTokens: number;
|
|
95
|
+
cost: number;
|
|
96
|
+
timestamp: Date;
|
|
97
|
+
}
|
|
98
|
+
export interface BudgetCheckResult {
|
|
99
|
+
allowed: boolean;
|
|
100
|
+
currentSpend: number;
|
|
101
|
+
remainingBudget: number;
|
|
102
|
+
warning?: string;
|
|
103
|
+
}
|
|
104
|
+
export interface AuditRecord {
|
|
105
|
+
id: string;
|
|
106
|
+
timestamp: Date;
|
|
107
|
+
sessionId?: string;
|
|
108
|
+
agentId?: string;
|
|
109
|
+
userIdHash?: string;
|
|
110
|
+
requestType: "chat" | "tool_call" | "agent_to_agent";
|
|
111
|
+
inputHash: string;
|
|
112
|
+
inputTokenCount?: number;
|
|
113
|
+
model?: string;
|
|
114
|
+
securityDecision: ScanDecision;
|
|
115
|
+
securityReason?: string;
|
|
116
|
+
violations: Violation[];
|
|
117
|
+
scanDurationMs: number;
|
|
118
|
+
outputTokenCount?: number;
|
|
119
|
+
toolsCalled?: string[];
|
|
120
|
+
costUsd?: number;
|
|
121
|
+
}
|
|
122
|
+
export interface InjectionConfig {
|
|
123
|
+
enabled?: boolean;
|
|
124
|
+
strictness?: "low" | "medium" | "high";
|
|
125
|
+
action?: "block" | "warn" | "flag";
|
|
126
|
+
threshold?: number;
|
|
127
|
+
customPatterns?: RegExp[];
|
|
128
|
+
}
|
|
129
|
+
export interface PIIConfig {
|
|
130
|
+
enabled?: boolean;
|
|
131
|
+
action?: PIIAction;
|
|
132
|
+
locale?: string;
|
|
133
|
+
types?: Partial<Record<PIIType, PIIAction>>;
|
|
134
|
+
allowedTypes?: PIIType[];
|
|
135
|
+
}
|
|
136
|
+
export interface CostConfig {
|
|
137
|
+
enabled?: boolean;
|
|
138
|
+
budgets?: Record<string, BudgetConfig>;
|
|
139
|
+
pricing?: Record<string, {
|
|
140
|
+
inputPer1M: number;
|
|
141
|
+
outputPer1M: number;
|
|
142
|
+
}>;
|
|
143
|
+
redisUrl?: string;
|
|
144
|
+
}
|
|
145
|
+
export interface AuditConfig {
|
|
146
|
+
enabled?: boolean;
|
|
147
|
+
store?: "postgresql" | "memory" | "console";
|
|
148
|
+
connectionString?: string;
|
|
149
|
+
batchSize?: number;
|
|
150
|
+
flushIntervalMs?: number;
|
|
151
|
+
retentionDays?: number;
|
|
152
|
+
}
|
|
153
|
+
export interface ToolConfig {
|
|
154
|
+
enabled?: boolean;
|
|
155
|
+
policies?: Record<string, ToolPermissions>;
|
|
156
|
+
globalDangerousPatterns?: string[];
|
|
157
|
+
maxToolChainDepth?: number;
|
|
158
|
+
manifestPins?: ToolManifestPin[];
|
|
159
|
+
}
|
|
160
|
+
export interface CacheConfig {
|
|
161
|
+
/** Disable caching (default: enabled when cache config is provided) */
|
|
162
|
+
enabled?: boolean;
|
|
163
|
+
/** Maximum cached entries (default: 1000) */
|
|
164
|
+
maxSize?: number;
|
|
165
|
+
/** TTL in milliseconds (default: 300_000 = 5 minutes) */
|
|
166
|
+
ttlMs?: number;
|
|
167
|
+
}
|
|
168
|
+
export interface ShieldConfig {
|
|
169
|
+
injection?: InjectionConfig;
|
|
170
|
+
pii?: PIIConfig;
|
|
171
|
+
cost?: CostConfig;
|
|
172
|
+
audit?: AuditConfig;
|
|
173
|
+
tools?: ToolConfig;
|
|
174
|
+
cache?: CacheConfig;
|
|
175
|
+
preset?: PresetName;
|
|
176
|
+
}
|
|
177
|
+
export interface ModelPricing {
|
|
178
|
+
inputPer1M: number;
|
|
179
|
+
outputPer1M: number;
|
|
180
|
+
cachedInputPer1M?: number;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// AI Shield Core Types
|
|
4
|
+
// ============================================================
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,uBAAuB;AACvB,+DAA+D"}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai-shield-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "LLM Security SDK — Prompt Injection Detection, PII Protection, Cost Control, Audit",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"typecheck": "tsc --noEmit"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"ioredis": ">=5.0.0",
|
|
20
|
+
"pg": ">=8.0.0"
|
|
21
|
+
},
|
|
22
|
+
"peerDependenciesMeta": {
|
|
23
|
+
"ioredis": { "optional": true },
|
|
24
|
+
"pg": { "optional": true }
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT"
|
|
27
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import type { AuditRecord, ScanResult, ScanContext } from "../types.js";
|
|
4
|
+
import type { AuditStore } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// ============================================================
|
|
7
|
+
// Audit Logger — Batched writes to pluggable backend
|
|
8
|
+
// Stores metadata + hashes, NOT raw content (DSGVO)
|
|
9
|
+
// ============================================================
|
|
10
|
+
|
|
11
|
+
export interface AuditLoggerConfig {
|
|
12
|
+
store: AuditStore;
|
|
13
|
+
batchSize?: number;
|
|
14
|
+
flushIntervalMs?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class AuditLogger {
|
|
18
|
+
private store: AuditStore;
|
|
19
|
+
private buffer: AuditRecord[] = [];
|
|
20
|
+
private batchSize: number;
|
|
21
|
+
private flushTimer: ReturnType<typeof setInterval> | null = null;
|
|
22
|
+
|
|
23
|
+
constructor(config: AuditLoggerConfig) {
|
|
24
|
+
this.store = config.store;
|
|
25
|
+
this.batchSize = config.batchSize ?? 100;
|
|
26
|
+
const flushMs = config.flushIntervalMs ?? 1000;
|
|
27
|
+
|
|
28
|
+
this.flushTimer = setInterval(() => {
|
|
29
|
+
void this.flush();
|
|
30
|
+
}, flushMs);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Log a scan result */
|
|
34
|
+
async log(
|
|
35
|
+
input: string,
|
|
36
|
+
result: ScanResult,
|
|
37
|
+
context: ScanContext = {},
|
|
38
|
+
extra: {
|
|
39
|
+
model?: string;
|
|
40
|
+
outputTokenCount?: number;
|
|
41
|
+
toolsCalled?: string[];
|
|
42
|
+
costUsd?: number;
|
|
43
|
+
} = {},
|
|
44
|
+
): Promise<void> {
|
|
45
|
+
const record: AuditRecord = {
|
|
46
|
+
id: randomUUID(),
|
|
47
|
+
timestamp: new Date(),
|
|
48
|
+
sessionId: context.sessionId,
|
|
49
|
+
agentId: context.agentId,
|
|
50
|
+
userIdHash: context.userId
|
|
51
|
+
? createHash("sha256").update(context.userId).digest("hex").substring(0, 16)
|
|
52
|
+
: undefined,
|
|
53
|
+
requestType: context.tools?.length ? "tool_call" : "chat",
|
|
54
|
+
inputHash: createHash("sha256").update(input).digest("hex"),
|
|
55
|
+
inputTokenCount: Math.ceil(input.length / 4), // rough estimate
|
|
56
|
+
model: extra.model,
|
|
57
|
+
securityDecision: result.decision,
|
|
58
|
+
securityReason: result.violations.length > 0
|
|
59
|
+
? result.violations.map((v) => v.message).join("; ")
|
|
60
|
+
: undefined,
|
|
61
|
+
violations: result.violations,
|
|
62
|
+
scanDurationMs: result.meta.scanDurationMs,
|
|
63
|
+
outputTokenCount: extra.outputTokenCount,
|
|
64
|
+
toolsCalled: extra.toolsCalled,
|
|
65
|
+
costUsd: extra.costUsd,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
this.buffer.push(record);
|
|
69
|
+
|
|
70
|
+
if (this.buffer.length >= this.batchSize) {
|
|
71
|
+
await this.flush();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Flush buffered records to store */
|
|
76
|
+
async flush(): Promise<void> {
|
|
77
|
+
if (this.buffer.length === 0) return;
|
|
78
|
+
|
|
79
|
+
const batch = this.buffer.splice(0);
|
|
80
|
+
await this.store.writeBatch(batch);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Close the logger (flush + stop timer) */
|
|
84
|
+
async close(): Promise<void> {
|
|
85
|
+
if (this.flushTimer) {
|
|
86
|
+
clearInterval(this.flushTimer);
|
|
87
|
+
this.flushTimer = null;
|
|
88
|
+
}
|
|
89
|
+
await this.flush();
|
|
90
|
+
await this.store.close();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// --- Console Store (for development) ---
|
|
95
|
+
|
|
96
|
+
export class ConsoleAuditStore implements AuditStore {
|
|
97
|
+
async write(record: AuditRecord): Promise<void> {
|
|
98
|
+
this.print(record);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async writeBatch(records: AuditRecord[]): Promise<void> {
|
|
102
|
+
for (const record of records) this.print(record);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async flush(): Promise<void> { /* noop */ }
|
|
106
|
+
async close(): Promise<void> { /* noop */ }
|
|
107
|
+
|
|
108
|
+
private print(record: AuditRecord): void {
|
|
109
|
+
const icon = record.securityDecision === "block" ? "BLOCK" : record.securityDecision === "warn" ? "WARN " : "ALLOW";
|
|
110
|
+
const violations = record.violations.length > 0
|
|
111
|
+
? ` [${record.violations.map((v) => v.message).join(", ")}]`
|
|
112
|
+
: "";
|
|
113
|
+
// Using stderr to not interfere with application output
|
|
114
|
+
process.stderr.write(
|
|
115
|
+
`[AI-Shield] ${icon} | ${record.scanDurationMs.toFixed(1)}ms | agent=${record.agentId ?? "-"} | ${record.inputHash.substring(0, 8)}...${violations}\n`,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// --- Memory Store (for testing) ---
|
|
121
|
+
|
|
122
|
+
export class MemoryAuditStore implements AuditStore {
|
|
123
|
+
records: AuditRecord[] = [];
|
|
124
|
+
|
|
125
|
+
async write(record: AuditRecord): Promise<void> {
|
|
126
|
+
this.records.push(record);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async writeBatch(records: AuditRecord[]): Promise<void> {
|
|
130
|
+
this.records.push(...records);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async flush(): Promise<void> { /* noop */ }
|
|
134
|
+
async close(): Promise<void> { /* noop */ }
|
|
135
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
-- AI Shield Audit Schema
|
|
2
|
+
-- Append-only, partitioned by month for retention policies
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS ai_shield_audit (
|
|
5
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
6
|
+
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
7
|
+
session_id UUID,
|
|
8
|
+
agent_id VARCHAR(64),
|
|
9
|
+
user_id_hash VARCHAR(64),
|
|
10
|
+
request_type VARCHAR(20) NOT NULL,
|
|
11
|
+
input_hash VARCHAR(64) NOT NULL,
|
|
12
|
+
input_token_count INTEGER,
|
|
13
|
+
model VARCHAR(64),
|
|
14
|
+
security_decision VARCHAR(10) NOT NULL,
|
|
15
|
+
security_reason TEXT,
|
|
16
|
+
violations JSONB NOT NULL DEFAULT '[]',
|
|
17
|
+
scan_duration_ms INTEGER,
|
|
18
|
+
output_token_count INTEGER,
|
|
19
|
+
tools_called TEXT[],
|
|
20
|
+
cost_usd NUMERIC(10, 6),
|
|
21
|
+
created_month DATE NOT NULL DEFAULT DATE_TRUNC('month', NOW())
|
|
22
|
+
) PARTITION BY RANGE (created_month);
|
|
23
|
+
|
|
24
|
+
-- Indexes
|
|
25
|
+
CREATE INDEX IF NOT EXISTS idx_ai_shield_audit_session ON ai_shield_audit (session_id);
|
|
26
|
+
CREATE INDEX IF NOT EXISTS idx_ai_shield_audit_agent ON ai_shield_audit (agent_id, timestamp);
|
|
27
|
+
CREATE INDEX IF NOT EXISTS idx_ai_shield_audit_decision ON ai_shield_audit (security_decision) WHERE security_decision != 'allow';
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_ai_shield_audit_violations ON ai_shield_audit USING GIN (violations);
|
|
29
|
+
|
|
30
|
+
-- Cost tracking table
|
|
31
|
+
CREATE TABLE IF NOT EXISTS ai_shield_cost_records (
|
|
32
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
33
|
+
entity_id VARCHAR(128) NOT NULL,
|
|
34
|
+
model VARCHAR(64) NOT NULL,
|
|
35
|
+
input_tokens INTEGER NOT NULL,
|
|
36
|
+
output_tokens INTEGER NOT NULL,
|
|
37
|
+
cost_usd NUMERIC(10, 6) NOT NULL,
|
|
38
|
+
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_ai_shield_cost_entity ON ai_shield_cost_records (entity_id, timestamp);
|
|
42
|
+
|
|
43
|
+
-- Tool manifest pins
|
|
44
|
+
CREATE TABLE IF NOT EXISTS ai_shield_manifest_pins (
|
|
45
|
+
server_id VARCHAR(128) PRIMARY KEY,
|
|
46
|
+
tools_hash VARCHAR(64) NOT NULL,
|
|
47
|
+
tool_count INTEGER NOT NULL,
|
|
48
|
+
known_tools JSONB NOT NULL,
|
|
49
|
+
pinned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
50
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
51
|
+
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AuditRecord } from "../types.js";
|
|
2
|
+
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Audit Store Interface — pluggable backends
|
|
5
|
+
// ============================================================
|
|
6
|
+
|
|
7
|
+
export interface AuditStore {
|
|
8
|
+
/** Write a single record */
|
|
9
|
+
write(record: AuditRecord): Promise<void>;
|
|
10
|
+
/** Write a batch of records */
|
|
11
|
+
writeBatch(records: AuditRecord[]): Promise<void>;
|
|
12
|
+
/** Flush any buffered records */
|
|
13
|
+
flush(): Promise<void>;
|
|
14
|
+
/** Close the store */
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|