@parmanasystems/audit-db 1.10.0 → 1.14.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/index.d.ts CHANGED
@@ -13,6 +13,7 @@ interface AuditDecision {
13
13
  runtime_version: string;
14
14
  runtime_hash: string;
15
15
  decision: string;
16
+ execution_state: string;
16
17
  signals_hash: string;
17
18
  signature: string;
18
19
  attestation: ExecutionAttestation;
@@ -60,6 +61,7 @@ interface DecisionTimelineRow {
60
61
  policy_id: string;
61
62
  policy_version: string;
62
63
  decision: string;
64
+ execution_state: string;
63
65
  runtime_version: string;
64
66
  runtime_hash: string;
65
67
  executed_at: Date;
@@ -96,6 +98,17 @@ interface AuditStats {
96
98
  total_security_events: string;
97
99
  total_api_calls: string;
98
100
  }
101
+ interface AuditOverride {
102
+ id: number;
103
+ override_id: string;
104
+ execution_id: string;
105
+ approved_by: string;
106
+ approver_role: string;
107
+ reason: string;
108
+ override_signature: string;
109
+ approved_at: Date;
110
+ recorded_at: Date;
111
+ }
99
112
 
100
113
  declare class AuditDb {
101
114
  private readonly pool;
@@ -117,9 +130,11 @@ declare class AuditDb {
117
130
  set(key: string, value: string): Promise<void>;
118
131
  get(key: string): Promise<string | null>;
119
132
  markExecuted(executionId: string): Promise<void>;
133
+ recordOverride(override: AuditOverride): Promise<void>;
134
+ getOverridesForExecution(executionId: string): Promise<AuditOverride[]>;
120
135
  close(): Promise<void>;
121
136
  }
122
137
 
123
138
  declare function runMigrations(client: PoolClient): Promise<void>;
124
139
 
125
- export { type ApiAccessInput, type AuditApiAccess, AuditDb, type AuditDecision, type AuditSecurityEvent, type AuditStats, type AuditVerification, type DecisionFilter, type DecisionTimelineRow, type SecurityDashboardRow, type SecurityEventInput, type SecurityEventSeverity, runMigrations };
140
+ export { type ApiAccessInput, type AuditApiAccess, AuditDb, type AuditDecision, type AuditOverride, type AuditSecurityEvent, type AuditStats, type AuditVerification, type DecisionFilter, type DecisionTimelineRow, type SecurityDashboardRow, type SecurityEventInput, type SecurityEventSeverity, runMigrations };
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ CREATE TABLE IF NOT EXISTS audit_decisions (
12
12
  runtime_version TEXT NOT NULL,
13
13
  runtime_hash TEXT NOT NULL,
14
14
  decision TEXT NOT NULL,
15
+ execution_state TEXT NOT NULL,
15
16
  signals_hash TEXT NOT NULL,
16
17
  signature TEXT NOT NULL,
17
18
  attestation JSONB NOT NULL,
@@ -21,8 +22,10 @@ CREATE TABLE IF NOT EXISTS audit_decisions (
21
22
 
22
23
  CREATE INDEX IF NOT EXISTS idx_audit_decisions_policy_id
23
24
  ON audit_decisions (policy_id);
25
+
24
26
  CREATE INDEX IF NOT EXISTS idx_audit_decisions_executed_at
25
27
  ON audit_decisions (executed_at DESC);
28
+
26
29
  CREATE INDEX IF NOT EXISTS idx_audit_decisions_decision
27
30
  ON audit_decisions (decision);
28
31
 
@@ -38,15 +41,24 @@ CREATE TABLE IF NOT EXISTS audit_verifications (
38
41
 
39
42
  CREATE INDEX IF NOT EXISTS idx_audit_verifications_execution_id
40
43
  ON audit_verifications (execution_id);
44
+
41
45
  CREATE INDEX IF NOT EXISTS idx_audit_verifications_valid
42
46
  ON audit_verifications (valid);
47
+
43
48
  CREATE INDEX IF NOT EXISTS idx_audit_verifications_verified_at
44
49
  ON audit_verifications (verified_at DESC);
45
50
 
46
51
  CREATE TABLE IF NOT EXISTS audit_security_events (
47
52
  id BIGSERIAL PRIMARY KEY,
48
53
  event_type TEXT NOT NULL,
49
- severity TEXT NOT NULL CHECK (severity IN ('low','medium','high','critical')),
54
+ severity TEXT NOT NULL CHECK (
55
+ severity IN (
56
+ 'low',
57
+ 'medium',
58
+ 'high',
59
+ 'critical'
60
+ )
61
+ ),
50
62
  ip_address TEXT,
51
63
  path TEXT,
52
64
  method TEXT,
@@ -57,8 +69,10 @@ CREATE TABLE IF NOT EXISTS audit_security_events (
57
69
 
58
70
  CREATE INDEX IF NOT EXISTS idx_audit_security_events_event_type
59
71
  ON audit_security_events (event_type);
72
+
60
73
  CREATE INDEX IF NOT EXISTS idx_audit_security_events_severity
61
74
  ON audit_security_events (severity);
75
+
62
76
  CREATE INDEX IF NOT EXISTS idx_audit_security_events_occurred_at
63
77
  ON audit_security_events (occurred_at DESC);
64
78
 
@@ -76,17 +90,38 @@ CREATE TABLE IF NOT EXISTS audit_api_access (
76
90
 
77
91
  CREATE INDEX IF NOT EXISTS idx_audit_api_access_path
78
92
  ON audit_api_access (path);
93
+
79
94
  CREATE INDEX IF NOT EXISTS idx_audit_api_access_status_code
80
95
  ON audit_api_access (status_code);
96
+
81
97
  CREATE INDEX IF NOT EXISTS idx_audit_api_access_accessed_at
82
98
  ON audit_api_access (accessed_at DESC);
83
99
 
100
+ CREATE TABLE IF NOT EXISTS audit_overrides (
101
+ id BIGSERIAL PRIMARY KEY,
102
+ override_id UUID NOT NULL UNIQUE,
103
+ execution_id UUID NOT NULL,
104
+ approved_by TEXT NOT NULL,
105
+ approver_role TEXT NOT NULL,
106
+ reason TEXT NOT NULL,
107
+ override_signature TEXT NOT NULL,
108
+ approved_at TIMESTAMPTZ NOT NULL,
109
+ recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
110
+ );
111
+
112
+ CREATE INDEX IF NOT EXISTS idx_audit_overrides_execution_id
113
+ ON audit_overrides (execution_id);
114
+
115
+ CREATE INDEX IF NOT EXISTS idx_audit_overrides_approved_at
116
+ ON audit_overrides (approved_at DESC);
117
+
84
118
  CREATE OR REPLACE VIEW view_decision_timeline AS
85
119
  SELECT
86
120
  d.execution_id,
87
121
  d.policy_id,
88
122
  d.policy_version,
89
123
  d.decision,
124
+ d.execution_state,
90
125
  d.runtime_version,
91
126
  d.runtime_hash,
92
127
  d.executed_at,
@@ -96,8 +131,9 @@ SELECT
96
131
  v.runtime_verified,
97
132
  v.schema_compatible,
98
133
  v.verified_at
99
- FROM audit_decisions d
100
- LEFT JOIN audit_verifications v ON d.execution_id = v.execution_id;
134
+ FROM audit_decisions d
135
+ LEFT JOIN audit_verifications v
136
+ ON d.execution_id = v.execution_id;
101
137
 
102
138
  CREATE OR REPLACE VIEW view_security_dashboard AS
103
139
  SELECT
@@ -106,16 +142,22 @@ SELECT
106
142
  COUNT(*) AS event_count,
107
143
  MAX(occurred_at) AS last_occurrence,
108
144
  MIN(occurred_at) AS first_occurrence
109
- FROM audit_security_events
145
+ FROM audit_security_events
110
146
  GROUP BY event_type, severity;
111
147
  `;
112
148
  async function runMigrations(client) {
113
149
  await client.query("BEGIN");
114
150
  try {
115
- await client.query(SCHEMA_SQL);
116
- await client.query("COMMIT");
151
+ await client.query(
152
+ SCHEMA_SQL
153
+ );
154
+ await client.query(
155
+ "COMMIT"
156
+ );
117
157
  } catch (err) {
118
- await client.query("ROLLBACK");
158
+ await client.query(
159
+ "ROLLBACK"
160
+ );
119
161
  throw err;
120
162
  }
121
163
  }
@@ -162,6 +204,7 @@ var AuditDb = class {
162
204
  attestation,
163
205
  executed_at
164
206
  )
207
+
165
208
  VALUES ($1,$2,$3,$4,$5,$6,$7)
166
209
 
167
210
  ON CONFLICT (execution_id)
@@ -169,7 +212,9 @@ var AuditDb = class {
169
212
  `,
170
213
  [
171
214
  attestation.execution_id,
172
- attestation.decision,
215
+ JSON.stringify(
216
+ attestation.decision
217
+ ),
173
218
  attestation.execution_state,
174
219
  attestation.runtime_hash,
175
220
  attestation.signature,
@@ -192,6 +237,7 @@ var AuditDb = class {
192
237
  runtime_verified,
193
238
  schema_compatible
194
239
  )
240
+
195
241
  VALUES ($1,$2,$3,$4,$5)
196
242
  `,
197
243
  [
@@ -219,6 +265,7 @@ var AuditDb = class {
219
265
  user_agent,
220
266
  details
221
267
  )
268
+
222
269
  VALUES ($1,$2,$3,$4,$5,$6,$7)
223
270
  `,
224
271
  [
@@ -248,6 +295,7 @@ var AuditDb = class {
248
295
  user_agent,
249
296
  execution_id
250
297
  )
298
+
251
299
  VALUES ($1,$2,$3,$4,$5,$6,$7)
252
300
  `,
253
301
  [
@@ -374,6 +422,7 @@ var AuditDb = class {
374
422
  `
375
423
  SELECT *
376
424
  FROM audit_decisions
425
+
377
426
  WHERE execution_id = $1
378
427
  `,
379
428
  [executionId]
@@ -453,7 +502,9 @@ var AuditDb = class {
453
502
  `,
454
503
  [
455
504
  attestation.execution_id,
456
- attestation.decision,
505
+ JSON.stringify(
506
+ attestation.decision
507
+ ),
457
508
  "pending_override",
458
509
  attestation.runtime_hash,
459
510
  attestation.signature,
@@ -470,6 +521,7 @@ var AuditDb = class {
470
521
  "pending:",
471
522
  ""
472
523
  );
524
+ const parsed = JSON.parse(value);
473
525
  await this.pool.query(
474
526
  `
475
527
  INSERT INTO audit_decisions
@@ -488,7 +540,9 @@ var AuditDb = class {
488
540
  `,
489
541
  [
490
542
  executionId,
491
- {},
543
+ JSON.stringify(
544
+ parsed.token.decision_payload
545
+ ),
492
546
  "pending_override",
493
547
  value,
494
548
  (/* @__PURE__ */ new Date()).toISOString()
@@ -526,28 +580,68 @@ var AuditDb = class {
526
580
  async markExecuted(executionId) {
527
581
  await this.pool.query(
528
582
  `
529
- INSERT INTO audit_decisions
583
+ UPDATE audit_decisions
584
+
585
+ SET
586
+ execution_state = $2
587
+
588
+ WHERE execution_id = $1
589
+ `,
590
+ [
591
+ executionId,
592
+ "completed"
593
+ ]
594
+ );
595
+ }
596
+ // ----------------------------------
597
+ // Override authority recording
598
+ // ----------------------------------
599
+ async recordOverride(override) {
600
+ await this.pool.query(
601
+ `
602
+ INSERT INTO audit_overrides
530
603
  (
604
+ override_id,
531
605
  execution_id,
532
- execution_state,
533
- executed_at
606
+ approved_by,
607
+ approver_role,
608
+ reason,
609
+ override_signature,
610
+ approved_at
534
611
  )
535
612
 
536
- VALUES ($1,$2,$3)
537
-
538
- ON CONFLICT (execution_id)
539
-
540
- DO UPDATE SET
541
- execution_state = EXCLUDED.execution_state
613
+ VALUES ($1,$2,$3,$4,$5,$6,$7)
542
614
  `,
543
615
  [
544
- executionId,
545
- "completed",
546
- (/* @__PURE__ */ new Date()).toISOString()
616
+ override.override_id,
617
+ override.execution_id,
618
+ override.approved_by,
619
+ override.approver_role,
620
+ override.reason,
621
+ override.override_signature,
622
+ override.approved_at
547
623
  ]
548
624
  );
549
625
  }
550
626
  // ----------------------------------
627
+ // Override lookup
628
+ // ----------------------------------
629
+ async getOverridesForExecution(executionId) {
630
+ const { rows } = await this.pool.query(
631
+ `
632
+ SELECT *
633
+
634
+ FROM audit_overrides
635
+
636
+ WHERE execution_id = $1
637
+
638
+ ORDER BY approved_at DESC
639
+ `,
640
+ [executionId]
641
+ );
642
+ return rows;
643
+ }
644
+ // ----------------------------------
551
645
  // Cleanup
552
646
  // ----------------------------------
553
647
  async close() {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/migrations.ts"],"sourcesContent":["import { Pool } from \"pg\";\r\nimport type { PoolClient } from \"pg\";\r\n\r\nimport type { ExecutionAttestation } from \"@parmanasystems/execution\";\r\nimport type { VerificationResult } from \"@parmanasystems/verifier\";\r\n\r\nimport type {\r\n AuditDecision,\r\n AuditVerification,\r\n SecurityEventInput,\r\n ApiAccessInput,\r\n DecisionTimelineRow,\r\n DecisionFilter,\r\n SecurityDashboardRow,\r\n AuditStats,\r\n} from \"./types.js\";\r\n\r\nimport { runMigrations } from \"./migrations.js\";\r\n\r\nexport class AuditDb {\r\n\r\n private readonly pool:\r\n InstanceType<typeof Pool>;\r\n\r\n constructor(\r\n connectionString: string\r\n ) {\r\n\r\n this.pool =\r\n new Pool({\r\n connectionString\r\n });\r\n }\r\n\r\n async ping(): Promise<void> {\r\n\r\n await this.pool.query(\r\n \"SELECT 1\"\r\n );\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n\r\n await this.pool.end();\r\n }\r\n\r\n async migrate(): Promise<void> {\r\n\r\n const client:\r\n PoolClient =\r\n await this.pool.connect();\r\n\r\n try {\r\n\r\n await runMigrations(\r\n client\r\n );\r\n\r\n } finally {\r\n\r\n client.release();\r\n }\r\n }\r\n\r\n // ----------------------------------\r\n // Decision recording\r\n // ----------------------------------\r\n\r\n recordDecision(\r\n attestation: ExecutionAttestation\r\n ): void {\r\n\r\n this.pool\r\n .query(\r\n `\r\n INSERT INTO audit_decisions\r\n (\r\n execution_id,\r\n decision,\r\n execution_state,\r\n runtime_hash,\r\n signature,\r\n attestation,\r\n executed_at\r\n )\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n\r\n ON CONFLICT (execution_id)\r\n DO NOTHING\r\n `,\r\n [\r\n attestation.execution_id,\r\n attestation.decision,\r\n attestation.execution_state,\r\n attestation.runtime_hash,\r\n attestation.signature,\r\n JSON.stringify(attestation),\r\n new Date().toISOString()\r\n ]\r\n )\r\n .catch(() => undefined);\r\n }\r\n\r\n // ----------------------------------\r\n // Verification recording\r\n // ----------------------------------\r\n\r\n recordVerification(\r\n executionId: string,\r\n result: VerificationResult\r\n ): void {\r\n\r\n this.pool\r\n .query(\r\n `\r\n INSERT INTO audit_verifications\r\n (\r\n execution_id,\r\n valid,\r\n signature_verified,\r\n runtime_verified,\r\n schema_compatible\r\n )\r\n VALUES ($1,$2,$3,$4,$5)\r\n `,\r\n [\r\n executionId,\r\n result.valid,\r\n result.checks.signature_verified,\r\n result.checks.runtime_verified,\r\n result.checks.schema_compatible\r\n ]\r\n )\r\n .catch(() => undefined);\r\n }\r\n\r\n // ----------------------------------\r\n // Security event recording\r\n // ----------------------------------\r\n\r\n recordSecurityEvent(\r\n event: SecurityEventInput\r\n ): void {\r\n\r\n this.pool\r\n .query(\r\n `\r\n INSERT INTO audit_security_events\r\n (\r\n event_type,\r\n severity,\r\n ip_address,\r\n path,\r\n method,\r\n user_agent,\r\n details\r\n )\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n `,\r\n [\r\n event.event_type,\r\n event.severity,\r\n event.ip_address ?? null,\r\n event.path ?? null,\r\n event.method ?? null,\r\n event.user_agent ?? null,\r\n\r\n event.details != null\r\n ? JSON.stringify(event.details)\r\n : null\r\n ]\r\n )\r\n .catch(() => undefined);\r\n }\r\n\r\n // ----------------------------------\r\n // API access recording\r\n // ----------------------------------\r\n\r\n recordApiAccess(\r\n access: ApiAccessInput\r\n ): void {\r\n\r\n this.pool\r\n .query(\r\n `\r\n INSERT INTO audit_api_access\r\n (\r\n method,\r\n path,\r\n status_code,\r\n response_time_ms,\r\n ip_address,\r\n user_agent,\r\n execution_id\r\n )\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n `,\r\n [\r\n access.method,\r\n access.path,\r\n access.status_code,\r\n access.response_time_ms ?? null,\r\n access.ip_address ?? null,\r\n access.user_agent ?? null,\r\n access.execution_id ?? null\r\n ]\r\n )\r\n .catch(() => undefined);\r\n }\r\n\r\n // ----------------------------------\r\n // Decision timeline\r\n // ----------------------------------\r\n\r\n async getDecisionTimeline(\r\n limit = 100,\r\n filter?: DecisionFilter\r\n ): Promise<DecisionTimelineRow[]> {\r\n\r\n const conditions: string[] = [];\r\n\r\n const values: unknown[] = [];\r\n\r\n if (filter?.policy_id) {\r\n\r\n values.push(\r\n filter.policy_id\r\n );\r\n\r\n conditions.push(\r\n `policy_id = $${values.length}`\r\n );\r\n }\r\n\r\n if (filter?.decision) {\r\n\r\n values.push(\r\n filter.decision\r\n );\r\n\r\n conditions.push(\r\n `decision = $${values.length}`\r\n );\r\n }\r\n\r\n if (filter?.from_date) {\r\n\r\n values.push(\r\n filter.from_date\r\n );\r\n\r\n conditions.push(\r\n `executed_at >= $${values.length}`\r\n );\r\n }\r\n\r\n if (filter?.to_date) {\r\n\r\n values.push(\r\n filter.to_date\r\n );\r\n\r\n conditions.push(\r\n `executed_at <= $${values.length}`\r\n );\r\n }\r\n\r\n values.push(limit);\r\n\r\n const limitParam =\r\n `$${values.length}`;\r\n\r\n const where =\r\n conditions.length\r\n ? `WHERE ${conditions.join(\" AND \")}`\r\n : \"\";\r\n\r\n const { rows } =\r\n await this.pool.query<DecisionTimelineRow>(\r\n `\r\n SELECT *\r\n FROM view_decision_timeline\r\n\r\n ${where}\r\n\r\n ORDER BY executed_at DESC\r\n\r\n LIMIT ${limitParam}\r\n `,\r\n values\r\n );\r\n\r\n return rows;\r\n }\r\n\r\n // ----------------------------------\r\n // Stats\r\n // ----------------------------------\r\n\r\n async getStats(): Promise<AuditStats> {\r\n\r\n const { rows } =\r\n await this.pool.query<AuditStats>(\r\n `\r\n SELECT\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_decisions\r\n )::text AS total_decisions,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_decisions\r\n WHERE executed_at >= CURRENT_DATE\r\n )::text AS decisions_today,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_verifications\r\n )::text AS total_verifications,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_verifications\r\n WHERE valid = true\r\n )::text AS valid_verifications,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_verifications\r\n WHERE valid = false\r\n )::text AS invalid_verifications,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_security_events\r\n )::text AS total_security_events,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_api_access\r\n )::text AS total_api_calls\r\n `\r\n );\r\n\r\n return rows[0]!;\r\n }\r\n\r\n // ----------------------------------\r\n // Decision lookup\r\n // ----------------------------------\r\n\r\n async getDecisionById(\r\n executionId: string\r\n ): Promise<AuditDecision | null> {\r\n\r\n const { rows } =\r\n await this.pool.query<AuditDecision>(\r\n `\r\n SELECT *\r\n FROM audit_decisions\r\n WHERE execution_id = $1\r\n `,\r\n [executionId]\r\n );\r\n\r\n return rows[0] ?? null;\r\n }\r\n\r\n // ----------------------------------\r\n // Verification lookup\r\n // ----------------------------------\r\n\r\n async getVerificationsByExecution(\r\n executionId: string\r\n ): Promise<AuditVerification[]> {\r\n\r\n const { rows } =\r\n await this.pool.query<AuditVerification>(\r\n `\r\n SELECT *\r\n FROM audit_verifications\r\n\r\n WHERE execution_id = $1\r\n\r\n ORDER BY verified_at DESC\r\n `,\r\n [executionId]\r\n );\r\n\r\n return rows;\r\n }\r\n\r\n // ----------------------------------\r\n // Security dashboard\r\n // ----------------------------------\r\n\r\n async getSecurityDashboard():\r\n Promise<SecurityDashboardRow[]> {\r\n\r\n const { rows } =\r\n await this.pool.query<SecurityDashboardRow>(\r\n `\r\n SELECT *\r\n FROM view_security_dashboard\r\n\r\n ORDER BY event_count DESC\r\n `\r\n );\r\n\r\n return rows;\r\n }\r\n\r\n // ----------------------------------\r\n // Replay protection\r\n // ----------------------------------\r\n\r\n async hasExecution(\r\n executionId: string\r\n ): Promise<boolean> {\r\n\r\n const { rows } =\r\n await this.pool.query(\r\n `\r\n SELECT execution_id\r\n\r\n FROM audit_decisions\r\n\r\n WHERE execution_id = $1\r\n\r\n LIMIT 1\r\n `,\r\n [executionId]\r\n );\r\n\r\n return rows.length > 0;\r\n }\r\n\r\n // ----------------------------------\r\n // Pending override storage\r\n // ----------------------------------\r\n\r\n async storePendingExecution(\r\n attestation: ExecutionAttestation\r\n ): Promise<void> {\r\n\r\n await this.pool.query(\r\n `\r\n INSERT INTO audit_decisions\r\n (\r\n execution_id,\r\n decision,\r\n execution_state,\r\n runtime_hash,\r\n signature,\r\n attestation,\r\n executed_at\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n\r\n ON CONFLICT (execution_id)\r\n DO NOTHING\r\n `,\r\n [\r\n attestation.execution_id,\r\n attestation.decision,\r\n \"pending_override\",\r\n attestation.runtime_hash,\r\n attestation.signature,\r\n JSON.stringify(attestation),\r\n new Date().toISOString()\r\n ]\r\n );\r\n }\r\n\r\n // ----------------------------------\r\n // Redis-compatible KV set\r\n // ----------------------------------\r\n\r\n async set(\r\n key: string,\r\n value: string\r\n ): Promise<void> {\r\n\r\n const executionId =\r\n key.replace(\r\n \"pending:\",\r\n \"\"\r\n );\r\n\r\n await this.pool.query(\r\n `\r\n INSERT INTO audit_decisions\r\n (\r\n execution_id,\r\n decision,\r\n execution_state,\r\n attestation,\r\n executed_at\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5)\r\n\r\n ON CONFLICT (execution_id)\r\n DO NOTHING\r\n `,\r\n [\r\n executionId,\r\n {},\r\n \"pending_override\",\r\n value,\r\n new Date().toISOString()\r\n ]\r\n );\r\n }\r\n\r\n // ----------------------------------\r\n // Redis-compatible KV get\r\n // ----------------------------------\r\n\r\n async get(\r\n key: string\r\n ): Promise<string | null> {\r\n\r\n const executionId =\r\n key.replace(\r\n \"pending:\",\r\n \"\"\r\n );\r\n\r\n const { rows } =\r\n await this.pool.query(\r\n `\r\n SELECT attestation\r\n\r\n FROM audit_decisions\r\n\r\n WHERE execution_id = $1\r\n\r\n LIMIT 1\r\n `,\r\n [executionId]\r\n );\r\n\r\n if (rows.length === 0) {\r\n return null;\r\n }\r\n\r\n return rows[0].attestation;\r\n }\r\n\r\n // ----------------------------------\r\n // Completed execution marking\r\n // ----------------------------------\r\n\r\n async markExecuted(\r\n executionId: string\r\n ): Promise<void> {\r\n\r\n await this.pool.query(\r\n `\r\n INSERT INTO audit_decisions\r\n (\r\n execution_id,\r\n execution_state,\r\n executed_at\r\n )\r\n\r\n VALUES ($1,$2,$3)\r\n\r\n ON CONFLICT (execution_id)\r\n\r\n DO UPDATE SET\r\n execution_state = EXCLUDED.execution_state\r\n `,\r\n [\r\n executionId,\r\n \"completed\",\r\n new Date().toISOString()\r\n ]\r\n );\r\n }\r\n\r\n // ----------------------------------\r\n // Cleanup\r\n // ----------------------------------\r\n\r\n async close(): Promise<void> {\r\n\r\n await this.pool.end();\r\n }\r\n}","import type { PoolClient } from \"pg\";\r\n\r\n// Inlined so the bundle has no runtime fs dependency.\r\n// The canonical reference lives in schema.sql alongside this file.\r\nconst SCHEMA_SQL = `\r\nCREATE TABLE IF NOT EXISTS audit_decisions (\r\n id BIGSERIAL PRIMARY KEY,\r\n execution_id UUID NOT NULL UNIQUE,\r\n policy_id TEXT NOT NULL,\r\n policy_version TEXT NOT NULL,\r\n schema_version TEXT NOT NULL,\r\n runtime_version TEXT NOT NULL,\r\n runtime_hash TEXT NOT NULL,\r\n decision TEXT NOT NULL,\r\n signals_hash TEXT NOT NULL,\r\n signature TEXT NOT NULL,\r\n attestation JSONB NOT NULL,\r\n executed_at TIMESTAMPTZ NOT NULL,\r\n recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_decisions_policy_id\r\n ON audit_decisions (policy_id);\r\nCREATE INDEX IF NOT EXISTS idx_audit_decisions_executed_at\r\n ON audit_decisions (executed_at DESC);\r\nCREATE INDEX IF NOT EXISTS idx_audit_decisions_decision\r\n ON audit_decisions (decision);\r\n\r\nCREATE TABLE IF NOT EXISTS audit_verifications (\r\n id BIGSERIAL PRIMARY KEY,\r\n execution_id UUID NOT NULL,\r\n valid BOOLEAN NOT NULL,\r\n signature_verified BOOLEAN NOT NULL,\r\n runtime_verified BOOLEAN NOT NULL,\r\n schema_compatible BOOLEAN NOT NULL,\r\n verified_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_verifications_execution_id\r\n ON audit_verifications (execution_id);\r\nCREATE INDEX IF NOT EXISTS idx_audit_verifications_valid\r\n ON audit_verifications (valid);\r\nCREATE INDEX IF NOT EXISTS idx_audit_verifications_verified_at\r\n ON audit_verifications (verified_at DESC);\r\n\r\nCREATE TABLE IF NOT EXISTS audit_security_events (\r\n id BIGSERIAL PRIMARY KEY,\r\n event_type TEXT NOT NULL,\r\n severity TEXT NOT NULL CHECK (severity IN ('low','medium','high','critical')),\r\n ip_address TEXT,\r\n path TEXT,\r\n method TEXT,\r\n user_agent TEXT,\r\n details JSONB,\r\n occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_security_events_event_type\r\n ON audit_security_events (event_type);\r\nCREATE INDEX IF NOT EXISTS idx_audit_security_events_severity\r\n ON audit_security_events (severity);\r\nCREATE INDEX IF NOT EXISTS idx_audit_security_events_occurred_at\r\n ON audit_security_events (occurred_at DESC);\r\n\r\nCREATE TABLE IF NOT EXISTS audit_api_access (\r\n id BIGSERIAL PRIMARY KEY,\r\n method TEXT NOT NULL,\r\n path TEXT NOT NULL,\r\n status_code INTEGER NOT NULL,\r\n response_time_ms INTEGER,\r\n ip_address TEXT,\r\n user_agent TEXT,\r\n execution_id UUID,\r\n accessed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_api_access_path\r\n ON audit_api_access (path);\r\nCREATE INDEX IF NOT EXISTS idx_audit_api_access_status_code\r\n ON audit_api_access (status_code);\r\nCREATE INDEX IF NOT EXISTS idx_audit_api_access_accessed_at\r\n ON audit_api_access (accessed_at DESC);\r\n\r\nCREATE OR REPLACE VIEW view_decision_timeline AS\r\nSELECT\r\n d.execution_id,\r\n d.policy_id,\r\n d.policy_version,\r\n d.decision,\r\n d.runtime_version,\r\n d.runtime_hash,\r\n d.executed_at,\r\n d.recorded_at,\r\n v.valid AS verification_valid,\r\n v.signature_verified,\r\n v.runtime_verified,\r\n v.schema_compatible,\r\n v.verified_at\r\nFROM audit_decisions d\r\nLEFT JOIN audit_verifications v ON d.execution_id = v.execution_id;\r\n\r\nCREATE OR REPLACE VIEW view_security_dashboard AS\r\nSELECT\r\n event_type,\r\n severity,\r\n COUNT(*) AS event_count,\r\n MAX(occurred_at) AS last_occurrence,\r\n MIN(occurred_at) AS first_occurrence\r\nFROM audit_security_events\r\nGROUP BY event_type, severity;\r\n`;\r\n\r\nexport async function runMigrations(client: PoolClient): Promise<void> {\r\n await client.query(\"BEGIN\");\r\n try {\r\n await client.query(SCHEMA_SQL);\r\n await client.query(\"COMMIT\");\r\n } catch (err) {\r\n await client.query(\"ROLLBACK\");\r\n throw err;\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/migrations.ts"],"sourcesContent":["import { Pool } from \"pg\";\r\nimport type { PoolClient } from \"pg\";\r\n\r\nimport type { ExecutionAttestation } from \"@parmanasystems/execution\";\r\nimport type { VerificationResult } from \"@parmanasystems/verifier\";\r\n\r\nimport type {\r\n AuditDecision,\r\n AuditVerification,\r\n AuditOverride,\r\n SecurityEventInput,\r\n ApiAccessInput,\r\n DecisionTimelineRow,\r\n DecisionFilter,\r\n SecurityDashboardRow,\r\n AuditStats,\r\n} from \"./types.js\";\r\n\r\nimport { runMigrations } from \"./migrations.js\";\r\n\r\nexport class AuditDb {\r\n\r\n private readonly pool:\r\n InstanceType<typeof Pool>;\r\n\r\n constructor(\r\n connectionString: string\r\n ) {\r\n\r\n this.pool =\r\n new Pool({\r\n connectionString\r\n });\r\n }\r\n\r\n async ping(): Promise<void> {\r\n\r\n await this.pool.query(\r\n \"SELECT 1\"\r\n );\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n\r\n await this.pool.end();\r\n }\r\n\r\n async migrate(): Promise<void> {\r\n\r\n const client:\r\n PoolClient =\r\n await this.pool.connect();\r\n\r\n try {\r\n\r\n await runMigrations(\r\n client\r\n );\r\n\r\n } finally {\r\n\r\n client.release();\r\n }\r\n }\r\n\r\n // ----------------------------------\r\n // Decision recording\r\n // ----------------------------------\r\n\r\n recordDecision(\r\n attestation: ExecutionAttestation\r\n ): void {\r\n\r\n this.pool\r\n .query(\r\n `\r\n INSERT INTO audit_decisions\r\n (\r\n execution_id,\r\n decision,\r\n execution_state,\r\n runtime_hash,\r\n signature,\r\n attestation,\r\n executed_at\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n\r\n ON CONFLICT (execution_id)\r\n DO NOTHING\r\n `,\r\n [\r\n attestation.execution_id,\r\n\r\n JSON.stringify(\r\n attestation.decision\r\n ),\r\n\r\n attestation.execution_state,\r\n\r\n attestation.runtime_hash,\r\n\r\n attestation.signature,\r\n\r\n JSON.stringify(attestation),\r\n\r\n new Date().toISOString()\r\n ]\r\n )\r\n .catch(() => undefined);\r\n }\r\n\r\n // ----------------------------------\r\n // Verification recording\r\n // ----------------------------------\r\n\r\n recordVerification(\r\n executionId: string,\r\n result: VerificationResult\r\n ): void {\r\n\r\n this.pool\r\n .query(\r\n `\r\n INSERT INTO audit_verifications\r\n (\r\n execution_id,\r\n valid,\r\n signature_verified,\r\n runtime_verified,\r\n schema_compatible\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5)\r\n `,\r\n [\r\n executionId,\r\n result.valid,\r\n result.checks.signature_verified,\r\n result.checks.runtime_verified,\r\n result.checks.schema_compatible\r\n ]\r\n )\r\n .catch(() => undefined);\r\n }\r\n\r\n // ----------------------------------\r\n // Security event recording\r\n // ----------------------------------\r\n\r\n recordSecurityEvent(\r\n event: SecurityEventInput\r\n ): void {\r\n\r\n this.pool\r\n .query(\r\n `\r\n INSERT INTO audit_security_events\r\n (\r\n event_type,\r\n severity,\r\n ip_address,\r\n path,\r\n method,\r\n user_agent,\r\n details\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n `,\r\n [\r\n event.event_type,\r\n event.severity,\r\n event.ip_address ?? null,\r\n event.path ?? null,\r\n event.method ?? null,\r\n event.user_agent ?? null,\r\n\r\n event.details != null\r\n ? JSON.stringify(event.details)\r\n : null\r\n ]\r\n )\r\n .catch(() => undefined);\r\n }\r\n\r\n // ----------------------------------\r\n // API access recording\r\n // ----------------------------------\r\n\r\n recordApiAccess(\r\n access: ApiAccessInput\r\n ): void {\r\n\r\n this.pool\r\n .query(\r\n `\r\n INSERT INTO audit_api_access\r\n (\r\n method,\r\n path,\r\n status_code,\r\n response_time_ms,\r\n ip_address,\r\n user_agent,\r\n execution_id\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n `,\r\n [\r\n access.method,\r\n access.path,\r\n access.status_code,\r\n access.response_time_ms ?? null,\r\n access.ip_address ?? null,\r\n access.user_agent ?? null,\r\n access.execution_id ?? null\r\n ]\r\n )\r\n .catch(() => undefined);\r\n }\r\n\r\n // ----------------------------------\r\n // Decision timeline\r\n // ----------------------------------\r\n\r\n async getDecisionTimeline(\r\n limit = 100,\r\n filter?: DecisionFilter\r\n ): Promise<DecisionTimelineRow[]> {\r\n\r\n const conditions: string[] = [];\r\n\r\n const values: unknown[] = [];\r\n\r\n if (filter?.policy_id) {\r\n\r\n values.push(\r\n filter.policy_id\r\n );\r\n\r\n conditions.push(\r\n `policy_id = $${values.length}`\r\n );\r\n }\r\n\r\n if (filter?.decision) {\r\n\r\n values.push(\r\n filter.decision\r\n );\r\n\r\n conditions.push(\r\n `decision = $${values.length}`\r\n );\r\n }\r\n\r\n if (filter?.from_date) {\r\n\r\n values.push(\r\n filter.from_date\r\n );\r\n\r\n conditions.push(\r\n `executed_at >= $${values.length}`\r\n );\r\n }\r\n\r\n if (filter?.to_date) {\r\n\r\n values.push(\r\n filter.to_date\r\n );\r\n\r\n conditions.push(\r\n `executed_at <= $${values.length}`\r\n );\r\n }\r\n\r\n values.push(limit);\r\n\r\n const limitParam =\r\n `$${values.length}`;\r\n\r\n const where =\r\n conditions.length\r\n ? `WHERE ${conditions.join(\" AND \")}`\r\n : \"\";\r\n\r\n const { rows } =\r\n await this.pool.query<DecisionTimelineRow>(\r\n `\r\n SELECT *\r\n FROM view_decision_timeline\r\n\r\n ${where}\r\n\r\n ORDER BY executed_at DESC\r\n\r\n LIMIT ${limitParam}\r\n `,\r\n values\r\n );\r\n\r\n return rows;\r\n }\r\n\r\n // ----------------------------------\r\n // Stats\r\n // ----------------------------------\r\n\r\n async getStats(): Promise<AuditStats> {\r\n\r\n const { rows } =\r\n await this.pool.query<AuditStats>(\r\n `\r\n SELECT\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_decisions\r\n )::text AS total_decisions,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_decisions\r\n WHERE executed_at >= CURRENT_DATE\r\n )::text AS decisions_today,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_verifications\r\n )::text AS total_verifications,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_verifications\r\n WHERE valid = true\r\n )::text AS valid_verifications,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_verifications\r\n WHERE valid = false\r\n )::text AS invalid_verifications,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_security_events\r\n )::text AS total_security_events,\r\n\r\n (\r\n SELECT COUNT(*)\r\n FROM audit_api_access\r\n )::text AS total_api_calls\r\n `\r\n );\r\n\r\n return rows[0]!;\r\n }\r\n\r\n // ----------------------------------\r\n // Decision lookup\r\n // ----------------------------------\r\n\r\n async getDecisionById(\r\n executionId: string\r\n ): Promise<AuditDecision | null> {\r\n\r\n const { rows } =\r\n await this.pool.query<AuditDecision>(\r\n `\r\n SELECT *\r\n FROM audit_decisions\r\n\r\n WHERE execution_id = $1\r\n `,\r\n [executionId]\r\n );\r\n\r\n return rows[0] ?? null;\r\n }\r\n\r\n // ----------------------------------\r\n // Verification lookup\r\n // ----------------------------------\r\n\r\n async getVerificationsByExecution(\r\n executionId: string\r\n ): Promise<AuditVerification[]> {\r\n\r\n const { rows } =\r\n await this.pool.query<AuditVerification>(\r\n `\r\n SELECT *\r\n FROM audit_verifications\r\n\r\n WHERE execution_id = $1\r\n\r\n ORDER BY verified_at DESC\r\n `,\r\n [executionId]\r\n );\r\n\r\n return rows;\r\n }\r\n\r\n // ----------------------------------\r\n // Security dashboard\r\n // ----------------------------------\r\n\r\n async getSecurityDashboard():\r\n Promise<SecurityDashboardRow[]> {\r\n\r\n const { rows } =\r\n await this.pool.query<SecurityDashboardRow>(\r\n `\r\n SELECT *\r\n FROM view_security_dashboard\r\n\r\n ORDER BY event_count DESC\r\n `\r\n );\r\n\r\n return rows;\r\n }\r\n\r\n // ----------------------------------\r\n // Replay protection\r\n // ----------------------------------\r\n\r\n async hasExecution(\r\n executionId: string\r\n ): Promise<boolean> {\r\n\r\n const { rows } =\r\n await this.pool.query(\r\n `\r\n SELECT execution_id\r\n\r\n FROM audit_decisions\r\n\r\n WHERE execution_id = $1\r\n\r\n LIMIT 1\r\n `,\r\n [executionId]\r\n );\r\n\r\n return rows.length > 0;\r\n }\r\n\r\n // ----------------------------------\r\n // Pending override storage\r\n // ----------------------------------\r\n\r\n async storePendingExecution(\r\n attestation: ExecutionAttestation\r\n ): Promise<void> {\r\n\r\n await this.pool.query(\r\n `\r\n INSERT INTO audit_decisions\r\n (\r\n execution_id,\r\n decision,\r\n execution_state,\r\n runtime_hash,\r\n signature,\r\n attestation,\r\n executed_at\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n\r\n ON CONFLICT (execution_id)\r\n DO NOTHING\r\n `,\r\n [\r\n attestation.execution_id,\r\n\r\n JSON.stringify(\r\n attestation.decision\r\n ),\r\n\r\n \"pending_override\",\r\n\r\n attestation.runtime_hash,\r\n\r\n attestation.signature,\r\n\r\n JSON.stringify(attestation),\r\n\r\n new Date().toISOString()\r\n ]\r\n );\r\n }\r\n\r\n // ----------------------------------\r\n // Redis-compatible KV set\r\n // ----------------------------------\r\n\r\n async set(\r\n key: string,\r\n value: string\r\n ): Promise<void> {\r\n\r\n const executionId =\r\n key.replace(\r\n \"pending:\",\r\n \"\"\r\n );\r\n\r\n const parsed =\r\n JSON.parse(value);\r\n\r\n await this.pool.query(\r\n `\r\n INSERT INTO audit_decisions\r\n (\r\n execution_id,\r\n decision,\r\n execution_state,\r\n attestation,\r\n executed_at\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5)\r\n\r\n ON CONFLICT (execution_id)\r\n DO NOTHING\r\n `,\r\n [\r\n executionId,\r\n\r\n JSON.stringify(\r\n parsed.token.decision_payload\r\n ),\r\n\r\n \"pending_override\",\r\n\r\n value,\r\n\r\n new Date().toISOString()\r\n ]\r\n );\r\n }\r\n\r\n // ----------------------------------\r\n // Redis-compatible KV get\r\n // ----------------------------------\r\n\r\n async get(\r\n key: string\r\n ): Promise<string | null> {\r\n\r\n const executionId =\r\n key.replace(\r\n \"pending:\",\r\n \"\"\r\n );\r\n\r\n const { rows } =\r\n await this.pool.query(\r\n `\r\n SELECT attestation\r\n\r\n FROM audit_decisions\r\n\r\n WHERE execution_id = $1\r\n\r\n LIMIT 1\r\n `,\r\n [executionId]\r\n );\r\n\r\n if (rows.length === 0) {\r\n return null;\r\n }\r\n\r\n return rows[0].attestation;\r\n }\r\n\r\n // ----------------------------------\r\n // Completed execution marking\r\n // ----------------------------------\r\n\r\n async markExecuted(\r\n executionId: string\r\n ): Promise<void> {\r\n\r\n await this.pool.query(\r\n `\r\n UPDATE audit_decisions\r\n\r\n SET\r\n execution_state = $2\r\n\r\n WHERE execution_id = $1\r\n `,\r\n [\r\n executionId,\r\n \"completed\"\r\n ]\r\n );\r\n }\r\n\r\n // ----------------------------------\r\n // Override authority recording\r\n // ----------------------------------\r\n\r\n async recordOverride(\r\n override: AuditOverride\r\n ): Promise<void> {\r\n\r\n await this.pool.query(\r\n `\r\n INSERT INTO audit_overrides\r\n (\r\n override_id,\r\n execution_id,\r\n approved_by,\r\n approver_role,\r\n reason,\r\n override_signature,\r\n approved_at\r\n )\r\n\r\n VALUES ($1,$2,$3,$4,$5,$6,$7)\r\n `,\r\n [\r\n override.override_id,\r\n override.execution_id,\r\n override.approved_by,\r\n override.approver_role,\r\n override.reason,\r\n override.override_signature,\r\n override.approved_at\r\n ]\r\n );\r\n }\r\n\r\n // ----------------------------------\r\n // Override lookup\r\n // ----------------------------------\r\n\r\n async getOverridesForExecution(\r\n executionId: string\r\n ): Promise<AuditOverride[]> {\r\n\r\n const { rows } =\r\n await this.pool.query<AuditOverride>(\r\n `\r\n SELECT *\r\n\r\n FROM audit_overrides\r\n\r\n WHERE execution_id = $1\r\n\r\n ORDER BY approved_at DESC\r\n `,\r\n [executionId]\r\n );\r\n\r\n return rows;\r\n }\r\n\r\n // ----------------------------------\r\n // Cleanup\r\n // ----------------------------------\r\n\r\n async close(): Promise<void> {\r\n\r\n await this.pool.end();\r\n }\r\n}","import type { PoolClient } from \"pg\";\r\n\r\n// Inlined so the bundle has no runtime fs dependency.\r\n// The canonical reference lives in schema.sql alongside this file.\r\nconst SCHEMA_SQL = `\r\nCREATE TABLE IF NOT EXISTS audit_decisions (\r\n id BIGSERIAL PRIMARY KEY,\r\n execution_id UUID NOT NULL UNIQUE,\r\n policy_id TEXT NOT NULL,\r\n policy_version TEXT NOT NULL,\r\n schema_version TEXT NOT NULL,\r\n runtime_version TEXT NOT NULL,\r\n runtime_hash TEXT NOT NULL,\r\n decision TEXT NOT NULL,\r\n execution_state TEXT NOT NULL,\r\n signals_hash TEXT NOT NULL,\r\n signature TEXT NOT NULL,\r\n attestation JSONB NOT NULL,\r\n executed_at TIMESTAMPTZ NOT NULL,\r\n recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_decisions_policy_id\r\n ON audit_decisions (policy_id);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_decisions_executed_at\r\n ON audit_decisions (executed_at DESC);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_decisions_decision\r\n ON audit_decisions (decision);\r\n\r\nCREATE TABLE IF NOT EXISTS audit_verifications (\r\n id BIGSERIAL PRIMARY KEY,\r\n execution_id UUID NOT NULL,\r\n valid BOOLEAN NOT NULL,\r\n signature_verified BOOLEAN NOT NULL,\r\n runtime_verified BOOLEAN NOT NULL,\r\n schema_compatible BOOLEAN NOT NULL,\r\n verified_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_verifications_execution_id\r\n ON audit_verifications (execution_id);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_verifications_valid\r\n ON audit_verifications (valid);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_verifications_verified_at\r\n ON audit_verifications (verified_at DESC);\r\n\r\nCREATE TABLE IF NOT EXISTS audit_security_events (\r\n id BIGSERIAL PRIMARY KEY,\r\n event_type TEXT NOT NULL,\r\n severity TEXT NOT NULL CHECK (\r\n severity IN (\r\n 'low',\r\n 'medium',\r\n 'high',\r\n 'critical'\r\n )\r\n ),\r\n ip_address TEXT,\r\n path TEXT,\r\n method TEXT,\r\n user_agent TEXT,\r\n details JSONB,\r\n occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_security_events_event_type\r\n ON audit_security_events (event_type);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_security_events_severity\r\n ON audit_security_events (severity);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_security_events_occurred_at\r\n ON audit_security_events (occurred_at DESC);\r\n\r\nCREATE TABLE IF NOT EXISTS audit_api_access (\r\n id BIGSERIAL PRIMARY KEY,\r\n method TEXT NOT NULL,\r\n path TEXT NOT NULL,\r\n status_code INTEGER NOT NULL,\r\n response_time_ms INTEGER,\r\n ip_address TEXT,\r\n user_agent TEXT,\r\n execution_id UUID,\r\n accessed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_api_access_path\r\n ON audit_api_access (path);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_api_access_status_code\r\n ON audit_api_access (status_code);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_api_access_accessed_at\r\n ON audit_api_access (accessed_at DESC);\r\n\r\nCREATE TABLE IF NOT EXISTS audit_overrides (\r\n id BIGSERIAL PRIMARY KEY,\r\n override_id UUID NOT NULL UNIQUE,\r\n execution_id UUID NOT NULL,\r\n approved_by TEXT NOT NULL,\r\n approver_role TEXT NOT NULL,\r\n reason TEXT NOT NULL,\r\n override_signature TEXT NOT NULL,\r\n approved_at TIMESTAMPTZ NOT NULL,\r\n recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\r\n);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_overrides_execution_id\r\n ON audit_overrides (execution_id);\r\n\r\nCREATE INDEX IF NOT EXISTS idx_audit_overrides_approved_at\r\n ON audit_overrides (approved_at DESC);\r\n\r\nCREATE OR REPLACE VIEW view_decision_timeline AS\r\nSELECT\r\n d.execution_id,\r\n d.policy_id,\r\n d.policy_version,\r\n d.decision,\r\n d.execution_state,\r\n d.runtime_version,\r\n d.runtime_hash,\r\n d.executed_at,\r\n d.recorded_at,\r\n v.valid AS verification_valid,\r\n v.signature_verified,\r\n v.runtime_verified,\r\n v.schema_compatible,\r\n v.verified_at\r\nFROM audit_decisions d\r\nLEFT JOIN audit_verifications v\r\nON d.execution_id = v.execution_id;\r\n\r\nCREATE OR REPLACE VIEW view_security_dashboard AS\r\nSELECT\r\n event_type,\r\n severity,\r\n COUNT(*) AS event_count,\r\n MAX(occurred_at) AS last_occurrence,\r\n MIN(occurred_at) AS first_occurrence\r\nFROM audit_security_events\r\nGROUP BY event_type, severity;\r\n`;\r\n\r\nexport async function runMigrations(\r\n client: PoolClient\r\n): Promise<void> {\r\n\r\n await client.query(\"BEGIN\");\r\n\r\n try {\r\n\r\n await client.query(\r\n SCHEMA_SQL\r\n );\r\n\r\n await client.query(\r\n \"COMMIT\"\r\n );\r\n\r\n } catch (err) {\r\n\r\n await client.query(\r\n \"ROLLBACK\"\r\n );\r\n\r\n throw err;\r\n }\r\n}"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parmanasystems/audit-db",
3
- "version": "1.10.0",
3
+ "version": "1.14.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "PostgreSQL audit database client for parmanasystems governance decisions, verifications, and security events.",
@@ -19,8 +19,8 @@
19
19
  ],
20
20
  "sideEffects": false,
21
21
  "dependencies": {
22
- "@parmanasystems/execution": "^1.10.0",
23
- "@parmanasystems/verifier": "^1.10.0",
22
+ "@parmanasystems/execution": "^1.14.0",
23
+ "@parmanasystems/verifier": "^1.14.0",
24
24
  "pg": "^8.13.3"
25
25
  },
26
26
  "devDependencies": {