@stratum-hq/control-plane 1.0.0 → 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 (53) hide show
  1. package/README.md +4 -2
  2. package/dist/app.js.map +1 -1
  3. package/dist/config.d.ts +2 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +26 -0
  6. package/dist/config.js.map +1 -1
  7. package/dist/middleware/auth.d.ts +1 -1
  8. package/dist/middleware/auth.d.ts.map +1 -1
  9. package/dist/middleware/auth.js +7 -2
  10. package/dist/middleware/auth.js.map +1 -1
  11. package/dist/middleware/authorize.d.ts +1 -1
  12. package/dist/middleware/authorize.d.ts.map +1 -1
  13. package/dist/middleware/authorize.js +17 -7
  14. package/dist/middleware/authorize.js.map +1 -1
  15. package/dist/middleware/per-key-rate-limit.d.ts +11 -1
  16. package/dist/middleware/per-key-rate-limit.d.ts.map +1 -1
  17. package/dist/middleware/per-key-rate-limit.js +14 -4
  18. package/dist/middleware/per-key-rate-limit.js.map +1 -1
  19. package/dist/middleware/rate-limit-redis.d.ts +2 -1
  20. package/dist/middleware/rate-limit-redis.d.ts.map +1 -1
  21. package/dist/middleware/rate-limit-redis.js +7 -4
  22. package/dist/middleware/rate-limit-redis.js.map +1 -1
  23. package/dist/middleware/tenant-scope.d.ts +9 -3
  24. package/dist/middleware/tenant-scope.d.ts.map +1 -1
  25. package/dist/middleware/tenant-scope.js +26 -3
  26. package/dist/middleware/tenant-scope.js.map +1 -1
  27. package/dist/openapi.js.map +1 -1
  28. package/dist/redis.d.ts +3 -1
  29. package/dist/redis.d.ts.map +1 -1
  30. package/dist/redis.js +5 -6
  31. package/dist/redis.js.map +1 -1
  32. package/dist/routes/abac.d.ts.map +1 -1
  33. package/dist/routes/abac.js +3 -2
  34. package/dist/routes/abac.js.map +1 -1
  35. package/dist/routes/api-keys.d.ts.map +1 -1
  36. package/dist/routes/api-keys.js +18 -4
  37. package/dist/routes/api-keys.js.map +1 -1
  38. package/dist/routes/maintenance.js +3 -3
  39. package/dist/routes/maintenance.js.map +1 -1
  40. package/dist/routes/regions.d.ts.map +1 -1
  41. package/dist/routes/regions.js +5 -4
  42. package/dist/routes/regions.js.map +1 -1
  43. package/dist/routes/roles.d.ts.map +1 -1
  44. package/dist/routes/roles.js +15 -3
  45. package/dist/routes/roles.js.map +1 -1
  46. package/dist/routes/tenants.d.ts.map +1 -1
  47. package/dist/routes/tenants.js +51 -9
  48. package/dist/routes/tenants.js.map +1 -1
  49. package/dist/services/isolation-service.d.ts +6 -5
  50. package/dist/services/isolation-service.d.ts.map +1 -1
  51. package/dist/services/isolation-service.js +17 -11
  52. package/dist/services/isolation-service.js.map +1 -1
  53. package/package.json +6 -6
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/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
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"}
@@ -16,6 +16,6 @@ declare module "fastify" {
16
16
  authMethod?: "api_key" | "jwt";
17
17
  }
18
18
  }
19
- export declare function createAuthMiddleware(stratum: Stratum): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
19
+ export declare function createAuthMiddleware(stratum: Stratum): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
20
20
  export {};
21
21
  //# sourceMappingURL=auth.d.ts.map
@@ -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,OAAO,YAAY,KAClB,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"}
@@ -8,7 +8,7 @@ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
8
  const config_js_1 = require("../config.js");
9
9
  const core_1 = require("@stratum-hq/core");
10
10
  function createAuthMiddleware(stratum) {
11
- return async function authMiddleware(request, reply) {
11
+ return async function authMiddleware(request, _reply) {
12
12
  // Skip auth for health and documentation endpoints
13
13
  if (request.url === "/api/v1/health" ||
14
14
  request.url.startsWith("/api/v1/health?") ||
@@ -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,3 +1,3 @@
1
1
  import { FastifyRequest, FastifyReply } from "fastify";
2
- export declare function createAuthorizeMiddleware(): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
2
+ export declare function createAuthorizeMiddleware(): (request: FastifyRequest, _reply: FastifyReply) => Promise<void>;
3
3
  //# sourceMappingURL=authorize.d.ts.map
@@ -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,OAAO,YAAY,KAClB,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,19 +23,25 @@ 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
- return async function authorizeMiddleware(request, reply) {
44
+ return async function authorizeMiddleware(request, _reply) {
39
45
  // Skip for health and documentation endpoints
40
46
  if (request.url === "/api/v1/health" ||
41
47
  request.url.startsWith("/api/v1/health?") ||
@@ -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,KAAmB;QAEnB,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":"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"}
1
+ {"version":3,"file":"tenant-scope.js","sourceRoot":"","sources":["../../src/middleware/tenant-scope.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":";;;;;AAIA,0CAkCC;AArCD,+DAAuC;AACvC,qEAA4C;AAErC,KAAK,UAAU,eAAe,CAAC,GAAoB;IACxD,MAAM,GAAG,CAAC,QAAQ,CAAC,iBAAc,EAAE;QACjC,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,KAAK,EAAE,2BAA2B;gBAClC,OAAO,EAAE,OAAO;gBAChB,WAAW,EAAE,iDAAiD;aAC/D;YACD,UAAU,EAAE;gBACV,eAAe,EAAE;oBACf,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,EAAE,EAAE,QAAQ;wBACZ,IAAI,EAAE,WAAW;qBAClB;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,MAAM;wBACZ,MAAM,EAAE,QAAQ;wBAChB,YAAY,EAAE,KAAK;qBACpB;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;SAC/C;KACF,CAAC,CAAC;IAEH,MAAM,GAAG,CAAC,QAAQ,CAAC,oBAAgB,EAAE;QACnC,WAAW,EAAE,WAAW;QACxB,QAAQ,EAAE;YACR,YAAY,EAAE,MAAM;YACpB,WAAW,EAAE,IAAI;SAClB;QACD,SAAS,EAAE,KAAK;KACjB,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":";;;;;AAIA,0CAkCC;AArCD,+DAAuC;AACvC,qEAA4C;AAErC,KAAK,UAAU,eAAe,CAAC,GAAoB;IACxD,MAAM,GAAG,CAAC,QAAQ,CAAC,iBAAO,EAAE;QAC1B,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,KAAK,EAAE,2BAA2B;gBAClC,OAAO,EAAE,OAAO;gBAChB,WAAW,EAAE,iDAAiD;aAC/D;YACD,UAAU,EAAE;gBACV,eAAe,EAAE;oBACf,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,EAAE,EAAE,QAAQ;wBACZ,IAAI,EAAE,WAAW;qBAClB;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,MAAM;wBACZ,MAAM,EAAE,QAAQ;wBAChB,YAAY,EAAE,KAAK;qBACpB;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;SAC/C;KACF,CAAC,CAAC;IAEH,MAAM,GAAG,CAAC,QAAQ,CAAC,oBAAS,EAAE;QAC5B,WAAW,EAAE,WAAW;QACxB,QAAQ,EAAE;YACR,YAAY,EAAE,MAAM;YACpB,WAAW,EAAE,IAAI;SAClB;QACD,SAAS,EAAE,KAAK;KACjB,CAAC,CAAC;AACL,CAAC"}
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"}