openclaw-observability 1.0.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/config.d.ts +60 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +140 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1114 -0
- package/dist/index.js.map +1 -0
- package/dist/redaction.d.ts +20 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +93 -0
- package/dist/redaction.js.map +1 -0
- package/dist/security/chain-detector.d.ts +37 -0
- package/dist/security/chain-detector.d.ts.map +1 -0
- package/dist/security/chain-detector.js +187 -0
- package/dist/security/chain-detector.js.map +1 -0
- package/dist/security/rules.d.ts +22 -0
- package/dist/security/rules.d.ts.map +1 -0
- package/dist/security/rules.js +479 -0
- package/dist/security/rules.js.map +1 -0
- package/dist/security/scanner.d.ts +47 -0
- package/dist/security/scanner.d.ts.map +1 -0
- package/dist/security/scanner.js +150 -0
- package/dist/security/scanner.js.map +1 -0
- package/dist/security/types.d.ts +47 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +23 -0
- package/dist/security/types.js.map +1 -0
- package/dist/storage/buffer.d.ts +64 -0
- package/dist/storage/buffer.d.ts.map +1 -0
- package/dist/storage/buffer.js +120 -0
- package/dist/storage/buffer.js.map +1 -0
- package/dist/storage/duckdb-local-writer.d.ts +26 -0
- package/dist/storage/duckdb-local-writer.d.ts.map +1 -0
- package/dist/storage/duckdb-local-writer.js +454 -0
- package/dist/storage/duckdb-local-writer.js.map +1 -0
- package/dist/storage/mysql-writer.d.ts +55 -0
- package/dist/storage/mysql-writer.d.ts.map +1 -0
- package/dist/storage/mysql-writer.js +287 -0
- package/dist/storage/mysql-writer.js.map +1 -0
- package/dist/storage/schema.d.ts +13 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +94 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/writer.d.ts +31 -0
- package/dist/storage/writer.d.ts.map +1 -0
- package/dist/storage/writer.js +7 -0
- package/dist/storage/writer.js.map +1 -0
- package/dist/types.d.ts +72 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +44 -0
- package/dist/types.js.map +1 -0
- package/dist/web/api.d.ts +115 -0
- package/dist/web/api.d.ts.map +1 -0
- package/dist/web/api.js +219 -0
- package/dist/web/api.js.map +1 -0
- package/dist/web/routes.d.ts +20 -0
- package/dist/web/routes.d.ts.map +1 -0
- package/dist/web/routes.js +175 -0
- package/dist/web/routes.js.map +1 -0
- package/dist/web/ui.d.ts +9 -0
- package/dist/web/ui.d.ts.map +1 -0
- package/dist/web/ui.js +1327 -0
- package/dist/web/ui.js.map +1 -0
- package/openclaw.plugin.json +231 -0
- package/package.json +41 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SecurityScanner — main entry point for security detection
|
|
4
|
+
* Coordinates L1 rule engine + L2 behavior chain detector
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SecurityScanner = exports.DEFAULT_SECURITY_CONFIG = void 0;
|
|
8
|
+
exports.resolveSecurityConfig = resolveSecurityConfig;
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
const types_1 = require("./types");
|
|
11
|
+
const rules_1 = require("./rules");
|
|
12
|
+
const chain_detector_1 = require("./chain-detector");
|
|
13
|
+
exports.DEFAULT_SECURITY_CONFIG = {
|
|
14
|
+
enabled: true,
|
|
15
|
+
rules: {
|
|
16
|
+
secretLeakage: true,
|
|
17
|
+
highRiskOps: true,
|
|
18
|
+
promptInjection: true,
|
|
19
|
+
chainDetection: true,
|
|
20
|
+
},
|
|
21
|
+
domainWhitelist: [],
|
|
22
|
+
};
|
|
23
|
+
function resolveSecurityConfig(raw) {
|
|
24
|
+
if (!raw)
|
|
25
|
+
return { ...exports.DEFAULT_SECURITY_CONFIG };
|
|
26
|
+
return {
|
|
27
|
+
enabled: raw.enabled ?? exports.DEFAULT_SECURITY_CONFIG.enabled,
|
|
28
|
+
rules: {
|
|
29
|
+
...exports.DEFAULT_SECURITY_CONFIG.rules,
|
|
30
|
+
...raw.rules,
|
|
31
|
+
},
|
|
32
|
+
domainWhitelist: raw.domainWhitelist ?? exports.DEFAULT_SECURITY_CONFIG.domainWhitelist,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/* ------------------------------------------------------------------ */
|
|
36
|
+
/* Scanner */
|
|
37
|
+
/* ------------------------------------------------------------------ */
|
|
38
|
+
/** Rule category -> config toggle mapping */
|
|
39
|
+
const CATEGORY_TOGGLE = {
|
|
40
|
+
[types_1.RuleCategory.SecretLeakage]: 'secretLeakage',
|
|
41
|
+
[types_1.RuleCategory.HighRiskOp]: 'highRiskOps',
|
|
42
|
+
[types_1.RuleCategory.DataExfil]: 'highRiskOps',
|
|
43
|
+
[types_1.RuleCategory.PromptInjection]: 'promptInjection',
|
|
44
|
+
[types_1.RuleCategory.SkillAnomaly]: 'highRiskOps',
|
|
45
|
+
};
|
|
46
|
+
class SecurityScanner {
|
|
47
|
+
rules;
|
|
48
|
+
chainDetector;
|
|
49
|
+
config;
|
|
50
|
+
/** Runtime context — passed to each rule's detect method */
|
|
51
|
+
ruleCtx;
|
|
52
|
+
/** Cumulative statistics */
|
|
53
|
+
stats = {
|
|
54
|
+
scanned: 0,
|
|
55
|
+
alertsGenerated: 0,
|
|
56
|
+
};
|
|
57
|
+
constructor(config) {
|
|
58
|
+
this.config = config;
|
|
59
|
+
// Filter rules based on config
|
|
60
|
+
this.rules = rules_1.ALL_RULES.filter(rule => {
|
|
61
|
+
const toggle = CATEGORY_TOGGLE[rule.category];
|
|
62
|
+
return toggle ? this.config.rules[toggle] : true;
|
|
63
|
+
});
|
|
64
|
+
this.chainDetector = new chain_detector_1.ChainDetector();
|
|
65
|
+
// Build runtime context
|
|
66
|
+
this.ruleCtx = {
|
|
67
|
+
domainWhitelist: config.domainWhitelist,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Scan a single AuditAction, return 0~N security alerts
|
|
72
|
+
*/
|
|
73
|
+
scan(action) {
|
|
74
|
+
if (!this.config.enabled)
|
|
75
|
+
return [];
|
|
76
|
+
this.stats.scanned++;
|
|
77
|
+
const alerts = [];
|
|
78
|
+
// --- L1: Rule quick scan ---
|
|
79
|
+
const text = this.extractText(action);
|
|
80
|
+
for (const rule of this.rules) {
|
|
81
|
+
if (!rule.enabled)
|
|
82
|
+
continue;
|
|
83
|
+
try {
|
|
84
|
+
const findings = rule.detect(text, action, this.ruleCtx);
|
|
85
|
+
for (const f of findings) {
|
|
86
|
+
alerts.push(this.toAlert(f, action));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
console.error(`[audit-security] Rule ${rule.id} error:`, err);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// --- L2: Behavior chain detection ---
|
|
94
|
+
if (this.config.rules.chainDetection) {
|
|
95
|
+
try {
|
|
96
|
+
const chainFindings = this.chainDetector.process(action);
|
|
97
|
+
for (const f of chainFindings) {
|
|
98
|
+
alerts.push(this.toAlert(f, action));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
console.error('[audit-security] Chain detector error:', err);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
this.stats.alertsGenerated += alerts.length;
|
|
106
|
+
return alerts;
|
|
107
|
+
}
|
|
108
|
+
/** Get statistics */
|
|
109
|
+
getStats() {
|
|
110
|
+
return { ...this.stats };
|
|
111
|
+
}
|
|
112
|
+
/** Reset */
|
|
113
|
+
reset() {
|
|
114
|
+
this.chainDetector.reset();
|
|
115
|
+
this.stats = { scanned: 0, alertsGenerated: 0 };
|
|
116
|
+
}
|
|
117
|
+
/* ---------------------------------------------------------------- */
|
|
118
|
+
/* Internal methods */
|
|
119
|
+
/* ---------------------------------------------------------------- */
|
|
120
|
+
/** Extract all scannable text from an action */
|
|
121
|
+
extractText(action) {
|
|
122
|
+
const parts = [];
|
|
123
|
+
if (action.inputParams)
|
|
124
|
+
parts.push(JSON.stringify(action.inputParams));
|
|
125
|
+
if (action.outputResult)
|
|
126
|
+
parts.push(JSON.stringify(action.outputResult));
|
|
127
|
+
return parts.join('\n');
|
|
128
|
+
}
|
|
129
|
+
/** SecurityFinding -> SecurityAlert */
|
|
130
|
+
toAlert(finding, action) {
|
|
131
|
+
return {
|
|
132
|
+
alertId: (0, crypto_1.randomUUID)(),
|
|
133
|
+
sessionId: action.sessionId,
|
|
134
|
+
actionType: action.actionType,
|
|
135
|
+
actionName: action.actionName,
|
|
136
|
+
ruleId: finding.ruleId,
|
|
137
|
+
ruleName: finding.ruleName,
|
|
138
|
+
category: finding.category,
|
|
139
|
+
severity: finding.severity,
|
|
140
|
+
finding: finding.finding,
|
|
141
|
+
context: finding.context,
|
|
142
|
+
status: 'open',
|
|
143
|
+
userId: action.userId,
|
|
144
|
+
modelName: action.modelName,
|
|
145
|
+
createdAt: new Date(),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
exports.SecurityScanner = SecurityScanner;
|
|
150
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/security/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security audit type definitions
|
|
3
|
+
*/
|
|
4
|
+
/** Security rule severity level */
|
|
5
|
+
export declare enum Severity {
|
|
6
|
+
INFO = "info",
|
|
7
|
+
WARN = "warn",
|
|
8
|
+
CRITICAL = "critical"
|
|
9
|
+
}
|
|
10
|
+
/** Security rule category */
|
|
11
|
+
export declare enum RuleCategory {
|
|
12
|
+
SecretLeakage = "secret_leakage",
|
|
13
|
+
HighRiskOp = "high_risk_operation",
|
|
14
|
+
DataExfil = "data_exfiltration",
|
|
15
|
+
PromptInjection = "prompt_injection",
|
|
16
|
+
SkillAnomaly = "skill_anomaly"
|
|
17
|
+
}
|
|
18
|
+
/** Security alert record */
|
|
19
|
+
export interface SecurityAlert {
|
|
20
|
+
alertId: string;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
actionType: string;
|
|
23
|
+
actionName: string;
|
|
24
|
+
ruleId: string;
|
|
25
|
+
ruleName: string;
|
|
26
|
+
category: RuleCategory;
|
|
27
|
+
severity: Severity;
|
|
28
|
+
/** Finding summary (redacted) */
|
|
29
|
+
finding: string;
|
|
30
|
+
/** Context (match location, surrounding text, etc.) */
|
|
31
|
+
context: string;
|
|
32
|
+
/** Processing status */
|
|
33
|
+
status: 'open' | 'acknowledged' | 'resolved' | 'false_positive';
|
|
34
|
+
userId: string;
|
|
35
|
+
modelName: string;
|
|
36
|
+
createdAt: Date;
|
|
37
|
+
}
|
|
38
|
+
/** Security scan finding (intermediate state, not yet persisted) */
|
|
39
|
+
export interface SecurityFinding {
|
|
40
|
+
ruleId: string;
|
|
41
|
+
ruleName: string;
|
|
42
|
+
category: RuleCategory;
|
|
43
|
+
severity: Severity;
|
|
44
|
+
finding: string;
|
|
45
|
+
context: string;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/security/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,mCAAmC;AACnC,oBAAY,QAAQ;IAClB,IAAI,SAAS;IACb,IAAI,SAAS;IACb,QAAQ,aAAa;CACtB;AAED,6BAA6B;AAC7B,oBAAY,YAAY;IACtB,aAAa,mBAAmB;IAChC,UAAU,wBAAwB;IAClC,SAAS,sBAAsB;IAC/B,eAAe,qBAAqB;IACpC,YAAY,kBAAkB;CAC/B;AAED,4BAA4B;AAC5B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,QAAQ,CAAC;IAEnB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,UAAU,GAAG,gBAAgB,CAAC;IAEhE,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security audit type definitions
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RuleCategory = exports.Severity = void 0;
|
|
7
|
+
/** Security rule severity level */
|
|
8
|
+
var Severity;
|
|
9
|
+
(function (Severity) {
|
|
10
|
+
Severity["INFO"] = "info";
|
|
11
|
+
Severity["WARN"] = "warn";
|
|
12
|
+
Severity["CRITICAL"] = "critical";
|
|
13
|
+
})(Severity || (exports.Severity = Severity = {}));
|
|
14
|
+
/** Security rule category */
|
|
15
|
+
var RuleCategory;
|
|
16
|
+
(function (RuleCategory) {
|
|
17
|
+
RuleCategory["SecretLeakage"] = "secret_leakage";
|
|
18
|
+
RuleCategory["HighRiskOp"] = "high_risk_operation";
|
|
19
|
+
RuleCategory["DataExfil"] = "data_exfiltration";
|
|
20
|
+
RuleCategory["PromptInjection"] = "prompt_injection";
|
|
21
|
+
RuleCategory["SkillAnomaly"] = "skill_anomaly";
|
|
22
|
+
})(RuleCategory || (exports.RuleCategory = RuleCategory = {}));
|
|
23
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/security/types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,mCAAmC;AACnC,IAAY,QAIX;AAJD,WAAY,QAAQ;IAClB,yBAAa,CAAA;IACb,yBAAa,CAAA;IACb,iCAAqB,CAAA;AACvB,CAAC,EAJW,QAAQ,wBAAR,QAAQ,QAInB;AAED,6BAA6B;AAC7B,IAAY,YAMX;AAND,WAAY,YAAY;IACtB,gDAAgC,CAAA;IAChC,kDAAkC,CAAA;IAClC,+CAA+B,CAAA;IAC/B,oDAAoC,CAAA;IACpC,8CAA8B,CAAA;AAChC,CAAC,EANW,YAAY,4BAAZ,YAAY,QAMvB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async batch buffer queue
|
|
3
|
+
* Dual-trigger flush mechanism based on count threshold + time threshold
|
|
4
|
+
*/
|
|
5
|
+
import { AuditAction, AuditSession } from '../types';
|
|
6
|
+
import { BufferConfig } from '../config';
|
|
7
|
+
/** Buffer entry type */
|
|
8
|
+
export type BufferEntry = {
|
|
9
|
+
type: 'action';
|
|
10
|
+
data: AuditAction;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'session';
|
|
13
|
+
data: AuditSession;
|
|
14
|
+
};
|
|
15
|
+
/** Flush callback function type */
|
|
16
|
+
export type FlushCallback = (entries: BufferEntry[]) => Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Async batch buffer
|
|
19
|
+
* - Triggers flush when buffer size reaches batchSize
|
|
20
|
+
* - Auto-flushes every flushIntervalMs milliseconds
|
|
21
|
+
* - Supports manual forced flush (e.g. on session end)
|
|
22
|
+
* - Discards oldest entries when buffer exceeds MAX_BUFFER_SIZE
|
|
23
|
+
*/
|
|
24
|
+
export declare class AsyncBatchBuffer {
|
|
25
|
+
private buffer;
|
|
26
|
+
private timer;
|
|
27
|
+
private flushing;
|
|
28
|
+
private flushCallback;
|
|
29
|
+
private config;
|
|
30
|
+
constructor(config: BufferConfig, flushCallback: FlushCallback);
|
|
31
|
+
/**
|
|
32
|
+
* Start periodic flush timer
|
|
33
|
+
*/
|
|
34
|
+
start(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Stop periodic flush timer
|
|
37
|
+
*/
|
|
38
|
+
stop(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Add audit record to buffer
|
|
41
|
+
*/
|
|
42
|
+
add(entry: BufferEntry): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Add audit action record
|
|
45
|
+
*/
|
|
46
|
+
addAction(action: AuditAction): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Add or update session summary record
|
|
49
|
+
*/
|
|
50
|
+
addSession(session: AuditSession): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Force flush buffer (write all entries to database)
|
|
53
|
+
*/
|
|
54
|
+
flush(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Get current buffer size
|
|
57
|
+
*/
|
|
58
|
+
get size(): number;
|
|
59
|
+
/**
|
|
60
|
+
* Graceful shutdown: stop timer and flush remaining data
|
|
61
|
+
*/
|
|
62
|
+
shutdown(): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../src/storage/buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,wBAAwB;AACxB,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC;AAE5C,mCAAmC;AACnC,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAKtE;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa;IAK9D;;OAEG;IACH,KAAK,IAAI,IAAI;IAiBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACG,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB5C;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB5B;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAIhC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Async batch buffer queue
|
|
4
|
+
* Dual-trigger flush mechanism based on count threshold + time threshold
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.AsyncBatchBuffer = void 0;
|
|
8
|
+
/** Max buffer entries (oldest entries are discarded when exceeded) */
|
|
9
|
+
const MAX_BUFFER_SIZE = 5000;
|
|
10
|
+
/**
|
|
11
|
+
* Async batch buffer
|
|
12
|
+
* - Triggers flush when buffer size reaches batchSize
|
|
13
|
+
* - Auto-flushes every flushIntervalMs milliseconds
|
|
14
|
+
* - Supports manual forced flush (e.g. on session end)
|
|
15
|
+
* - Discards oldest entries when buffer exceeds MAX_BUFFER_SIZE
|
|
16
|
+
*/
|
|
17
|
+
class AsyncBatchBuffer {
|
|
18
|
+
buffer = [];
|
|
19
|
+
timer = null;
|
|
20
|
+
flushing = false;
|
|
21
|
+
flushCallback;
|
|
22
|
+
config;
|
|
23
|
+
constructor(config, flushCallback) {
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.flushCallback = flushCallback;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start periodic flush timer
|
|
29
|
+
*/
|
|
30
|
+
start() {
|
|
31
|
+
if (this.timer) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.timer = setInterval(async () => {
|
|
35
|
+
if (this.buffer.length > 0) {
|
|
36
|
+
await this.flush();
|
|
37
|
+
}
|
|
38
|
+
}, this.config.flushIntervalMs);
|
|
39
|
+
// Ensure timer does not prevent process exit
|
|
40
|
+
if (this.timer && typeof this.timer === 'object' && 'unref' in this.timer) {
|
|
41
|
+
this.timer.unref();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Stop periodic flush timer
|
|
46
|
+
*/
|
|
47
|
+
stop() {
|
|
48
|
+
if (this.timer) {
|
|
49
|
+
clearInterval(this.timer);
|
|
50
|
+
this.timer = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Add audit record to buffer
|
|
55
|
+
*/
|
|
56
|
+
async add(entry) {
|
|
57
|
+
// Prevent unbounded buffer growth (when flush keeps failing)
|
|
58
|
+
if (this.buffer.length >= MAX_BUFFER_SIZE) {
|
|
59
|
+
const drop = Math.floor(MAX_BUFFER_SIZE * 0.1); // discard oldest 10%
|
|
60
|
+
this.buffer.splice(0, drop);
|
|
61
|
+
console.warn(`[audit-duckdb] Buffer overflow, dropped ${drop} oldest entries`);
|
|
62
|
+
}
|
|
63
|
+
this.buffer.push(entry);
|
|
64
|
+
// Threshold reached, trigger flush
|
|
65
|
+
if (this.buffer.length >= this.config.batchSize) {
|
|
66
|
+
await this.flush();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Add audit action record
|
|
71
|
+
*/
|
|
72
|
+
async addAction(action) {
|
|
73
|
+
await this.add({ type: 'action', data: action });
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Add or update session summary record
|
|
77
|
+
*/
|
|
78
|
+
async addSession(session) {
|
|
79
|
+
await this.add({ type: 'session', data: session });
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Force flush buffer (write all entries to database)
|
|
83
|
+
*/
|
|
84
|
+
async flush() {
|
|
85
|
+
// Prevent concurrent flushes
|
|
86
|
+
if (this.flushing || this.buffer.length === 0) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.flushing = true;
|
|
90
|
+
// Take all current buffer contents
|
|
91
|
+
const entries = [...this.buffer];
|
|
92
|
+
this.buffer = [];
|
|
93
|
+
try {
|
|
94
|
+
await this.flushCallback(entries);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
// On flush failure, put entries back (prepend to maintain order)
|
|
98
|
+
this.buffer = [...entries, ...this.buffer];
|
|
99
|
+
console.error('[audit-duckdb] Failed to flush buffer:', error);
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
this.flushing = false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get current buffer size
|
|
107
|
+
*/
|
|
108
|
+
get size() {
|
|
109
|
+
return this.buffer.length;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Graceful shutdown: stop timer and flush remaining data
|
|
113
|
+
*/
|
|
114
|
+
async shutdown() {
|
|
115
|
+
this.stop();
|
|
116
|
+
await this.flush();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.AsyncBatchBuffer = AsyncBatchBuffer;
|
|
120
|
+
//# sourceMappingURL=buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buffer.js","sourceRoot":"","sources":["../../src/storage/buffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DuckDB local write layer
|
|
3
|
+
* Uses embedded DuckDB (@duckdb/node-api), zero-config out of the box
|
|
4
|
+
*/
|
|
5
|
+
import { SecurityAlert } from '../security/types';
|
|
6
|
+
import { BufferEntry } from './buffer';
|
|
7
|
+
import { QueryPool, AuditWriter } from './writer';
|
|
8
|
+
import { DuckDBConfig } from '../config';
|
|
9
|
+
export declare class DuckDBLocalWriter implements AuditWriter {
|
|
10
|
+
private pool;
|
|
11
|
+
private config;
|
|
12
|
+
private initialized;
|
|
13
|
+
private initializing;
|
|
14
|
+
constructor(config: DuckDBConfig);
|
|
15
|
+
initialize(maxRetries?: number, retryDelayMs?: number): Promise<void>;
|
|
16
|
+
ensureReady(): Promise<boolean>;
|
|
17
|
+
private _doInitialize;
|
|
18
|
+
writeBatch(entries: BufferEntry[]): Promise<void>;
|
|
19
|
+
private writeActions;
|
|
20
|
+
private writeSessions;
|
|
21
|
+
writeAlerts(alerts: SecurityAlert[]): Promise<void>;
|
|
22
|
+
getPool(): QueryPool | null;
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
private _formatDate;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=duckdb-local-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duckdb-local-writer.d.ts","sourceRoot":"","sources":["../../src/storage/duckdb-local-writer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AA+NzC,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,EAAE,YAAY;IAI1B,UAAU,CAAC,UAAU,SAAI,EAAE,YAAY,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB9D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YAUvB,aAAa;IAqCrB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAWzC,YAAY;YAsBZ,aAAa;IAqErB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBzD,OAAO,IAAI,SAAS,GAAG,IAAI;IAIrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,OAAO,CAAC,WAAW;CAKpB"}
|