@nodii/grpc-interceptors 0.3.7 → 0.4.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/configure.d.ts +26 -0
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +27 -1
- package/dist/configure.js.map +1 -1
- package/dist/framing.d.ts +122 -0
- package/dist/framing.d.ts.map +1 -0
- package/dist/framing.js +232 -0
- package/dist/framing.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interceptors/audit.d.ts.map +1 -1
- package/dist/interceptors/audit.js +100 -25
- package/dist/interceptors/audit.js.map +1 -1
- package/dist/types.d.ts +26 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -5
package/dist/configure.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type FramingSqlExecutor, type FramingWriter } from "./framing";
|
|
1
2
|
import type { AuditConfig, CancellationConfig, DbConnection, DeadlineConfig, EnrichAuthConfig, ErrorMapEntry, InterceptorLogger, LoggingConfig, UnaryInterceptor } from "./types";
|
|
2
3
|
export interface ConfigureGrpcInterceptorsOptions {
|
|
3
4
|
/** Service short-name baked into the `<short>.audit_ctx` GUC. Required. */
|
|
@@ -18,6 +19,31 @@ export interface ConfigureGrpcInterceptorsOptions {
|
|
|
18
19
|
errorCatalog?: Record<string, ErrorMapEntry>;
|
|
19
20
|
logging?: LoggingConfig;
|
|
20
21
|
audit?: AuditConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Pattern-C framing-row target (request 2ecefe7c / D191 / 02-audit § 13).
|
|
24
|
+
*
|
|
25
|
+
* The audit interceptor writes coarse per-RPC framing rows to a SEPARATE,
|
|
26
|
+
* UNCHAINED `<svc>_audit_framing` table — distinct from the doctrinal
|
|
27
|
+
* in-tx RICH chain emit. This block makes the target CONFIGURABLE:
|
|
28
|
+
*
|
|
29
|
+
* - `sql` set → a `PostgresFramingWriter` is built automatically
|
|
30
|
+
* against `table` (DEFAULT `getAuditFramingTableName(serviceShortName)`,
|
|
31
|
+
* i.e. `<svc>_audit_framing`). `table` is the BACK-COMPAT override an
|
|
32
|
+
* existing consumer (e.g. billing) uses to point framing at its prior
|
|
33
|
+
* table.
|
|
34
|
+
* - `writer` set → that writer is used verbatim (full override).
|
|
35
|
+
* - neither → no framing writer; the interceptor falls back to the
|
|
36
|
+
* legacy `audit.emitter` / `@nodii/telemetry.audit.emit` path
|
|
37
|
+
* (back-compat).
|
|
38
|
+
*/
|
|
39
|
+
framing?: {
|
|
40
|
+
/** Postgres executor (postgres.js / pg / drizzle wrapper) for the default writer. */
|
|
41
|
+
sql?: FramingSqlExecutor;
|
|
42
|
+
/** Override the framing table name. Default `<svc>_audit_framing`. */
|
|
43
|
+
table?: string;
|
|
44
|
+
/** Provide a fully-built writer instead of letting the helper construct one. */
|
|
45
|
+
writer?: FramingWriter;
|
|
46
|
+
};
|
|
21
47
|
enrich?: EnrichAuthConfig;
|
|
22
48
|
deadline?: DeadlineConfig;
|
|
23
49
|
cancellation?: CancellationConfig;
|
package/dist/configure.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AA8BA,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAanB,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,aAAa,EAGb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,gCAAgC;IAC/C,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,iEAAiE;IACjE,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,EAAE;QACR,qFAAqF;QACrF,GAAG,CAAC,EAAE,kBAAkB,CAAC;QACzB,sEAAsE;QACtE,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,gFAAgF;QAChF,MAAM,CAAC,EAAE,aAAa,CAAC;KACxB,CAAC;IACF,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,gEAAgE;IAChE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;OAGG;IACH,yBAAyB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CACxC;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,aAAa,IAAI,gBAAgB,CAAC;IAClC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,8BAA8B,CAAC;CACnD;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrD,QAAQ,CAAC,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACxD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChD;AAID;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,0BAA0B,CAgG5B;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,IAAI,0BAA0B,GAAG,IAAI,CAEvE;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
|
package/dist/configure.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
// → error-map → handler).
|
|
28
28
|
import { idempotencyGuard } from "@nodii/idempotency";
|
|
29
29
|
import { sagaContext } from "@nodii/saga";
|
|
30
|
+
import { getAuditFramingTableName, PostgresFramingWriter, } from "./framing";
|
|
30
31
|
import { signalBinder } from "./interceptors/signal-binder";
|
|
31
32
|
import { cancellationGuard, deadlineGuard, enrichAuthContext, errorMap, STANDARD_ERROR_CATALOG, tenantContext, withAuditUnary, withLoggingUnary, } from "./interceptors-exports";
|
|
32
33
|
import { auditContext } from "./interceptors/audit-context";
|
|
@@ -62,12 +63,19 @@ export function configureGrpcInterceptors(options) {
|
|
|
62
63
|
requireSagaContextMethods: options.requireSagaContextMethods ?? new Set(),
|
|
63
64
|
sagaContextEnforce: options.sagaContextEnforce ?? "warn",
|
|
64
65
|
};
|
|
66
|
+
const framingWriter = resolveFramingWriter(options);
|
|
65
67
|
const interceptors = [
|
|
66
68
|
withLoggingUnary({
|
|
67
69
|
...(options.logging ?? {}),
|
|
68
70
|
logger: options.logger ?? options.logging?.logger,
|
|
69
71
|
}),
|
|
70
|
-
withAuditUnary(
|
|
72
|
+
withAuditUnary({
|
|
73
|
+
...(options.audit ?? {}),
|
|
74
|
+
serviceShortName: options.audit?.serviceShortName ?? options.serviceShortName,
|
|
75
|
+
// Explicit audit.framingWriter wins; else the resolved one from the
|
|
76
|
+
// `framing` block; else undefined (legacy emitter fallback).
|
|
77
|
+
framingWriter: options.audit?.framingWriter ?? framingWriter,
|
|
78
|
+
}),
|
|
71
79
|
// withAuthUnary slot: services supply their own configured wrapper
|
|
72
80
|
// via the re-exported `withAuthUnary` (it requires JWKS / token
|
|
73
81
|
// manager wiring that varies per service). This factory composes
|
|
@@ -127,6 +135,24 @@ export function _resetConfigureForTests() {
|
|
|
127
135
|
resolved = null;
|
|
128
136
|
}
|
|
129
137
|
// ── Internal slot helpers ────────────────────────────────────────────────────
|
|
138
|
+
/**
|
|
139
|
+
* Resolve the Pattern-C framing writer from the `framing` block (request
|
|
140
|
+
* 2ecefe7c / D191). Precedence: explicit `framing.writer` → built
|
|
141
|
+
* `PostgresFramingWriter` against `framing.table` (default
|
|
142
|
+
* `<svc>_audit_framing`) when `framing.sql` is supplied → undefined.
|
|
143
|
+
*/
|
|
144
|
+
function resolveFramingWriter(options) {
|
|
145
|
+
const f = options.framing;
|
|
146
|
+
if (!f)
|
|
147
|
+
return undefined;
|
|
148
|
+
if (f.writer)
|
|
149
|
+
return f.writer;
|
|
150
|
+
if (f.sql) {
|
|
151
|
+
const tableName = f.table ?? getAuditFramingTableName(options.serviceShortName);
|
|
152
|
+
return new PostgresFramingWriter({ sql: f.sql, tableName });
|
|
153
|
+
}
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
130
156
|
function passthroughSlot() {
|
|
131
157
|
return (_method, handler) => async (call) => handler(call);
|
|
132
158
|
}
|
package/dist/configure.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,qEAAqE;AACrE,mEAAmE;AACnE,+DAA+D;AAC/D,oEAAoE;AACpE,sEAAsE;AACtE,EAAE;AACF,WAAW;AACX,gCAAgC;AAChC,mCAAmC;AACnC,UAAU;AACV,gEAAgE;AAChE,qBAAqB;AACrB,gBAAgB;AAChB,cAAc;AACd,eAAe;AACf,iBAAiB;AACjB,qBAAqB;AACrB,mFAAmF;AACnF,8EAA8E;AAC9E,QAAQ;AACR,EAAE;AACF,sEAAsE;AACtE,yEAAyE;AACzE,yEAAyE;AACzE,0BAA0B;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,QAAQ,EACR,sBAAsB,EACtB,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAc5D,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { InterceptorLogger } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the unchained framing-table name for a service.
|
|
4
|
+
*
|
|
5
|
+
* D191 / request 2ecefe7c: the DEFAULT target for new services is
|
|
6
|
+
* `<svc>_audit_framing`. `serviceName` is normalised the same way the rich
|
|
7
|
+
* `<svc>_audit_event` table is (lower-cased, `-`/spaces → `_`).
|
|
8
|
+
*
|
|
9
|
+
* @throws if the normalised name is not a safe Postgres identifier.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getAuditFramingTableName(serviceName: string): string;
|
|
12
|
+
/** Lower-case + `[-\s]` → `_`; matches telemetry's `<svc>_audit_event` derivation. */
|
|
13
|
+
export declare function normaliseServiceName(serviceName: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* `CREATE TYPE` DDL for the shared `audit_actor_kind` enum (02-audit § 4).
|
|
16
|
+
* Re-emitted here so the framing migration is self-contained for services
|
|
17
|
+
* that adopt framing WITHOUT the rich `<svc>_audit_event` table. Idempotent.
|
|
18
|
+
* Identical to `@nodii/telemetry/drizzle`'s `AUDIT_ACTOR_KIND_ENUM_DDL`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const AUDIT_ACTOR_KIND_ENUM_DDL: string;
|
|
21
|
+
/** `CREATE TYPE` DDL for the shared `audit_outcome` enum (02-audit § 7). Idempotent. */
|
|
22
|
+
export declare const AUDIT_OUTCOME_ENUM_DDL: string;
|
|
23
|
+
/**
|
|
24
|
+
* Raw `CREATE TABLE` DDL for the UNCHAINED `<svc>_audit_framing` table.
|
|
25
|
+
*
|
|
26
|
+
* The column set is byte-for-byte the rich `<svc>_audit_event` shape (the
|
|
27
|
+
* exact columns `@nodii/telemetry/drizzle`'s `makeAuditEventTable` /
|
|
28
|
+
* `auditEventPartitionDDL` emit) MINUS the three chain columns:
|
|
29
|
+
* - `prev_hash` (BYTEA) — chain only
|
|
30
|
+
* - `row_hash` (BYTEA) — chain only
|
|
31
|
+
* - `tenant_audit_seq` (BIGINT) — chain only
|
|
32
|
+
*
|
|
33
|
+
* No `(tenant_id, tenant_audit_seq)` unique index either (that invariant is
|
|
34
|
+
* chain-only). Framing rows are observability-only and are NEVER hashed, so
|
|
35
|
+
* the per-tenant monotonic seq + linked hashes are intentionally absent.
|
|
36
|
+
*
|
|
37
|
+
* Unlike the rich table this is NOT partitioned and carries NO FK to
|
|
38
|
+
* `tenants(id)` — a framing row can be written for an RPC that was rejected
|
|
39
|
+
* before tenant resolution (e.g. UNAUTHENTICATED), so `tenant_id` is
|
|
40
|
+
* nullable here. (The rich table's `tenant_id` is `NOT NULL` because rich
|
|
41
|
+
* rows are emitted in-handler after tenant context is established.)
|
|
42
|
+
*
|
|
43
|
+
* @param serviceName service short-name; normalised to the table prefix.
|
|
44
|
+
* @param opts.includeEnumDdl prepend the two `CREATE TYPE` enum DDLs
|
|
45
|
+
* (idempotent) so the migration is self-contained. Default `true`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function makeAuditFramingTableDDL(serviceName: string, opts?: {
|
|
48
|
+
includeEnumDdl?: boolean;
|
|
49
|
+
}): string;
|
|
50
|
+
/**
|
|
51
|
+
* The supplementary B-tree indexes on the framing table. Mirrors the rich
|
|
52
|
+
* table's queryable read-paths MINUS the chain-only `(tenant_id,
|
|
53
|
+
* tenant_audit_seq)` index. Returned as one `CREATE INDEX` per element so
|
|
54
|
+
* the caller applies them individually.
|
|
55
|
+
*/
|
|
56
|
+
export declare function auditFramingIndexDDL(serviceName: string): string[];
|
|
57
|
+
/** The resolved row a `FramingWriter` persists to the unchained framing table. */
|
|
58
|
+
export interface FramingRow {
|
|
59
|
+
tenant_id: string | null;
|
|
60
|
+
actor_kind: string;
|
|
61
|
+
actor_id: string | null;
|
|
62
|
+
action: string;
|
|
63
|
+
resource_type: string;
|
|
64
|
+
resource_id: string | null;
|
|
65
|
+
outcome: string;
|
|
66
|
+
grpc_code: string | null;
|
|
67
|
+
error_message: string | null;
|
|
68
|
+
correlation_id: string | null;
|
|
69
|
+
request_id: string | null;
|
|
70
|
+
trace_id: string | null;
|
|
71
|
+
span_id: string | null;
|
|
72
|
+
intent_id: string | null;
|
|
73
|
+
saga_id: string | null;
|
|
74
|
+
idempotency_key: string | null;
|
|
75
|
+
metadata: Record<string, unknown>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Pattern-C framing writer. The interceptor hands a resolved `FramingRow`;
|
|
79
|
+
* the writer persists it to the UNCHAINED framing table on its own tx.
|
|
80
|
+
* Failures are best-effort per audit doctrine § 6.2 — the interceptor logs
|
|
81
|
+
* and proceeds (framing is observability, not the forensic record).
|
|
82
|
+
*/
|
|
83
|
+
export interface FramingWriter {
|
|
84
|
+
write(row: FramingRow): Promise<void>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Minimal Postgres handle the `PostgresFramingWriter` needs. `postgres.js`,
|
|
88
|
+
* `pg`, and `drizzle` all expose a parameterised exec; consumers adapt with
|
|
89
|
+
* a thin wrapper. Only `unsafe(sql, params)` (text + positional params) is
|
|
90
|
+
* used — Pattern C, no row-returning queries.
|
|
91
|
+
*/
|
|
92
|
+
export interface FramingSqlExecutor {
|
|
93
|
+
unsafe(sql: string, params?: readonly unknown[]): Promise<unknown>;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Real Postgres `FramingWriter` (R1 — no Noop default in production paths).
|
|
97
|
+
* Writes one unchained row to the configured framing table per RPC entry.
|
|
98
|
+
* Each write is an independent INSERT (Pattern C — fresh connection from the
|
|
99
|
+
* caller's pool; NO caller tx, NO advisory lock, NO chain columns).
|
|
100
|
+
*
|
|
101
|
+
* `tableName` is the CONFIGURABLE target. New services pass
|
|
102
|
+
* `getAuditFramingTableName(svc)` (the default); a back-compat consumer that
|
|
103
|
+
* historically pointed framing at another table passes that name instead.
|
|
104
|
+
*/
|
|
105
|
+
export declare class PostgresFramingWriter implements FramingWriter {
|
|
106
|
+
readonly tableName: string;
|
|
107
|
+
private readonly sql;
|
|
108
|
+
constructor(opts: {
|
|
109
|
+
sql: FramingSqlExecutor;
|
|
110
|
+
tableName: string;
|
|
111
|
+
});
|
|
112
|
+
write(row: FramingRow): Promise<void>;
|
|
113
|
+
}
|
|
114
|
+
/** A framing writer that records rows in memory — TEST DOUBLE ONLY (never a default). */
|
|
115
|
+
export declare class RecordingFramingWriter implements FramingWriter {
|
|
116
|
+
readonly rows: FramingRow[];
|
|
117
|
+
failOnce: boolean;
|
|
118
|
+
write(row: FramingRow): Promise<void>;
|
|
119
|
+
}
|
|
120
|
+
/** Helper used by the interceptor to log a best-effort framing write failure. */
|
|
121
|
+
export declare function logFramingWriteFailure(log: InterceptorLogger, method: string, err: unknown): void;
|
|
122
|
+
//# sourceMappingURL=framing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framing.d.ts","sourceRoot":"","sources":["../src/framing.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAKjD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CASpE;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAQ9B,CAAC;AAET,wFAAwF;AACxF,eAAO,MAAM,sBAAsB,QAO3B,CAAC;AAET;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,MAAM,CAoDR;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAQlE;AAED,kFAAkF;AAClF,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAED;;;;;;;;;GASG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;gBAE7B,IAAI,EAAE;QAAE,GAAG,EAAE,kBAAkB,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAe1D,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CA+B5C;AAED,yFAAyF;AACzF,qBAAa,sBAAuB,YAAW,aAAa;IAC1D,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAM;IACjC,QAAQ,UAAS;IACX,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAO5C;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,OAAO,GACX,IAAI,CAKN"}
|
package/dist/framing.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Pattern-C audit FRAMING rows — request 2ecefe7c / D191 / 02-audit-doctrine § 13.
|
|
2
|
+
//
|
|
3
|
+
// `withAuditUnary` emits a coarse "framing" row on every RPC entry (Pattern
|
|
4
|
+
// C — no caller tx, fresh-connection emit). The doctrinal tamper-evident
|
|
5
|
+
// forensic record is the in-tx RICH chain emit (`audit.emit(tx, args)`,
|
|
6
|
+
// Pattern A/B) hashed by `@nodii/audit-chain`. Pattern C CANNOT acquire the
|
|
7
|
+
// per-tenant `pg_advisory_xact_lock` the chain append requires, so framing
|
|
8
|
+
// rows are NOT chained.
|
|
9
|
+
//
|
|
10
|
+
// Option B (recommended + locked by request 2ecefe7c): framing rows are
|
|
11
|
+
// OPERATIONAL TELEMETRY, not the forensic record. They land in a SEPARATE,
|
|
12
|
+
// UNCHAINED `<svc>_audit_framing` table whose columns mirror the rich
|
|
13
|
+
// `<svc>_audit_event` table MINUS the three chain columns (`prev_hash`,
|
|
14
|
+
// `row_hash`, `tenant_audit_seq`). The framing table is never hashed; it
|
|
15
|
+
// rides into ClickHouse / obs as needed.
|
|
16
|
+
//
|
|
17
|
+
// Cross-link: 02-audit-doctrine § 13 — chain = primary forensic record;
|
|
18
|
+
// framing = supplementary observability.
|
|
19
|
+
/** Postgres identifier guard — service short-names + table names are bare idents. */
|
|
20
|
+
const SAFE_IDENT = /^[a-z_][a-z0-9_]*$/;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the unchained framing-table name for a service.
|
|
23
|
+
*
|
|
24
|
+
* D191 / request 2ecefe7c: the DEFAULT target for new services is
|
|
25
|
+
* `<svc>_audit_framing`. `serviceName` is normalised the same way the rich
|
|
26
|
+
* `<svc>_audit_event` table is (lower-cased, `-`/spaces → `_`).
|
|
27
|
+
*
|
|
28
|
+
* @throws if the normalised name is not a safe Postgres identifier.
|
|
29
|
+
*/
|
|
30
|
+
export function getAuditFramingTableName(serviceName) {
|
|
31
|
+
const norm = normaliseServiceName(serviceName);
|
|
32
|
+
const name = `${norm}_audit_framing`;
|
|
33
|
+
if (!SAFE_IDENT.test(name)) {
|
|
34
|
+
throw new Error(`@nodii/grpc-interceptors: unsafe framing table name derived from serviceName=${JSON.stringify(serviceName)} (got ${JSON.stringify(name)}).`);
|
|
35
|
+
}
|
|
36
|
+
return name;
|
|
37
|
+
}
|
|
38
|
+
/** Lower-case + `[-\s]` → `_`; matches telemetry's `<svc>_audit_event` derivation. */
|
|
39
|
+
export function normaliseServiceName(serviceName) {
|
|
40
|
+
return serviceName
|
|
41
|
+
.trim()
|
|
42
|
+
.toLowerCase()
|
|
43
|
+
.replace(/[-\s]+/g, "_");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* `CREATE TYPE` DDL for the shared `audit_actor_kind` enum (02-audit § 4).
|
|
47
|
+
* Re-emitted here so the framing migration is self-contained for services
|
|
48
|
+
* that adopt framing WITHOUT the rich `<svc>_audit_event` table. Idempotent.
|
|
49
|
+
* Identical to `@nodii/telemetry/drizzle`'s `AUDIT_ACTOR_KIND_ENUM_DDL`.
|
|
50
|
+
*/
|
|
51
|
+
export const AUDIT_ACTOR_KIND_ENUM_DDL = `
|
|
52
|
+
DO $$ BEGIN
|
|
53
|
+
CREATE TYPE audit_actor_kind AS ENUM (
|
|
54
|
+
'employee_user','tenant_user','tenant_customer','service','worker',
|
|
55
|
+
'webhook_provider','external_system','agent','system','unknown'
|
|
56
|
+
);
|
|
57
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
58
|
+
END $$;
|
|
59
|
+
`.trim();
|
|
60
|
+
/** `CREATE TYPE` DDL for the shared `audit_outcome` enum (02-audit § 7). Idempotent. */
|
|
61
|
+
export const AUDIT_OUTCOME_ENUM_DDL = `
|
|
62
|
+
DO $$ BEGIN
|
|
63
|
+
CREATE TYPE audit_outcome AS ENUM (
|
|
64
|
+
'success','failure','partial','queued','dry_run','denied_by_authz','denied_by_mfa'
|
|
65
|
+
);
|
|
66
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
67
|
+
END $$;
|
|
68
|
+
`.trim();
|
|
69
|
+
/**
|
|
70
|
+
* Raw `CREATE TABLE` DDL for the UNCHAINED `<svc>_audit_framing` table.
|
|
71
|
+
*
|
|
72
|
+
* The column set is byte-for-byte the rich `<svc>_audit_event` shape (the
|
|
73
|
+
* exact columns `@nodii/telemetry/drizzle`'s `makeAuditEventTable` /
|
|
74
|
+
* `auditEventPartitionDDL` emit) MINUS the three chain columns:
|
|
75
|
+
* - `prev_hash` (BYTEA) — chain only
|
|
76
|
+
* - `row_hash` (BYTEA) — chain only
|
|
77
|
+
* - `tenant_audit_seq` (BIGINT) — chain only
|
|
78
|
+
*
|
|
79
|
+
* No `(tenant_id, tenant_audit_seq)` unique index either (that invariant is
|
|
80
|
+
* chain-only). Framing rows are observability-only and are NEVER hashed, so
|
|
81
|
+
* the per-tenant monotonic seq + linked hashes are intentionally absent.
|
|
82
|
+
*
|
|
83
|
+
* Unlike the rich table this is NOT partitioned and carries NO FK to
|
|
84
|
+
* `tenants(id)` — a framing row can be written for an RPC that was rejected
|
|
85
|
+
* before tenant resolution (e.g. UNAUTHENTICATED), so `tenant_id` is
|
|
86
|
+
* nullable here. (The rich table's `tenant_id` is `NOT NULL` because rich
|
|
87
|
+
* rows are emitted in-handler after tenant context is established.)
|
|
88
|
+
*
|
|
89
|
+
* @param serviceName service short-name; normalised to the table prefix.
|
|
90
|
+
* @param opts.includeEnumDdl prepend the two `CREATE TYPE` enum DDLs
|
|
91
|
+
* (idempotent) so the migration is self-contained. Default `true`.
|
|
92
|
+
*/
|
|
93
|
+
export function makeAuditFramingTableDDL(serviceName, opts = {}) {
|
|
94
|
+
const table = getAuditFramingTableName(serviceName);
|
|
95
|
+
const includeEnumDdl = opts.includeEnumDdl ?? true;
|
|
96
|
+
const enumPrefix = includeEnumDdl
|
|
97
|
+
? `${AUDIT_ACTOR_KIND_ENUM_DDL}\n${AUDIT_OUTCOME_ENUM_DDL}\n`
|
|
98
|
+
: "";
|
|
99
|
+
return `${enumPrefix}CREATE TABLE IF NOT EXISTS ${table} (
|
|
100
|
+
id UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
101
|
+
tenant_id UUID,
|
|
102
|
+
at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
103
|
+
actor_kind audit_actor_kind NOT NULL,
|
|
104
|
+
actor_id TEXT,
|
|
105
|
+
actor_external_id TEXT,
|
|
106
|
+
actor_display TEXT,
|
|
107
|
+
actor_ip INET,
|
|
108
|
+
actor_user_agent TEXT,
|
|
109
|
+
actor JSONB,
|
|
110
|
+
action TEXT NOT NULL,
|
|
111
|
+
resource_type TEXT NOT NULL,
|
|
112
|
+
resource_id TEXT,
|
|
113
|
+
resource_label TEXT,
|
|
114
|
+
secondary_resource_type TEXT,
|
|
115
|
+
secondary_resource_id TEXT,
|
|
116
|
+
outcome audit_outcome NOT NULL DEFAULT 'success',
|
|
117
|
+
http_status INTEGER,
|
|
118
|
+
grpc_code TEXT,
|
|
119
|
+
error_code TEXT,
|
|
120
|
+
error_message TEXT,
|
|
121
|
+
error_details JSONB,
|
|
122
|
+
before JSONB,
|
|
123
|
+
after JSONB,
|
|
124
|
+
patch JSONB,
|
|
125
|
+
changed_fields TEXT[],
|
|
126
|
+
reason_code TEXT,
|
|
127
|
+
reason_text TEXT,
|
|
128
|
+
request_id TEXT,
|
|
129
|
+
correlation_id TEXT,
|
|
130
|
+
trace_id TEXT,
|
|
131
|
+
span_id TEXT,
|
|
132
|
+
intent_id UUID,
|
|
133
|
+
saga_id TEXT,
|
|
134
|
+
step_id TEXT,
|
|
135
|
+
idempotency_key TEXT,
|
|
136
|
+
queue_name TEXT,
|
|
137
|
+
job_id TEXT,
|
|
138
|
+
parent_audit_event_id UUID,
|
|
139
|
+
read_count INTEGER,
|
|
140
|
+
first_read_at TIMESTAMPTZ,
|
|
141
|
+
last_read_at TIMESTAMPTZ,
|
|
142
|
+
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
143
|
+
PRIMARY KEY (id)
|
|
144
|
+
);`;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The supplementary B-tree indexes on the framing table. Mirrors the rich
|
|
148
|
+
* table's queryable read-paths MINUS the chain-only `(tenant_id,
|
|
149
|
+
* tenant_audit_seq)` index. Returned as one `CREATE INDEX` per element so
|
|
150
|
+
* the caller applies them individually.
|
|
151
|
+
*/
|
|
152
|
+
export function auditFramingIndexDDL(serviceName) {
|
|
153
|
+
const t = getAuditFramingTableName(serviceName);
|
|
154
|
+
const norm = normaliseServiceName(serviceName);
|
|
155
|
+
return [
|
|
156
|
+
`CREATE INDEX IF NOT EXISTS ${norm}_audit_framing_tenant_time ON ${t} (tenant_id, at);`,
|
|
157
|
+
`CREATE INDEX IF NOT EXISTS ${norm}_audit_framing_action_outcome ON ${t} (tenant_id, action, outcome, at);`,
|
|
158
|
+
`CREATE INDEX IF NOT EXISTS ${norm}_audit_framing_correlation ON ${t} (tenant_id, correlation_id);`,
|
|
159
|
+
];
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Real Postgres `FramingWriter` (R1 — no Noop default in production paths).
|
|
163
|
+
* Writes one unchained row to the configured framing table per RPC entry.
|
|
164
|
+
* Each write is an independent INSERT (Pattern C — fresh connection from the
|
|
165
|
+
* caller's pool; NO caller tx, NO advisory lock, NO chain columns).
|
|
166
|
+
*
|
|
167
|
+
* `tableName` is the CONFIGURABLE target. New services pass
|
|
168
|
+
* `getAuditFramingTableName(svc)` (the default); a back-compat consumer that
|
|
169
|
+
* historically pointed framing at another table passes that name instead.
|
|
170
|
+
*/
|
|
171
|
+
export class PostgresFramingWriter {
|
|
172
|
+
tableName;
|
|
173
|
+
sql;
|
|
174
|
+
constructor(opts) {
|
|
175
|
+
if (!opts?.sql) {
|
|
176
|
+
throw new Error("@nodii/grpc-interceptors: PostgresFramingWriter requires a `sql` executor (R1 — no Noop default).");
|
|
177
|
+
}
|
|
178
|
+
if (!opts.tableName || !SAFE_IDENT.test(opts.tableName)) {
|
|
179
|
+
throw new Error(`@nodii/grpc-interceptors: PostgresFramingWriter requires a safe \`tableName\`; got ${JSON.stringify(opts.tableName)}.`);
|
|
180
|
+
}
|
|
181
|
+
this.sql = opts.sql;
|
|
182
|
+
this.tableName = opts.tableName;
|
|
183
|
+
}
|
|
184
|
+
async write(row) {
|
|
185
|
+
// Positional INSERT into the UNCHAINED table. Note: NO prev_hash /
|
|
186
|
+
// row_hash / tenant_audit_seq — framing rows are never in the chain.
|
|
187
|
+
await this.sql.unsafe(`INSERT INTO ${this.tableName}
|
|
188
|
+
(tenant_id, actor_kind, actor_id, action, resource_type, resource_id,
|
|
189
|
+
outcome, grpc_code, error_message, correlation_id, request_id,
|
|
190
|
+
trace_id, span_id, intent_id, saga_id, idempotency_key, metadata)
|
|
191
|
+
VALUES
|
|
192
|
+
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17::jsonb)`, [
|
|
193
|
+
row.tenant_id,
|
|
194
|
+
row.actor_kind,
|
|
195
|
+
row.actor_id,
|
|
196
|
+
row.action,
|
|
197
|
+
row.resource_type,
|
|
198
|
+
row.resource_id,
|
|
199
|
+
row.outcome,
|
|
200
|
+
row.grpc_code,
|
|
201
|
+
row.error_message,
|
|
202
|
+
row.correlation_id,
|
|
203
|
+
row.request_id,
|
|
204
|
+
row.trace_id,
|
|
205
|
+
row.span_id,
|
|
206
|
+
row.intent_id,
|
|
207
|
+
row.saga_id,
|
|
208
|
+
row.idempotency_key,
|
|
209
|
+
JSON.stringify(row.metadata ?? {}),
|
|
210
|
+
]);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/** A framing writer that records rows in memory — TEST DOUBLE ONLY (never a default). */
|
|
214
|
+
export class RecordingFramingWriter {
|
|
215
|
+
rows = [];
|
|
216
|
+
failOnce = false;
|
|
217
|
+
async write(row) {
|
|
218
|
+
if (this.failOnce) {
|
|
219
|
+
this.failOnce = false;
|
|
220
|
+
throw new Error("recording-framing-writer forced failure");
|
|
221
|
+
}
|
|
222
|
+
this.rows.push(row);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/** Helper used by the interceptor to log a best-effort framing write failure. */
|
|
226
|
+
export function logFramingWriteFailure(log, method, err) {
|
|
227
|
+
log.error("audit.framing_write_failed", {
|
|
228
|
+
method,
|
|
229
|
+
error: err instanceof Error ? err.message : String(err),
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=framing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framing.js","sourceRoot":"","sources":["../src/framing.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export { cancellationGuard } from "./interceptors/cancellation-guard";
|
|
|
10
10
|
export { errorMap, STANDARD_ERROR_CATALOG, } from "./interceptors/error-map";
|
|
11
11
|
export { createStandardServerStack } from "./factory";
|
|
12
12
|
export { composeUnaryInterceptors } from "./compose";
|
|
13
|
+
export { getAuditFramingTableName, normaliseServiceName, makeAuditFramingTableDDL, auditFramingIndexDDL, AUDIT_ACTOR_KIND_ENUM_DDL, AUDIT_OUTCOME_ENUM_DDL, PostgresFramingWriter, RecordingFramingWriter, } from "./framing";
|
|
14
|
+
export type { FramingRow, FramingWriter, FramingSqlExecutor, } from "./framing";
|
|
13
15
|
export { configureGrpcInterceptors, getConfiguredOrNull, _resetConfigureForTests, } from "./configure";
|
|
14
16
|
export type { ConfigureGrpcInterceptorsOptions, ConfiguredGrpcInterceptors, ResolvedGrpcInterceptorsConfig, } from "./configure";
|
|
15
17
|
export { _resetTelemetryShimForTests, _setTelemetryShimForTests, } from "./telemetry-shim";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,QAAQ,sBAAsB,CAAC;AAC5C,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,gCAAgC,EAChC,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAI1B,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGtE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,yBAAyB,EACzB,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,QAAQ,sBAAsB,CAAC;AAC5C,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,UAAU,EACV,aAAa,EACb,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,gCAAgC,EAChC,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAI1B,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGtE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,yBAAyB,EACzB,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,8 @@ export { errorMap, STANDARD_ERROR_CATALOG, } from "./interceptors/error-map";
|
|
|
21
21
|
// Composed-stack factory + composer.
|
|
22
22
|
export { createStandardServerStack } from "./factory";
|
|
23
23
|
export { composeUnaryInterceptors } from "./compose";
|
|
24
|
+
// Pattern-C UNCHAINED audit framing (request 2ecefe7c / D191 / § 13).
|
|
25
|
+
export { getAuditFramingTableName, normaliseServiceName, makeAuditFramingTableDDL, auditFramingIndexDDL, AUDIT_ACTOR_KIND_ENUM_DDL, AUDIT_OUTCOME_ENUM_DDL, PostgresFramingWriter, RecordingFramingWriter, } from "./framing";
|
|
24
26
|
// Boot helper (spec § 5.2 + § 5.5).
|
|
25
27
|
export { configureGrpcInterceptors, getConfiguredOrNull, _resetConfigureForTests, } from "./configure";
|
|
26
28
|
// Test doubles + helpers.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,gFAAgF;AAChF,EAAE;AACF,mEAAmE;AACnE,oEAAoE;AACpE,qEAAqE;AACrE,oEAAoE;AACpE,6DAA6D;AAE7D,MAAM,CAAC,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AAC5C,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAElC,qCAAqC;AACrC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,oCAAoC;AACpC,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAOrB,0BAA0B;AAC1B,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,0EAA0E;AAC1E,mCAAmC;AACnC,cAAc,aAAa,CAAC;AAwB5B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,gFAAgF;AAChF,EAAE;AACF,mEAAmE;AACnE,oEAAoE;AACpE,qEAAqE;AACrE,oEAAoE;AACpE,6DAA6D;AAE7D,MAAM,CAAC,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AAC5C,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAElC,qCAAqC;AACrC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,sEAAsE;AACtE,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AAOnB,oCAAoC;AACpC,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAOrB,0BAA0B;AAC1B,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,0EAA0E;AAC1E,mCAAmC;AACnC,cAAc,aAAa,CAAC;AAwB5B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/interceptors/audit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/interceptors/audit.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EACV,WAAW,EAIX,gBAAgB,EACjB,MAAM,UAAU,CAAC;AA+BlB;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,GAAE,WAAgB,GAAG,gBAAgB,CAmGzE"}
|
|
@@ -1,12 +1,30 @@
|
|
|
1
|
-
// withAuditUnary — spec § 5.6.
|
|
1
|
+
// withAuditUnary — spec § 5.6 + request 2ecefe7c (D191 / 02-audit-doctrine § 13).
|
|
2
2
|
//
|
|
3
3
|
// Emits the *framing* row on every gRPC call (mutator + audited reads,
|
|
4
4
|
// including rejections). The handler is still responsible for the
|
|
5
|
-
// state-change row inside its own tx via `audit.emit(tx, ...)
|
|
6
|
-
//
|
|
5
|
+
// state-change row inside its own tx via `audit.emit(tx, ...)` — that
|
|
6
|
+
// in-tx RICH emit (Pattern A/B) is the DOCTRINAL tamper-evident forensic
|
|
7
|
+
// record, hashed by `@nodii/audit-chain`. This interceptor NEVER touches
|
|
8
|
+
// that path.
|
|
7
9
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
+
// Framing rows are Pattern C (no caller tx, fresh-connection emit) and so
|
|
11
|
+
// CANNOT acquire the per-tenant `pg_advisory_xact_lock` the chain append
|
|
12
|
+
// requires — they are therefore NOT chained. Per request 2ecefe7c
|
|
13
|
+
// (Option B), framing rows are OPERATIONAL TELEMETRY written to a SEPARATE,
|
|
14
|
+
// UNCHAINED `<svc>_audit_framing` table (§ 13: chain = primary forensic
|
|
15
|
+
// record; framing = supplementary observability). The framing + state-change
|
|
16
|
+
// row join via `correlation_id`.
|
|
17
|
+
//
|
|
18
|
+
// Target resolution (configurable):
|
|
19
|
+
// 1. `config.framingWriter` set → write the unchained framing row there
|
|
20
|
+
// (RECOMMENDED; new services point it at `<svc>_audit_framing`).
|
|
21
|
+
// 2. else `config.emitter` set → legacy Pattern-C emit (back-compat for
|
|
22
|
+
// consumers that historically pointed framing at their own table).
|
|
23
|
+
// 3. else → `@nodii/telemetry.audit.emit` fallback.
|
|
24
|
+
//
|
|
25
|
+
// All paths are best-effort — emitter/writer failures log and proceed per
|
|
26
|
+
// audit doctrine § 6.2.
|
|
27
|
+
import { logFramingWriteFailure } from "../framing";
|
|
10
28
|
import { resolveTelemetry } from "../telemetry-shim";
|
|
11
29
|
import { GrpcStatusError } from "../types";
|
|
12
30
|
function mapOutcome(code, detail) {
|
|
@@ -45,7 +63,6 @@ export function withAuditUnary(config = {}) {
|
|
|
45
63
|
if (skip.has(methodName))
|
|
46
64
|
return handler(call);
|
|
47
65
|
const t = resolveTelemetry();
|
|
48
|
-
const emitter = config.emitter ?? t.audit;
|
|
49
66
|
const log = t.logger;
|
|
50
67
|
const isAuditOnRead = auditOnRead.has(methodName) || isLikelyMutator(methodName);
|
|
51
68
|
let resultErr;
|
|
@@ -63,26 +80,74 @@ export function withAuditUnary(config = {}) {
|
|
|
63
80
|
: "OK";
|
|
64
81
|
const detail = resultErr ? classify(resultErr).detail : undefined;
|
|
65
82
|
const outcome = mapOutcome(code, detail);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
const action = `rpc.${methodName.replace(/^\/+/, "")}`;
|
|
84
|
+
const tenantId = call.auth?.requestContext?.tenant_id ?? null;
|
|
85
|
+
const correlationId = call.auth?.requestContext?.correlation_id ?? null;
|
|
86
|
+
const actorKind = deriveActorKind(call);
|
|
87
|
+
if (config.framingWriter) {
|
|
88
|
+
// Option B — write the UNCHAINED framing row to the separate
|
|
89
|
+
// `<svc>_audit_framing` table. NOT hashed, NOT in the chain.
|
|
90
|
+
const row = {
|
|
91
|
+
tenant_id: tenantId,
|
|
92
|
+
actor_kind: actorKind,
|
|
93
|
+
actor_id: deriveActorId(call),
|
|
94
|
+
action,
|
|
95
|
+
resource_type: "rpc",
|
|
96
|
+
resource_id: null,
|
|
97
|
+
outcome,
|
|
98
|
+
grpc_code: code,
|
|
99
|
+
error_message: detail ?? null,
|
|
100
|
+
correlation_id: correlationId,
|
|
101
|
+
request_id: call.auth?.requestContext?.intent_id ?? null,
|
|
102
|
+
trace_id: null,
|
|
103
|
+
span_id: null,
|
|
104
|
+
intent_id: call.auth?.requestContext?.intent_id ?? null,
|
|
105
|
+
saga_id: null,
|
|
106
|
+
idempotency_key: null,
|
|
107
|
+
metadata: {
|
|
108
|
+
framing: true,
|
|
109
|
+
...(config.serviceShortName
|
|
110
|
+
? { service: config.serviceShortName }
|
|
111
|
+
: {}),
|
|
78
112
|
},
|
|
79
|
-
}
|
|
113
|
+
};
|
|
114
|
+
// NOTE: deliberately NOT `return` here — a `return` inside a
|
|
115
|
+
// `finally` block would clobber the try-block's return value
|
|
116
|
+
// (the handler's response). Use if/else so the finally only
|
|
117
|
+
// performs side effects.
|
|
118
|
+
try {
|
|
119
|
+
await config.framingWriter.write(row);
|
|
120
|
+
}
|
|
121
|
+
catch (writeErr) {
|
|
122
|
+
logFramingWriteFailure(log, methodName, writeErr);
|
|
123
|
+
}
|
|
80
124
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
125
|
+
else {
|
|
126
|
+
// Back-compat: legacy Pattern-C emit via the provided emitter or
|
|
127
|
+
// `@nodii/telemetry.audit.emit`. Consumers that historically
|
|
128
|
+
// pointed framing at their own table keep working unchanged.
|
|
129
|
+
const emitter = config.emitter ?? t.audit;
|
|
130
|
+
try {
|
|
131
|
+
await emitter.emit({
|
|
132
|
+
action,
|
|
133
|
+
target_kind: "rpc",
|
|
134
|
+
target_id: null,
|
|
135
|
+
payload: {
|
|
136
|
+
outcome,
|
|
137
|
+
code,
|
|
138
|
+
detail,
|
|
139
|
+
correlation_id: correlationId ?? undefined,
|
|
140
|
+
actor_kind: actorKind,
|
|
141
|
+
tenant_id: tenantId,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
catch (emitErr) {
|
|
146
|
+
log.error("audit.emit_failed", {
|
|
147
|
+
method: methodName,
|
|
148
|
+
error: emitErr instanceof Error ? emitErr.message : String(emitErr),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
86
151
|
}
|
|
87
152
|
}
|
|
88
153
|
}
|
|
@@ -90,12 +155,22 @@ export function withAuditUnary(config = {}) {
|
|
|
90
155
|
};
|
|
91
156
|
}
|
|
92
157
|
function deriveActorKind(call) {
|
|
158
|
+
// Map the coarse interceptor-level actor to the canonical 02-audit § 4
|
|
159
|
+
// `audit_actor_kind` enum so the framing row's `actor_kind` column (same
|
|
160
|
+
// enum type as the rich table) accepts the value.
|
|
93
161
|
if (call.auth?.userActor?.user_id)
|
|
94
|
-
return "
|
|
162
|
+
return "tenant_user";
|
|
95
163
|
if (call.auth?.serviceActor?.service_id || call.auth?.serviceActor?.serviceId)
|
|
96
164
|
return "service";
|
|
97
165
|
return "unknown";
|
|
98
166
|
}
|
|
167
|
+
function deriveActorId(call) {
|
|
168
|
+
if (call.auth?.userActor?.user_id)
|
|
169
|
+
return call.auth.userActor.user_id;
|
|
170
|
+
return (call.auth?.serviceActor?.service_id ??
|
|
171
|
+
call.auth?.serviceActor?.serviceId ??
|
|
172
|
+
null);
|
|
173
|
+
}
|
|
99
174
|
/**
|
|
100
175
|
* Heuristic: at v0.1.0 we emit a framing row for every method unless the
|
|
101
176
|
* service explicitly opts out via `skipMethods` (e.g. health probes).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/interceptors/audit.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/interceptors/audit.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -138,9 +138,33 @@ export interface LoggingConfig {
|
|
|
138
138
|
/** Optional sample-rate hook for deterministic tests. Default `Math.random`. */
|
|
139
139
|
random?: () => number;
|
|
140
140
|
}
|
|
141
|
-
/** Audit interceptor config — spec § 5.6. */
|
|
141
|
+
/** Audit interceptor config — spec § 5.6 + request 2ecefe7c (D191 / § 13). */
|
|
142
142
|
export interface AuditConfig {
|
|
143
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* UNCHAINED framing-row writer (request 2ecefe7c / Option B). When set,
|
|
145
|
+
* the interceptor writes Pattern-C framing rows to a SEPARATE
|
|
146
|
+
* `<svc>_audit_framing` table via this writer (NOT the chained forensic
|
|
147
|
+
* record). This is the RECOMMENDED target for new services — wire a
|
|
148
|
+
* `PostgresFramingWriter` against `getAuditFramingTableName(svc)`.
|
|
149
|
+
*
|
|
150
|
+
* Precedence: `framingWriter` (unchained table) takes precedence over the
|
|
151
|
+
* legacy `emitter` path. If neither is set the interceptor falls back to
|
|
152
|
+
* `@nodii/telemetry.audit.emit` (back-compat for existing consumers that
|
|
153
|
+
* historically pointed framing at their own table).
|
|
154
|
+
*/
|
|
155
|
+
framingWriter?: import("./framing").FramingWriter;
|
|
156
|
+
/**
|
|
157
|
+
* Service short-name. Stamped into the framing row's `metadata.service`
|
|
158
|
+
* and used by `configureGrpcInterceptors` to derive the default
|
|
159
|
+
* `<svc>_audit_framing` table when building a `PostgresFramingWriter`.
|
|
160
|
+
*/
|
|
161
|
+
serviceShortName?: string;
|
|
162
|
+
/**
|
|
163
|
+
* Legacy / back-compat emitter (Pattern C via `@nodii/telemetry.audit.emit`).
|
|
164
|
+
* Used only when `framingWriter` is NOT set. An existing consumer (e.g.
|
|
165
|
+
* billing) that pointed the interceptor at its chained audit table keeps
|
|
166
|
+
* working through this path. New services should prefer `framingWriter`.
|
|
167
|
+
*/
|
|
144
168
|
emitter?: AuditEmitter;
|
|
145
169
|
/**
|
|
146
170
|
* Method names (`/svc/Method`) that emit an audit-on-read framing row
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodii/grpc-interceptors",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Substrate gRPC interceptor library for the Nodii microservice stack — 8 cross-cutting interceptors (logging, audit, enrichAuthContext, tenantContext, auditContext, deadlineGuard, cancellationGuard, errorMap) + re-export façade over @nodii/grpc-auth/saga/idempotency + locked-order createStandardServerStack factory. Spec: planning hub docKey=grpc-interceptors.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,12 +24,14 @@
|
|
|
24
24
|
"test": "bun test"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@nodii/grpc-auth": "0.
|
|
28
|
-
"@nodii/idempotency": "0.2.
|
|
29
|
-
"@nodii/saga": "0.4.
|
|
30
|
-
"@nodii/telemetry": "0.
|
|
27
|
+
"@nodii/grpc-auth": "0.4.0",
|
|
28
|
+
"@nodii/idempotency": "0.2.8",
|
|
29
|
+
"@nodii/saga": "0.4.6",
|
|
30
|
+
"@nodii/telemetry": "0.5.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
+
"@nodii/audit-chain": "0.4.0",
|
|
34
|
+
"postgres": "^3.4.0",
|
|
33
35
|
"typescript": "^5.9.3"
|
|
34
36
|
},
|
|
35
37
|
"repository": {
|