@nodii/db-rls 0.3.1 → 0.4.1
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 +17 -0
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +43 -3
- package/dist/configure.js.map +1 -1
- package/dist/context.d.ts +28 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +40 -0
- package/dist/context.js.map +1 -1
- package/dist/drizzle-grants.d.ts +203 -0
- package/dist/drizzle-grants.d.ts.map +1 -0
- package/dist/drizzle-grants.js +68 -0
- package/dist/drizzle-grants.js.map +1 -0
- package/dist/drizzle-policies.d.ts +67 -0
- package/dist/drizzle-policies.d.ts.map +1 -1
- package/dist/drizzle-policies.js +109 -0
- package/dist/drizzle-policies.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +10 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +20 -2
- package/dist/init.js.map +1 -1
- package/dist/types.d.ts +41 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +7 -3
package/dist/configure.d.ts
CHANGED
|
@@ -4,6 +4,10 @@ export interface ConfigureDbRlsPools {
|
|
|
4
4
|
owner: Pool;
|
|
5
5
|
services?: Pool;
|
|
6
6
|
authenticated?: Pool;
|
|
7
|
+
/** D185 platform-ops pool — required in `3-pool-with-platform-ops`
|
|
8
|
+
* mode, forbidden otherwise. Wire against the `nodii_platform_ops`
|
|
9
|
+
* Postgres role per D185 § 1. */
|
|
10
|
+
platformOps?: Pool;
|
|
7
11
|
}
|
|
8
12
|
export interface ConfigureDbRlsOpts {
|
|
9
13
|
/** Per `nodii-libs/telemetry.md` § 5.4. Used in error messages + spans. */
|
|
@@ -48,6 +52,19 @@ export declare class PoolCredentialMismatch extends DbRlsError {
|
|
|
48
52
|
* per the spec's failure modes.
|
|
49
53
|
*/
|
|
50
54
|
export declare function configureDbRls(opts: ConfigureDbRlsOpts): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Convenience wrapper for services with a platform-ops surface
|
|
57
|
+
* per hub decision D185. Equivalent to
|
|
58
|
+
* `configureDbRls({ ..., mode: "3-pool-with-platform-ops" })`.
|
|
59
|
+
*/
|
|
60
|
+
export declare function configureDbRls4Pool(opts: Omit<ConfigureDbRlsOpts, "mode"> & {
|
|
61
|
+
pools: {
|
|
62
|
+
owner: Pool;
|
|
63
|
+
services: Pool;
|
|
64
|
+
authenticated: Pool;
|
|
65
|
+
platformOps: Pool;
|
|
66
|
+
};
|
|
67
|
+
}): Promise<void>;
|
|
51
68
|
/**
|
|
52
69
|
* Convenience wrapper for nodii-auth-shape services per 08-rls § 7.
|
|
53
70
|
* Equivalent to `configureDbRls({ ..., mode: "2-pool" })`.
|
package/dist/configure.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAEL,KAAK,SAAS,EACd,UAAU,EACV,KAAK,QAAQ,EACd,MAAM,SAAS,CAAC;AAIjB,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAEL,KAAK,SAAS,EACd,UAAU,EACV,KAAK,QAAQ,EACd,MAAM,SAAS,CAAC;AAIjB,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB;;sCAEkC;IAClC,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB;;0CAEsC;IACtC,KAAK,EAAE,mBAAmB,CAAC;IAC3B;oDACgD;IAChD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;uEAEmE;IACnE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE,uDAAuD;IACvD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,IAAI,EAAE,QAAQ,CAAC;QACf,OAAO,EAAE,WAAW,GAAG,aAAa,GAAG,OAAO,CAAC;QAC/C,UAAU,EAAE,MAAM,CAAC;KACpB,KAAK,IAAI,CAAC;CACZ;AASD,qBAAa,sBAAuB,SAAQ,UAAU;IACpD,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAS7D;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyF5E;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG;IACvC,KAAK,EAAE;QACL,KAAK,EAAE,IAAI,CAAC;QACZ,QAAQ,EAAE,IAAI,CAAC;QACf,aAAa,EAAE,IAAI,CAAC;QACpB,WAAW,EAAE,IAAI,CAAC;KACnB,CAAC;CACH,GACA,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG;IACvC,KAAK,EAAE;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC;CACzC,GACA,OAAO,CAAC,IAAI,CAAC,CAMf;AAgBD,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
|
package/dist/configure.js
CHANGED
|
@@ -18,6 +18,7 @@ const EXPECTED_ROLES = {
|
|
|
18
18
|
owner: "nodii_owner",
|
|
19
19
|
services: "nodii_services",
|
|
20
20
|
authenticated: "authenticated",
|
|
21
|
+
platform_ops: "nodii_platform_ops",
|
|
21
22
|
};
|
|
22
23
|
export class PoolCredentialMismatch extends DbRlsError {
|
|
23
24
|
pool;
|
|
@@ -46,9 +47,25 @@ export async function configureDbRls(opts) {
|
|
|
46
47
|
if (!opts.pools.services || !opts.pools.authenticated) {
|
|
47
48
|
throw new DbRlsConfigError("configureDbRls: 3-pool mode requires owner + services + authenticated pools. Either supply both, or set mode: '2-pool'.");
|
|
48
49
|
}
|
|
50
|
+
if (opts.pools.platformOps) {
|
|
51
|
+
throw new DbRlsConfigError("configureDbRls: 3-pool mode must not supply a 'platformOps' pool — use mode: '3-pool-with-platform-ops' per hub decision D185.");
|
|
52
|
+
}
|
|
49
53
|
}
|
|
50
|
-
if (mode === "2-pool"
|
|
51
|
-
|
|
54
|
+
if (mode === "2-pool") {
|
|
55
|
+
if (opts.pools.authenticated) {
|
|
56
|
+
throw new DbRlsConfigError("configureDbRls: 2-pool mode must not supply an 'authenticated' pool — the 2-pool exception per 08-rls § 7 has no user-context. Use mode: '3-pool' instead.");
|
|
57
|
+
}
|
|
58
|
+
if (opts.pools.platformOps) {
|
|
59
|
+
throw new DbRlsConfigError("configureDbRls: 2-pool mode must not supply a 'platformOps' pool — the 2-pool exception per 08-rls § 7 has no platform-ops surface. Use mode: '3-pool-with-platform-ops' per D185.");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (mode === "3-pool-with-platform-ops") {
|
|
63
|
+
if (!opts.pools.services || !opts.pools.authenticated) {
|
|
64
|
+
throw new DbRlsConfigError("configureDbRls: '3-pool-with-platform-ops' mode requires owner + services + authenticated + platformOps pools (D185). All four are mandatory.");
|
|
65
|
+
}
|
|
66
|
+
if (!opts.pools.platformOps) {
|
|
67
|
+
throw new DbRlsConfigError("configureDbRls: '3-pool-with-platform-ops' mode requires a 'platformOps' pool wired against the nodii_platform_ops Postgres role (D185 § 1). Did you mean mode: '3-pool'?");
|
|
68
|
+
}
|
|
52
69
|
}
|
|
53
70
|
if (validate) {
|
|
54
71
|
await assertPoolRole(opts.pools.owner, "owner");
|
|
@@ -58,6 +75,9 @@ export async function configureDbRls(opts) {
|
|
|
58
75
|
if (opts.pools.authenticated) {
|
|
59
76
|
await assertPoolRole(opts.pools.authenticated, "authenticated");
|
|
60
77
|
}
|
|
78
|
+
if (opts.pools.platformOps) {
|
|
79
|
+
await assertPoolRole(opts.pools.platformOps, "platform_ops");
|
|
80
|
+
}
|
|
61
81
|
}
|
|
62
82
|
const owner = new PgClientPool({
|
|
63
83
|
pool: opts.pools.owner,
|
|
@@ -84,7 +104,27 @@ export async function configureDbRls(opts) {
|
|
|
84
104
|
onTxFinish: opts.onTxFinish,
|
|
85
105
|
})
|
|
86
106
|
: undefined;
|
|
87
|
-
|
|
107
|
+
const platformOps = opts.pools.platformOps
|
|
108
|
+
? new PgClientPool({
|
|
109
|
+
pool: opts.pools.platformOps,
|
|
110
|
+
kind: "platform_ops",
|
|
111
|
+
slowAcquireMs: opts.slowAcquireMs,
|
|
112
|
+
onSlowAcquire: opts.onSlowAcquire,
|
|
113
|
+
onTxFinish: opts.onTxFinish,
|
|
114
|
+
})
|
|
115
|
+
: undefined;
|
|
116
|
+
initDbRls({ owner, services, authenticated, platformOps, mode });
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Convenience wrapper for services with a platform-ops surface
|
|
120
|
+
* per hub decision D185. Equivalent to
|
|
121
|
+
* `configureDbRls({ ..., mode: "3-pool-with-platform-ops" })`.
|
|
122
|
+
*/
|
|
123
|
+
export async function configureDbRls4Pool(opts) {
|
|
124
|
+
return configureDbRls({
|
|
125
|
+
...opts,
|
|
126
|
+
mode: "3-pool-with-platform-ops",
|
|
127
|
+
});
|
|
88
128
|
}
|
|
89
129
|
/**
|
|
90
130
|
* Convenience wrapper for nodii-auth-shape services per 08-rls § 7.
|
package/dist/configure.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,wBAAwB;AACxB,yEAAyE;AACzE,6EAA6E;AAC7E,4EAA4E;AAC5E,qEAAqE;AACrE,mBAAmB;AACnB,iEAAiE;AACjE,qCAAqC;AACrC,EAAE;AACF,sEAAsE;AACtE,yCAAyC;AAGzC,OAAO,EACL,gBAAgB,EAEhB,UAAU,GAEX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,IAAI,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"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"}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type OwnerContextOpts } from "./migrate-guard";
|
|
2
|
-
import { type AutoDispatchOpts, type PgTx, type SystemContextOpts, type UserContextOpts } from "./types";
|
|
2
|
+
import { type AutoDispatchOpts, type PgTx, type PlatformOpsContextOpts, type SystemContextOpts, type UserContextOpts } from "./types";
|
|
3
3
|
/**
|
|
4
4
|
* withUserContext — opens a tx on the `authenticated` pool, sets
|
|
5
5
|
* `auth.user_id` + `auth.tenant_id` (+ optional `auth.source_ip`) via
|
|
@@ -28,6 +28,33 @@ export declare function withSystemContext<T>(opts: SystemContextOpts, fn: (tx: P
|
|
|
28
28
|
* Throws `OwnerContextOutsideMigrate` if neither is satisfied.
|
|
29
29
|
*/
|
|
30
30
|
export declare function withOwnerContext<T>(fnOrOpts: OwnerContextOpts | ((tx: PgTx) => Promise<T>), maybeFn?: (tx: PgTx) => Promise<T>): Promise<T>;
|
|
31
|
+
/**
|
|
32
|
+
* withPlatformOps — opens a tx on the `platform_ops` pool
|
|
33
|
+
* (nodii_platform_ops Postgres role) per hub decision D185.
|
|
34
|
+
*
|
|
35
|
+
* Sets the three transaction-local GUCs the platform-ops RLS
|
|
36
|
+
* predicates read (D185 § 4):
|
|
37
|
+
* - `app.user_id` — verified principal id (sub) from JWT.
|
|
38
|
+
* - `app.platform_ops_service_id` — which consumer service's
|
|
39
|
+
* platform-ops surface this request is exercising.
|
|
40
|
+
* - `app.platform_ops_permission` — the specific catalog entry
|
|
41
|
+
* being exercised (e.g. `"modules.write"`).
|
|
42
|
+
*
|
|
43
|
+
* The policies on the table being accessed join against
|
|
44
|
+
* `platform_ops_grants_replica` to decide allow/deny per-row. Unlike
|
|
45
|
+
* `nodii_owner` (BYPASSRLS escape hatch), the platform_ops pool is
|
|
46
|
+
* RLS-bound — it just uses a different predicate shape.
|
|
47
|
+
*
|
|
48
|
+
* `grantId` and `supportTicketId` are optional audit-trail bindings;
|
|
49
|
+
* they are emitted as span attributes for forensic tracing but are
|
|
50
|
+
* NOT pushed into GUCs (the policy predicate doesn't read them).
|
|
51
|
+
*
|
|
52
|
+
* Throws `DbRlsNotInitialized` if `initDbRls` hasn't run.
|
|
53
|
+
* Throws `PoolUnavailable("platform_ops")` if db-rls was initialized
|
|
54
|
+
* in 3-pool / 2-pool mode (no platformOps pool wired).
|
|
55
|
+
* Wraps any error thrown by `fn` in `TransactionRolledBack`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function withPlatformOps<T>(opts: PlatformOpsContextOpts, fn: (tx: PgTx) => Promise<T>): Promise<T>;
|
|
31
58
|
/**
|
|
32
59
|
* autoDispatch — chooses the right pool based on what's bound.
|
|
33
60
|
*
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AASA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,IAAI,EACT,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EACrB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,IAAI,EAAE,eAAe,EACrB,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,CAAC,CAAC,CAcZ;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,IAAI,EAAE,iBAAiB,EACvB,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,CAAC,CAAC,CAUZ;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,QAAQ,EAAE,gBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,EACvD,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAiBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,IAAI,EAAE,gBAAgB,EACtB,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,CAAC,CAAC,CAeZ"}
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AASA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,IAAI,EACT,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EACrB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,IAAI,EAAE,eAAe,EACrB,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,CAAC,CAAC,CAcZ;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,IAAI,EAAE,iBAAiB,EACvB,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,CAAC,CAAC,CAUZ;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,QAAQ,EAAE,gBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,EACvD,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,IAAI,EAAE,sBAAsB,EAC5B,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,CAAC,CAAC,CAYZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,IAAI,EAAE,gBAAgB,EACtB,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,CAAC,CAAC,CAeZ"}
|
package/dist/context.js
CHANGED
|
@@ -90,6 +90,46 @@ function normalizeOwnerArgs(fnOrOpts, maybeFn) {
|
|
|
90
90
|
}
|
|
91
91
|
return { opts: fnOrOpts, fn: maybeFn };
|
|
92
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* withPlatformOps — opens a tx on the `platform_ops` pool
|
|
95
|
+
* (nodii_platform_ops Postgres role) per hub decision D185.
|
|
96
|
+
*
|
|
97
|
+
* Sets the three transaction-local GUCs the platform-ops RLS
|
|
98
|
+
* predicates read (D185 § 4):
|
|
99
|
+
* - `app.user_id` — verified principal id (sub) from JWT.
|
|
100
|
+
* - `app.platform_ops_service_id` — which consumer service's
|
|
101
|
+
* platform-ops surface this request is exercising.
|
|
102
|
+
* - `app.platform_ops_permission` — the specific catalog entry
|
|
103
|
+
* being exercised (e.g. `"modules.write"`).
|
|
104
|
+
*
|
|
105
|
+
* The policies on the table being accessed join against
|
|
106
|
+
* `platform_ops_grants_replica` to decide allow/deny per-row. Unlike
|
|
107
|
+
* `nodii_owner` (BYPASSRLS escape hatch), the platform_ops pool is
|
|
108
|
+
* RLS-bound — it just uses a different predicate shape.
|
|
109
|
+
*
|
|
110
|
+
* `grantId` and `supportTicketId` are optional audit-trail bindings;
|
|
111
|
+
* they are emitted as span attributes for forensic tracing but are
|
|
112
|
+
* NOT pushed into GUCs (the policy predicate doesn't read them).
|
|
113
|
+
*
|
|
114
|
+
* Throws `DbRlsNotInitialized` if `initDbRls` hasn't run.
|
|
115
|
+
* Throws `PoolUnavailable("platform_ops")` if db-rls was initialized
|
|
116
|
+
* in 3-pool / 2-pool mode (no platformOps pool wired).
|
|
117
|
+
* Wraps any error thrown by `fn` in `TransactionRolledBack`.
|
|
118
|
+
*/
|
|
119
|
+
export async function withPlatformOps(opts, fn) {
|
|
120
|
+
const pool = requirePool("platform_ops");
|
|
121
|
+
return pool.withTransaction(async (tx) => {
|
|
122
|
+
await tx.setConfig("app.user_id", opts.userId);
|
|
123
|
+
await tx.setConfig("app.platform_ops_service_id", opts.serviceId);
|
|
124
|
+
await tx.setConfig("app.platform_ops_permission", opts.permission);
|
|
125
|
+
try {
|
|
126
|
+
return await fn(tx);
|
|
127
|
+
}
|
|
128
|
+
catch (cause) {
|
|
129
|
+
throw new TransactionRolledBack(cause);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
93
133
|
/**
|
|
94
134
|
* autoDispatch — chooses the right pool based on what's bound.
|
|
95
135
|
*
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,kEAAkE;AAClE,YAAY;AAEZ,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAyB,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAEL,oBAAoB,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
export type PlatformOpsScopeKind = "tenant" | "platform_global" | "all_tenants";
|
|
2
|
+
/**
|
|
3
|
+
* Returns a Drizzle pgTable definition for the
|
|
4
|
+
* `platform_ops_grants_replica` table per D185 § 2.
|
|
5
|
+
*
|
|
6
|
+
* Schema:
|
|
7
|
+
* - id UUID PRIMARY KEY DEFAULT gen_random_uuid()
|
|
8
|
+
* - user_id UUID NOT NULL -- principal with platform-admin membership
|
|
9
|
+
* - service_id TEXT NOT NULL -- consumer service id
|
|
10
|
+
* - scope_kind TEXT NOT NULL CHECK (IN ('tenant','platform_global','all_tenants'))
|
|
11
|
+
* - scope_target UUID -- tenant_id when scope_kind='tenant'; NULL otherwise
|
|
12
|
+
* - permission TEXT NOT NULL -- catalog entry name
|
|
13
|
+
* - granted_by_user_id UUID NOT NULL -- audit trail
|
|
14
|
+
* - granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
15
|
+
* - expires_at TIMESTAMPTZ -- optional time-bound
|
|
16
|
+
* - revoked_at TIMESTAMPTZ -- soft revoke
|
|
17
|
+
*
|
|
18
|
+
* Constraints:
|
|
19
|
+
* - UNIQUE (user_id, service_id, scope_kind, scope_target, permission)
|
|
20
|
+
* - CHECK ((scope_kind = 'tenant' AND scope_target IS NOT NULL)
|
|
21
|
+
* OR (scope_kind IN ('platform_global','all_tenants') AND scope_target IS NULL))
|
|
22
|
+
*
|
|
23
|
+
* Indexes:
|
|
24
|
+
* - (user_id, service_id) WHERE revoked_at IS NULL
|
|
25
|
+
*/
|
|
26
|
+
export declare function platformOpsGrantsReplica(name?: string): import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
27
|
+
name: string;
|
|
28
|
+
schema: undefined;
|
|
29
|
+
columns: {
|
|
30
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
31
|
+
name: "id";
|
|
32
|
+
tableName: string;
|
|
33
|
+
dataType: "string";
|
|
34
|
+
columnType: "PgUUID";
|
|
35
|
+
data: string;
|
|
36
|
+
driverParam: string;
|
|
37
|
+
notNull: true;
|
|
38
|
+
hasDefault: true;
|
|
39
|
+
isPrimaryKey: true;
|
|
40
|
+
isAutoincrement: false;
|
|
41
|
+
hasRuntimeDefault: false;
|
|
42
|
+
enumValues: undefined;
|
|
43
|
+
baseColumn: never;
|
|
44
|
+
identity: undefined;
|
|
45
|
+
generated: undefined;
|
|
46
|
+
}, {}, {}>;
|
|
47
|
+
userId: import("drizzle-orm/pg-core").PgColumn<{
|
|
48
|
+
name: "user_id";
|
|
49
|
+
tableName: string;
|
|
50
|
+
dataType: "string";
|
|
51
|
+
columnType: "PgUUID";
|
|
52
|
+
data: string;
|
|
53
|
+
driverParam: string;
|
|
54
|
+
notNull: true;
|
|
55
|
+
hasDefault: false;
|
|
56
|
+
isPrimaryKey: false;
|
|
57
|
+
isAutoincrement: false;
|
|
58
|
+
hasRuntimeDefault: false;
|
|
59
|
+
enumValues: undefined;
|
|
60
|
+
baseColumn: never;
|
|
61
|
+
identity: undefined;
|
|
62
|
+
generated: undefined;
|
|
63
|
+
}, {}, {}>;
|
|
64
|
+
serviceId: import("drizzle-orm/pg-core").PgColumn<{
|
|
65
|
+
name: "service_id";
|
|
66
|
+
tableName: string;
|
|
67
|
+
dataType: "string";
|
|
68
|
+
columnType: "PgText";
|
|
69
|
+
data: string;
|
|
70
|
+
driverParam: string;
|
|
71
|
+
notNull: true;
|
|
72
|
+
hasDefault: false;
|
|
73
|
+
isPrimaryKey: false;
|
|
74
|
+
isAutoincrement: false;
|
|
75
|
+
hasRuntimeDefault: false;
|
|
76
|
+
enumValues: [string, ...string[]];
|
|
77
|
+
baseColumn: never;
|
|
78
|
+
identity: undefined;
|
|
79
|
+
generated: undefined;
|
|
80
|
+
}, {}, {}>;
|
|
81
|
+
scopeKind: import("drizzle-orm/pg-core").PgColumn<{
|
|
82
|
+
name: "scope_kind";
|
|
83
|
+
tableName: string;
|
|
84
|
+
dataType: "string";
|
|
85
|
+
columnType: "PgText";
|
|
86
|
+
data: string;
|
|
87
|
+
driverParam: string;
|
|
88
|
+
notNull: true;
|
|
89
|
+
hasDefault: false;
|
|
90
|
+
isPrimaryKey: false;
|
|
91
|
+
isAutoincrement: false;
|
|
92
|
+
hasRuntimeDefault: false;
|
|
93
|
+
enumValues: [string, ...string[]];
|
|
94
|
+
baseColumn: never;
|
|
95
|
+
identity: undefined;
|
|
96
|
+
generated: undefined;
|
|
97
|
+
}, {}, {}>;
|
|
98
|
+
scopeTarget: import("drizzle-orm/pg-core").PgColumn<{
|
|
99
|
+
name: "scope_target";
|
|
100
|
+
tableName: string;
|
|
101
|
+
dataType: "string";
|
|
102
|
+
columnType: "PgUUID";
|
|
103
|
+
data: string;
|
|
104
|
+
driverParam: string;
|
|
105
|
+
notNull: false;
|
|
106
|
+
hasDefault: false;
|
|
107
|
+
isPrimaryKey: false;
|
|
108
|
+
isAutoincrement: false;
|
|
109
|
+
hasRuntimeDefault: false;
|
|
110
|
+
enumValues: undefined;
|
|
111
|
+
baseColumn: never;
|
|
112
|
+
identity: undefined;
|
|
113
|
+
generated: undefined;
|
|
114
|
+
}, {}, {}>;
|
|
115
|
+
permission: import("drizzle-orm/pg-core").PgColumn<{
|
|
116
|
+
name: "permission";
|
|
117
|
+
tableName: string;
|
|
118
|
+
dataType: "string";
|
|
119
|
+
columnType: "PgText";
|
|
120
|
+
data: string;
|
|
121
|
+
driverParam: string;
|
|
122
|
+
notNull: true;
|
|
123
|
+
hasDefault: false;
|
|
124
|
+
isPrimaryKey: false;
|
|
125
|
+
isAutoincrement: false;
|
|
126
|
+
hasRuntimeDefault: false;
|
|
127
|
+
enumValues: [string, ...string[]];
|
|
128
|
+
baseColumn: never;
|
|
129
|
+
identity: undefined;
|
|
130
|
+
generated: undefined;
|
|
131
|
+
}, {}, {}>;
|
|
132
|
+
grantedByUserId: import("drizzle-orm/pg-core").PgColumn<{
|
|
133
|
+
name: "granted_by_user_id";
|
|
134
|
+
tableName: string;
|
|
135
|
+
dataType: "string";
|
|
136
|
+
columnType: "PgUUID";
|
|
137
|
+
data: string;
|
|
138
|
+
driverParam: string;
|
|
139
|
+
notNull: true;
|
|
140
|
+
hasDefault: false;
|
|
141
|
+
isPrimaryKey: false;
|
|
142
|
+
isAutoincrement: false;
|
|
143
|
+
hasRuntimeDefault: false;
|
|
144
|
+
enumValues: undefined;
|
|
145
|
+
baseColumn: never;
|
|
146
|
+
identity: undefined;
|
|
147
|
+
generated: undefined;
|
|
148
|
+
}, {}, {}>;
|
|
149
|
+
grantedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
150
|
+
name: "granted_at";
|
|
151
|
+
tableName: string;
|
|
152
|
+
dataType: "date";
|
|
153
|
+
columnType: "PgTimestamp";
|
|
154
|
+
data: Date;
|
|
155
|
+
driverParam: string;
|
|
156
|
+
notNull: true;
|
|
157
|
+
hasDefault: true;
|
|
158
|
+
isPrimaryKey: false;
|
|
159
|
+
isAutoincrement: false;
|
|
160
|
+
hasRuntimeDefault: false;
|
|
161
|
+
enumValues: undefined;
|
|
162
|
+
baseColumn: never;
|
|
163
|
+
identity: undefined;
|
|
164
|
+
generated: undefined;
|
|
165
|
+
}, {}, {}>;
|
|
166
|
+
expiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
167
|
+
name: "expires_at";
|
|
168
|
+
tableName: string;
|
|
169
|
+
dataType: "date";
|
|
170
|
+
columnType: "PgTimestamp";
|
|
171
|
+
data: Date;
|
|
172
|
+
driverParam: string;
|
|
173
|
+
notNull: false;
|
|
174
|
+
hasDefault: false;
|
|
175
|
+
isPrimaryKey: false;
|
|
176
|
+
isAutoincrement: false;
|
|
177
|
+
hasRuntimeDefault: false;
|
|
178
|
+
enumValues: undefined;
|
|
179
|
+
baseColumn: never;
|
|
180
|
+
identity: undefined;
|
|
181
|
+
generated: undefined;
|
|
182
|
+
}, {}, {}>;
|
|
183
|
+
revokedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
184
|
+
name: "revoked_at";
|
|
185
|
+
tableName: string;
|
|
186
|
+
dataType: "date";
|
|
187
|
+
columnType: "PgTimestamp";
|
|
188
|
+
data: Date;
|
|
189
|
+
driverParam: string;
|
|
190
|
+
notNull: false;
|
|
191
|
+
hasDefault: false;
|
|
192
|
+
isPrimaryKey: false;
|
|
193
|
+
isAutoincrement: false;
|
|
194
|
+
hasRuntimeDefault: false;
|
|
195
|
+
enumValues: undefined;
|
|
196
|
+
baseColumn: never;
|
|
197
|
+
identity: undefined;
|
|
198
|
+
generated: undefined;
|
|
199
|
+
}, {}, {}>;
|
|
200
|
+
};
|
|
201
|
+
dialect: "pg";
|
|
202
|
+
}>;
|
|
203
|
+
//# sourceMappingURL=drizzle-grants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-grants.d.ts","sourceRoot":"","sources":["../src/drizzle-grants.ts"],"names":[],"mappings":"AA8BA,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,iBAAiB,GAAG,aAAa,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,SAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsC5E"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// D185 — Drizzle table builder for `platform_ops_grants_replica`.
|
|
2
|
+
//
|
|
3
|
+
// Per hub decision D185 § 2 + § 6.2. The canonical schema lives in
|
|
4
|
+
// `nodii-tenant-service` (source of truth); each consumer service that
|
|
5
|
+
// wires a 4-pool db-rls replicates the table locally via the
|
|
6
|
+
// `@nodii/replica-consumer` outbox-consumer pattern (`09-replication
|
|
7
|
+
// § 6.2`). This helper emits the Drizzle schema for the replica so
|
|
8
|
+
// consumer services don't drift on column shape.
|
|
9
|
+
//
|
|
10
|
+
// Subpath export: `@nodii/db-rls/drizzle/platform-ops-grants`.
|
|
11
|
+
//
|
|
12
|
+
// Usage:
|
|
13
|
+
//
|
|
14
|
+
// import { platformOpsGrantsReplica } from "@nodii/db-rls/drizzle/platform-ops-grants";
|
|
15
|
+
//
|
|
16
|
+
// export const grantsReplica = platformOpsGrantsReplica();
|
|
17
|
+
// // OR with custom name:
|
|
18
|
+
// export const grantsReplica = platformOpsGrantsReplica("tenant_platform_ops_grants_replica");
|
|
19
|
+
import { sql } from "drizzle-orm";
|
|
20
|
+
import { check, index, pgTable, text, timestamp, unique, uuid, } from "drizzle-orm/pg-core";
|
|
21
|
+
/**
|
|
22
|
+
* Returns a Drizzle pgTable definition for the
|
|
23
|
+
* `platform_ops_grants_replica` table per D185 § 2.
|
|
24
|
+
*
|
|
25
|
+
* Schema:
|
|
26
|
+
* - id UUID PRIMARY KEY DEFAULT gen_random_uuid()
|
|
27
|
+
* - user_id UUID NOT NULL -- principal with platform-admin membership
|
|
28
|
+
* - service_id TEXT NOT NULL -- consumer service id
|
|
29
|
+
* - scope_kind TEXT NOT NULL CHECK (IN ('tenant','platform_global','all_tenants'))
|
|
30
|
+
* - scope_target UUID -- tenant_id when scope_kind='tenant'; NULL otherwise
|
|
31
|
+
* - permission TEXT NOT NULL -- catalog entry name
|
|
32
|
+
* - granted_by_user_id UUID NOT NULL -- audit trail
|
|
33
|
+
* - granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
34
|
+
* - expires_at TIMESTAMPTZ -- optional time-bound
|
|
35
|
+
* - revoked_at TIMESTAMPTZ -- soft revoke
|
|
36
|
+
*
|
|
37
|
+
* Constraints:
|
|
38
|
+
* - UNIQUE (user_id, service_id, scope_kind, scope_target, permission)
|
|
39
|
+
* - CHECK ((scope_kind = 'tenant' AND scope_target IS NOT NULL)
|
|
40
|
+
* OR (scope_kind IN ('platform_global','all_tenants') AND scope_target IS NULL))
|
|
41
|
+
*
|
|
42
|
+
* Indexes:
|
|
43
|
+
* - (user_id, service_id) WHERE revoked_at IS NULL
|
|
44
|
+
*/
|
|
45
|
+
export function platformOpsGrantsReplica(name = "platform_ops_grants_replica") {
|
|
46
|
+
return pgTable(name, {
|
|
47
|
+
id: uuid("id").primaryKey().default(sql `gen_random_uuid()`),
|
|
48
|
+
userId: uuid("user_id").notNull(),
|
|
49
|
+
serviceId: text("service_id").notNull(),
|
|
50
|
+
scopeKind: text("scope_kind").notNull(),
|
|
51
|
+
scopeTarget: uuid("scope_target"),
|
|
52
|
+
permission: text("permission").notNull(),
|
|
53
|
+
grantedByUserId: uuid("granted_by_user_id").notNull(),
|
|
54
|
+
grantedAt: timestamp("granted_at", { withTimezone: true })
|
|
55
|
+
.notNull()
|
|
56
|
+
.default(sql `NOW()`),
|
|
57
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
58
|
+
revokedAt: timestamp("revoked_at", { withTimezone: true }),
|
|
59
|
+
}, (t) => [
|
|
60
|
+
unique(`${name}_grant_uniq`).on(t.userId, t.serviceId, t.scopeKind, t.scopeTarget, t.permission),
|
|
61
|
+
check(`${name}_scope_target_shape`, sql `(${t.scopeKind} = 'tenant' AND ${t.scopeTarget} IS NOT NULL) OR (${t.scopeKind} IN ('platform_global','all_tenants') AND ${t.scopeTarget} IS NULL)`),
|
|
62
|
+
check(`${name}_scope_kind_enum`, sql `${t.scopeKind} IN ('tenant','platform_global','all_tenants')`),
|
|
63
|
+
index(`${name}_user_service_active`)
|
|
64
|
+
.on(t.userId, t.serviceId)
|
|
65
|
+
.where(sql `${t.revokedAt} IS NULL`),
|
|
66
|
+
]);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=drizzle-grants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-grants.js","sourceRoot":"","sources":["../src/drizzle-grants.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,mEAAmE;AACnE,uEAAuE;AACvE,6DAA6D;AAC7D,qEAAqE;AACrE,mEAAmE;AACnE,iDAAiD;AACjD,EAAE;AACF,+DAA+D;AAC/D,EAAE;AACF,SAAS;AACT,EAAE;AACF,0FAA0F;AAC1F,EAAE;AACF,6DAA6D;AAC7D,4BAA4B;AAC5B,iGAAiG;AAEjG,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,IAAI,EACJ,SAAS,EACT,MAAM,EACN,IAAI,GACL,MAAM,qBAAqB,CAAC;AAI7B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAI,GAAG,6BAA6B;IAC3E,OAAO,OAAO,CACZ,IAAI,EACJ;QACE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,GAAG,CAAA,mBAAmB,CAAC;QAC3D,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;QACjC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;QACvC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;QACvC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC;QACjC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;QACxC,eAAe,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC,OAAO,EAAE;QACrD,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;aACvD,OAAO,EAAE;aACT,OAAO,CAAC,GAAG,CAAA,OAAO,CAAC;QACtB,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QAC1D,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;KAC3D,EACD,CAAC,CAAC,EAAE,EAAE,CAAC;QACL,MAAM,CAAC,GAAG,IAAI,aAAa,CAAC,CAAC,EAAE,CAC7B,CAAC,CAAC,MAAM,EACR,CAAC,CAAC,SAAS,EACX,CAAC,CAAC,SAAS,EACX,CAAC,CAAC,WAAW,EACb,CAAC,CAAC,UAAU,CACb;QACD,KAAK,CACH,GAAG,IAAI,qBAAqB,EAC5B,GAAG,CAAA,IAAI,CAAC,CAAC,SAAS,mBAAmB,CAAC,CAAC,WAAW,qBAAqB,CAAC,CAAC,SAAS,6CAA6C,CAAC,CAAC,WAAW,WAAW,CACxJ;QACD,KAAK,CACH,GAAG,IAAI,kBAAkB,EACzB,GAAG,CAAA,GAAG,CAAC,CAAC,SAAS,gDAAgD,CAClE;QACD,KAAK,CAAC,GAAG,IAAI,sBAAsB,CAAC;aACjC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;aACzB,KAAK,CAAC,GAAG,CAAA,GAAG,CAAC,CAAC,SAAS,UAAU,CAAC;KACtC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -20,4 +20,71 @@ import type { WithRlsOpts } from "./rls-policy-gen";
|
|
|
20
20
|
* drizzle-kit performs).
|
|
21
21
|
*/
|
|
22
22
|
export declare function withRls(tenantCol: PgColumn, opts?: WithRlsOpts): PgPolicy[];
|
|
23
|
+
/** Per-verb permission name binding for the platform-ops policies. Each
|
|
24
|
+
* string is a catalog entry name (e.g. `"modules.write"`) — when a
|
|
25
|
+
* request runs with `app.platform_ops_permission` matching this name,
|
|
26
|
+
* the corresponding policy applies. A missing entry means there's no
|
|
27
|
+
* policy emitted for that verb (deny-by-default RLS behavior). */
|
|
28
|
+
export interface PlatformOpsPerVerbPermissions {
|
|
29
|
+
read?: string;
|
|
30
|
+
insert?: string;
|
|
31
|
+
update?: string;
|
|
32
|
+
delete?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface WithPlatformOpsOpts {
|
|
35
|
+
/** Override the default `platform_ops_grants_replica` table name.
|
|
36
|
+
* Use when the consuming service replicates the grants table under
|
|
37
|
+
* a different name (e.g. prefixed with the service slug). */
|
|
38
|
+
grantsTable?: string;
|
|
39
|
+
/** Override the tenant column name in the generated predicate. Falls
|
|
40
|
+
* back to the Drizzle column's name. */
|
|
41
|
+
tenantColumn?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Returns the platform-ops policy bundle (per D185 § 3) for a
|
|
45
|
+
* **tenant-scoped** table exposed via a platform-ops cross-tenant
|
|
46
|
+
* surface. Emits one policy per verb in `perms`:
|
|
47
|
+
*
|
|
48
|
+
* - `<table>_platform_ops_read` FOR SELECT TO nodii_platform_ops USING (<grants-predicate with perms.read>)
|
|
49
|
+
* - `<table>_platform_ops_insert` FOR INSERT TO nodii_platform_ops WITH CHECK (<grants-predicate with perms.insert>)
|
|
50
|
+
* - `<table>_platform_ops_update` FOR UPDATE TO nodii_platform_ops USING + WITH CHECK (<grants-predicate with perms.update>)
|
|
51
|
+
* - `<table>_platform_ops_delete` FOR DELETE TO nodii_platform_ops USING (<grants-predicate with perms.delete>)
|
|
52
|
+
*
|
|
53
|
+
* Predicate shape (per D185 § 3):
|
|
54
|
+
*
|
|
55
|
+
* EXISTS (
|
|
56
|
+
* SELECT 1 FROM platform_ops_grants_replica g
|
|
57
|
+
* WHERE g.user_id = current_setting('app.user_id')::uuid
|
|
58
|
+
* AND g.service_id = current_setting('app.platform_ops_service_id')
|
|
59
|
+
* AND g.permission = <permission name literal>
|
|
60
|
+
* AND g.revoked_at IS NULL
|
|
61
|
+
* AND (g.expires_at IS NULL OR g.expires_at > NOW())
|
|
62
|
+
* AND (
|
|
63
|
+
* g.scope_kind = 'all_tenants'
|
|
64
|
+
* OR (g.scope_kind = 'tenant' AND g.scope_target = <tenantCol>)
|
|
65
|
+
* )
|
|
66
|
+
* )
|
|
67
|
+
*
|
|
68
|
+
* Note: the permission literal is embedded in the policy body at
|
|
69
|
+
* migration-emit time (not read from `app.platform_ops_permission` at
|
|
70
|
+
* runtime). This means each verb can be bound to a distinct catalog
|
|
71
|
+
* entry — `app.platform_ops_permission` GUC is set by `withPlatformOps`
|
|
72
|
+
* to enable auditing/forensics but is NOT what the policy checks.
|
|
73
|
+
*
|
|
74
|
+
* Compose alongside `withRls(t.tenantId)` on the same table when both
|
|
75
|
+
* platform-ops AND in-tenant surfaces are exposed.
|
|
76
|
+
*/
|
|
77
|
+
export declare function withPlatformOpsTenant(tenantCol: PgColumn, perms: PlatformOpsPerVerbPermissions, opts?: WithPlatformOpsOpts): PgPolicy[];
|
|
78
|
+
/**
|
|
79
|
+
* Returns the platform-ops policy bundle (per D185 § 3) for a
|
|
80
|
+
* **platform-global** table that has no tenant_id column (modules,
|
|
81
|
+
* role catalogs, etc.). Emits one policy per verb in `perms` using the
|
|
82
|
+
* `scope_kind='platform_global'` predicate variant.
|
|
83
|
+
*/
|
|
84
|
+
export declare function withPlatformOpsGlobal(table: {
|
|
85
|
+
_: {
|
|
86
|
+
name: string;
|
|
87
|
+
};
|
|
88
|
+
[key: string]: unknown;
|
|
89
|
+
}, perms: PlatformOpsPerVerbPermissions, opts?: WithPlatformOpsOpts): PgPolicy[];
|
|
23
90
|
//# sourceMappingURL=drizzle-policies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle-policies.d.ts","sourceRoot":"","sources":["../src/drizzle-policies.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAW,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI7D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,QAAQ,EACnB,IAAI,GAAE,WAAgB,GACrB,QAAQ,EAAE,CAsCZ"}
|
|
1
|
+
{"version":3,"file":"drizzle-policies.d.ts","sourceRoot":"","sources":["../src/drizzle-policies.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAW,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI7D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,QAAQ,EACnB,IAAI,GAAE,WAAgB,GACrB,QAAQ,EAAE,CAsCZ;AA6ED;;;;mEAImE;AACnE,MAAM,WAAW,6BAA6B;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,mBAAmB;IAClC;;kEAE8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;6CACyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,QAAQ,EACnB,KAAK,EAAE,6BAA6B,EACpC,IAAI,GAAE,mBAAwB,GAC7B,QAAQ,EAAE,CA0BZ;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE;IAAE,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EACtD,KAAK,EAAE,6BAA6B,EACpC,IAAI,GAAE,mBAAwB,GAC7B,QAAQ,EAAE,CA0BZ"}
|
package/dist/drizzle-policies.js
CHANGED
|
@@ -111,4 +111,113 @@ function unqualifiedName(table) {
|
|
|
111
111
|
const tail = table.includes(".") ? (table.split(".").pop() ?? table) : table;
|
|
112
112
|
return tail.replace(/^"|"$/g, "");
|
|
113
113
|
}
|
|
114
|
+
const PLATFORM_OPS_GRANTS_REPLICA_DEFAULT = "platform_ops_grants_replica";
|
|
115
|
+
/**
|
|
116
|
+
* Returns the platform-ops policy bundle (per D185 § 3) for a
|
|
117
|
+
* **tenant-scoped** table exposed via a platform-ops cross-tenant
|
|
118
|
+
* surface. Emits one policy per verb in `perms`:
|
|
119
|
+
*
|
|
120
|
+
* - `<table>_platform_ops_read` FOR SELECT TO nodii_platform_ops USING (<grants-predicate with perms.read>)
|
|
121
|
+
* - `<table>_platform_ops_insert` FOR INSERT TO nodii_platform_ops WITH CHECK (<grants-predicate with perms.insert>)
|
|
122
|
+
* - `<table>_platform_ops_update` FOR UPDATE TO nodii_platform_ops USING + WITH CHECK (<grants-predicate with perms.update>)
|
|
123
|
+
* - `<table>_platform_ops_delete` FOR DELETE TO nodii_platform_ops USING (<grants-predicate with perms.delete>)
|
|
124
|
+
*
|
|
125
|
+
* Predicate shape (per D185 § 3):
|
|
126
|
+
*
|
|
127
|
+
* EXISTS (
|
|
128
|
+
* SELECT 1 FROM platform_ops_grants_replica g
|
|
129
|
+
* WHERE g.user_id = current_setting('app.user_id')::uuid
|
|
130
|
+
* AND g.service_id = current_setting('app.platform_ops_service_id')
|
|
131
|
+
* AND g.permission = <permission name literal>
|
|
132
|
+
* AND g.revoked_at IS NULL
|
|
133
|
+
* AND (g.expires_at IS NULL OR g.expires_at > NOW())
|
|
134
|
+
* AND (
|
|
135
|
+
* g.scope_kind = 'all_tenants'
|
|
136
|
+
* OR (g.scope_kind = 'tenant' AND g.scope_target = <tenantCol>)
|
|
137
|
+
* )
|
|
138
|
+
* )
|
|
139
|
+
*
|
|
140
|
+
* Note: the permission literal is embedded in the policy body at
|
|
141
|
+
* migration-emit time (not read from `app.platform_ops_permission` at
|
|
142
|
+
* runtime). This means each verb can be bound to a distinct catalog
|
|
143
|
+
* entry — `app.platform_ops_permission` GUC is set by `withPlatformOps`
|
|
144
|
+
* to enable auditing/forensics but is NOT what the policy checks.
|
|
145
|
+
*
|
|
146
|
+
* Compose alongside `withRls(t.tenantId)` on the same table when both
|
|
147
|
+
* platform-ops AND in-tenant surfaces are exposed.
|
|
148
|
+
*/
|
|
149
|
+
export function withPlatformOpsTenant(tenantCol, perms, opts = {}) {
|
|
150
|
+
const tableName = getTableName(tenantCol.table);
|
|
151
|
+
const policyBase = unqualifiedName(tableName);
|
|
152
|
+
const tenantColumn = opts.tenantColumn ?? tenantCol.name;
|
|
153
|
+
const grantsTable = opts.grantsTable ?? PLATFORM_OPS_GRANTS_REPLICA_DEFAULT;
|
|
154
|
+
const policies = [];
|
|
155
|
+
for (const verb of ["read", "insert", "update", "delete"]) {
|
|
156
|
+
const permission = perms[verb];
|
|
157
|
+
if (!permission)
|
|
158
|
+
continue;
|
|
159
|
+
const predicate = platformOpsTenantPredicate(grantsTable, tenantColumn, permission);
|
|
160
|
+
policies.push(pgPolicy(`${policyBase}_platform_ops_${verb}`, {
|
|
161
|
+
as: "permissive",
|
|
162
|
+
for: drizzleForPlatformOps(verb),
|
|
163
|
+
to: "nodii_platform_ops",
|
|
164
|
+
...platformOpsPredicates(verb, predicate),
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
return policies;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Returns the platform-ops policy bundle (per D185 § 3) for a
|
|
171
|
+
* **platform-global** table that has no tenant_id column (modules,
|
|
172
|
+
* role catalogs, etc.). Emits one policy per verb in `perms` using the
|
|
173
|
+
* `scope_kind='platform_global'` predicate variant.
|
|
174
|
+
*/
|
|
175
|
+
export function withPlatformOpsGlobal(table, perms, opts = {}) {
|
|
176
|
+
// For platform-global tables, callers pass the Drizzle pgTable itself
|
|
177
|
+
// (no tenant column to thread). We derive the policy name from the
|
|
178
|
+
// table's symbol identifier via getTableName(table).
|
|
179
|
+
const tableName = getTableName(table);
|
|
180
|
+
const policyBase = unqualifiedName(tableName);
|
|
181
|
+
const grantsTable = opts.grantsTable ?? PLATFORM_OPS_GRANTS_REPLICA_DEFAULT;
|
|
182
|
+
const policies = [];
|
|
183
|
+
for (const verb of ["read", "insert", "update", "delete"]) {
|
|
184
|
+
const permission = perms[verb];
|
|
185
|
+
if (!permission)
|
|
186
|
+
continue;
|
|
187
|
+
const predicate = platformOpsGlobalPredicate(grantsTable, permission);
|
|
188
|
+
policies.push(pgPolicy(`${policyBase}_platform_ops_${verb}`, {
|
|
189
|
+
as: "permissive",
|
|
190
|
+
for: drizzleForPlatformOps(verb),
|
|
191
|
+
to: "nodii_platform_ops",
|
|
192
|
+
...platformOpsPredicates(verb, predicate),
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
return policies;
|
|
196
|
+
}
|
|
197
|
+
function platformOpsTenantPredicate(grantsTable, tenantColumn, permission) {
|
|
198
|
+
const lit = sqlLiteral(permission);
|
|
199
|
+
return sql.raw(`EXISTS (SELECT 1 FROM ${grantsTable} g WHERE g.user_id = current_setting('app.user_id')::uuid AND g.service_id = current_setting('app.platform_ops_service_id') AND g.permission = ${lit} AND g.revoked_at IS NULL AND (g.expires_at IS NULL OR g.expires_at > NOW()) AND (g.scope_kind = 'all_tenants' OR (g.scope_kind = 'tenant' AND g.scope_target = ${tenantColumn})))`);
|
|
200
|
+
}
|
|
201
|
+
function platformOpsGlobalPredicate(grantsTable, permission) {
|
|
202
|
+
const lit = sqlLiteral(permission);
|
|
203
|
+
return sql.raw(`EXISTS (SELECT 1 FROM ${grantsTable} g WHERE g.user_id = current_setting('app.user_id')::uuid AND g.service_id = current_setting('app.platform_ops_service_id') AND g.scope_kind = 'platform_global' AND g.permission = ${lit} AND g.revoked_at IS NULL AND (g.expires_at IS NULL OR g.expires_at > NOW()))`);
|
|
204
|
+
}
|
|
205
|
+
function drizzleForPlatformOps(verb) {
|
|
206
|
+
return verb === "read" ? "select" : verb;
|
|
207
|
+
}
|
|
208
|
+
function platformOpsPredicates(verb, predicate) {
|
|
209
|
+
switch (verb) {
|
|
210
|
+
case "insert":
|
|
211
|
+
return { withCheck: predicate };
|
|
212
|
+
case "update":
|
|
213
|
+
return { using: predicate, withCheck: predicate };
|
|
214
|
+
default:
|
|
215
|
+
return { using: predicate };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/** SQL literal escape — doubles single quotes, wraps in quotes. */
|
|
219
|
+
function sqlLiteral(s) {
|
|
220
|
+
const escaped = s.replace(/'/g, "''");
|
|
221
|
+
return `'${escaped}'`;
|
|
222
|
+
}
|
|
114
223
|
//# sourceMappingURL=drizzle-policies.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle-policies.js","sourceRoot":"","sources":["../src/drizzle-policies.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"drizzle-policies.js","sourceRoot":"","sources":["../src/drizzle-policies.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export declare const LIB_NAME = "db-rls";
|
|
2
|
-
export declare const VERSION = "0.
|
|
2
|
+
export declare const VERSION = "0.4.0";
|
|
3
3
|
export { initDbRls, requireDbRls, getDbRlsOrNull, requirePool, _resetForTests, } from "./init";
|
|
4
4
|
export type { InitDbRlsConfig, ResolvedDbRls } from "./init";
|
|
5
|
-
export { configureDbRls, configureDbRls2Pool, PoolCredentialMismatch, _resetConfigureForTests, } from "./configure";
|
|
5
|
+
export { configureDbRls, configureDbRls2Pool, configureDbRls4Pool, PoolCredentialMismatch, _resetConfigureForTests, } from "./configure";
|
|
6
6
|
export type { ConfigureDbRlsOpts, ConfigureDbRlsPools, } from "./configure";
|
|
7
7
|
export { PgClientPool } from "./pg-pool-adapter";
|
|
8
8
|
export type { PgPoolAdapterOpts } from "./pg-pool-adapter";
|
|
9
|
-
export { withUserContext, withSystemContext, withOwnerContext, autoDispatch, } from "./context";
|
|
9
|
+
export { withUserContext, withSystemContext, withOwnerContext, withPlatformOps, autoDispatch, } from "./context";
|
|
10
10
|
export { withUserContextDb, withSystemContextDb, withOwnerContextDb, } from "./drizzle-client";
|
|
11
11
|
export type { DrizzleClient, NodePgDatabase } from "./drizzle-client";
|
|
12
12
|
export type { OwnerContextOpts } from "./migrate-guard";
|
|
@@ -22,5 +22,5 @@ export { InMemoryPgPool } from "./in-memory-pool";
|
|
|
22
22
|
export type { TranscriptEntry } from "./in-memory-pool";
|
|
23
23
|
export { DB_RLS_METRIC_VOCABULARY, _resetMetricsWarnLedgerForTests, } from "./metrics";
|
|
24
24
|
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, MissingTenantContext, OwnerContextOutsideMigrate, PoolUnavailable, TransactionRolledBack, } from "./types";
|
|
25
|
-
export type { AuthContext, AutoDispatchOpts, DbRlsMode, GenerateRlsPolicyOpts, PgPool, PgTx, PoolKind, SystemContextOpts, UserContextOpts, } from "./types";
|
|
25
|
+
export type { AuthContext, AutoDispatchOpts, DbRlsMode, GenerateRlsPolicyOpts, PgPool, PgTx, PlatformOpsContextOpts, PoolKind, SystemContextOpts, UserContextOpts, } from "./types";
|
|
26
26
|
//# 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":"AAiCA,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAChE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIvE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,iBAAiB,EACjB,eAAe,GAChB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAChE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIvE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,sBAAsB,EACtB,QAAQ,EACR,iBAAiB,EACjB,eAAe,GAChB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
// PoolCredentialMismatch + OwnerContextOutsideMigrate +
|
|
32
32
|
// DbRlsConfigError
|
|
33
33
|
export const LIB_NAME = "db-rls";
|
|
34
|
-
export const VERSION = "0.
|
|
34
|
+
export const VERSION = "0.4.0";
|
|
35
35
|
export { initDbRls, requireDbRls, getDbRlsOrNull, requirePool, _resetForTests, } from "./init";
|
|
36
|
-
export { configureDbRls, configureDbRls2Pool, PoolCredentialMismatch, _resetConfigureForTests, } from "./configure";
|
|
36
|
+
export { configureDbRls, configureDbRls2Pool, configureDbRls4Pool, PoolCredentialMismatch, _resetConfigureForTests, } from "./configure";
|
|
37
37
|
export { PgClientPool } from "./pg-pool-adapter";
|
|
38
|
-
export { withUserContext, withSystemContext, withOwnerContext, autoDispatch, } from "./context";
|
|
38
|
+
export { withUserContext, withSystemContext, withOwnerContext, withPlatformOps, autoDispatch, } from "./context";
|
|
39
39
|
export { withUserContextDb, withSystemContextDb, withOwnerContextDb, } from "./drizzle-client";
|
|
40
40
|
export { assertMigrateAllowed } from "./migrate-guard";
|
|
41
41
|
export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, } from "./auth-schema";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,wDAAwD;AACxD,6CAA6C;AAC7C,EAAE;AACF,yCAAyC;AACzC,sEAAsE;AACtE,wCAAwC;AACxC,sDAAsD;AACtD,+DAA+D;AAC/D,4EAA4E;AAC5E,gDAAgD;AAChD,mEAAmE;AACnE,mDAAmD;AACnD,wEAAwE;AACxE,2EAA2E;AAC3E,+EAA+E;AAC/E,wEAAwE;AACxE,sEAAsE;AACtE,6EAA6E;AAC7E,6EAA6E;AAC7E,sCAAsC;AACtC,uEAAuE;AACvE,0EAA0E;AAC1E,8EAA8E;AAC9E,kFAAkF;AAClF,yEAAyE;AACzE,mEAAmE;AACnE,0EAA0E;AAC1E,qCAAqC;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AACjC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGhE,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAGvB,qEAAqE;AACrE,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,wDAAwD;AACxD,6CAA6C;AAC7C,EAAE;AACF,yCAAyC;AACzC,sEAAsE;AACtE,wCAAwC;AACxC,sDAAsD;AACtD,+DAA+D;AAC/D,4EAA4E;AAC5E,gDAAgD;AAChD,mEAAmE;AACnE,mDAAmD;AACnD,wEAAwE;AACxE,2EAA2E;AAC3E,+EAA+E;AAC/E,wEAAwE;AACxE,sEAAsE;AACtE,6EAA6E;AAC7E,6EAA6E;AAC7E,sCAAsC;AACtC,uEAAuE;AACvE,0EAA0E;AAC1E,8EAA8E;AAC9E,kFAAkF;AAClF,yEAAyE;AACzE,mEAAmE;AACnE,0EAA0E;AAC1E,qCAAqC;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AACjC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGhE,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAGvB,qEAAqE;AACrE,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC"}
|
package/dist/init.d.ts
CHANGED
|
@@ -3,19 +3,28 @@ import { type DbRlsMode, type PgPool, type PoolKind } from "./types";
|
|
|
3
3
|
* Process-local config. `services` and `authenticated` are optional ONLY
|
|
4
4
|
* in 2-pool mode; in 3-pool mode (the default) the type guard runs at
|
|
5
5
|
* init time and throws `DbRlsConfigError` if either is missing.
|
|
6
|
+
*
|
|
7
|
+
* v0.4.0 (D185): `platformOps` is REQUIRED when `mode:
|
|
8
|
+
* "3-pool-with-platform-ops"` and FORBIDDEN otherwise.
|
|
6
9
|
*/
|
|
7
10
|
export interface InitDbRlsConfig {
|
|
8
11
|
owner: PgPool;
|
|
9
12
|
services?: PgPool;
|
|
10
13
|
authenticated?: PgPool;
|
|
14
|
+
/** D185 platform-ops pool. Required in 4-pool mode; forbidden in
|
|
15
|
+
* 3-pool / 2-pool modes. RLS-bound (NOT BYPASSRLS); policies use
|
|
16
|
+
* the grants-lookup predicate against `platform_ops_grants_replica`. */
|
|
17
|
+
platformOps?: PgPool;
|
|
11
18
|
/** Defaults to `"3-pool"`. Set `"2-pool"` for nodii-auth-shape services
|
|
12
|
-
* per 08-rls § 7
|
|
19
|
+
* per 08-rls § 7. Set `"3-pool-with-platform-ops"` for services with a
|
|
20
|
+
* platform-ops surface per D185 (nodii-tenant-service, etc.). */
|
|
13
21
|
mode?: DbRlsMode;
|
|
14
22
|
}
|
|
15
23
|
export interface ResolvedDbRls {
|
|
16
24
|
owner: PgPool;
|
|
17
25
|
services: PgPool | null;
|
|
18
26
|
authenticated: PgPool | null;
|
|
27
|
+
platform_ops: PgPool | null;
|
|
19
28
|
mode: DbRlsMode;
|
|
20
29
|
}
|
|
21
30
|
export declare function initDbRls(config: InitDbRlsConfig): void;
|
package/dist/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,MAAM,EAEX,KAAK,QAAQ,EACd,MAAM,SAAS,CAAC;AAEjB
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,MAAM,EAEX,KAAK,QAAQ,EACd,MAAM,SAAS,CAAC;AAEjB;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;6EAEyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;sEAEkE;IAClE,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,SAAS,CAAC;CACjB;AAID,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAwDvD;AAED,wBAAgB,YAAY,IAAI,aAAa,CAK5C;AAED,wBAAgB,cAAc,IAAI,aAAa,GAAG,IAAI,CAErD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAOlD;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
|
package/dist/init.js
CHANGED
|
@@ -19,16 +19,34 @@ export function initDbRls(config) {
|
|
|
19
19
|
if (!config.services || !config.authenticated) {
|
|
20
20
|
throw new DbRlsConfigError("initDbRls: 3-pool mode requires owner + services + authenticated pools. Either supply both, or set mode: '2-pool' (nodii-auth shape per 08-rls § 7).");
|
|
21
21
|
}
|
|
22
|
+
if (config.platformOps) {
|
|
23
|
+
throw new DbRlsConfigError("initDbRls: 3-pool mode must not supply a 'platformOps' pool — use mode: '3-pool-with-platform-ops' per hub decision D185 if you have a platform-ops surface.");
|
|
24
|
+
}
|
|
22
25
|
}
|
|
23
26
|
// 2-pool: services optional, authenticated forbidden (the whole point
|
|
24
27
|
// of the exception is that nodii-auth has no user-context surface yet).
|
|
25
|
-
if (mode === "2-pool"
|
|
26
|
-
|
|
28
|
+
if (mode === "2-pool") {
|
|
29
|
+
if (config.authenticated) {
|
|
30
|
+
throw new DbRlsConfigError("initDbRls: 2-pool mode must not supply an 'authenticated' pool — the 2-pool exception per 08-rls § 7 covers services without user-context. Use mode: '3-pool' if you have an authenticated pool.");
|
|
31
|
+
}
|
|
32
|
+
if (config.platformOps) {
|
|
33
|
+
throw new DbRlsConfigError("initDbRls: 2-pool mode must not supply a 'platformOps' pool — the 2-pool exception per 08-rls § 7 has no platform-ops surface. Use mode: '3-pool-with-platform-ops' per D185.");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// 4-pool (D185): owner + services + authenticated + platformOps all required.
|
|
37
|
+
if (mode === "3-pool-with-platform-ops") {
|
|
38
|
+
if (!config.services || !config.authenticated) {
|
|
39
|
+
throw new DbRlsConfigError("initDbRls: '3-pool-with-platform-ops' mode requires owner + services + authenticated + platformOps pools (D185). All four are mandatory.");
|
|
40
|
+
}
|
|
41
|
+
if (!config.platformOps) {
|
|
42
|
+
throw new DbRlsConfigError("initDbRls: '3-pool-with-platform-ops' mode requires a 'platformOps' pool wired against the nodii_platform_ops Postgres role (D185 § 1). Did you mean mode: '3-pool'?");
|
|
43
|
+
}
|
|
27
44
|
}
|
|
28
45
|
resolved = {
|
|
29
46
|
owner: config.owner,
|
|
30
47
|
services: config.services ?? null,
|
|
31
48
|
authenticated: config.authenticated ?? null,
|
|
49
|
+
platform_ops: config.platformOps ?? null,
|
|
32
50
|
mode,
|
|
33
51
|
};
|
|
34
52
|
}
|
package/dist/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;AAChF,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,wEAAwE;AACxE,UAAU;AAEV,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAGnB,eAAe,GAEhB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;AAChF,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,wEAAwE;AACxE,UAAU;AAEV,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAGnB,eAAe,GAEhB,MAAM,SAAS,CAAC;AAgCjB,IAAI,QAAQ,GAAyB,IAAI,CAAC;AAE1C,MAAM,UAAU,SAAS,CAAC,MAAuB;IAC/C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,8EAA8E,CAC/E,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAc,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC;IAChD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC9C,MAAM,IAAI,gBAAgB,CACxB,sJAAsJ,CACvJ,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,IAAI,gBAAgB,CACxB,8JAA8J,CAC/J,CAAC;QACJ,CAAC;IACH,CAAC;IACD,sEAAsE;IACtE,wEAAwE;IACxE,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,MAAM,IAAI,gBAAgB,CACxB,kMAAkM,CACnM,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,IAAI,gBAAgB,CACxB,+KAA+K,CAChL,CAAC;QACJ,CAAC;IACH,CAAC;IACD,8EAA8E;IAC9E,IAAI,IAAI,KAAK,0BAA0B,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC9C,MAAM,IAAI,gBAAgB,CACxB,0IAA0I,CAC3I,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACxB,MAAM,IAAI,gBAAgB,CACxB,sKAAsK,CACvK,CAAC;QACJ,CAAC;IACH,CAAC;IAED,QAAQ,GAAG;QACT,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI;QACjC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;QAC3C,YAAY,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI;QACxC,IAAI;KACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,mBAAmB,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,cAAc;IAC5B,QAAQ,GAAG,IAAI,CAAC;AAClB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
/** PoolKind names map 1:1 to the canonical
|
|
2
|
-
|
|
1
|
+
/** PoolKind names map 1:1 to the canonical pool roles.
|
|
2
|
+
*
|
|
3
|
+
* v0.4.0 adds `platform_ops` per hub decision D185 — a 4th
|
|
4
|
+
* RLS-bound pool with RBAC-gated cross-tenant + platform-global
|
|
5
|
+
* predicates via the `platform_ops_grants` table. NOT BYPASSRLS
|
|
6
|
+
* (unlike owner): just a different predicate shape. */
|
|
7
|
+
export type PoolKind = "owner" | "services" | "authenticated" | "platform_ops";
|
|
3
8
|
/** Pluggable transaction handle — substrate-agnostic. v0.1.0 ships the
|
|
4
9
|
* in-memory transcript-recording test double; pg / psycopg / pgx adapters
|
|
5
10
|
* arrive in v0.1.x. */
|
|
@@ -21,9 +26,13 @@ export interface PgPool {
|
|
|
21
26
|
/**
|
|
22
27
|
* Pool topology mode. v0.2.x adds the `2-pool` exception per
|
|
23
28
|
* `08-rls-doctrine § 7` — nodii-auth runs owner + services only until
|
|
24
|
-
* its admin portal lands.
|
|
29
|
+
* its admin portal lands. v0.4.0 adds the 4-pool platform-ops variant
|
|
30
|
+
* per hub decision D185 — services that expose a platform-ops surface
|
|
31
|
+
* (nodii-tenant-service, nodii-billing-service, etc.) add a 4th
|
|
32
|
+
* `platform_ops` pool with RBAC-gated grants policies. Default is
|
|
33
|
+
* `3-pool`.
|
|
25
34
|
*/
|
|
26
|
-
export type DbRlsMode = "3-pool" | "2-pool";
|
|
35
|
+
export type DbRlsMode = "3-pool" | "2-pool" | "3-pool-with-platform-ops";
|
|
27
36
|
/** Auth context bound by `@nodii/auth-sdk` middleware. Mirrors the
|
|
28
37
|
* fields autoDispatch reads — kept structural so the real auth-sdk
|
|
29
38
|
* context shape can grow without breaking us. */
|
|
@@ -50,6 +59,34 @@ export interface AutoDispatchOpts {
|
|
|
50
59
|
authContext?: AuthContext;
|
|
51
60
|
tenantId?: string;
|
|
52
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* withPlatformOps opts. Per hub decision D185:
|
|
64
|
+
* - `userId` — verified principal id (sub) from JWT.
|
|
65
|
+
* - `serviceId` — which consumer service's platform-ops surface
|
|
66
|
+
* this request is exercising. Must match the `service_id` column
|
|
67
|
+
* in `platform_ops_grants_replica` for the grants-predicate to
|
|
68
|
+
* allow the row.
|
|
69
|
+
* - `permission` — the specific catalog entry being exercised
|
|
70
|
+
* (e.g. `"modules.write"`, `"tenant.read"`). Denormalized in the
|
|
71
|
+
* JWT `permissions[]` array per E6; matched against the
|
|
72
|
+
* `permission` column in `platform_ops_grants_replica`.
|
|
73
|
+
* - `grantId` — optional audit linkage to a specific grant row.
|
|
74
|
+
* - `supportTicketId` — optional linkage for support-engineer
|
|
75
|
+
* flows; emitted as a span attribute for forensic tracing.
|
|
76
|
+
*
|
|
77
|
+
* Sets transaction-local GUCs `app.user_id` +
|
|
78
|
+
* `app.platform_ops_service_id` + `app.platform_ops_permission` per
|
|
79
|
+
* D185 § 4. The RLS policies on the table being accessed read these
|
|
80
|
+
* GUCs and join against `platform_ops_grants_replica` to decide
|
|
81
|
+
* allow/deny per-row.
|
|
82
|
+
*/
|
|
83
|
+
export interface PlatformOpsContextOpts {
|
|
84
|
+
userId: string;
|
|
85
|
+
serviceId: string;
|
|
86
|
+
permission: string;
|
|
87
|
+
grantId?: string;
|
|
88
|
+
supportTicketId?: string;
|
|
89
|
+
}
|
|
53
90
|
/** generateRlsPolicy opts. */
|
|
54
91
|
export interface GenerateRlsPolicyOpts {
|
|
55
92
|
/** Table name (unqualified). */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAoBA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAoBA;;;;;wDAKwD;AACxD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,eAAe,GAAG,cAAc,CAAC;AAE/E;;wBAEwB;AACxB,MAAM,WAAW,IAAI;IACnB,6CAA6C;IAC7C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,uDAAuD;IACvD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC7B;AAED,sEAAsE;AACtE,MAAM,WAAW,MAAM;IACrB,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,oEAAoE;IACpE,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC9D;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,0BAA0B,CAAC;AAEzE;;kDAEkD;AAClD,MAAM,WAAW,WAAW;IAC1B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,4BAA4B;AAC5B,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,8BAA8B;AAC9B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,yBAAyB;AACzB,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,8BAA8B;AAC9B,MAAM,WAAW,qBAAqB;IACpC,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAKD,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,mBAAoB,SAAQ,UAAU;;CAOlD;AAED,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;gBACZ,IAAI,EAAE,QAAQ;CAK3B;AAED,qBAAa,oBAAqB,SAAQ,UAAU;;CAOnD;AAED,qBAAa,qBAAsB,SAAQ,UAAU;IACnD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBACZ,KAAK,EAAE,OAAO;CAS3B;AAED;;;;;;;;GAQG;AACH,qBAAa,0BAA2B,SAAQ,UAAU;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBACd,QAAQ,EAAE,MAAM;CAO7B;AAED;;;;;;GAMG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;gBAClC,OAAO,EAAE,MAAM;CAI5B"}
|
package/dist/types.js
CHANGED
|
@@ -27,7 +27,7 @@ export class DbRlsError extends Error {
|
|
|
27
27
|
}
|
|
28
28
|
export class DbRlsNotInitialized extends DbRlsError {
|
|
29
29
|
constructor() {
|
|
30
|
-
super("@nodii/db-rls is not initialized — call initDbRls({ owner, services, authenticated }) at process start.");
|
|
30
|
+
super("@nodii/db-rls is not initialized — call initDbRls({ owner, services, authenticated, platformOps? }) at process start.");
|
|
31
31
|
this.name = "DbRlsNotInitialized";
|
|
32
32
|
}
|
|
33
33
|
}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,oEAAoE;AACpE,uEAAuE;AACvE,EAAE;AACF,gBAAgB;AAChB,qDAAqD;AACrD,uEAAuE;AACvE,0EAA0E;AAC1E,oDAAoD;AACpD,0EAA0E;AAC1E,wBAAwB;AACxB,+DAA+D;AAC/D,iDAAiD;AACjD,EAAE;AACF,uCAAuC;AACvC,0CAA0C;AAC1C,kDAAkD;AAClD,0EAA0E;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,oEAAoE;AACpE,uEAAuE;AACvE,EAAE;AACF,gBAAgB;AAChB,qDAAqD;AACrD,uEAAuE;AACvE,0EAA0E;AAC1E,oDAAoD;AACpD,0EAA0E;AAC1E,wBAAwB;AACxB,+DAA+D;AAC/D,iDAAiD;AACjD,EAAE;AACF,uCAAuC;AACvC,0CAA0C;AAC1C,kDAAkD;AAClD,0EAA0E;AA4G1E,+EAA+E;AAC/E,yBAAyB;AAEzB,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,UAAU;IACjD;QACE,KAAK,CACH,uHAAuH,CACxH,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,UAAU;IACpC,IAAI,CAAW;IACxB,YAAY,IAAc;QACxB,KAAK,CAAC,yBAAyB,IAAI,sCAAsC,CAAC,CAAC;QAC3E,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,UAAU;IAClD;QACE,KAAK,CACH,+EAA+E,CAChF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,UAAU;IAC1C,KAAK,CAAU;IACxB,YAAY,KAAc;QACxB,KAAK,CACH,4BACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,OAAO,0BAA2B,SAAQ,UAAU;IAC/C,QAAQ,CAAS;IAC1B,YAAY,QAAgB;QAC1B,KAAK,CACH,4CAA4C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,gOAAgO,CACrS,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodii/db-rls",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Three-pool RLS dispatch + GUC-set + entry-point helpers + RLS policy DDL generator for the Nodii microservice stack. Polyglot per D159 (TS + Python + Go). Spec: planning hub docKey=db-rls.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"types": "./dist/drizzle-policies.d.ts",
|
|
19
19
|
"default": "./dist/drizzle-policies.js"
|
|
20
20
|
},
|
|
21
|
+
"./drizzle/platform-ops-grants": {
|
|
22
|
+
"types": "./dist/drizzle-grants.d.ts",
|
|
23
|
+
"default": "./dist/drizzle-grants.js"
|
|
24
|
+
},
|
|
21
25
|
"./postgres-js": {
|
|
22
26
|
"types": "./dist/postgres-js-client.d.ts",
|
|
23
27
|
"default": "./dist/postgres-js-client.js"
|
|
@@ -53,7 +57,7 @@
|
|
|
53
57
|
}
|
|
54
58
|
},
|
|
55
59
|
"devDependencies": {
|
|
56
|
-
"@nodii/telemetry": "0.3.
|
|
60
|
+
"@nodii/telemetry": "0.3.1",
|
|
57
61
|
"@types/bun": "^1.3.13",
|
|
58
62
|
"@types/pg": "^8.11.10",
|
|
59
63
|
"drizzle-orm": "^0.36.4",
|
|
@@ -67,6 +71,6 @@
|
|
|
67
71
|
"directory": "ts/db-rls"
|
|
68
72
|
},
|
|
69
73
|
"dependencies": {
|
|
70
|
-
"@nodii/telemetry": "0.3.
|
|
74
|
+
"@nodii/telemetry": "0.3.1"
|
|
71
75
|
}
|
|
72
76
|
}
|