@stratum-hq/control-plane 1.0.1 → 1.1.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.
Files changed (49) hide show
  1. package/README.md +4 -2
  2. package/dist/config.d.ts +2 -0
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +26 -0
  5. package/dist/config.js.map +1 -1
  6. package/dist/middleware/auth.d.ts.map +1 -1
  7. package/dist/middleware/auth.js +6 -1
  8. package/dist/middleware/auth.js.map +1 -1
  9. package/dist/middleware/authorize.d.ts.map +1 -1
  10. package/dist/middleware/authorize.js +16 -6
  11. package/dist/middleware/authorize.js.map +1 -1
  12. package/dist/middleware/per-key-rate-limit.d.ts +11 -1
  13. package/dist/middleware/per-key-rate-limit.d.ts.map +1 -1
  14. package/dist/middleware/per-key-rate-limit.js +14 -4
  15. package/dist/middleware/per-key-rate-limit.js.map +1 -1
  16. package/dist/middleware/rate-limit-redis.d.ts +2 -1
  17. package/dist/middleware/rate-limit-redis.d.ts.map +1 -1
  18. package/dist/middleware/rate-limit-redis.js +7 -4
  19. package/dist/middleware/rate-limit-redis.js.map +1 -1
  20. package/dist/middleware/tenant-scope.d.ts +9 -3
  21. package/dist/middleware/tenant-scope.d.ts.map +1 -1
  22. package/dist/middleware/tenant-scope.js +26 -3
  23. package/dist/middleware/tenant-scope.js.map +1 -1
  24. package/dist/redis.d.ts +3 -1
  25. package/dist/redis.d.ts.map +1 -1
  26. package/dist/redis.js +5 -6
  27. package/dist/redis.js.map +1 -1
  28. package/dist/routes/abac.d.ts.map +1 -1
  29. package/dist/routes/abac.js +3 -2
  30. package/dist/routes/abac.js.map +1 -1
  31. package/dist/routes/api-keys.d.ts.map +1 -1
  32. package/dist/routes/api-keys.js +18 -4
  33. package/dist/routes/api-keys.js.map +1 -1
  34. package/dist/routes/maintenance.js +3 -3
  35. package/dist/routes/maintenance.js.map +1 -1
  36. package/dist/routes/regions.d.ts.map +1 -1
  37. package/dist/routes/regions.js +5 -4
  38. package/dist/routes/regions.js.map +1 -1
  39. package/dist/routes/roles.d.ts.map +1 -1
  40. package/dist/routes/roles.js +15 -3
  41. package/dist/routes/roles.js.map +1 -1
  42. package/dist/routes/tenants.d.ts.map +1 -1
  43. package/dist/routes/tenants.js +51 -9
  44. package/dist/routes/tenants.js.map +1 -1
  45. package/dist/services/isolation-service.d.ts +6 -5
  46. package/dist/services/isolation-service.d.ts.map +1 -1
  47. package/dist/services/isolation-service.js +17 -11
  48. package/dist/services/isolation-service.js.map +1 -1
  49. package/package.json +4 -4
