@nodii/db-rls 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -1
- package/bin/migrate-gen.mjs +11 -0
- package/dist/auth-schema.d.ts +87 -1
- package/dist/auth-schema.d.ts.map +1 -1
- package/dist/auth-schema.js +155 -5
- package/dist/auth-schema.js.map +1 -1
- package/dist/claims-context.d.ts +100 -0
- package/dist/claims-context.d.ts.map +1 -0
- package/dist/claims-context.js +262 -0
- package/dist/claims-context.js.map +1 -0
- package/dist/context.d.ts +59 -13
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +124 -34
- package/dist/context.js.map +1 -1
- package/dist/drizzle-client.d.ts +21 -3
- package/dist/drizzle-client.d.ts.map +1 -1
- package/dist/drizzle-client.js +28 -7
- package/dist/drizzle-client.js.map +1 -1
- package/dist/fence-cli.d.ts +21 -0
- package/dist/fence-cli.d.ts.map +1 -0
- package/dist/fence-cli.js +191 -0
- package/dist/fence-cli.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/index.js.map +1 -1
- package/dist/postgres-js-client.d.ts +26 -4
- package/dist/postgres-js-client.d.ts.map +1 -1
- package/dist/postgres-js-client.js +36 -8
- package/dist/postgres-js-client.js.map +1 -1
- package/dist/tenant-fence-gate.d.ts +54 -0
- package/dist/tenant-fence-gate.d.ts.map +1 -0
- package/dist/tenant-fence-gate.js +291 -0
- package/dist/tenant-fence-gate.js.map +1 -0
- package/dist/types.d.ts +161 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +126 -3
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/dist/drizzle-client.d.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { type NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
2
2
|
import { type OwnerContextOpts } from "./migrate-guard.js";
|
|
3
|
-
import type { SystemContextOpts,
|
|
3
|
+
import type { SystemContextOpts, UserMembershipContextOpts } from "./types.js";
|
|
4
4
|
type DrizzleClient<TSchema extends Record<string, unknown> = Record<string, unknown>> = NodePgDatabase<TSchema>;
|
|
5
5
|
/**
|
|
6
6
|
* withUserContext (Drizzle variant) — opens a tx on the `authenticated`
|
|
7
7
|
* pool, sets `app.user_id` + `app.tenant_id` via `auth.init(...)` (the
|
|
8
8
|
* canonical helper from § 5.7), yields a Drizzle client bound to the tx,
|
|
9
9
|
* commits/rolls back.
|
|
10
|
+
*
|
|
11
|
+
* BREAKING (unforgeable tenant binding): the tenant is NO LONGER an
|
|
12
|
+
* argument — it is read from the request's verified claims, bound once by
|
|
13
|
+
* auth middleware via `runWithVerifiedTenantClaims`. See
|
|
14
|
+
* {@link withUserContext} in `src/context.ts` for the full rationale.
|
|
15
|
+
*
|
|
16
|
+
* Throws `NoVerifiedTenantClaims` if no claims are bound.
|
|
10
17
|
*/
|
|
11
|
-
export declare function withUserContextDb<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(
|
|
18
|
+
export declare function withUserContextDb<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(fn: (db: DrizzleClient<TSchema>) => Promise<T>): Promise<T>;
|
|
12
19
|
/**
|
|
13
20
|
* @deprecated REMOVED — always throws {@link CrossTenantSessionRefused}.
|
|
14
21
|
*
|
|
@@ -19,7 +26,9 @@ export declare function withUserContextDb<T, TSchema extends Record<string, unkn
|
|
|
19
26
|
* a legitimate tenant-A session transitioned a tenant-B approval task, got
|
|
20
27
|
* HTTP 200, and released a 250,000 INR refund.
|
|
21
28
|
*
|
|
22
|
-
* Migrate to `withUserContextDb(
|
|
29
|
+
* Migrate to `withUserContextDb(fn)` — the same pool, with the tenant the
|
|
30
|
+
* request's VERIFIED claims resolved to (bound by auth middleware via
|
|
31
|
+
* `runWithVerifiedTenantClaims`; it is no longer an argument).
|
|
23
32
|
* To LIST a user's tenants (switcher / login picker), query
|
|
24
33
|
* `auth.user_tenant_ids` from a services-pool context — that function is
|
|
25
34
|
* intact; what is gone is opening a DATA session that spans them.
|
|
@@ -31,6 +40,15 @@ export declare function withUserMembershipContextDb<T, TSchema extends Record<st
|
|
|
31
40
|
/**
|
|
32
41
|
* withSystemContext (Drizzle variant) — opens a tx on the `services` pool
|
|
33
42
|
* with `app.tenant_id` GUC bound; yields a Drizzle client.
|
|
43
|
+
*
|
|
44
|
+
* Carries the STEP-1 FENCE: with verified claims bound
|
|
45
|
+
* (`hasVerifiedTenantClaims()` true) this throws
|
|
46
|
+
* `SystemContextUnderClaimsRefused` before touching a pool unless the
|
|
47
|
+
* caller passes an explicit non-blank `{ reason }` — the services-pool
|
|
48
|
+
* predicate is the bare `tenant_id = auth.get_tenant_id()` with no
|
|
49
|
+
* membership proof, the seam where the ₹250,000 cross-tenant refund
|
|
50
|
+
* reproduced. Unbound contexts (workers, cron, boot) are unchanged.
|
|
51
|
+
* See {@link withSystemContext} in `src/context.ts`.
|
|
34
52
|
*/
|
|
35
53
|
export declare function withSystemContextDb<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(opts: SystemContextOpts, fn: (db: DrizzleClient<TSchema>) => Promise<T>): Promise<T>;
|
|
36
54
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle-client.d.ts","sourceRoot":"","sources":["../src/drizzle-client.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"drizzle-client.d.ts","sourceRoot":"","sources":["../src/drizzle-client.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAczE,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAW/E,KAAK,aAAa,CAChB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC/D,cAAc,CAAC,OAAO,CAAC,CAAC;AA2D5B;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,CAAC,EACD,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoB5D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,2BAA2B,CAC/C,CAAC,EACD,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAEjE,KAAK,EAAE,yBAAyB,EAChC,GAAG,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAC9C,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,CAAC,EACD,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAEjE,IAAI,EAAE,iBAAiB,EACvB,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,CAAC,EACD,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAEjE,QAAQ,EAAE,gBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,EACzE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACnD,OAAO,CAAC,CAAC,CAAC,CAeZ;AAoBD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC"}
|
package/dist/drizzle-client.js
CHANGED
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
// original `withUserContext` (in src/context.ts) still works for
|
|
18
18
|
// services using the raw `PgTx` surface.
|
|
19
19
|
import { drizzle } from "drizzle-orm/node-postgres";
|
|
20
|
+
import { assertNoTenantArgument, assertSystemContextEscapeAllowed, requireVerifiedTenantClaims, } from "./claims-context.js";
|
|
20
21
|
import { requirePool } from "./init.js";
|
|
21
|
-
import { recordOwnerContextInvocation, withTxSpan } from "./metrics.js";
|
|
22
|
+
import { recordCrossPoolNesting, recordOwnerContextInvocation, withTxSpan, } from "./metrics.js";
|
|
22
23
|
import { assertMigrateAllowed, } from "./migrate-guard.js";
|
|
23
24
|
import { PgClientPool } from "./pg-pool-adapter.js";
|
|
24
25
|
import { CrossTenantSessionRefused, MissingTenantContext, TransactionRolledBack, } from "./types.js";
|
|
@@ -76,12 +77,17 @@ function requireRealPool(kind) {
|
|
|
76
77
|
* pool, sets `app.user_id` + `app.tenant_id` via `auth.init(...)` (the
|
|
77
78
|
* canonical helper from § 5.7), yields a Drizzle client bound to the tx,
|
|
78
79
|
* commits/rolls back.
|
|
80
|
+
*
|
|
81
|
+
* BREAKING (unforgeable tenant binding): the tenant is NO LONGER an
|
|
82
|
+
* argument — it is read from the request's verified claims, bound once by
|
|
83
|
+
* auth middleware via `runWithVerifiedTenantClaims`. See
|
|
84
|
+
* {@link withUserContext} in `src/context.ts` for the full rationale.
|
|
85
|
+
*
|
|
86
|
+
* Throws `NoVerifiedTenantClaims` if no claims are bound.
|
|
79
87
|
*/
|
|
80
|
-
export async function withUserContextDb(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (!opts.tenantId)
|
|
84
|
-
throw new MissingTenantContext();
|
|
88
|
+
export async function withUserContextDb(fn) {
|
|
89
|
+
assertNoTenantArgument("withUserContextDb", fn);
|
|
90
|
+
const opts = requireVerifiedTenantClaims("withUserContextDb");
|
|
85
91
|
const pool = requireRealPool("authenticated");
|
|
86
92
|
return withRealTx(pool, async (client) => {
|
|
87
93
|
// Set both GUCs via the canonical auth.init helper.
|
|
@@ -106,7 +112,9 @@ export async function withUserContextDb(opts, fn) {
|
|
|
106
112
|
* a legitimate tenant-A session transitioned a tenant-B approval task, got
|
|
107
113
|
* HTTP 200, and released a 250,000 INR refund.
|
|
108
114
|
*
|
|
109
|
-
* Migrate to `withUserContextDb(
|
|
115
|
+
* Migrate to `withUserContextDb(fn)` — the same pool, with the tenant the
|
|
116
|
+
* request's VERIFIED claims resolved to (bound by auth middleware via
|
|
117
|
+
* `runWithVerifiedTenantClaims`; it is no longer an argument).
|
|
110
118
|
* To LIST a user's tenants (switcher / login picker), query
|
|
111
119
|
* `auth.user_tenant_ids` from a services-pool context — that function is
|
|
112
120
|
* intact; what is gone is opening a DATA session that spans them.
|
|
@@ -120,10 +128,23 @@ export async function withUserMembershipContextDb(_opts, _fn) {
|
|
|
120
128
|
/**
|
|
121
129
|
* withSystemContext (Drizzle variant) — opens a tx on the `services` pool
|
|
122
130
|
* with `app.tenant_id` GUC bound; yields a Drizzle client.
|
|
131
|
+
*
|
|
132
|
+
* Carries the STEP-1 FENCE: with verified claims bound
|
|
133
|
+
* (`hasVerifiedTenantClaims()` true) this throws
|
|
134
|
+
* `SystemContextUnderClaimsRefused` before touching a pool unless the
|
|
135
|
+
* caller passes an explicit non-blank `{ reason }` — the services-pool
|
|
136
|
+
* predicate is the bare `tenant_id = auth.get_tenant_id()` with no
|
|
137
|
+
* membership proof, the seam where the ₹250,000 cross-tenant refund
|
|
138
|
+
* reproduced. Unbound contexts (workers, cron, boot) are unchanged.
|
|
139
|
+
* See {@link withSystemContext} in `src/context.ts`.
|
|
123
140
|
*/
|
|
124
141
|
export async function withSystemContextDb(opts, fn) {
|
|
125
142
|
if (!opts.tenantId)
|
|
126
143
|
throw new MissingTenantContext();
|
|
144
|
+
const sanctioned = assertSystemContextEscapeAllowed("withSystemContextDb", opts);
|
|
145
|
+
if (sanctioned) {
|
|
146
|
+
recordCrossPoolNesting("authenticated", "services", sanctioned.reason);
|
|
147
|
+
}
|
|
127
148
|
const pool = requireRealPool("services");
|
|
128
149
|
return withRealTx(pool, async (client) => {
|
|
129
150
|
await client.query("SELECT auth.init_tenant($1::uuid)", [opts.tenantId]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle-client.js","sourceRoot":"","sources":["../src/drizzle-client.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,iEAAiE;AACjE,uEAAuE;AACvE,2DAA2D;AAC3D,EAAE;AACF,iBAAiB;AACjB,0EAA0E;AAC1E,sEAAsE;AACtE,0BAA0B;AAC1B,sEAAsE;AACtE,wCAAwC;AACxC,8DAA8D;AAC9D,sEAAsE;AACtE,qEAAqE;AACrE,6CAA6C;AAE7C,OAAO,EAAE,OAAO,EAAuB,MAAM,2BAA2B,CAAC;AAGzE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,
|
|
1
|
+
{"version":3,"file":"drizzle-client.js","sourceRoot":"","sources":["../src/drizzle-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface FenceCliResult {
|
|
2
|
+
/** 0 = clean, 1 = fence defect, 2 = usage / connection error. */
|
|
3
|
+
code: number;
|
|
4
|
+
message: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* `install-fence` — apply the delivery unit (resolver + gate).
|
|
8
|
+
*
|
|
9
|
+
* Idempotent and re-runnable. Must be run with OWNER credentials: it creates
|
|
10
|
+
* functions in the `auth` schema. Safe to run on every deploy; safe to run
|
|
11
|
+
* twice; and re-running is how a service that has since landed a membership
|
|
12
|
+
* mirror upgrades itself from the degraded body to the strict one.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runInstallFenceCli(args: readonly string[]): Promise<FenceCliResult>;
|
|
15
|
+
/**
|
|
16
|
+
* `verify-fence` — assert the fence from the CATALOG, using the TypeScript
|
|
17
|
+
* verifier (which reports EVERY offender at once rather than raising on the
|
|
18
|
+
* first, and covers the unique-index check the SQL gate leaves to deploy time).
|
|
19
|
+
*/
|
|
20
|
+
export declare function runVerifyFenceCli(args: readonly string[]): Promise<FenceCliResult>;
|
|
21
|
+
//# sourceMappingURL=fence-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fence-cli.d.ts","sourceRoot":"","sources":["../src/fence-cli.ts"],"names":[],"mappings":"AA+BA,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAkDD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,OAAO,CAAC,cAAc,CAAC,CAsCzB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,OAAO,CAAC,cAAc,CAAC,CAkCzB"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// `nodii-db-rls install-fence` and `nodii-db-rls verify-fence`.
|
|
2
|
+
//
|
|
3
|
+
// The eager, pipeline-facing half of the gate. `withUserContext` runs
|
|
4
|
+
// `auth.assert_tenant_fence()` on first authenticated use, which is the
|
|
5
|
+
// unforgettable check — but "unforgettable" is not the same as "early", and a
|
|
6
|
+
// deploy that can fail at 09:00 rather than on the first customer request at
|
|
7
|
+
// 09:04 should.
|
|
8
|
+
//
|
|
9
|
+
// THIS IS NOT OFFERED AS THE PRIMARY MECHANISM, and the reason is measured
|
|
10
|
+
// rather than stylistic. Of the ten services that call neither
|
|
11
|
+
// `applyAuthSchemaMigrations` nor `authSchemaHelpers`, SIX — billing, kyc,
|
|
12
|
+
// notification, task-tracking, tenant and geo — have NO database step in
|
|
13
|
+
// `deploy-dev.yml`. Wiring the fence exclusively into a deploy script would
|
|
14
|
+
// leave those six permanently unchecked while reporting green, which is the
|
|
15
|
+
// precise failure mode this release exists to end. So the CLI is the
|
|
16
|
+
// belt-and-braces for pipelines that DO have a database step, and the runtime
|
|
17
|
+
// gate is the floor for everyone.
|
|
18
|
+
//
|
|
19
|
+
// `install-fence` exists because the delivery unit has to be applicable to a
|
|
20
|
+
// service that is on none of the library paths — one command, owner
|
|
21
|
+
// credentials, no code change:
|
|
22
|
+
//
|
|
23
|
+
// bunx @nodii/db-rls install-fence --db "$DATABASE_URL"
|
|
24
|
+
import { SESSION_FENCE_BOOTSTRAP_SQL, SESSION_TENANT_IDS_GRANTS_SQL, } from "./auth-schema.js";
|
|
25
|
+
import { TENANT_FENCE_GATE_GRANTS_SQL } from "./tenant-fence-gate.js";
|
|
26
|
+
import { TenantFenceError, verifyTenantFence } from "./tenant-fence.js";
|
|
27
|
+
function splitList(value) {
|
|
28
|
+
if (!value)
|
|
29
|
+
return [];
|
|
30
|
+
return value
|
|
31
|
+
.split(",")
|
|
32
|
+
.map((s) => s.trim())
|
|
33
|
+
.filter((s) => s.length > 0);
|
|
34
|
+
}
|
|
35
|
+
function parse(args) {
|
|
36
|
+
const out = {
|
|
37
|
+
allowDegraded: true,
|
|
38
|
+
skipGrants: false,
|
|
39
|
+
help: false,
|
|
40
|
+
};
|
|
41
|
+
for (let i = 0; i < args.length; i++) {
|
|
42
|
+
const a = args[i];
|
|
43
|
+
if (a === "--db" && i + 1 < args.length)
|
|
44
|
+
out.dbUrl = args[++i];
|
|
45
|
+
else if (a === "--schema" && i + 1 < args.length)
|
|
46
|
+
out.schema = args[++i];
|
|
47
|
+
else if (a === "--exempt-policies" && i + 1 < args.length)
|
|
48
|
+
out.exemptPolicies = args[++i];
|
|
49
|
+
else if (a === "--exempt-tables" && i + 1 < args.length)
|
|
50
|
+
out.exemptTables = args[++i];
|
|
51
|
+
// Default is to ACCEPT the degraded resolver: it is the D415-sanctioned
|
|
52
|
+
// terminal state for a service with no membership mirror, and a gate that
|
|
53
|
+
// is red on a legitimate configuration gets switched off. `--strict-only`
|
|
54
|
+
// is for a service that HAS a mirror and wants to prove it never silently
|
|
55
|
+
// regresses to fence-only.
|
|
56
|
+
else if (a === "--strict-only")
|
|
57
|
+
out.allowDegraded = false;
|
|
58
|
+
else if (a === "--skip-grants")
|
|
59
|
+
out.skipGrants = true;
|
|
60
|
+
else if (a === "--help" || a === "-h")
|
|
61
|
+
out.help = true;
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
function connectionString(parsed) {
|
|
66
|
+
return parsed.dbUrl ?? process.env.DATABASE_URL ?? process.env.DB_RLS_PG_URL;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* `install-fence` — apply the delivery unit (resolver + gate).
|
|
70
|
+
*
|
|
71
|
+
* Idempotent and re-runnable. Must be run with OWNER credentials: it creates
|
|
72
|
+
* functions in the `auth` schema. Safe to run on every deploy; safe to run
|
|
73
|
+
* twice; and re-running is how a service that has since landed a membership
|
|
74
|
+
* mirror upgrades itself from the degraded body to the strict one.
|
|
75
|
+
*/
|
|
76
|
+
export async function runInstallFenceCli(args) {
|
|
77
|
+
const parsed = parse(args);
|
|
78
|
+
if (parsed.help)
|
|
79
|
+
return { code: 0, message: installUsage() };
|
|
80
|
+
const conn = connectionString(parsed);
|
|
81
|
+
if (!conn) {
|
|
82
|
+
return {
|
|
83
|
+
code: 2,
|
|
84
|
+
message: "install-fence: no connection string — pass --db <url> or set DATABASE_URL / DB_RLS_PG_URL.",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const { Pool } = await import("pg");
|
|
88
|
+
const pool = new Pool({ connectionString: conn, max: 1 });
|
|
89
|
+
try {
|
|
90
|
+
await pool.query(SESSION_FENCE_BOOTSTRAP_SQL);
|
|
91
|
+
if (!parsed.skipGrants) {
|
|
92
|
+
await pool.query(SESSION_TENANT_IDS_GRANTS_SQL);
|
|
93
|
+
await pool.query(TENANT_FENCE_GATE_GRANTS_SQL);
|
|
94
|
+
}
|
|
95
|
+
const { rows } = await pool.query(`SELECT prosrc FROM pg_proc p JOIN pg_namespace n ON n.oid = p.pronamespace
|
|
96
|
+
WHERE n.nspname = 'auth' AND p.proname = 'session_tenant_ids'`);
|
|
97
|
+
const body = rows[0]?.prosrc ?? "";
|
|
98
|
+
const variant = body.includes("DB_RLS_DEGRADED_NO_MEMBERSHIP_MIRROR")
|
|
99
|
+
? "DEGRADED (fence-only, D415) — auth.user_tenant_ids is absent or still the bootstrap stub"
|
|
100
|
+
: "STRICT — session tenant INTERSECT server-resolved membership";
|
|
101
|
+
return {
|
|
102
|
+
code: 0,
|
|
103
|
+
message: `install-fence: OK. auth.session_tenant_ids() installed as ${variant}\ninstall-fence: auth.assert_tenant_fence() installed.`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
return { code: 2, message: `install-fence: ${err.message}` };
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
await pool.end().catch(() => { });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* `verify-fence` — assert the fence from the CATALOG, using the TypeScript
|
|
115
|
+
* verifier (which reports EVERY offender at once rather than raising on the
|
|
116
|
+
* first, and covers the unique-index check the SQL gate leaves to deploy time).
|
|
117
|
+
*/
|
|
118
|
+
export async function runVerifyFenceCli(args) {
|
|
119
|
+
const parsed = parse(args);
|
|
120
|
+
if (parsed.help)
|
|
121
|
+
return { code: 0, message: verifyUsage() };
|
|
122
|
+
const conn = connectionString(parsed);
|
|
123
|
+
if (!conn) {
|
|
124
|
+
return {
|
|
125
|
+
code: 2,
|
|
126
|
+
message: "verify-fence: no connection string — pass --db <url> or set DATABASE_URL / DB_RLS_PG_URL.",
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const { Pool } = await import("pg");
|
|
130
|
+
const pool = new Pool({ connectionString: conn, max: 1 });
|
|
131
|
+
try {
|
|
132
|
+
await verifyTenantFence(pool, {
|
|
133
|
+
schema: parsed.schema,
|
|
134
|
+
exemptPolicies: splitList(parsed.exemptPolicies),
|
|
135
|
+
exemptTables: splitList(parsed.exemptTables),
|
|
136
|
+
allowDegradedResolver: parsed.allowDegraded,
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
code: 0,
|
|
140
|
+
message: "verify-fence: OK — every authenticated policy resolves through auth.session_tenant_ids(), every tenant-scoped relation is protected.",
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
if (err instanceof TenantFenceError)
|
|
145
|
+
return { code: 1, message: err.message };
|
|
146
|
+
return { code: 2, message: `verify-fence: ${err.message}` };
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
await pool.end().catch(() => { });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function installUsage() {
|
|
153
|
+
return `usage: install-fence [--db <url>] [--skip-grants]
|
|
154
|
+
|
|
155
|
+
Applies the tenant-fence delivery unit with OWNER credentials:
|
|
156
|
+
- auth.session_tenant_ids() — the authenticated-pool resolver. The STRICT
|
|
157
|
+
body (session tenant INTERSECT membership) is installed where a real
|
|
158
|
+
auth.user_tenant_ids exists; the DEGRADED fence-only body (D415) where it
|
|
159
|
+
is absent or still the bootstrap stub. Derived from the catalog on every
|
|
160
|
+
run — there is no per-service list to get wrong, and re-running after a
|
|
161
|
+
membership mirror lands upgrades degraded to strict automatically.
|
|
162
|
+
- auth.assert_tenant_fence() — the runtime gate @nodii/db-rls calls on the
|
|
163
|
+
first authenticated-pool checkout.
|
|
164
|
+
|
|
165
|
+
Idempotent. Safe on every deploy. Run BEFORE any migration that creates a
|
|
166
|
+
policy referencing the resolver: Postgres validates the reference at CREATE
|
|
167
|
+
POLICY time, so an absent resolver fails the migration with 42883.
|
|
168
|
+
|
|
169
|
+
Connection string: --db <url>, else DATABASE_URL, else DB_RLS_PG_URL.`;
|
|
170
|
+
}
|
|
171
|
+
function verifyUsage() {
|
|
172
|
+
return `usage: verify-fence [--db <url>] [--schema <name>] [--strict-only]
|
|
173
|
+
[--exempt-policies <a.b,c>] [--exempt-tables <x,y>]
|
|
174
|
+
|
|
175
|
+
Asserts from the CATALOG that every permissive policy applying to the
|
|
176
|
+
'authenticated' role resolves through auth.session_tenant_ids(), that every
|
|
177
|
+
relation carrying a tenant column can enforce RLS, and that the resolver is
|
|
178
|
+
installed, loud, and SECURITY DEFINER. Exits 1 (loud) listing every offender.
|
|
179
|
+
|
|
180
|
+
Tables are DISCOVERED from the catalog, never supplied by the caller: the
|
|
181
|
+
author who forgets ENABLE ROW LEVEL SECURITY forgets the list entry in the
|
|
182
|
+
same migration, which is why a caller-supplied list is blind to exactly the
|
|
183
|
+
tables at risk.
|
|
184
|
+
|
|
185
|
+
--strict-only additionally rejects the DEGRADED fence-only resolver. The
|
|
186
|
+
default accepts it: it is the D415-sanctioned terminal state for a service
|
|
187
|
+
with no membership mirror.
|
|
188
|
+
|
|
189
|
+
Connection string: --db <url>, else DATABASE_URL, else DB_RLS_PG_URL.`;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=fence-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fence-cli.js","sourceRoot":"","sources":["../src/fence-cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,13 +6,15 @@ export { configureDbRls, configureDbRls2Pool, configureDbRls4Pool, PoolCredentia
|
|
|
6
6
|
export type { ConfigureDbRlsOpts, ConfigureDbRlsPools, } from "./configure.js";
|
|
7
7
|
export { PgClientPool } from "./pg-pool-adapter.js";
|
|
8
8
|
export type { PgPoolAdapterOpts } from "./pg-pool-adapter.js";
|
|
9
|
+
export { assertNoTenantArgument, assertSystemContextEscapeAllowed, getVerifiedTenantClaimsOrNull, hasVerifiedTenantClaims, requireVerifiedTenantClaims, runWithVerifiedTenantClaims, } from "./claims-context.js";
|
|
9
10
|
export { withUserContext, withUserMembershipContext, withSystemContext, withOwnerContext, withPlatformOpsContext, withPlatformOps, _resetWithPlatformOpsDeprecationWarnedForTests, autoDispatch, } from "./context.js";
|
|
10
11
|
export type { OwnerContextOpts } from "./migrate-guard.js";
|
|
11
12
|
export { assertMigrateAllowed } from "./migrate-guard.js";
|
|
12
13
|
export { RlsCoverageError, verifyRls } from "./verify-rls.js";
|
|
13
14
|
export type { AnyRlsQuerier, ReferenceTablePredicate, RlsCoverageOffender, RlsQuerier, RlsQuerierPostgresJs, VerifyRlsOpts, } from "./verify-rls.js";
|
|
14
|
-
export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, SESSION_TENANT_IDS_DEGRADED_MARKER, SESSION_TENANT_IDS_DEGRADED_SQL, SESSION_TENANT_IDS_GRANTS_SQL, SESSION_TENANT_IDS_SQL, } from "./auth-schema.js";
|
|
15
|
+
export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, SESSION_TENANT_IDS_DEGRADED_MARKER, SESSION_TENANT_IDS_DEGRADED_SQL, SESSION_TENANT_IDS_GRANTS_SQL, SESSION_TENANT_IDS_SQL, applySessionFenceBootstrap, INSTALL_SESSION_RESOLVER_SQL, SESSION_FENCE_BOOTSTRAP_SQL, } from "./auth-schema.js";
|
|
15
16
|
export type { SqlExecutor } from "./auth-schema.js";
|
|
17
|
+
export { TENANT_FENCE_GATE_CALL_SQL, TENANT_FENCE_GATE_GRANTS_SQL, TENANT_FENCE_GATE_SQL, sessionFenceBootstrapSql, } from "./tenant-fence-gate.js";
|
|
16
18
|
export { withRls, generateTableGrants, authenticatedPredicate, SESSION_TENANT_IDS_CALL, SESSION_TENANT_IDS_SUBQUERY, withPlatformOpsTenantSql, withPlatformOpsGlobalSql, platformOpsTenantPredicateSql, platformOpsGlobalPredicateSql, platformOpsVerbClauseSql, sqlLiteral, PLATFORM_OPS_GRANTS_REPLICA_DEFAULT, referenceTableGrantsSql, findTenantColumn, ReferenceTableTenantColumnError, REFERENCE_TABLE_SKIP_RLS_MARKER, } from "./rls-policy-gen.js";
|
|
17
19
|
export type { RlsVerb, WithRlsOpts, AuthPoolMode, PlatformOpsVerb, PlatformOpsPerVerbPermissions, WithPlatformOpsSqlOpts, ReferenceTableReadRole, ReferenceTableSqlOpts, } from "./rls-policy-gen.js";
|
|
18
20
|
export { migrateGen, runMigrateGenCli, userTenantIdsRealSql, userTenantIdsStubSql, platformOpsPoliciesSql, referenceTablesSql, } from "./migrate-gen.js";
|
|
@@ -21,8 +23,8 @@ export { generateRlsPolicy, authSchemaHelpers } from "./rls-policy.js";
|
|
|
21
23
|
export { InMemoryPgPool } from "./in-memory-pool.js";
|
|
22
24
|
export type { TranscriptEntry } from "./in-memory-pool.js";
|
|
23
25
|
export { DB_RLS_METRIC_VOCABULARY, _resetMetricsWarnLedgerForTests, } from "./metrics.js";
|
|
24
|
-
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, CrossTenantSessionRefused, MissingTenantContext, OwnerContextOutsideMigrate, PoolUnavailable, TransactionRolledBack, } from "./types.js";
|
|
25
|
-
export type {
|
|
26
|
+
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, CrossTenantSessionRefused, InvalidVerifiedTenantClaims, MissingTenantContext, NoVerifiedTenantClaims, OwnerContextOutsideMigrate, PoolUnavailable, SystemContextUnderClaimsRefused, TenantArgumentRefused, TransactionRolledBack, VerifiedTenantClaimsAlreadyBound, } from "./types.js";
|
|
27
|
+
export type { AutoDispatchOpts, DbRlsMode, GenerateRlsPolicyOpts, PgPool, PgTx, PlatformOpsContextOpts, PoolKind, SystemContextOpts, UserMembershipContextOpts, VerifiedTenantClaims, } from "./types.js";
|
|
26
28
|
export { classifyAuthPolicy, consultsMembershipUnion, isStubMembershipHelper, resolvesThroughSession, TenantFenceError, verifyTenantFence, } from "./tenant-fence.js";
|
|
27
29
|
export type { TenantFenceOffender, TenantFenceReason, VerifyTenantFenceOpts, } from "./tenant-fence.js";
|
|
28
30
|
//# 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":"AAmCA,eAAO,MAAM,QAAQ,WAAW,CAAC;AAejC,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC;AAE3C,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEhE,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,14 @@ export const VERSION = pkg.version;
|
|
|
49
49
|
export { initDbRls, requireDbRls, getDbRlsOrNull, requirePool, _resetForTests, } from "./init.js";
|
|
50
50
|
export { configureDbRls, configureDbRls2Pool, configureDbRls4Pool, PoolCredentialMismatch, _resetConfigureForTests, } from "./configure.js";
|
|
51
51
|
export { PgClientPool } from "./pg-pool-adapter.js";
|
|
52
|
+
// Unforgeable tenant binding — the request-scoped VERIFIED-claims context
|
|
53
|
+
// the authenticated-pool helpers derive their tenant from. `runWith…` is
|
|
54
|
+
// the ONLY way to establish it, and auth middleware is the only thing that
|
|
55
|
+
// should call it. See the migration note in README.md § "Unforgeable tenant
|
|
56
|
+
// binding". `assertSystemContextEscapeAllowed` is the step-1 fence the
|
|
57
|
+
// system-pool helpers run — exported so a bespoke wrapper can carry the
|
|
58
|
+
// same fence rather than silently bypassing it.
|
|
59
|
+
export { assertNoTenantArgument, assertSystemContextEscapeAllowed, getVerifiedTenantClaimsOrNull, hasVerifiedTenantClaims, requireVerifiedTenantClaims, runWithVerifiedTenantClaims, } from "./claims-context.js";
|
|
52
60
|
export { withUserContext, withUserMembershipContext, withSystemContext, withOwnerContext, withPlatformOpsContext,
|
|
53
61
|
// Deprecated re-export alias of `withPlatformOpsContext`, kept for one
|
|
54
62
|
// minor (v0.4.1) for v0.4.0 adopters; removed in v0.5.0. Canonical name
|
|
@@ -72,7 +80,18 @@ export { assertMigrateAllowed } from "./migrate-guard.js";
|
|
|
72
80
|
// no `pg` installed) could not satisfy; that is why this had zero adoption
|
|
73
81
|
// while five services hand-rolled the same pg_class query in their tests.
|
|
74
82
|
export { RlsCoverageError, verifyRls } from "./verify-rls.js";
|
|
75
|
-
export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, SESSION_TENANT_IDS_DEGRADED_MARKER, SESSION_TENANT_IDS_DEGRADED_SQL, SESSION_TENANT_IDS_GRANTS_SQL, SESSION_TENANT_IDS_SQL,
|
|
83
|
+
export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, SESSION_TENANT_IDS_DEGRADED_MARKER, SESSION_TENANT_IDS_DEGRADED_SQL, SESSION_TENANT_IDS_GRANTS_SQL, SESSION_TENANT_IDS_SQL,
|
|
84
|
+
// THE DELIVERY PATH. `INSTALL_SESSION_RESOLVER_SQL` picks the strict or
|
|
85
|
+
// degraded resolver body from what the database actually contains;
|
|
86
|
+
// `SESSION_FENCE_BOOTSTRAP_SQL` is that plus the runtime gate, and
|
|
87
|
+
// `applySessionFenceBootstrap` applies it. A service with no other delivery
|
|
88
|
+
// path calls the last of these from its boot sequence, before anything opens
|
|
89
|
+
// an authenticated transaction.
|
|
90
|
+
applySessionFenceBootstrap, INSTALL_SESSION_RESOLVER_SQL, SESSION_FENCE_BOOTSTRAP_SQL, } from "./auth-schema.js";
|
|
91
|
+
// The RUNTIME gate. `withUserContext` calls `auth.assert_tenant_fence()` once
|
|
92
|
+
// per process on the first authenticated checkout — these are exported for the
|
|
93
|
+
// CLI, for a bespoke `db:verify`, and so the wiring is greppable.
|
|
94
|
+
export { TENANT_FENCE_GATE_CALL_SQL, TENANT_FENCE_GATE_GRANTS_SQL, TENANT_FENCE_GATE_SQL, sessionFenceBootstrapSql, } from "./tenant-fence-gate.js";
|
|
76
95
|
export { withRls, generateTableGrants,
|
|
77
96
|
// 08-rls § 6 — the authenticated-pool predicate (single source of truth,
|
|
78
97
|
// pool-mode aware). Exported so consumers can compose it directly.
|
|
@@ -85,6 +104,6 @@ export { migrateGen, runMigrateGenCli, userTenantIdsRealSql, userTenantIdsStubSq
|
|
|
85
104
|
export { generateRlsPolicy, authSchemaHelpers } from "./rls-policy.js";
|
|
86
105
|
export { InMemoryPgPool } from "./in-memory-pool.js";
|
|
87
106
|
export { DB_RLS_METRIC_VOCABULARY, _resetMetricsWarnLedgerForTests, } from "./metrics.js";
|
|
88
|
-
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, CrossTenantSessionRefused, MissingTenantContext, OwnerContextOutsideMigrate, PoolUnavailable, TransactionRolledBack, } from "./types.js";
|
|
107
|
+
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, CrossTenantSessionRefused, InvalidVerifiedTenantClaims, MissingTenantContext, NoVerifiedTenantClaims, OwnerContextOutsideMigrate, PoolUnavailable, SystemContextUnderClaimsRefused, TenantArgumentRefused, TransactionRolledBack, VerifiedTenantClaimsAlreadyBound, } from "./types.js";
|
|
89
108
|
export { classifyAuthPolicy, consultsMembershipUnion, isStubMembershipHelper, resolvesThroughSession, TenantFenceError, verifyTenantFence, } from "./tenant-fence.js";
|
|
90
109
|
//# sourceMappingURL=index.js.map
|
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,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAEjC,yEAAyE;AACzE,4EAA4E;AAC5E,sEAAsE;AACtE,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,2EAA2E;AAC3E,kEAAkE;AAClE,sEAAsE;AACtE,8BAA8B;AAC9B,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,MAAM,GAAG,GAAG,QAAQ,CAAC,iBAAiB,CAAwB,CAAC;AAC/D,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC;AAE3C,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB;AACtB,uEAAuE;AACvE,wEAAwE;AACxE,sCAAsC;AACtC,eAAe,EACf,8CAA8C,EAC9C,YAAY,GACb,MAAM,cAAc,CAAC;AAetB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,wEAAwE;AACxE,wEAAwE;AACxE,qEAAqE;AACrE,yEAAyE;AACzE,EAAE;AACF,uCAAuC;AACvC,sEAAsE;AACtE,qBAAqB;AACrB,wDAAwD;AACxD,yCAAyC;AACzC,+DAA+D;AAC/D,EAAE;AACF,uEAAuE;AACvE,6EAA6E;AAC7E,2EAA2E;AAC3E,0EAA0E;AAC1E,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU9D,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,EACjB,kCAAkC,EAClC,+BAA+B,EAC/B,6BAA6B,EAC7B,sBAAsB,
|
|
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,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAEjC,yEAAyE;AACzE,4EAA4E;AAC5E,sEAAsE;AACtE,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,2EAA2E;AAC3E,kEAAkE;AAClE,sEAAsE;AACtE,8BAA8B;AAC9B,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,MAAM,GAAG,GAAG,QAAQ,CAAC,iBAAiB,CAAwB,CAAC;AAC/D,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC;AAE3C,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,4EAA4E;AAC5E,uEAAuE;AACvE,wEAAwE;AACxE,gDAAgD;AAChD,OAAO,EACL,sBAAsB,EACtB,gCAAgC,EAChC,6BAA6B,EAC7B,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB;AACtB,uEAAuE;AACvE,wEAAwE;AACxE,sCAAsC;AACtC,eAAe,EACf,8CAA8C,EAC9C,YAAY,GACb,MAAM,cAAc,CAAC;AAetB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,wEAAwE;AACxE,wEAAwE;AACxE,qEAAqE;AACrE,yEAAyE;AACzE,EAAE;AACF,uCAAuC;AACvC,sEAAsE;AACtE,qBAAqB;AACrB,wDAAwD;AACxD,yCAAyC;AACzC,+DAA+D;AAC/D,EAAE;AACF,uEAAuE;AACvE,6EAA6E;AAC7E,2EAA2E;AAC3E,0EAA0E;AAC1E,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU9D,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,EACjB,kCAAkC,EAClC,+BAA+B,EAC/B,6BAA6B,EAC7B,sBAAsB;AACtB,wEAAwE;AACxE,mEAAmE;AACnE,mEAAmE;AACnE,4EAA4E;AAC5E,6EAA6E;AAC7E,gCAAgC;AAChC,0BAA0B,EAC1B,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAG1B,8EAA8E;AAC9E,+EAA+E;AAC/E,kEAAkE;AAClE,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,OAAO,EACP,mBAAmB;AACnB,yEAAyE;AACzE,mEAAmE;AACnE,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,6BAA6B,EAC7B,wBAAwB,EACxB,UAAU,EACV,mCAAmC;AACnC,2EAA2E;AAC3E,uBAAuB,EACvB,gBAAgB,EAChB,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAQ1B,qEAAqE;AACrE,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,yBAAyB,EACzB,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,EAC1B,eAAe,EACf,+BAA+B,EAC/B,qBAAqB,EACrB,qBAAqB,EACrB,gCAAgC,GACjC,MAAM,YAAY,CAAC;AAkBpB,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
2
|
import type { Sql } from "postgres";
|
|
3
3
|
import { type OwnerContextOpts } from "./migrate-guard.js";
|
|
4
|
-
import { type PgPool, type PgTx, type PlatformOpsContextOpts, type PoolKind, type SystemContextOpts, type
|
|
4
|
+
import { type PgPool, type PgTx, type PlatformOpsContextOpts, type PoolKind, type SystemContextOpts, type UserMembershipContextOpts } from "./types.js";
|
|
5
5
|
type PostgresJsDrizzleClient<TSchema extends Record<string, unknown> = Record<string, unknown>> = PostgresJsDatabase<TSchema>;
|
|
6
6
|
/**
|
|
7
7
|
* PgPool adapter wrapping a postgres-js `Sql` instance. Caller owns the
|
|
@@ -64,8 +64,17 @@ export declare class PgPostgresJsPool implements PgPool {
|
|
|
64
64
|
* postgres-js Drizzle variant of `withUserContext`. Opens a tx on the
|
|
65
65
|
* `authenticated` pool, sets `app.user_id` + `app.tenant_id` via the
|
|
66
66
|
* canonical `auth.init(...)` helper, yields a Drizzle client.
|
|
67
|
+
*
|
|
68
|
+
* BREAKING (unforgeable tenant binding): the tenant is NO LONGER an
|
|
69
|
+
* argument — it is read from the request's verified claims, bound once by
|
|
70
|
+
* auth middleware via `runWithVerifiedTenantClaims`. See
|
|
71
|
+
* {@link withUserContext} in `src/context.ts` for the full rationale.
|
|
72
|
+
* This is the fleet-default driver, so this is the variant most of the
|
|
73
|
+
* 271 call sites go through.
|
|
74
|
+
*
|
|
75
|
+
* Throws `NoVerifiedTenantClaims` if no claims are bound.
|
|
67
76
|
*/
|
|
68
|
-
export declare function withUserContextDbPostgresJs<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(
|
|
77
|
+
export declare function withUserContextDbPostgresJs<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(fn: (db: PostgresJsDrizzleClient<TSchema>) => Promise<T>): Promise<T>;
|
|
69
78
|
/**
|
|
70
79
|
* @deprecated REMOVED — always throws {@link CrossTenantSessionRefused}.
|
|
71
80
|
*
|
|
@@ -76,7 +85,9 @@ export declare function withUserContextDbPostgresJs<T, TSchema extends Record<st
|
|
|
76
85
|
* a legitimate tenant-A session transitioned a tenant-B approval task, got
|
|
77
86
|
* HTTP 200, and released a 250,000 INR refund.
|
|
78
87
|
*
|
|
79
|
-
* Migrate to `withUserContextDbPostgresJs(
|
|
88
|
+
* Migrate to `withUserContextDbPostgresJs(fn)` — the same pool, with the
|
|
89
|
+
* tenant the request's VERIFIED claims resolved to (bound by auth middleware
|
|
90
|
+
* via `runWithVerifiedTenantClaims`; it is no longer an argument).
|
|
80
91
|
* To LIST a user's tenants (switcher / login picker), query
|
|
81
92
|
* `auth.user_tenant_ids` from a services-pool context — that function is
|
|
82
93
|
* intact; what is gone is opening a DATA session that spans them.
|
|
@@ -88,6 +99,15 @@ export declare function withUserMembershipContextDbPostgresJs<T, TSchema extends
|
|
|
88
99
|
/**
|
|
89
100
|
* postgres-js Drizzle variant of `withSystemContext`. Opens a tx on the
|
|
90
101
|
* `services` pool with `app.tenant_id` GUC bound; yields a Drizzle client.
|
|
102
|
+
*
|
|
103
|
+
* Carries the STEP-1 FENCE: with verified claims bound
|
|
104
|
+
* (`hasVerifiedTenantClaims()` true) this throws
|
|
105
|
+
* `SystemContextUnderClaimsRefused` before touching a pool unless the
|
|
106
|
+
* caller passes an explicit non-blank `{ reason }` — the services-pool
|
|
107
|
+
* predicate is the bare `tenant_id = auth.get_tenant_id()` with no
|
|
108
|
+
* membership proof, the seam where the ₹250,000 cross-tenant refund
|
|
109
|
+
* reproduced. Unbound contexts (workers, cron, boot) are unchanged.
|
|
110
|
+
* See {@link withSystemContext} in `src/context.ts`.
|
|
91
111
|
*/
|
|
92
112
|
export declare function withSystemContextDbPostgresJs<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(opts: SystemContextOpts, fn: (db: PostgresJsDrizzleClient<TSchema>) => Promise<T>): Promise<T>;
|
|
93
113
|
/**
|
|
@@ -121,7 +141,9 @@ export declare function withOwnerContextDbPostgresJs<T, TSchema extends Record<s
|
|
|
121
141
|
export type { PostgresJsDrizzleClient };
|
|
122
142
|
export { _resetForTests, getDbRlsOrNull, type InitDbRlsConfig, initDbRls, requireDbRls, requirePool, type ResolvedDbRls, } from "./init.js";
|
|
123
143
|
export { assertMigrateAllowed } from "./migrate-guard.js";
|
|
144
|
+
export { assertNoTenantArgument, assertSystemContextEscapeAllowed, getVerifiedTenantClaimsOrNull, hasVerifiedTenantClaims, requireVerifiedTenantClaims, runWithVerifiedTenantClaims, } from "./claims-context.js";
|
|
124
145
|
export { DB_RLS_METRIC_VOCABULARY } from "./metrics.js";
|
|
125
146
|
export { generateTableGrants, withRls } from "./rls-policy-gen.js";
|
|
126
|
-
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, MissingTenantContext, OwnerContextOutsideMigrate, PoolUnavailable, TransactionRolledBack, } from "./types.js";
|
|
147
|
+
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, InvalidVerifiedTenantClaims, MissingTenantContext, NoVerifiedTenantClaims, OwnerContextOutsideMigrate, PoolUnavailable, SystemContextUnderClaimsRefused, TenantArgumentRefused, TransactionRolledBack, VerifiedTenantClaimsAlreadyBound, } from "./types.js";
|
|
148
|
+
export type { VerifiedTenantClaims } from "./types.js";
|
|
127
149
|
//# sourceMappingURL=postgres-js-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-js-client.d.ts","sourceRoot":"","sources":["../src/postgres-js-client.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAW,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,GAAG,EAAkB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"postgres-js-client.d.ts","sourceRoot":"","sources":["../src/postgres-js-client.ts"],"names":[],"mappings":"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"}
|