@elsium-ai/observe 0.9.1 → 0.10.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/compliance.d.ts +60 -0
- package/dist/compliance.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +335 -0
- package/package.json +2 -2
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { AuditEvent, AuditTrail } from './audit';
|
|
2
|
+
export type ComplianceFramework = 'eu-ai-act' | 'colorado-ai-act' | 'owasp-agentic' | 'custom';
|
|
3
|
+
export interface ComplianceReportConfig {
|
|
4
|
+
framework: ComplianceFramework;
|
|
5
|
+
systemName: string;
|
|
6
|
+
systemVersion: string;
|
|
7
|
+
reportPeriod: {
|
|
8
|
+
from: number;
|
|
9
|
+
to: number;
|
|
10
|
+
};
|
|
11
|
+
riskLevel?: 'minimal' | 'limited' | 'high' | 'unacceptable';
|
|
12
|
+
customChecks?: ComplianceCheck[];
|
|
13
|
+
}
|
|
14
|
+
export interface ComplianceCheck {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
category: string;
|
|
19
|
+
evaluate: (events: AuditEvent[]) => ComplianceCheckResult;
|
|
20
|
+
}
|
|
21
|
+
export interface ComplianceCheckResult {
|
|
22
|
+
status: 'pass' | 'fail' | 'warning' | 'not-applicable';
|
|
23
|
+
details: string;
|
|
24
|
+
evidence?: string[];
|
|
25
|
+
recommendations?: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface ComplianceReport {
|
|
28
|
+
id: string;
|
|
29
|
+
framework: ComplianceFramework;
|
|
30
|
+
systemName: string;
|
|
31
|
+
systemVersion: string;
|
|
32
|
+
generatedAt: number;
|
|
33
|
+
reportPeriod: {
|
|
34
|
+
from: number;
|
|
35
|
+
to: number;
|
|
36
|
+
};
|
|
37
|
+
summary: ComplianceSummary;
|
|
38
|
+
checks: ComplianceReportEntry[];
|
|
39
|
+
auditIntegrity: {
|
|
40
|
+
valid: boolean;
|
|
41
|
+
totalEvents: number;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export interface ComplianceSummary {
|
|
45
|
+
totalChecks: number;
|
|
46
|
+
passed: number;
|
|
47
|
+
failed: number;
|
|
48
|
+
warnings: number;
|
|
49
|
+
notApplicable: number;
|
|
50
|
+
overallStatus: 'compliant' | 'non-compliant' | 'needs-review';
|
|
51
|
+
}
|
|
52
|
+
export interface ComplianceReportEntry {
|
|
53
|
+
id: string;
|
|
54
|
+
name: string;
|
|
55
|
+
category: string;
|
|
56
|
+
result: ComplianceCheckResult;
|
|
57
|
+
}
|
|
58
|
+
export declare function generateComplianceReport(auditTrail: AuditTrail, config: ComplianceReportConfig): Promise<ComplianceReport>;
|
|
59
|
+
export declare function formatComplianceReport(report: ComplianceReport): string;
|
|
60
|
+
//# sourceMappingURL=compliance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance.d.ts","sourceRoot":"","sources":["../src/compliance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAErD,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,iBAAiB,GAAG,eAAe,GAAG,QAAQ,CAAA;AAE9F,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE,mBAAmB,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,cAAc,CAAA;IAC3D,YAAY,CAAC,EAAE,eAAe,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,qBAAqB,CAAA;CACzD;AAED,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAAA;IACtD,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,mBAAmB,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,OAAO,EAAE,iBAAiB,CAAA;IAC1B,MAAM,EAAE,qBAAqB,EAAE,CAAA;IAC/B,cAAc,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD;AAED,MAAM,WAAW,iBAAiB;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,WAAW,GAAG,eAAe,GAAG,cAAc,CAAA;CAC7D;AAED,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,qBAAqB,CAAA;CAC7B;AAqQD,wBAAsB,wBAAwB,CAC7C,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,sBAAsB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CA2C3B;AA2BD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAsCvE"}
|
package/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export { instrumentComplete, instrumentAgent } from './instrument';
|
|
|
24
24
|
export type { InstrumentableAgent } from './instrument';
|
|
25
25
|
export { createStudioExporter } from './studio-exporter';
|
|
26
26
|
export type { StudioExporter, StudioExporterConfig } from './studio-exporter';
|
|
27
|
+
export { generateComplianceReport, formatComplianceReport } from './compliance';
|
|
28
|
+
export type { ComplianceFramework, ComplianceReportConfig, ComplianceCheck, ComplianceCheckResult, ComplianceReport, ComplianceSummary, ComplianceReportEntry, } from './compliance';
|
|
27
29
|
export { toOTelSpan, toOTelExportRequest, toTraceparent, parseTraceparent, injectTraceContext, extractTraceContext, createOTLPExporter, } from './otel';
|
|
28
30
|
export type { OTelSpan, OTelSpanKind, OTelStatusCode, OTelAttribute, OTelAttributeValue, OTelEvent, OTelResource, OTelExportRequest, TraceContext, OTLPExporterConfig, } from './otel';
|
|
29
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAG1F,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACnE,YAAY,EACX,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,cAAc,GACd,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAClC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG9F,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG9D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAClF,YAAY,EACX,cAAc,EACd,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,GACV,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAG7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAGvE,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AAC1E,YAAY,EACX,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GACf,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAClE,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAGvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAG7E,OAAO,EACN,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,QAAQ,CAAA;AACf,YAAY,EACX,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,GAClB,MAAM,QAAQ,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAG1F,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACnE,YAAY,EACX,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,cAAc,GACd,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAClC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG9F,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG9D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAClF,YAAY,EACX,cAAc,EACd,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,GACV,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAG7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AACtD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAGvE,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AAC1E,YAAY,EACX,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GACf,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAClE,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAGvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAG7E,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAC/E,YAAY,EACX,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,GACrB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACN,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,QAAQ,CAAA;AACf,YAAY,EACX,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,GAClB,MAAM,QAAQ,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1585,6 +1585,339 @@ function createStudioExporter(config) {
|
|
|
1585
1585
|
}
|
|
1586
1586
|
};
|
|
1587
1587
|
}
|
|
1588
|
+
// src/compliance.ts
|
|
1589
|
+
function createOWASPAgenticChecks() {
|
|
1590
|
+
return [
|
|
1591
|
+
{
|
|
1592
|
+
id: "owasp-ag-01",
|
|
1593
|
+
name: "Prompt Injection Detection",
|
|
1594
|
+
description: "Verify security violation events exist for injection attempts",
|
|
1595
|
+
category: "Goal Hijacking",
|
|
1596
|
+
evaluate: (events) => {
|
|
1597
|
+
const violations = events.filter((e) => e.type === "security_violation" && e.data.category === "injection");
|
|
1598
|
+
return {
|
|
1599
|
+
status: "pass",
|
|
1600
|
+
details: `${violations.length} injection attempts detected and blocked`,
|
|
1601
|
+
evidence: violations.slice(0, 5).map((v) => `Event ${v.id} at ${new Date(v.timestamp).toISOString()}`)
|
|
1602
|
+
};
|
|
1603
|
+
}
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
id: "owasp-ag-02",
|
|
1607
|
+
name: "Tool Execution Audit",
|
|
1608
|
+
description: "All tool executions are logged in audit trail",
|
|
1609
|
+
category: "Tool Abuse",
|
|
1610
|
+
evaluate: (events) => {
|
|
1611
|
+
const toolEvents = events.filter((e) => e.type === "tool_execution");
|
|
1612
|
+
if (toolEvents.length === 0) {
|
|
1613
|
+
return {
|
|
1614
|
+
status: "warning",
|
|
1615
|
+
details: "No tool execution events found in audit trail",
|
|
1616
|
+
recommendations: ["Enable audit middleware for tool executions"]
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
return {
|
|
1620
|
+
status: "pass",
|
|
1621
|
+
details: `${toolEvents.length} tool executions audited`
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
},
|
|
1625
|
+
{
|
|
1626
|
+
id: "owasp-ag-03",
|
|
1627
|
+
name: "Budget Enforcement",
|
|
1628
|
+
description: "Budget alerts and limits are enforced",
|
|
1629
|
+
category: "Runaway Agents",
|
|
1630
|
+
evaluate: (events) => {
|
|
1631
|
+
const budgetAlerts = events.filter((e) => e.type === "budget_alert");
|
|
1632
|
+
const policyViolations = events.filter((e) => e.type === "policy_violation" && (e.data.policyName === "cost-limit" || e.data.policyName === "token-limit"));
|
|
1633
|
+
return {
|
|
1634
|
+
status: "pass",
|
|
1635
|
+
details: `${budgetAlerts.length} budget alerts, ${policyViolations.length} policy violations enforced`
|
|
1636
|
+
};
|
|
1637
|
+
}
|
|
1638
|
+
},
|
|
1639
|
+
{
|
|
1640
|
+
id: "owasp-ag-04",
|
|
1641
|
+
name: "Audit Trail Integrity",
|
|
1642
|
+
description: "Audit trail hash chain is intact",
|
|
1643
|
+
category: "Audit Integrity",
|
|
1644
|
+
evaluate: () => ({
|
|
1645
|
+
status: "pass",
|
|
1646
|
+
details: "Audit trail integrity verified separately via verifyIntegrity()"
|
|
1647
|
+
})
|
|
1648
|
+
},
|
|
1649
|
+
{
|
|
1650
|
+
id: "owasp-ag-05",
|
|
1651
|
+
name: "Secret Redaction Active",
|
|
1652
|
+
description: "Security middleware redacts secrets from inputs and outputs",
|
|
1653
|
+
category: "Data Exfiltration",
|
|
1654
|
+
evaluate: (events) => {
|
|
1655
|
+
const redactions = events.filter((e) => e.type === "security_violation" && (e.data.category === "secret_detected" || e.data.redacted === true));
|
|
1656
|
+
return {
|
|
1657
|
+
status: "pass",
|
|
1658
|
+
details: `${redactions.length} secret redaction events recorded`
|
|
1659
|
+
};
|
|
1660
|
+
}
|
|
1661
|
+
},
|
|
1662
|
+
{
|
|
1663
|
+
id: "owasp-ag-06",
|
|
1664
|
+
name: "Approval Gates Active",
|
|
1665
|
+
description: "High-risk operations require approval",
|
|
1666
|
+
category: "Privilege Escalation",
|
|
1667
|
+
evaluate: (events) => {
|
|
1668
|
+
const approvalRequests = events.filter((e) => e.type === "approval_request");
|
|
1669
|
+
const approvalDecisions = events.filter((e) => e.type === "approval_decision");
|
|
1670
|
+
if (approvalRequests.length === 0) {
|
|
1671
|
+
return {
|
|
1672
|
+
status: "warning",
|
|
1673
|
+
details: "No approval requests found — ensure approval gates are configured",
|
|
1674
|
+
recommendations: ["Configure approval gates for high-risk tool calls"]
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
const denied = approvalDecisions.filter((e) => e.data.approved === false);
|
|
1678
|
+
return {
|
|
1679
|
+
status: "pass",
|
|
1680
|
+
details: `${approvalRequests.length} approval requests, ${denied.length} denied`
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
];
|
|
1685
|
+
}
|
|
1686
|
+
function createEUAIActChecks(riskLevel) {
|
|
1687
|
+
return [
|
|
1688
|
+
{
|
|
1689
|
+
id: "eu-ai-01",
|
|
1690
|
+
name: "Risk Classification",
|
|
1691
|
+
description: "System risk level is documented",
|
|
1692
|
+
category: "Risk Management",
|
|
1693
|
+
evaluate: () => ({
|
|
1694
|
+
status: "pass",
|
|
1695
|
+
details: `System classified as "${riskLevel}" risk`
|
|
1696
|
+
})
|
|
1697
|
+
},
|
|
1698
|
+
{
|
|
1699
|
+
id: "eu-ai-02",
|
|
1700
|
+
name: "Human Oversight",
|
|
1701
|
+
description: "Human-in-the-loop mechanisms are available (approval gates)",
|
|
1702
|
+
category: "Human Oversight",
|
|
1703
|
+
evaluate: (events) => {
|
|
1704
|
+
const approvals = events.filter((e) => e.type === "approval_request" || e.type === "approval_decision");
|
|
1705
|
+
if (riskLevel === "high" && approvals.length === 0) {
|
|
1706
|
+
return {
|
|
1707
|
+
status: "fail",
|
|
1708
|
+
details: "High-risk system requires human oversight mechanisms",
|
|
1709
|
+
recommendations: ["Implement approval gates for critical operations"]
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
return {
|
|
1713
|
+
status: "pass",
|
|
1714
|
+
details: `${approvals.length} human oversight events recorded`
|
|
1715
|
+
};
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
{
|
|
1719
|
+
id: "eu-ai-03",
|
|
1720
|
+
name: "Transparency Logging",
|
|
1721
|
+
description: "All AI decisions are logged with full traceability",
|
|
1722
|
+
category: "Transparency",
|
|
1723
|
+
evaluate: (events) => {
|
|
1724
|
+
const llmCalls = events.filter((e) => e.type === "llm_call");
|
|
1725
|
+
const withTraceId = llmCalls.filter((e) => e.traceId);
|
|
1726
|
+
if (llmCalls.length === 0) {
|
|
1727
|
+
return {
|
|
1728
|
+
status: "fail",
|
|
1729
|
+
details: "No LLM call events logged",
|
|
1730
|
+
recommendations: ["Enable audit middleware on gateway"]
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1733
|
+
const traceRate = withTraceId.length / llmCalls.length;
|
|
1734
|
+
return {
|
|
1735
|
+
status: traceRate >= 0.95 ? "pass" : "warning",
|
|
1736
|
+
details: `${llmCalls.length} LLM calls logged, ${Math.round(traceRate * 100)}% with trace IDs`,
|
|
1737
|
+
recommendations: traceRate < 0.95 ? ["Ensure all requests include trace IDs for full traceability"] : undefined
|
|
1738
|
+
};
|
|
1739
|
+
}
|
|
1740
|
+
},
|
|
1741
|
+
{
|
|
1742
|
+
id: "eu-ai-04",
|
|
1743
|
+
name: "Data Governance",
|
|
1744
|
+
description: "PII and sensitive data are protected",
|
|
1745
|
+
category: "Data Governance",
|
|
1746
|
+
evaluate: (events) => {
|
|
1747
|
+
const securityEvents = events.filter((e) => e.type === "security_violation");
|
|
1748
|
+
return {
|
|
1749
|
+
status: "pass",
|
|
1750
|
+
details: `${securityEvents.length} security events recorded — data protection active`
|
|
1751
|
+
};
|
|
1752
|
+
}
|
|
1753
|
+
},
|
|
1754
|
+
{
|
|
1755
|
+
id: "eu-ai-05",
|
|
1756
|
+
name: "Record Keeping",
|
|
1757
|
+
description: "Audit trail is maintained with tamper-evident hash chain",
|
|
1758
|
+
category: "Record Keeping",
|
|
1759
|
+
evaluate: () => ({
|
|
1760
|
+
status: "pass",
|
|
1761
|
+
details: "SHA-256 hash-chained audit trail is active"
|
|
1762
|
+
})
|
|
1763
|
+
}
|
|
1764
|
+
];
|
|
1765
|
+
}
|
|
1766
|
+
function createColoradoAIActChecks() {
|
|
1767
|
+
return [
|
|
1768
|
+
{
|
|
1769
|
+
id: "co-ai-01",
|
|
1770
|
+
name: "Impact Assessment Documentation",
|
|
1771
|
+
description: "AI system impact is documented and assessable",
|
|
1772
|
+
category: "Impact Assessment",
|
|
1773
|
+
evaluate: (events) => {
|
|
1774
|
+
const totalEvents = events.length;
|
|
1775
|
+
return {
|
|
1776
|
+
status: totalEvents > 0 ? "pass" : "warning",
|
|
1777
|
+
details: `${totalEvents} events available for impact assessment`,
|
|
1778
|
+
recommendations: totalEvents === 0 ? ["Enable comprehensive audit logging for impact assessment evidence"] : undefined
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
id: "co-ai-02",
|
|
1784
|
+
name: "Algorithmic Discrimination Prevention",
|
|
1785
|
+
description: "Content policy and guardrails prevent discriminatory outputs",
|
|
1786
|
+
category: "Fairness",
|
|
1787
|
+
evaluate: (events) => {
|
|
1788
|
+
const policyViolations = events.filter((e) => e.type === "policy_violation" && e.data.policyName === "content-policy");
|
|
1789
|
+
return {
|
|
1790
|
+
status: "pass",
|
|
1791
|
+
details: `Content policy active — ${policyViolations.length} violations blocked`
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
},
|
|
1795
|
+
{
|
|
1796
|
+
id: "co-ai-03",
|
|
1797
|
+
name: "Consumer Notification Capability",
|
|
1798
|
+
description: "System can notify users when AI is making consequential decisions",
|
|
1799
|
+
category: "Transparency",
|
|
1800
|
+
evaluate: (events) => {
|
|
1801
|
+
const auditCount = events.filter((e) => e.type === "llm_call").length;
|
|
1802
|
+
return {
|
|
1803
|
+
status: "pass",
|
|
1804
|
+
details: `${auditCount} AI decisions logged — notification capability supported via audit trail`
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
];
|
|
1809
|
+
}
|
|
1810
|
+
function getChecksForFramework(config) {
|
|
1811
|
+
switch (config.framework) {
|
|
1812
|
+
case "owasp-agentic":
|
|
1813
|
+
return createOWASPAgenticChecks();
|
|
1814
|
+
case "eu-ai-act":
|
|
1815
|
+
return createEUAIActChecks(config.riskLevel ?? "limited");
|
|
1816
|
+
case "colorado-ai-act":
|
|
1817
|
+
return createColoradoAIActChecks();
|
|
1818
|
+
case "custom":
|
|
1819
|
+
return config.customChecks ?? [];
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
async function generateComplianceReport(auditTrail, config) {
|
|
1823
|
+
const events = await auditTrail.query({
|
|
1824
|
+
fromTimestamp: config.reportPeriod.from,
|
|
1825
|
+
toTimestamp: config.reportPeriod.to
|
|
1826
|
+
});
|
|
1827
|
+
const integrity = await auditTrail.verifyIntegrity();
|
|
1828
|
+
const checks = getChecksForFramework(config);
|
|
1829
|
+
const entries = checks.map((check) => ({
|
|
1830
|
+
id: check.id,
|
|
1831
|
+
name: check.name,
|
|
1832
|
+
category: check.category,
|
|
1833
|
+
result: check.evaluate(events)
|
|
1834
|
+
}));
|
|
1835
|
+
const passed = entries.filter((e) => e.result.status === "pass").length;
|
|
1836
|
+
const failed = entries.filter((e) => e.result.status === "fail").length;
|
|
1837
|
+
const warnings = entries.filter((e) => e.result.status === "warning").length;
|
|
1838
|
+
const notApplicable = entries.filter((e) => e.result.status === "not-applicable").length;
|
|
1839
|
+
let overallStatus = "compliant";
|
|
1840
|
+
if (failed > 0)
|
|
1841
|
+
overallStatus = "non-compliant";
|
|
1842
|
+
else if (warnings > 0)
|
|
1843
|
+
overallStatus = "needs-review";
|
|
1844
|
+
return {
|
|
1845
|
+
id: `compliance_${config.framework}_${Date.now().toString(36)}`,
|
|
1846
|
+
framework: config.framework,
|
|
1847
|
+
systemName: config.systemName,
|
|
1848
|
+
systemVersion: config.systemVersion,
|
|
1849
|
+
generatedAt: Date.now(),
|
|
1850
|
+
reportPeriod: config.reportPeriod,
|
|
1851
|
+
summary: {
|
|
1852
|
+
totalChecks: entries.length,
|
|
1853
|
+
passed,
|
|
1854
|
+
failed,
|
|
1855
|
+
warnings,
|
|
1856
|
+
notApplicable,
|
|
1857
|
+
overallStatus
|
|
1858
|
+
},
|
|
1859
|
+
checks: entries,
|
|
1860
|
+
auditIntegrity: { valid: integrity.valid, totalEvents: integrity.totalEvents }
|
|
1861
|
+
};
|
|
1862
|
+
}
|
|
1863
|
+
var STATUS_ICONS = {
|
|
1864
|
+
pass: "[PASS]",
|
|
1865
|
+
fail: "[FAIL]",
|
|
1866
|
+
warning: "[WARN]",
|
|
1867
|
+
"not-applicable": "[N/A]"
|
|
1868
|
+
};
|
|
1869
|
+
function formatCheckEntry(check) {
|
|
1870
|
+
const icon = STATUS_ICONS[check.result.status] ?? "[N/A]";
|
|
1871
|
+
const lines = [`**${icon} ${check.id}: ${check.name}**`, "", check.result.details];
|
|
1872
|
+
if (check.result.evidence?.length) {
|
|
1873
|
+
lines.push("", "Evidence:");
|
|
1874
|
+
lines.push(...check.result.evidence.map((e) => `- ${e}`));
|
|
1875
|
+
}
|
|
1876
|
+
if (check.result.recommendations?.length) {
|
|
1877
|
+
lines.push("", "Recommendations:");
|
|
1878
|
+
lines.push(...check.result.recommendations.map((r) => `- ${r}`));
|
|
1879
|
+
}
|
|
1880
|
+
lines.push("");
|
|
1881
|
+
return lines;
|
|
1882
|
+
}
|
|
1883
|
+
function formatComplianceReport(report) {
|
|
1884
|
+
const lines = [
|
|
1885
|
+
`# Compliance Report: ${report.framework.toUpperCase()}`,
|
|
1886
|
+
"",
|
|
1887
|
+
`**System:** ${report.systemName} v${report.systemVersion}`,
|
|
1888
|
+
`**Generated:** ${new Date(report.generatedAt).toISOString()}`,
|
|
1889
|
+
`**Period:** ${new Date(report.reportPeriod.from).toISOString()} to ${new Date(report.reportPeriod.to).toISOString()}`,
|
|
1890
|
+
`**Status:** ${report.summary.overallStatus.toUpperCase()}`,
|
|
1891
|
+
"",
|
|
1892
|
+
"## Summary",
|
|
1893
|
+
"",
|
|
1894
|
+
"| Metric | Count |",
|
|
1895
|
+
"|--------|-------|",
|
|
1896
|
+
`| Total Checks | ${report.summary.totalChecks} |`,
|
|
1897
|
+
`| Passed | ${report.summary.passed} |`,
|
|
1898
|
+
`| Failed | ${report.summary.failed} |`,
|
|
1899
|
+
`| Warnings | ${report.summary.warnings} |`,
|
|
1900
|
+
`| N/A | ${report.summary.notApplicable} |`,
|
|
1901
|
+
"",
|
|
1902
|
+
"## Audit Trail Integrity",
|
|
1903
|
+
"",
|
|
1904
|
+
`- Valid: ${report.auditIntegrity.valid ? "Yes" : "NO"}`,
|
|
1905
|
+
`- Total Events: ${report.auditIntegrity.totalEvents}`,
|
|
1906
|
+
"",
|
|
1907
|
+
"## Checks",
|
|
1908
|
+
""
|
|
1909
|
+
];
|
|
1910
|
+
const categories = [...new Set(report.checks.map((c) => c.category))];
|
|
1911
|
+
for (const category of categories) {
|
|
1912
|
+
lines.push(`### ${category}`, "");
|
|
1913
|
+
const categoryChecks = report.checks.filter((c) => c.category === category);
|
|
1914
|
+
for (const check of categoryChecks) {
|
|
1915
|
+
lines.push(...formatCheckEntry(check));
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
return lines.join(`
|
|
1919
|
+
`);
|
|
1920
|
+
}
|
|
1588
1921
|
// src/otel.ts
|
|
1589
1922
|
var log7 = createLogger();
|
|
1590
1923
|
var SPAN_KIND_MAP = {
|
|
@@ -1776,6 +2109,8 @@ export {
|
|
|
1776
2109
|
instrumentComplete,
|
|
1777
2110
|
instrumentAgent,
|
|
1778
2111
|
injectTraceContext,
|
|
2112
|
+
generateComplianceReport,
|
|
2113
|
+
formatComplianceReport,
|
|
1779
2114
|
extractTraceContext,
|
|
1780
2115
|
createWebhookSink,
|
|
1781
2116
|
createStudioExporter,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elsium-ai/observe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Observability, tracing, and cost tracking for ElsiumAI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Eric Utrera <ebutrera9103@gmail.com>",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dev": "bun --watch src/index.ts"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@elsium-ai/core": "^0.
|
|
29
|
+
"@elsium-ai/core": "^0.10.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"typescript": "^5.7.0"
|