package/README.md CHANGED
@@ -26,11 +26,13 @@ On startup the server runs database migrations, then listens on `PORT` (default
26
26
  |----------|---------|-------------|
27
27
  | `PORT` | `3001` | Listen port |
28
28
  | `DATABASE_URL` | `postgres://stratum:stratum_dev@localhost:5432/stratum` | PostgreSQL connection string |
29
- | `JWT_SECRET` | dev fallback | JWT signing secret — **required** in production/staging (server refuses to start without it) |
29
+ | `JWT_SECRET` | dev fallback | JWT signing secret — **required** in production/staging (server refuses to start without it). In production it must be at least 32 bytes and not a placeholder such as `change-me-in-production` |
30
+ | `JWT_AUDIENCE` | — | Optional; when set, Bearer tokens must carry this `aud` claim (for example `stratum-control-plane`). Recommended whenever `JWT_SECRET` is shared with another application |
31
+ | `JWT_ISSUER` | — | Optional; when set, Bearer tokens must carry this `iss` claim |
30
32
  | `ALLOWED_ORIGINS` | `localhost:3000,3300` | Comma-separated CORS allowlist |
31
33
  | `RATE_LIMIT_MAX` | `100` | Requests per window |
32
34
  | `RATE_LIMIT_WINDOW` | `1 minute` | Rate-limit window |
33
- | `REDIS_URL` | — | Optional; enables distributed rate limiting |
35
+ | `REDIS_URL` | — | Optional; enables distributed per-key rate limiting. While Redis is unreachable the client keeps reconnecting and per-key limits are counted in memory per process |
34
36
  | `NODE_ENV` | `development` | Environment |
35
37
 
36
38
  Security middleware (`@fastify/helmet`, CORS, rate limiting) is enabled by default.
package/dist/config.d.ts CHANGED
@@ -3,6 +3,8 @@ export declare const config: {
3
3
  databaseUrl: string;
4
4
  nodeEnv: string;
5
5
  jwtSecret: string;
6
+ jwtAudience: string | undefined;
7
+ jwtIssuer: string | undefined;
6
8
  allowedOrigins: string[];
7
9
  rateLimitMax: number;
8
10
  rateLimitWindow: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,MAAM;;;;;;;;;CAWlB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAyCA,eAAO,MAAM,MAAM;;;;;;;;;;;CAalB,CAAC"}
package/dist/config.js CHANGED
@@ -15,11 +15,37 @@ if (!jwtSecretEnv) {
15
15
  console.warn("[stratum] JWT_SECRET not set — using dev fallback. Set JWT_SECRET before deploying to production.");
16
16
  }
17
17
  }
18
+ // Placeholder secrets published in this repository's examples and scaffolds.
19
+ const PLACEHOLDER_JWT_SECRETS = new Set([
20
+ "change-me-in-production",
21
+ "stratum-demo-secret-do-not-use-in-production",
22
+ "your-jwt-secret-change-in-production",
23
+ ]);
24
+ const MIN_JWT_SECRET_BYTES = 32;
25
+ if (jwtSecretEnv && nodeEnv === "production") {
26
+ if (PLACEHOLDER_JWT_SECRETS.has(jwtSecretEnv)) {
27
+ throw new Error("FATAL: JWT_SECRET is a published placeholder value. Set a random secret. Refusing to start.");
28
+ }
29
+ if (Buffer.byteLength(jwtSecretEnv, "utf8") < MIN_JWT_SECRET_BYTES) {
30
+ throw new Error(`FATAL: JWT_SECRET must be at least ${MIN_JWT_SECRET_BYTES} bytes in production. Refusing to start.`);
31
+ }
32
+ }
33
+ // Optional JWT audience / issuer binding. When set, a Bearer token is accepted
34
+ // only if its `aud` (and `iss`) claim matches, so tokens minted for another
35
+ // application that shares JWT_SECRET are refused. Unset keeps the previous
36
+ // behavior (no aud / iss check) for deployments whose tokens do not carry them.
37
+ const jwtAudienceEnv = process.env.JWT_AUDIENCE || undefined;
38
+ const jwtIssuerEnv = process.env.JWT_ISSUER || undefined;
39
+ if (!jwtAudienceEnv && (nodeEnv === "production" || nodeEnv === "staging")) {
40
+ console.warn("[stratum] JWT_AUDIENCE not set — Bearer tokens are not bound to the control plane. Set JWT_AUDIENCE (for example stratum-control-plane).");
41
+ }
18
42
  exports.config = {
19
43
  port: parseInt(process.env.PORT || "3001"),
20
44
  databaseUrl: process.env.DATABASE_URL || "postgres://stratum:stratum_dev@localhost:5432/stratum",
21
45
  nodeEnv,
22
46
  jwtSecret: jwtSecretEnv || node_crypto_1.default.randomBytes(32).toString("hex"),
47
+ jwtAudience: jwtAudienceEnv,
48
+ jwtIssuer: jwtIssuerEnv,
23
49
  allowedOrigins: process.env.ALLOWED_ORIGINS
24
50
  ? process.env.ALLOWED_ORIGINS.split(",").map((o) => o.trim())
25
51
  : ["http://localhost:3000", "http://localhost:3300"],
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAiC;AAEjC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;AAEtD,IAAI,CAAC,YAAY,EAAE,CAAC;IAClB,IAAI,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,mGAAmG,CAAC,CAAC;IACpH,CAAC;AACH,CAAC;AAEY,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;IAC1C,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uDAAuD;IAChG,OAAO;IACP,SAAS,EAAE,YAAY,IAAI,qBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IACjE,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;QACzC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,CAAC,CAAC,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;IACtD,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,KAAK,CAAC;IAC3D,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,UAAU;IAC5D,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS;CAC7C,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAiC;AAEjC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;AAEtD,IAAI,CAAC,YAAY,EAAE,CAAC;IAClB,IAAI,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,mGAAmG,CAAC,CAAC;IACpH,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,yBAAyB;IACzB,8CAA8C;IAC9C,sCAAsC;CACvC,CAAC,CAAC;AACH,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,IAAI,YAAY,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;IAC7C,IAAI,uBAAuB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;IACjH,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,oBAAoB,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,sCAAsC,oBAAoB,0CAA0C,CAAC,CAAC;IACxH,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,gFAAgF;AAChF,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,SAAS,CAAC;AAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,SAAS,CAAC;AAEzD,IAAI,CAAC,cAAc,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,SAAS,CAAC,EAAE,CAAC;IAC3E,OAAO,CAAC,IAAI,CAAC,0IAA0I,CAAC,CAAC;AAC3J,CAAC;AAEY,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;IAC1C,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uDAAuD;IAChG,OAAO;IACP,SAAS,EAAE,YAAY,IAAI,qBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IACjE,WAAW,EAAE,cAAc;IAC3B,SAAS,EAAE,YAAY;IACvB,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;QACzC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,CAAC,CAAC,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;IACtD,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,KAAK,CAAC;IAC3D,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,UAAU;IAC5D,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS;CAC7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,MAAM,CAAC,EAAE,YAAY,CAAC;QACtB,UAAU,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;KAChC;CACF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,IAEjD,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CA8EjB"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,MAAM,CAAC,EAAE,YAAY,CAAC;QACtB,UAAU,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;KAChC;CACF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,IAEjD,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAmFjB"}
@@ -40,7 +40,12 @@ function createAuthMiddleware(stratum) {
40
40
  if (authHeader && typeof authHeader === "string" && authHeader.startsWith("Bearer ")) {
41
41
  const token = authHeader.slice(7);
42
42
  try {
43
- const payload = jsonwebtoken_1.default.verify(token, config_js_1.config.jwtSecret, { algorithms: ["HS256"] });
43
+ const payload = jsonwebtoken_1.default.verify(token, config_js_1.config.jwtSecret, {
44
+ algorithms: ["HS256"],
45
+ // Enforced only when configured (JWT_AUDIENCE / JWT_ISSUER).
46
+ ...(config_js_1.config.jwtAudience ? { audience: config_js_1.config.jwtAudience } : {}),
47
+ ...(config_js_1.config.jwtIssuer ? { issuer: config_js_1.config.jwtIssuer } : {}),
48
+ });
44
49
  // JWT must contain a tenant_id claim — JWTs without one are not allowed
45
50
  // global access (only API keys may have null tenant_id).
46
51
  if (!payload.tenant_id || typeof payload.tenant_id !== "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAwCvD,wBAAgB,yBAAyB,KAErC,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAwBjB"}
1
+ {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA+CvD,wBAAgB,yBAAyB,KAErC,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CA4BjB"}
@@ -23,16 +23,22 @@ const ADMIN_ROUTES = [
23
23
  /^\/api\/v1\/tenants\/[^/]+\/migrate-region$/,
24
24
  /^\/api\/v1\/tenants\/[^/]+\/context$/,
25
25
  ];
26
- function getRequiredScope(method, url) {
27
- // Match on the request path. Take everything before the first "?" so the
28
- // route match is evaluated on the normalized path alone.
29
- const path = url.split("?", 1)[0];
26
+ // Route patterns whose mutations require admin scope. Managing roles changes
27
+ // the scopes that API keys resolve to, so it is an admin operation.
28
+ const ADMIN_MUTATION_ROUTES = [
29
+ /^\/api\/v1\/roles/,
30
+ ];
31
+ function getRequiredScope(method, path) {
30
32
  for (const pattern of ADMIN_ROUTES) {
31
33
  if (pattern.test(path)) {
32
34
  return "admin";
33
35
  }
34
36
  }
35
- return methodToScope(method);
37
+ const scope = methodToScope(method);
38
+ if (scope === "write" && ADMIN_MUTATION_ROUTES.some((pattern) => pattern.test(path))) {
39
+ return "admin";
40
+ }
41
+ return scope;
36
42
  }
37
43
  function createAuthorizeMiddleware() {
38
44
  return async function authorizeMiddleware(request, _reply) {
@@ -46,7 +52,11 @@ function createAuthorizeMiddleware() {
46
52
  if (!request.apiKey) {
47
53
  throw new core_1.UnauthorizedError("Authentication required");
48
54
  }
49
- const requiredScope = getRequiredScope(request.method, request.url);
55
+ // Decide the scope from the route pattern that was matched (for example
56
+ // "/api/v1/tenants/:id/purge"), so it is a property of the route rather than
57
+ // of the request URL. With no matched route there is no handler to reach.
58
+ const routePath = request.routeOptions?.url ?? request.url.split("?", 1)[0];
59
+ const requiredScope = getRequiredScope(request.method, routePath);
50
60
  const scopes = request.apiKey.scopes ?? ["read"];
51
61
  // Hierarchical scopes: admin implies write implies read. A granted scope
52
62
  // satisfies any required scope of equal-or-lower rank.
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":";;AAwCA,8DA4BC;AAnED,2CAAqF;AAIrF,SAAS,aAAa,CAAC,MAAc;IACnC,QAAQ,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7B,KAAK,KAAK,CAAC;QACX,KAAK,MAAM,CAAC;QACZ,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,OAAO,CAAC;IACnB,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,MAAM,YAAY,GAAG;IACnB,sBAAsB;IACtB,wBAAwB;IACxB,yBAAyB;IACzB,qBAAqB;IACrB,oCAAoC;IACpC,qCAAqC;IACrC,6CAA6C;IAC7C,sCAAsC;CACvC,CAAC;AAEF,SAAS,gBAAgB,CAAC,MAAc,EAAE,GAAW;IACnD,yEAAyE;IACzE,yDAAyD;IACzD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,SAAgB,yBAAyB;IACvC,OAAO,KAAK,UAAU,mBAAmB,CACvC,OAAuB,EACvB,MAAoB;QAEpB,8CAA8C;QAC9C,IACE,OAAO,CAAC,GAAG,KAAK,gBAAgB;YAChC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EACnC,CAAC;YACD,OAAO;QACT,CAAC;QAED,mEAAmE;QACnE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,wBAAiB,CAAC,yBAAyB,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;QAEjD,yEAAyE;QACzE,uDAAuD;QACvD,IAAI,CAAC,IAAA,qBAAc,EAAC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,qBAAc,CAAC,6CAA6C,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":";;AA+CA,8DAgCC;AA9ED,2CAAqF;AAIrF,SAAS,aAAa,CAAC,MAAc;IACnC,QAAQ,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7B,KAAK,KAAK,CAAC;QACX,KAAK,MAAM,CAAC;QACZ,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,OAAO,CAAC;IACnB,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,MAAM,YAAY,GAAG;IACnB,sBAAsB;IACtB,wBAAwB;IACxB,yBAAyB;IACzB,qBAAqB;IACrB,oCAAoC;IACpC,qCAAqC;IACrC,6CAA6C;IAC7C,sCAAsC;CACvC,CAAC;AAEF,6EAA6E;AAC7E,oEAAoE;AACpE,MAAM,qBAAqB,GAAG;IAC5B,mBAAmB;CACpB,CAAC;AAEF,SAAS,gBAAgB,CAAC,MAAc,EAAE,IAAY;IACpD,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,KAAK,KAAK,OAAO,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACrF,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,yBAAyB;IACvC,OAAO,KAAK,UAAU,mBAAmB,CACvC,OAAuB,EACvB,MAAoB;QAEpB,8CAA8C;QAC9C,IACE,OAAO,CAAC,GAAG,KAAK,gBAAgB;YAChC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EACnC,CAAC;YACD,OAAO;QACT,CAAC;QAED,mEAAmE;QACnE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,wBAAiB,CAAC,yBAAyB,CAAC,CAAC;QACzD,CAAC;QAED,wEAAwE;QACxE,6EAA6E;QAC7E,0EAA0E;QAC1E,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;QAEjD,yEAAyE;QACzE,uDAAuD;QACvD,IAAI,CAAC,IAAA,qBAAc,EAAC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,qBAAc,CAAC,6CAA6C,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1,3 +1,13 @@
1
1
  import { FastifyRequest, FastifyReply } from "fastify";
2
- export declare function createPerKeyRateLimitMiddleware(): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
2
+ /** Parse a duration string like "1 minute", "30 seconds", "1 hour" into milliseconds. */
3
+ export declare function parseWindow(window: string): number;
4
+ /**
5
+ * The bucket a request is counted in. API keys count per key id. A JWT `sub`
6
+ * is only unique within its tenant, so JWT callers count per tenant and subject.
7
+ */
8
+ export declare function rateLimitBucket(request: FastifyRequest): string;
9
+ export declare function createPerKeyRateLimitMiddleware(defaults?: {
10
+ maxRequests: number;
11
+ windowMs: number;
12
+ }): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
3
13
  //# sourceMappingURL=per-key-rate-limit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"per-key-rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/per-key-rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAqCvD,wBAAgB,+BAA+B,KAK3C,SAAS,cAAc,EACvB,OAAO,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,CA2CjB"}
1
+ {"version":3,"file":"per-key-rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/per-key-rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAuBvD,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWlD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAG/D;AAED,wBAAgB,+BAA+B,CAAC,QAAQ,CAAC,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,IAKhG,SAAS,cAAc,EACvB,OAAO,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,CA2CjB"}
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseWindow = parseWindow;
4
+ exports.rateLimitBucket = rateLimitBucket;
3
5
  exports.createPerKeyRateLimitMiddleware = createPerKeyRateLimitMiddleware;
4
6
  const config_js_1 = require("../config.js");
5
7
  const keyLimits = new Map();
@@ -17,14 +19,22 @@ function parseWindow(window) {
17
19
  default: return 60_000;
18
20
  }
19
21
  }
20
- function createPerKeyRateLimitMiddleware() {
21
- const globalMax = config_js_1.config.rateLimitMax;
22
- const globalWindowMs = parseWindow(config_js_1.config.rateLimitWindow);
22
+ /**
23
+ * The bucket a request is counted in. API keys count per key id. A JWT `sub`
24
+ * is only unique within its tenant, so JWT callers count per tenant and subject.
25
+ */
26
+ function rateLimitBucket(request) {
27
+ const apiKey = request.apiKey;
28
+ return request.authMethod === "jwt" ? `jwt:${apiKey.tenant_id}:${apiKey.id}` : apiKey.id;
29
+ }
30
+ function createPerKeyRateLimitMiddleware(defaults) {
31
+ const globalMax = defaults?.maxRequests ?? config_js_1.config.rateLimitMax;
32
+ const globalWindowMs = defaults?.windowMs ?? parseWindow(config_js_1.config.rateLimitWindow);
23
33
  return async function perKeyRateLimitMiddleware(request, reply) {
24
34
  // Skip for unauthenticated requests (health endpoint)
25
35
  if (!request.apiKey)
26
36
  return;
27
- const keyId = request.apiKey.id;
37
+ const keyId = rateLimitBucket(request);
28
38
  const max = request.apiKey.rate_limit_max ?? globalMax;
29
39
  const windowMs = request.apiKey.rate_limit_window
30
40
  ? parseWindow(request.apiKey.rate_limit_window)
@@ -1 +1 @@
1
- {"version":3,"file":"per-key-rate-limit.js","sourceRoot":"","sources":["../../src/middleware/per-key-rate-limit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"per-key-rate-limit.js","sourceRoot":"","sources":["../../src/middleware/per-key-rate-limit.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,8 @@ export interface RedisRateLimitConfig {
10
10
  * Create a Redis-backed per-key rate limiter.
11
11
  *
12
12
  * Returns a Fastify preHandler hook. If Redis is unavailable or slow (>500ms)
13
- * the request is allowed through (fail-open).
13
+ * the request is counted by the in-memory per-key limiter instead, so per-key
14
+ * limits stay enforced (per process) until Redis is reachable again.
14
15
  */
15
16
  export declare function createRedisRateLimiter(redis: Redis, defaults: RedisRateLimitConfig): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
16
17
  //# sourceMappingURL=rate-limit-redis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit-redis.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit-redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,oBAAoB,IAc5B,SAAS,cAAc,EACvB,OAAO,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,CA+CjB"}
1
+ {"version":3,"file":"rate-limit-redis.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit-redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAGjC,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwBD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,oBAAoB,IAgB5B,SAAS,cAAc,EACvB,OAAO,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,CA+CjB"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createRedisRateLimiter = createRedisRateLimiter;
4
+ const per_key_rate_limit_js_1 = require("./per-key-rate-limit.js");
4
5
  /**
5
6
  * Lua script implementing a sliding-window counter.
6
7
  *
@@ -26,9 +27,11 @@ return current
26
27
  * Create a Redis-backed per-key rate limiter.
27
28
  *
28
29
  * Returns a Fastify preHandler hook. If Redis is unavailable or slow (>500ms)
29
- * the request is allowed through (fail-open).
30
+ * the request is counted by the in-memory per-key limiter instead, so per-key
31
+ * limits stay enforced (per process) until Redis is reachable again.
30
32
  */
31
33
  function createRedisRateLimiter(redis, defaults) {
34
+ const fallback = (0, per_key_rate_limit_js_1.createPerKeyRateLimitMiddleware)(defaults);
32
35
  // Pre-load the Lua script so subsequent calls use EVALSHA
33
36
  let scriptSha = null;
34
37
  redis
@@ -43,7 +46,7 @@ function createRedisRateLimiter(redis, defaults) {
43
46
  // Skip for unauthenticated requests (health, docs)
44
47
  if (!request.apiKey)
45
48
  return;
46
- const keyId = request.apiKey.id;
49
+ const keyId = (0, per_key_rate_limit_js_1.rateLimitBucket)(request);
47
50
  const max = request.apiKey.rate_limit_max ?? defaults.maxRequests;
48
51
  const windowMs = request.apiKey.rate_limit_window
49
52
  ? parseWindowStr(request.apiKey.rate_limit_window)
@@ -59,8 +62,8 @@ function createRedisRateLimiter(redis, defaults) {
59
62
  currentCount = await withTimeout(evalScript(redis, scriptSha, redisKey, windowTtlSec), 500);
60
63
  }
61
64
  catch {
62
- // Redis unavailable or slow — fail-open
63
- return;
65
+ // Redis unavailable or slow: count this request in memory instead
66
+ return fallback(request, reply);
64
67
  }
65
68
  // Set rate-limit headers on every response
66
69
  const remaining = Math.max(0, max - currentCount);
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit-redis.js","sourceRoot":"","sources":["../../src/middleware/rate-limit-redis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rate-limit-redis.js","sourceRoot":"","sources":["../../src/middleware/rate-limit-redis.ts"],"names":[],"mappings":"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"}
@@ -5,10 +5,12 @@ export type TenantIdExtractor = (req: FastifyRequest) => string | null;
5
5
  /**
6
6
  * A route's tenant-scope declaration:
7
7
  * - an extractor: enforce that the caller's key may reach the extracted tenant;
8
- * - "global": operator-level route with no single tenant target, or one that
9
- * scopes itself in its handler. The middleware performs no tenant check.
8
+ * - "global": route with no single tenant target, or one that scopes itself
9
+ * in its handler. The middleware performs no tenant check.
10
+ * - "operator": route that acts across all tenants. Only global operator API
11
+ * keys (tenant_id === null) may call it; tenant-scoped callers are refused.
10
12
  */
11
- export type TenantScopeDeclaration = TenantIdExtractor | "global";
13
+ export type TenantScopeDeclaration = TenantIdExtractor | "global" | "operator";
12
14
  declare module "fastify" {
13
15
  interface FastifyContextConfig {
14
16
  tenantScope?: TenantScopeDeclaration;
@@ -26,6 +28,10 @@ declare module "fastify" {
26
28
  * must be resolved first (for example a role's owning tenant, looked up by id).
27
29
  */
28
30
  export declare function assertTenantInScope(stratum: Stratum, request: FastifyRequest, tenantId: string | null): Promise<void>;
31
+ /** True when the caller is a global operator API key (no tenant scope). */
32
+ export declare function isOperator(request: FastifyRequest): boolean;
33
+ /** Refuse the request unless the caller is a global operator API key. */
34
+ export declare function assertOperator(request: FastifyRequest): void;
29
35
  /**
30
36
  * Tenant-scope enforcement middleware for a single extractor.
31
37
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-scope.d.ts","sourceRoot":"","sources":["../../src/middleware/tenant-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAExE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,sFAAsF;AACtF,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,GAAG,IAAI,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAElE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,oBAAoB;QAC5B,WAAW,CAAC,EAAE,sBAAsB,CAAC;KACtC;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,OAAO,CAAC,IAAI,CAAC,CAgCf;AAaD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,iBAAiB,IAGhC,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAGjB;AA6BD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,IAEpD,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAIjB;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,IAEzD,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CASjB;AAYD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,sBAAsB,GAClC,IAAI,CAON;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,IAEtD,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAWjB;AAID,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAE9D;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED,0CAA0C;AAC1C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEtE"}
1
+ {"version":3,"file":"tenant-scope.d.ts","sourceRoot":"","sources":["../../src/middleware/tenant-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAExE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,sFAAsF;AACtF,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,GAAG,IAAI,CAAC;AAEvE;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,oBAAoB;QAC5B,WAAW,CAAC,EAAE,sBAAsB,CAAC;KACtC;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,OAAO,CAAC,IAAI,CAAC,CAgCf;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAE3D;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAI5D;AAaD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,iBAAiB,IAGhC,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAGjB;AA6BD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,IAEpD,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAIjB;AAKD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,IAEzD,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAcjB;AAYD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,sBAAsB,GAClC,IAAI,CAON;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,IAEtD,SAAS,cAAc,EACvB,QAAQ,YAAY,KACnB,OAAO,CAAC,IAAI,CAAC,CAejB;AAID,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAE9D;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED,0CAA0C;AAC1C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEpE;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEtE"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.assertTenantInScope = assertTenantInScope;
4
+ exports.isOperator = isOperator;
5
+ exports.assertOperator = assertOperator;
4
6
  exports.createTenantScopeGuard = createTenantScopeGuard;
5
7
  exports.createTenantCreateGuard = createTenantCreateGuard;
6
8
  exports.createTenantBatchCreateGuard = createTenantBatchCreateGuard;
@@ -37,7 +39,7 @@ async function assertTenantInScope(stratum, request, tenantId) {
37
39
  return;
38
40
  throw new core_1.ForbiddenError("JWT authentication requires a tenant scope");
39
41
  }
40
- if (!tenantId)
42
+ if (tenantId === null)
41
43
  return;
42
44
  // Fast path: exact match
43
45
  if (apiKey.tenant_id === tenantId)
@@ -55,6 +57,16 @@ async function assertTenantInScope(stratum, request, tenantId) {
55
57
  }
56
58
  throw new core_1.ForbiddenError("API key tenant scope does not grant access to this tenant");
57
59
  }
60
+ /** True when the caller is a global operator API key (no tenant scope). */
61
+ function isOperator(request) {
62
+ return request.authMethod === "api_key" && request.apiKey?.tenant_id === null;
63
+ }
64
+ /** Refuse the request unless the caller is a global operator API key. */
65
+ function assertOperator(request) {
66
+ if (!isOperator(request)) {
67
+ throw new core_1.ForbiddenError("This operation requires a global operator API key");
68
+ }
69
+ }
58
70
  /**
59
71
  * Core tenant-scope check for a tenant id read from the request by `extractTenantId`.
60
72
  */
@@ -101,6 +113,8 @@ function createTenantCreateGuard(stratum) {
101
113
  await authorizeCreateUnder(stratum, request, body?.parent_id ?? null);
102
114
  };
103
115
  }
116
+ /** Maximum number of tenants in one batch create. */
117
+ const MAX_BATCH_TENANTS = 100;
104
118
  /**
105
119
  * Guard for POST /tenants/batch: every tenant in the batch is authorized the
106
120
  * same way a single create is, so the batch route cannot sidestep the subtree
@@ -110,8 +124,13 @@ function createTenantBatchCreateGuard(stratum) {
110
124
  return async function tenantBatchCreateGuard(request, _reply) {
111
125
  const body = request.body;
112
126
  const tenants = Array.isArray(body?.tenants) ? body.tenants : [];
113
- for (const tenant of tenants) {
114
- await authorizeCreateUnder(stratum, request, tenant?.parent_id ?? null);
127
+ if (tenants.length > MAX_BATCH_TENANTS) {
128
+ throw new core_1.ValidationError(`Batch limited to ${MAX_BATCH_TENANTS} tenants`);
129
+ }
130
+ // Authorize each distinct parent once.
131
+ const parentIds = new Set(tenants.map((tenant) => tenant?.parent_id ?? null));
132
+ for (const parentId of parentIds) {
133
+ await authorizeCreateUnder(stratum, request, parentId);
115
134
  }
116
135
  };
117
136
  }
@@ -153,6 +172,10 @@ function createTenantScopeEnforcer(stratum) {
153
172
  }
154
173
  if (declaration === "global")
155
174
  return;
175
+ if (declaration === "operator") {
176
+ assertOperator(request);
177
+ return;
178
+ }
156
179
  await checkTenantScope(stratum, request, declaration);
157
180
  };
158
181
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-scope.js","sourceRoot":"","sources":["../../src/middleware/tenant-scope.ts"],"names":[],"mappings":";;AAgCA,kDAoCC;AAmBD,wDAUC;AAgCD,0DAQC;AAOD,oEAaC;AAkBD,gDAUC;AASD,8DAeC;AAKD,kCAEC;AAGD,8CAEC;AAGD,8CAEC;AAGD,4CAEC;AAGD,4CAEC;AAGD,4CAEC;AAYD,kDAEC;AA9PD,2CAAkD;AAoBlD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,mBAAmB,CACvC,OAAgB,EAChB,OAAuB,EACvB,QAAuB;IAEvB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,yDAAyD;IACzD,iFAAiF;IACjF,qCAAqC;IACrC,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO;QAC7C,MAAM,IAAI,qBAAc,CAAC,4CAA4C,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,CAAC,QAAQ;QAAE,OAAO;IAEtB,yBAAyB;IACzB,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO;IAE1C,mEAAmE;IACnE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpE,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;YAAE,OAAO;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;QAChD,MAAM,IAAI,qBAAc,CACtB,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,qBAAc,CACtB,2DAA2D,CAC5D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC7B,OAAgB,EAChB,OAAuB,EACvB,eAAkC;IAElC,MAAM,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;AACxE,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CACpC,OAAgB,EAChB,eAAkC;IAElC,OAAO,KAAK,UAAU,gBAAgB,CACpC,OAAuB,EACvB,MAAoB;QAEpB,MAAM,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,oBAAoB,CACjC,OAAgB,EAChB,OAAuB,EACvB,QAAuB;IAEvB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,6EAA6E;IAC7E,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO;IAE1E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,qBAAc,CACtB,kDAAkD,CACnD,CAAC;IACJ,CAAC;IACD,MAAM,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CAAC,OAAgB;IACtD,OAAO,KAAK,UAAU,iBAAiB,CACrC,OAAuB,EACvB,MAAoB;QAEpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAA4C,CAAC;QAClE,MAAM,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC;IACxE,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,4BAA4B,CAAC,OAAgB;IAC3D,OAAO,KAAK,UAAU,sBAAsB,CAC1C,OAAuB,EACvB,MAAoB;QAEpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAEb,CAAC;QACT,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,6EAA6E;AAC7E,SAAS,qBAAqB,CAAC,GAAW;IACxC,OAAO,CACL,GAAG,KAAK,gBAAgB;QACxB,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC;QACjC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAChC,GAAoB,EACpB,WAAmC;IAEnC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,YAAY,EAAE,EAAE;QACtC,YAAY,CAAC,MAAM,GAAG;YACpB,GAAG,YAAY,CAAC,MAAM;YACtB,WAAW,EAAE,YAAY,CAAC,MAAM,EAAE,WAAW,IAAI,WAAW;SAC7D,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,yBAAyB,CAAC,OAAgB;IACxD,OAAO,KAAK,UAAU,mBAAmB,CACvC,OAAuB,EACvB,MAAoB;QAEpB,IAAI,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO;QAE/C,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC;QAC9D,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,qBAAc,CAAC,uCAAuC,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,WAAW,KAAK,QAAQ;YAAE,OAAO;QAErC,MAAM,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IACxD,CAAC,CAAC;AACJ,CAAC;AAED,qBAAqB;AAErB,0EAA0E;AAC1E,SAAgB,WAAW,CAAC,GAAmB;IAC7C,OAAQ,GAAG,CAAC,MAAiC,CAAC,EAAE,IAAI,IAAI,CAAC;AAC3D,CAAC;AAED,+CAA+C;AAC/C,SAAgB,iBAAiB,CAAC,GAAmB;IACnD,OAAQ,GAAG,CAAC,MAAiC,CAAC,QAAQ,IAAI,IAAI,CAAC;AACjE,CAAC;AAED,0CAA0C;AAC1C,SAAgB,iBAAiB,CAAC,GAAmB;IACnD,OAAQ,GAAG,CAAC,KAAgC,CAAC,SAAS,IAAI,IAAI,CAAC;AACjE,CAAC;AAED,sEAAsE;AACtE,SAAgB,gBAAgB,CAAC,GAAmB;IAClD,OAAQ,GAAG,CAAC,KAAgC,CAAC,QAAQ,IAAI,IAAI,CAAC;AAChE,CAAC;AAED,uEAAuE;AACvE,SAAgB,gBAAgB,CAAC,GAAmB;IAClD,OAAQ,GAAG,CAAC,KAAgC,CAAC,QAAQ,IAAI,IAAI,CAAC;AAChE,CAAC;AAED,0CAA0C;AAC1C,SAAgB,gBAAgB,CAAC,GAAmB;IAClD,OAAQ,GAAG,CAAC,IAAsC,EAAE,SAAS,IAAI,IAAI,CAAC;AACxE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,mBAAmB,CAAC,GAAmB;IACrD,OAAQ,GAAG,CAAC,IAAsC,EAAE,aAAa,IAAI,IAAI,CAAC;AAC5E,CAAC"}
1
+ {"version":3,"file":"tenant-scope.js","sourceRoot":"","sources":["../../src/middleware/tenant-scope.ts"],"names":[],"mappings":"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"}
package/dist/redis.d.ts CHANGED
@@ -2,7 +2,9 @@ import Redis from "ioredis";
2
2
  /**
3
3
  * Create a Redis client from the REDIS_URL env var.
4
4
  * Returns null if REDIS_URL is not configured.
5
- * Connection errors are logged but never crash the process (fail-open).
5
+ * Connection errors are logged but never crash the process. The client keeps
6
+ * reconnecting with capped backoff; while it is down, per-key rate limiting
7
+ * falls back to the in-memory limiter.
6
8
  */
7
9
  export declare function createRedisClient(): Redis | null;
8
10
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../src/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,SAAS,CAAC;AAK5B;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,KAAK,GAAG,IAAI,CAiChD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,KAAK,GAAG,IAAI,CAE7C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC,CAgBjG"}
1
+ {"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../src/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,SAAS,CAAC;AAK5B;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,KAAK,GAAG,IAAI,CA8BhD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,KAAK,GAAG,IAAI,CAE7C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC,CAgBjG"}
package/dist/redis.js CHANGED
@@ -12,7 +12,9 @@ let redisClient = null;
12
12
  /**
13
13
  * Create a Redis client from the REDIS_URL env var.
14
14
  * Returns null if REDIS_URL is not configured.
15
- * Connection errors are logged but never crash the process (fail-open).
15
+ * Connection errors are logged but never crash the process. The client keeps
16
+ * reconnecting with capped backoff; while it is down, per-key rate limiting
17
+ * falls back to the in-memory limiter.
16
18
  */
17
19
  function createRedisClient() {
18
20
  if (!config_js_1.config.redisUrl) {
@@ -21,11 +23,8 @@ function createRedisClient() {
21
23
  const client = new ioredis_1.default(config_js_1.config.redisUrl, {
22
24
  maxRetriesPerRequest: 1,
23
25
  retryStrategy(times) {
24
- if (times > 3) {
25
- // Stop retrying after 3 attempts — the app can run without Redis
26
- return null;
27
- }
28
- return Math.min(times * 200, 2000);
26
+ // Never give up: returning null would stop reconnecting for good.
27
+ return Math.min(times * 200, 5000);
29
28
  },
30
29
  enableOfflineQueue: false,
31
30
  lazyConnect: true,
package/dist/redis.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"redis.js","sourceRoot":"","sources":["../src/redis.ts"],"names":[],"mappings":";;;;;AAUA,8CAiCC;AAKD,wCAEC;AAKD,4CAgBC;AAvED,sDAA4B;AAC5B,2CAAqC;AAErC,IAAI,WAAW,GAAiB,IAAI,CAAC;AAErC;;;;GAIG;AACH,SAAgB,iBAAiB;IAC/B,IAAI,CAAC,kBAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,iBAAK,CAAC,kBAAM,CAAC,QAAQ,EAAE;QACxC,oBAAoB,EAAE,CAAC;QACvB,aAAa,CAAC,KAAa;YACzB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,iEAAiE;gBACjE,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,kBAAkB,EAAE,KAAK;QACzB,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,OAAO,CAAC,IAAI,CAAC,+EAA+E,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7G,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,6CAA6C;IAC7C,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7B,OAAO,CAAC,IAAI,CAAC,uEAAuE,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACrG,CAAC,CAAC,CAAC;IAEH,WAAW,GAAG,MAAM,CAAC;IACrB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc;IAC5B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,WAAW,CAAC,IAAI,EAAE;YAClB,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CACrD;SACF,CAAC,CAAC;QACH,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../src/redis.ts"],"names":[],"mappings":";;;;;AAYA,8CA8BC;AAKD,wCAEC;AAKD,4CAgBC;AAtED,sDAA4B;AAC5B,2CAAqC;AAErC,IAAI,WAAW,GAAiB,IAAI,CAAC;AAErC;;;;;;GAMG;AACH,SAAgB,iBAAiB;IAC/B,IAAI,CAAC,kBAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,iBAAK,CAAC,kBAAM,CAAC,QAAQ,EAAE;QACxC,oBAAoB,EAAE,CAAC;QACvB,aAAa,CAAC,KAAa;YACzB,kEAAkE;YAClE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,kBAAkB,EAAE,KAAK;QACzB,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,OAAO,CAAC,IAAI,CAAC,+EAA+E,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7G,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,6CAA6C;IAC7C,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7B,OAAO,CAAC,IAAI,CAAC,uEAAuE,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACrG,CAAC,CAAC,CAAC;IAEH,WAAW,GAAG,MAAM,CAAC;IACrB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc;IAC5B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,WAAW,CAAC,IAAI,EAAE;YAClB,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CACrD;SACF,CAAC,CAAC;QACH,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"abac.d.ts","sourceRoot":"","sources":["../../src/routes/abac.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAI1C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CA0CtE"}
1
+ {"version":3,"file":"abac.d.ts","sourceRoot":"","sources":["../../src/routes/abac.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAK1C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CA4CtE"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createAbacRoutes = createAbacRoutes;
4
4
  const core_1 = require("@stratum-hq/core");
5
5
  const tenant_scope_js_1 = require("../middleware/tenant-scope.js");
6
+ const audit_logs_js_1 = require("./audit-logs.js");
6
7
  function createAbacRoutes(stratum) {
7
8
  return async function abacRoutes(app) {
8
9
  // Tenant-scoped keys can only access ABAC policies for their own tenant subtree
@@ -10,7 +11,7 @@ function createAbacRoutes(stratum) {
10
11
  // POST /api/v1/tenants/:tenantId/abac-policies — Create ABAC policy
11
12
  app.post("/", async (request, reply) => {
12
13
  const input = core_1.CreateAbacPolicyInputSchema.parse(request.body);
13
- const policy = await stratum.createAbacPolicy(request.params.tenantId, input);
14
+ const policy = await stratum.createAbacPolicy(request.params.tenantId, input, (0, audit_logs_js_1.buildAuditContext)(request));
14
15
  reply.status(201).send(policy);
15
16
  });
16
17
  // GET /api/v1/tenants/:tenantId/abac-policies — List own ABAC policies
@@ -26,7 +27,7 @@ function createAbacRoutes(stratum) {
26
27
  });
27
28
  // DELETE /api/v1/tenants/:tenantId/abac-policies/:policyId — Delete ABAC policy
28
29
  app.delete("/:policyId", async (request, reply) => {
29
- await stratum.deleteAbacPolicy(request.params.tenantId, request.params.policyId);
30
+ await stratum.deleteAbacPolicy(request.params.tenantId, request.params.policyId, (0, audit_logs_js_1.buildAuditContext)(request));
30
31
  reply.status(204).send();
31
32
  });
32
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"abac.js","sourceRoot":"","sources":["../../src/routes/abac.ts"],"names":[],"mappings":";;AAKA,4CA2CC;AA9CD,2CAAoJ;AACpJ,mEAAsF;AAEtF,SAAgB,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,KAAK,UAAU,UAAU,CAAC,GAAoB;QACnD,gFAAgF;QAChF,IAAA,oCAAkB,EAAC,GAAG,EAAE,mCAAiB,CAAC,CAAC;QAE3C,oEAAoE;QACpE,GAAG,CAAC,IAAI,CAAmC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACvE,MAAM,KAAK,GAAG,kCAA2B,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAA0B,CAAC;YACvF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,EACvB,KAAK,CACN,CAAC;YACF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,uEAAuE;QACvE,GAAG,CAAC,GAAG,CAAmC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACtE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACxE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,0EAA0E;QAC1E,GAAG,CAAC,IAAI,CAAmC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC/E,MAAM,WAAW,GAAG,kCAA2B,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAA0B,CAAC;YAC7F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,EACvB,WAAW,CACZ,CAAC;YACF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,gFAAgF;QAChF,GAAG,CAAC,MAAM,CACR,YAAY,EACZ,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,OAAO,CAAC,gBAAgB,CAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,EACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CACxB,CAAC;YACF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"abac.js","sourceRoot":"","sources":["../../src/routes/abac.ts"],"names":[],"mappings":";;AAMA,4CA6CC;AAjDD,2CAAoJ;AACpJ,mEAAsF;AACtF,mDAAoD;AAEpD,SAAgB,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,KAAK,UAAU,UAAU,CAAC,GAAoB;QACnD,gFAAgF;QAChF,IAAA,oCAAkB,EAAC,GAAG,EAAE,mCAAiB,CAAC,CAAC;QAE3C,oEAAoE;QACpE,GAAG,CAAC,IAAI,CAAmC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACvE,MAAM,KAAK,GAAG,kCAA2B,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAA0B,CAAC;YACvF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,EACvB,KAAK,EACL,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAC3B,CAAC;YACF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,uEAAuE;QACvE,GAAG,CAAC,GAAG,CAAmC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACtE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACxE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,0EAA0E;QAC1E,GAAG,CAAC,IAAI,CAAmC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC/E,MAAM,WAAW,GAAG,kCAA2B,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAA0B,CAAC;YAC7F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,EACvB,WAAW,CACZ,CAAC;YACF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,gFAAgF;QAChF,GAAG,CAAC,MAAM,CACR,YAAY,EACZ,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,OAAO,CAAC,gBAAgB,CAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,EACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,EACvB,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAC3B,CAAC;YACF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"api-keys.d.ts","sourceRoot":"","sources":["../../src/routes/api-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAW1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAkFxE"}
1
+ {"version":3,"file":"api-keys.d.ts","sourceRoot":"","sources":["../../src/routes/api-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAe1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CA4FxE"}
@@ -2,12 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createApiKeyRoutes = createApiKeyRoutes;
4
4
  const zod_1 = require("zod");
5
+ const core_1 = require("@stratum-hq/core");
5
6
  const tenant_scope_js_1 = require("../middleware/tenant-scope.js");
7
+ const per_key_rate_limit_js_1 = require("../middleware/per-key-rate-limit.js");
8
+ const config_js_1 = require("../config.js");
9
+ const audit_logs_js_1 = require("./audit-logs.js");
6
10
  const createApiKeySchema = zod_1.z.object({
7
11
  tenant_id: zod_1.z.string().uuid(),
8
12
  name: zod_1.z.string().optional(),
9
13
  rate_limit_max: zod_1.z.number().int().min(1).max(100_000).optional(),
10
- rate_limit_window: zod_1.z.string().regex(/^\d+\s+(second|minute|hour|day)s?$/i).optional(),
14
+ rate_limit_window: zod_1.z.string().regex(/^[1-9]\d*\s+(second|minute|hour|day)s?$/i).optional(),
11
15
  });
12
16
  function createApiKeyRoutes(stratum) {
13
17
  return async function apiKeyRoutes(app) {
@@ -23,11 +27,21 @@ function createApiKeyRoutes(stratum) {
23
27
  return;
24
28
  }
25
29
  const { tenant_id, name, rate_limit_max, rate_limit_window } = parsed.data;
30
+ // A tenant-scoped caller may tighten a key's rate limit but not loosen it
31
+ // beyond the operator's configured default.
32
+ if (!(0, tenant_scope_js_1.isOperator)(request) && (rate_limit_max !== undefined || rate_limit_window !== undefined)) {
33
+ const defaultWindowMs = (0, per_key_rate_limit_js_1.parseWindow)(config_js_1.config.rateLimitWindow);
34
+ const max = rate_limit_max ?? config_js_1.config.rateLimitMax;
35
+ const windowMs = rate_limit_window ? (0, per_key_rate_limit_js_1.parseWindow)(rate_limit_window) : defaultWindowMs;
36
+ if (max > config_js_1.config.rateLimitMax || max * defaultWindowMs > config_js_1.config.rateLimitMax * windowMs) {
37
+ throw new core_1.ForbiddenError("Only operator keys may set a per-key rate limit above the configured default");
38
+ }
39
+ }
26
40
  const result = await stratum.createApiKey(tenant_id, {
27
41
  name,
28
42
  rateLimitMax: rate_limit_max,
29
43
  rateLimitWindow: rate_limit_window,
30
- });
44
+ }, undefined, (0, audit_logs_js_1.buildAuditContext)(request));
31
45
  reply.status(201).send(result);
32
46
  });
33
47
  // GET /api/v1/api-keys — List API keys (optional ?tenant_id=)
@@ -63,7 +77,7 @@ function createApiKeyRoutes(stratum) {
63
77
  }
64
78
  const rotateSchema = zod_1.z.object({ name: zod_1.z.string().max(255).optional() });
65
79
  const parsed = rotateSchema.parse(request.body ?? {});
66
- const result = await stratum.rotateApiKey(request.params.id, parsed.name);
80
+ const result = await stratum.rotateApiKey(request.params.id, parsed.name, (0, audit_logs_js_1.buildAuditContext)(request));
67
81
  reply.status(201).send(result);
68
82
  });
69
83
  // DELETE /api/v1/api-keys/:id — Revoke an API key
@@ -76,7 +90,7 @@ function createApiKeyRoutes(stratum) {
76
90
  return;
77
91
  }
78
92
  }
79
- const revoked = await stratum.revokeApiKey(request.params.id);
93
+ const revoked = await stratum.revokeApiKey(request.params.id, (0, audit_logs_js_1.buildAuditContext)(request));
80
94
  if (!revoked) {
81
95
  reply.status(404).send({ error: { code: "NOT_FOUND", message: "API key not found or already revoked" } });
82
96
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../../src/routes/api-keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../../src/routes/api-keys.ts"],"names":[],"mappings":"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"}
@@ -5,8 +5,8 @@ const audit_logs_js_1 = require("./audit-logs.js");
5
5
  const tenant_scope_js_1 = require("../middleware/tenant-scope.js");
6
6
  function createMaintenanceRoutes(stratum) {
7
7
  return async function maintenanceRoutes(app) {
8
- // Operator-level maintenance tasks; no per-tenant target to enforce.
9
- (0, tenant_scope_js_1.declareTenantScope)(app, "global");
8
+ // Maintenance acts across all tenants: global operator keys only.
9
+ (0, tenant_scope_js_1.declareTenantScope)(app, "operator");
10
10
  // POST /api/v1/maintenance/purge-expired — Purge expired data
11
11
  app.post("/purge-expired", async (request, reply) => {
12
12
  const rawDays = request.query.retention_days
@@ -15,7 +15,7 @@ function createMaintenanceRoutes(stratum) {
15
15
  const retentionDays = rawDays !== undefined && (Number.isNaN(rawDays) || rawDays < 1)
16
16
  ? undefined
17
17
  : rawDays !== undefined ? Math.min(rawDays, 3650) : undefined;
18
- const result = await stratum.purgeExpiredData(retentionDays);
18
+ const result = await stratum.purgeExpiredData(retentionDays, (0, audit_logs_js_1.buildAuditContext)(request));
19
19
  reply.status(200).send(result);
20
20
  });
21
21
  // POST /api/v1/maintenance/rotate-encryption-key — Re-encrypt all sensitive data
@@ -1 +1 @@
1
- {"version":3,"file":"maintenance.js","sourceRoot":"","sources":["../../src/routes/maintenance.ts"],"names":[],"mappings":";;AAKA,0DAgCC;AAnCD,mDAAoD;AACpD,mEAAmE;AAEnE,SAAgB,uBAAuB,CAAC,OAAgB;IACtD,OAAO,KAAK,UAAU,iBAAiB,CAAC,GAAoB;QAC1D,qEAAqE;QACrE,IAAA,oCAAkB,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAElC,8DAA8D;QAC9D,GAAG,CAAC,IAAI,CAA+C,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAChG,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc;gBAC1C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;gBAC5C,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,aAAa,GAAG,OAAO,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;gBACnF,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAChE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;YAC7D,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,iFAAiF;QACjF,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAqD,CAAC;YAC3E,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;gBACrC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,2CAA2C,EAAE,EAAE,CAAC,CAAC;gBACtH,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,sCAAsC,EAAE,EAAE,CAAC,CAAC;gBACjH,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YACzG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"maintenance.js","sourceRoot":"","sources":["../../src/routes/maintenance.ts"],"names":[],"mappings":";;AAKA,0DAgCC;AAnCD,mDAAoD;AACpD,mEAAmE;AAEnE,SAAgB,uBAAuB,CAAC,OAAgB;IACtD,OAAO,KAAK,UAAU,iBAAiB,CAAC,GAAoB;QAC1D,kEAAkE;QAClE,IAAA,oCAAkB,EAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAEpC,8DAA8D;QAC9D,GAAG,CAAC,IAAI,CAA+C,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAChG,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc;gBAC1C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;gBAC5C,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,aAAa,GAAG,OAAO,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;gBACnF,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAChE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YACzF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,iFAAiF;QACjF,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAqD,CAAC;YAC3E,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;gBACrC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,2CAA2C,EAAE,EAAE,CAAC,CAAC;gBACtH,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,sCAAsC,EAAE,EAAE,CAAC,CAAC;gBACjH,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YACzG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"regions.d.ts","sourceRoot":"","sources":["../../src/routes/regions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAI1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAoCxE"}
1
+ {"version":3,"file":"regions.d.ts","sourceRoot":"","sources":["../../src/routes/regions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAI1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAqCxE"}
@@ -6,8 +6,9 @@ const audit_logs_js_1 = require("./audit-logs.js");
6
6
  const tenant_scope_js_1 = require("../middleware/tenant-scope.js");
7
7
  function createRegionRoutes(stratum) {
8
8
  return async function regionRoutes(app) {
9
- // Operator-level region registry; no per-tenant target to enforce.
10
- (0, tenant_scope_js_1.declareTenantScope)(app, "global");
9
+ // The region registry is shared by all tenants: changing it is limited to
10
+ // global operator keys. Reads declare "global" below.
11
+ (0, tenant_scope_js_1.declareTenantScope)(app, "operator");
11
12
  // POST /api/v1/regions — Create region
12
13
  app.post("/", async (request, reply) => {
13
14
  const input = core_1.CreateRegionInputSchema.parse(request.body);
@@ -15,12 +16,12 @@ function createRegionRoutes(stratum) {
15
16
  reply.status(201).send(region);
16
17
  });
17
18
  // GET /api/v1/regions — List regions
18
- app.get("/", async (_request, reply) => {
19
+ app.get("/", { config: { tenantScope: "global" } }, async (_request, reply) => {
19
20
  const regions = await stratum.listRegions();
20
21
  reply.status(200).send(regions);
21
22
  });
22
23
  // GET /api/v1/regions/:id — Get region by ID
23
- app.get("/:id", async (request, reply) => {
24
+ app.get("/:id", { config: { tenantScope: "global" } }, async (request, reply) => {
24
25
  const region = await stratum.getRegion(request.params.id);
25
26
  reply.status(200).send(region);
26
27
  });
@@ -1 +1 @@
1
- {"version":3,"file":"regions.js","sourceRoot":"","sources":["../../src/routes/regions.ts"],"names":[],"mappings":";;AAMA,gDAqCC;AA1CD,2CAAoF;AAEpF,mDAAoD;AACpD,mEAAmE;AAEnE,SAAgB,kBAAkB,CAAC,OAAgB;IACjD,OAAO,KAAK,UAAU,YAAY,CAAC,GAAoB;QACrD,mEAAmE;QACnE,IAAA,oCAAkB,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAElC,uCAAuC;QACvC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,8BAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YAC7E,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,qCAAqC;QACrC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YACrC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;YAC5C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,6CAA6C;QAC7C,GAAG,CAAC,GAAG,CAA6B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACnE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1D,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,4CAA4C;QAC5C,GAAG,CAAC,KAAK,CAA6B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACrE,MAAM,KAAK,GAAG,8BAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YAChG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,6CAA6C;QAC7C,GAAG,CAAC,MAAM,CAA6B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACtE,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YAC1E,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"regions.js","sourceRoot":"","sources":["../../src/routes/regions.ts"],"names":[],"mappings":";;AAMA,gDAsCC;AA3CD,2CAAoF;AAEpF,mDAAoD;AACpD,mEAAmE;AAEnE,SAAgB,kBAAkB,CAAC,OAAgB;IACjD,OAAO,KAAK,UAAU,YAAY,CAAC,GAAoB;QACrD,0EAA0E;QAC1E,sDAAsD;QACtD,IAAA,oCAAkB,EAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAEpC,uCAAuC;QACvC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,8BAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YAC7E,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,qCAAqC;QACrC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC5E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;YAC5C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,6CAA6C;QAC7C,GAAG,CAAC,GAAG,CAA6B,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC1G,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1D,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,4CAA4C;QAC5C,GAAG,CAAC,KAAK,CAA6B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACrE,MAAM,KAAK,GAAG,8BAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YAChG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,6CAA6C;QAC7C,GAAG,CAAC,MAAM,CAA6B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACtE,MAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAA,iCAAiB,EAAC,OAAO,CAAC,CAAC,CAAC;YAC1E,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../src/routes/roles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AA2B1C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAyHtE"}
1
+ {"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../src/routes/roles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AA6B1C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,IACd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CAmItE"}
@@ -33,7 +33,13 @@ function createRoleRoutes(stratum) {
33
33
  reply.status(400).send({ error: { code: "VALIDATION_ERROR", message: "Invalid request body" }, details: parsed.error.issues });
34
34
  return;
35
35
  }
36
- const role = await stratum.createRole(parsed.data, (0, audit_logs_js_1.buildAuditContext)(request));
36
+ // Global roles (no tenant) are operator-only. A tenant-scoped caller that
37
+ // names no tenant creates the role in its own tenant.
38
+ const input = parsed.data;
39
+ if (!input.tenant_id && !(0, tenant_scope_js_1.isOperator)(request)) {
40
+ input.tenant_id = request.apiKey?.tenant_id ?? null;
41
+ }
42
+ const role = await stratum.createRole(input, (0, audit_logs_js_1.buildAuditContext)(request));
37
43
  reply.status(201).send(role);
38
44
  });
39
45
  // GET /api/v1/roles — List roles (optional ?tenant_id=). A provided tenant_id
@@ -67,6 +73,9 @@ function createRoleRoutes(stratum) {
67
73
  reply.status(404).send({ error: { code: "NOT_FOUND", message: "Role not found" } });
68
74
  return;
69
75
  }
76
+ // Global roles are shared by every tenant: only an operator may change them.
77
+ if (existing.tenant_id === null)
78
+ (0, tenant_scope_js_1.assertOperator)(request);
70
79
  await (0, tenant_scope_js_1.assertTenantInScope)(stratum, request, existing.tenant_id);
71
80
  const role = await stratum.updateRole(request.params.id, parsed.data, (0, audit_logs_js_1.buildAuditContext)(request));
72
81
  if (!role) {
@@ -82,6 +91,9 @@ function createRoleRoutes(stratum) {
82
91
  reply.status(404).send({ error: { code: "NOT_FOUND", message: "Role not found" } });
83
92
  return;
84
93
  }
94
+ // Global roles are shared by every tenant: only an operator may change them.
95
+ if (existing.tenant_id === null)
96
+ (0, tenant_scope_js_1.assertOperator)(request);
85
97
  await (0, tenant_scope_js_1.assertTenantInScope)(stratum, request, existing.tenant_id);
86
98
  const deleted = await stratum.deleteRole(request.params.id, (0, audit_logs_js_1.buildAuditContext)(request));
87
99
  if (!deleted) {
@@ -110,7 +122,7 @@ function createRoleRoutes(stratum) {
110
122
  return;
111
123
  }
112
124
  await (0, tenant_scope_js_1.assertTenantInScope)(stratum, request, role.tenant_id);
113
- const success = await stratum.assignRoleToKey(request.params.keyId, parsed.data.role_id);
125
+ const success = await stratum.assignRoleToKey(request.params.keyId, parsed.data.role_id, (0, audit_logs_js_1.buildAuditContext)(request));
114
126
  if (!success) {
115
127
  reply.status(404).send({ error: { code: "NOT_FOUND", message: "API key not found or already revoked" } });
116
128
  return;
@@ -125,7 +137,7 @@ function createRoleRoutes(stratum) {
125
137
  return;
126
138
  }
127
139
  await (0, tenant_scope_js_1.assertTenantInScope)(stratum, request, key.tenant_id);
128
- const success = await stratum.removeRoleFromKey(request.params.keyId);
140
+ const success = await stratum.removeRoleFromKey(request.params.keyId, (0, audit_logs_js_1.buildAuditContext)(request));
129
141
  if (!success) {
130
142
  reply.status(404).send({ error: { code: "NOT_FOUND", message: "API key not found or already revoked" } });
131
143
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"roles.js","sourceRoot":"","sources":["../../src/routes/roles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"roles.js","sourceRoot":"","sources":["../../src/routes/roles.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tenants.d.ts","sourceRoot":"","sources":["../../src/routes/tenants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAU1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAQ1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IAYd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CA+IxE"}
1
+ {"version":3,"file":"tenants.d.ts","sourceRoot":"","sources":["../../src/routes/tenants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAe1C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAQ1C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,IAYd,KAAK,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC,CA2LxE"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createTenantRoutes = createTenantRoutes;
4
+ const zod_1 = require("zod");
4
5
  const core_1 = require("@stratum-hq/core");
5
6
  const isolation_service_js_1 = require("../services/isolation-service.js");
6
7
  const audit_logs_js_1 = require("./audit-logs.js");
@@ -29,7 +30,11 @@ function createTenantRoutes(stratum) {
29
30
  return;
30
31
  }
31
32
  const query = core_1.PaginationSchema.parse(request.query);
32
- const result = await stratum.listTenants(query);
33
+ // Active tenants by default; `?status=` lists pending, suspended or
34
+ // archived ones instead (for example to find a tenant whose storage
35
+ // provisioning failed).
36
+ const { status } = zod_1.z.object({ status: zod_1.z.nativeEnum(core_1.TenantStatus).optional() }).parse(request.query);
37
+ const result = await stratum.listTenants(query, { status });
33
38
  reply.status(200).send(result);
34
39
  });
35
40
  // POST /api/v1/tenants — Create tenant
@@ -45,13 +50,27 @@ function createTenantRoutes(stratum) {
45
50
  throw new core_1.IsolationStrategyUnsupportedError(input.isolation_strategy);
46
51
  }
47
52
  const tenant = await stratum.createTenant(input, (0, audit_logs_js_1.buildAuditContext)(request));
48
- // Provision isolation resources based on strategy
53
+ // A tenant with its own schema or database is created pending, which
54
+ // blocks every use of it. Provision its storage, then activate it. If
55
+ // provisioning fails the tenant stays pending: purge it to remove it
56
+ // (purging a pending tenant never drops storage), then create it again.
49
57
  const strategy = tenant.isolation_strategy ?? "SHARED_RLS";
50
- if (strategy === "SCHEMA_PER_TENANT") {
51
- await (0, isolation_service_js_1.setupSchemaForTenant)(tenant.slug);
52
- }
53
- else if (strategy === "DB_PER_TENANT") {
54
- await (0, isolation_service_js_1.setupDatabaseForTenant)(tenant.slug);
58
+ if (strategy === "SCHEMA_PER_TENANT" || strategy === "DB_PER_TENANT") {
59
+ try {
60
+ if (strategy === "SCHEMA_PER_TENANT") {
61
+ await (0, isolation_service_js_1.setupSchemaForTenant)(tenant.slug);
62
+ }
63
+ else {
64
+ await (0, isolation_service_js_1.setupDatabaseForTenant)(tenant.slug);
65
+ }
66
+ }
67
+ catch (err) {
68
+ request.log.error({ err, tenant_id: tenant.id }, "tenant storage provisioning failed; tenant left pending");
69
+ throw new core_1.TenantProvisioningError(tenant.id);
70
+ }
71
+ const active = await stratum.activateTenant(tenant.id, (0, audit_logs_js_1.buildAuditContext)(request));
72
+ reply.status(201).send(active);
73
+ return;
55
74
  }
56
75
  reply.status(201).send(tenant);
57
76
  });
@@ -73,6 +92,12 @@ function createTenantRoutes(stratum) {
73
92
  return;
74
93
  }
75
94
  const inputs = results.map((r) => r.data);
95
+ // Batch create does not provision schemas or databases, so it only
96
+ // accepts tenants that need none.
97
+ if (inputs.some((i) => i.isolation_strategy !== "SHARED_RLS")) {
98
+ reply.status(400).send({ error: { code: "VALIDATION_ERROR", message: "Batch create supports only SHARED_RLS tenants; create SCHEMA_PER_TENANT and DB_PER_TENANT tenants individually" } });
99
+ return;
100
+ }
76
101
  const result = await stratum.batchCreateTenants(inputs, (0, audit_logs_js_1.buildAuditContext)(request));
77
102
  reply.status(201).send(result);
78
103
  });
@@ -108,6 +133,15 @@ function createTenantRoutes(stratum) {
108
133
  // GET /api/v1/tenants/:id/ancestors — Get ancestors
109
134
  app.get("/:id/ancestors", async (request, reply) => {
110
135
  const ancestors = await stratum.getAncestors(request.params.id);
136
+ // A tenant-scoped caller gets full rows only for ancestors inside its own
137
+ // subtree; for those above it, only identifying fields.
138
+ const scopedTenantId = request.apiKey?.tenant_id;
139
+ if (scopedTenantId) {
140
+ reply.status(200).send(ancestors.map((a) => a.id === scopedTenantId || (0, core_1.getAncestorIds)(a.ancestry_path).includes(scopedTenantId)
141
+ ? a
142
+ : { id: a.id, parent_id: a.parent_id, name: a.name, slug: a.slug, depth: a.depth }));
143
+ return;
144
+ }
111
145
  reply.status(200).send(ancestors);
112
146
  });
113
147
  // GET /api/v1/tenants/:id/descendants — Get descendants
@@ -136,9 +170,17 @@ function createTenantRoutes(stratum) {
136
170
  const data = await stratum.exportTenantData(request.params.id);
137
171
  reply.status(200).send(data);
138
172
  });
139
- // GET /api/v1/tenants/:id/context — Resolve full tenant impersonation context (admin scope)
173
+ // GET /api/v1/tenants/:id/context — Resolve the flat ResolvedTenantContext (admin scope)
140
174
  app.get("/:id/context", async (request, reply) => {
141
- const context = await stratum.getTenantContext(request.params.id);
175
+ const { tenant, config, permissions } = await stratum.getTenantContext(request.params.id);
176
+ const context = {
177
+ tenant_id: tenant.id,
178
+ ancestry_path: tenant.ancestry_path,
179
+ depth: tenant.depth,
180
+ resolved_config: config,
181
+ resolved_permissions: permissions,
182
+ isolation_strategy: tenant.isolation_strategy,
183
+ };
142
184
  reply.status(200).send(context);
143
185
  });
144
186
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tenants.js","sourceRoot":"","sources":["../../src/routes/tenants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tenants.js","sourceRoot":"","sources":["../../src/routes/tenants.ts"],"names":[],"mappings":"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"}
@@ -12,11 +12,12 @@ export declare function teardownSchemaForTenant(tenantSlug: string): Promise<voi
12
12
  */
13
13
  export declare function setupDatabaseForTenant(tenantSlug: string, templateDb?: string): Promise<void>;
14
14
  /**
15
- * Tears down the DB_PER_TENANT isolation for a tenant.
15
+ * Drops the dedicated database of a DB_PER_TENANT tenant, named exactly as
16
+ * {@link setupDatabaseForTenant} names it. Purging a tenant already does this;
17
+ * close any pools to the tenant database first, or the drop fails.
16
18
  *
17
- * This closes any open connection pools for the tenant database but does NOT
18
- * drop the database — data preservation is left to the operator.
19
- * To actually drop the database, use dropDatabase() from @stratum-hq/db-adapters directly.
19
+ * DROP DATABASE cannot run inside a transaction, so like setup this uses a
20
+ * standalone client from the pool.
20
21
  */
21
- export declare function teardownDatabaseForTenant(_tenantSlug: string): Promise<void>;
22
+ export declare function teardownDatabaseForTenant(tenantSlug: string): Promise<void>;
22
23
  //# sourceMappingURL=isolation-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"isolation-service.d.ts","sourceRoot":"","sources":["../../src/services/isolation-service.ts"],"names":[],"mappings":"AAqBA,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAErD;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1E;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/E;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIlF"}
1
+ {"version":3,"file":"isolation-service.d.ts","sourceRoot":"","sources":["../../src/services/isolation-service.ts"],"names":[],"mappings":"AAsBA,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAErD;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1E;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/E;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjF"}
@@ -69,25 +69,31 @@ async function setupDatabaseForTenant(tenantSlug, templateDb) {
69
69
  const pool = (0, connection_js_1.getPool)();
70
70
  const client = await pool.connect();
71
71
  try {
72
- const exists = await (0, db_adapters_1.databaseExists)(client, tenantSlug);
73
- if (!exists) {
74
- await (0, db_adapters_1.createDatabase)(client, tenantSlug, templateDb);
72
+ // Never adopt an existing database: it may hold another tenant's data.
73
+ if (await (0, db_adapters_1.databaseExists)(client, tenantSlug)) {
74
+ throw new Error(`Database for tenant slug "${tenantSlug}" already exists`);
75
75
  }
76
+ await (0, db_adapters_1.createDatabase)(client, tenantSlug, templateDb);
76
77
  }
77
78
  finally {
78
79
  client.release();
79
80
  }
80
81
  }
81
82
  /**
82
- * Tears down the DB_PER_TENANT isolation for a tenant.
83
+ * Drops the dedicated database of a DB_PER_TENANT tenant, named exactly as
84
+ * {@link setupDatabaseForTenant} names it. Purging a tenant already does this;
85
+ * close any pools to the tenant database first, or the drop fails.
83
86
  *
84
- * This closes any open connection pools for the tenant database but does NOT
85
- * drop the database — data preservation is left to the operator.
86
- * To actually drop the database, use dropDatabase() from @stratum-hq/db-adapters directly.
87
+ * DROP DATABASE cannot run inside a transaction, so like setup this uses a
88
+ * standalone client from the pool.
87
89
  */
88
- async function teardownDatabaseForTenant(_tenantSlug) {
89
- // Pool cleanup is managed externally via DatabasePoolManager.closePool().
90
- // This function is intentionally a no-op at the isolation-service level
91
- // so that callers can decide whether to drop the database independently.
90
+ async function teardownDatabaseForTenant(tenantSlug) {
91
+ const client = await (0, connection_js_1.getPool)().connect();
92
+ try {
93
+ await (0, db_adapters_1.dropDatabase)(client, tenantSlug);
94
+ }
95
+ finally {
96
+ client.release();
97
+ }
92
98
  }
93
99
  //# sourceMappingURL=isolation-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"isolation-service.js","sourceRoot":"","sources":["../../src/services/isolation-service.ts"],"names":[],"mappings":";;AAqBA,sCAEC;AAED,4CAcC;AAED,kDAUC;AAED,kCAIC;AAED,oDAaC;AAED,0DAIC;AAQD,wDAcC;AASD,8DAIC;AAjHD,yCAAkD;AAClD,yDAOiC;AACjC,uDAA8C;AAE9C,MAAM,gBAAgB,GAAgB,IAAI,GAAG,EAAE,CAAC;AAEhD,wFAAwF;AACxF,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,aAAa,CAAC,SAAiB;IAC7C,gBAAgB,CAAC,GAAG,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;AACrD,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,SAAiB;IACtD,MAAM,IAAI,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,IAAA,qBAAe,EAAC,IAAA,uBAAO,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjD,MAAM,MAAM,CAAC,KAAK,CAChB,eAAe,IAAI,4BAA4B,CAChD,CAAC;QACF,MAAM,MAAM,CAAC,KAAK,CAChB,eAAe,IAAI,2BAA2B,CAC/C,CAAC;QACF,MAAM,MAAM,CAAC,KAAK,CAChB,qCAAqC,IAAI;0EAC2B,CACrE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,mBAAmB,CAAC,SAAiB;IACzD,MAAM,IAAI,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,IAAA,qBAAe,EAAC,IAAA,uBAAO,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjD,MAAM,MAAM,CAAC,KAAK,CAChB,6CAA6C,IAAI,EAAE,CACpD,CAAC;QACF,MAAM,MAAM,CAAC,KAAK,CAChB,eAAe,IAAI,6BAA6B,CACjD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,WAAW;IAC/B,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;QACzC,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,MAAiB;IAEjB,OAAO,IAAA,qBAAe,EAAC,IAAA,uBAAO,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjD,MAAM,IAAA,0BAAY,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACvC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,UAAU,GAAG,IAAA,8BAAgB,EAAC,UAAU,CAAC,CAAC;YAChD,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;gBAC/B,MAAM,IAAA,oCAAsB,EAAC,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,uBAAuB,CAAC,UAAkB;IAC9D,OAAO,IAAA,qBAAe,EAAC,IAAA,uBAAO,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjD,MAAM,IAAA,wBAAU,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,sBAAsB,CAC1C,UAAkB,EAClB,UAAmB;IAEnB,MAAM,IAAI,GAAG,IAAA,uBAAO,GAAE,CAAC;IACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAc,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAA,4BAAc,EAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,yBAAyB,CAAC,WAAmB;IACjE,0EAA0E;IAC1E,wEAAwE;IACxE,yEAAyE;AAC3E,CAAC"}
1
+ {"version":3,"file":"isolation-service.js","sourceRoot":"","sources":["../../src/services/isolation-service.ts"],"names":[],"mappings":";;AAsBA,sCAEC;AAED,4CAcC;AAED,kDAUC;AAED,kCAIC;AAED,oDAaC;AAED,0DAIC;AAQD,wDAeC;AAUD,8DAOC;AAvHD,yCAAkD;AAClD,yDAQiC;AACjC,uDAA8C;AAE9C,MAAM,gBAAgB,GAAgB,IAAI,GAAG,EAAE,CAAC;AAEhD,wFAAwF;AACxF,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,aAAa,CAAC,SAAiB;IAC7C,gBAAgB,CAAC,GAAG,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;AACrD,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,SAAiB;IACtD,MAAM,IAAI,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,IAAA,qBAAe,EAAC,IAAA,uBAAO,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjD,MAAM,MAAM,CAAC,KAAK,CAChB,eAAe,IAAI,4BAA4B,CAChD,CAAC;QACF,MAAM,MAAM,CAAC,KAAK,CAChB,eAAe,IAAI,2BAA2B,CAC/C,CAAC;QACF,MAAM,MAAM,CAAC,KAAK,CAChB,qCAAqC,IAAI;0EAC2B,CACrE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,mBAAmB,CAAC,SAAiB;IACzD,MAAM,IAAI,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,IAAA,qBAAe,EAAC,IAAA,uBAAO,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjD,MAAM,MAAM,CAAC,KAAK,CAChB,6CAA6C,IAAI,EAAE,CACpD,CAAC;QACF,MAAM,MAAM,CAAC,KAAK,CAChB,eAAe,IAAI,6BAA6B,CACjD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,WAAW;IAC/B,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;QACzC,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,MAAiB;IAEjB,OAAO,IAAA,qBAAe,EAAC,IAAA,uBAAO,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjD,MAAM,IAAA,0BAAY,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACvC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,UAAU,GAAG,IAAA,8BAAgB,EAAC,UAAU,CAAC,CAAC;YAChD,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;gBAC/B,MAAM,IAAA,oCAAsB,EAAC,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,uBAAuB,CAAC,UAAkB;IAC9D,OAAO,IAAA,qBAAe,EAAC,IAAA,uBAAO,GAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjD,MAAM,IAAA,wBAAU,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,sBAAsB,CAC1C,UAAkB,EAClB,UAAmB;IAEnB,MAAM,IAAI,GAAG,IAAA,uBAAO,GAAE,CAAC;IACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,uEAAuE;QACvE,IAAI,MAAM,IAAA,4BAAc,EAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,kBAAkB,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,IAAA,4BAAc,EAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IACvD,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,yBAAyB,CAAC,UAAkB;IAChE,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAO,GAAE,CAAC,OAAO,EAAE,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,IAAA,0BAAY,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stratum-hq/control-plane",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Stratum control plane REST API server",
5
5
  "keywords": [
6
6
  "multi-tenancy",
@@ -47,11 +47,11 @@
47
47
  "@fastify/cors": "^11.0.0",
48
48
  "@fastify/helmet": "^13.0.0",
49
49
  "@fastify/rate-limit": "^10.2.0",
50
- "@fastify/swagger": "^9.4.0",
50
+ "@fastify/swagger": "^9.9.0",
51
51
  "@fastify/swagger-ui": "^6.1.1",
52
52
  "@stratum-hq/core": "*",
53
53
  "@stratum-hq/lib": "*",
54
- "fastify": "^5.3.2",
54
+ "fastify": "^5.12.5",
55
55
  "jsonwebtoken": "^9.0.0",
56
56
  "ioredis": "^5.4.0",
57
57
  "pg": "^8.11.0",
@@ -61,7 +61,7 @@
61
61
  "devDependencies": {
62
62
  "@types/jsonwebtoken": "^9.0.0",
63
63
  "@types/pg": "^8.11.0",
64
- "tsx": "^4.7.0",
64
+ "tsx": "^4.23.15",
65
65
  "typescript": "^5.4.0",
66
66
  "vitest": "^4.1.11"
67
67
  },