@frontmcp/auth 1.7.2 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/authorities/authorities.context.d.ts +16 -1
  2. package/authorities/authorities.context.d.ts.map +1 -1
  3. package/authorities/authorities.evaluator.d.ts +1 -1
  4. package/authorities/authorities.evaluator.d.ts.map +1 -1
  5. package/authorities/authorities.types.d.ts +2 -2
  6. package/authorities/authorities.types.d.ts.map +1 -1
  7. package/authorities/index.d.ts +1 -1
  8. package/authorities/index.d.ts.map +1 -1
  9. package/cimd/cimd.service.d.ts.map +1 -1
  10. package/cimd/cimd.validator.d.ts.map +1 -1
  11. package/context/frontmcp-auth-context.impl.d.ts.map +1 -1
  12. package/detection/auth-provider-detection.d.ts +2 -0
  13. package/detection/auth-provider-detection.d.ts.map +1 -1
  14. package/errors/auth-internal.errors.d.ts +12 -0
  15. package/errors/auth-internal.errors.d.ts.map +1 -1
  16. package/errors/index.d.ts +1 -1
  17. package/errors/index.d.ts.map +1 -1
  18. package/esm/index.mjs +306 -247
  19. package/esm/package.json +5 -5
  20. package/index.d.ts +1 -1
  21. package/index.d.ts.map +1 -1
  22. package/index.js +459 -396
  23. package/jwks/jwks.service.d.ts.map +1 -1
  24. package/options/index.d.ts +4 -2
  25. package/options/index.d.ts.map +1 -1
  26. package/options/interfaces.d.ts +20 -2
  27. package/options/interfaces.d.ts.map +1 -1
  28. package/options/schema.d.ts +13 -1
  29. package/options/schema.d.ts.map +1 -1
  30. package/options/static.schema.d.ts +27 -0
  31. package/options/static.schema.d.ts.map +1 -0
  32. package/options/typecheck.d.ts.map +1 -1
  33. package/options/utils.d.ts +7 -2
  34. package/options/utils.d.ts.map +1 -1
  35. package/package.json +5 -5
  36. package/session/authorization-vault.d.ts +1 -1
package/index.js CHANGED
@@ -269,9 +269,9 @@ __export(index_exports, {
269
269
  EagerCredentialLoader: () => EagerCredentialLoader,
270
270
  ElicitationSecretRequiredError: () => ElicitationSecretRequiredError,
271
271
  EncryptedRedisVault: () => EncryptedRedisVault,
272
- EncryptedStorageError: () => import_utils23.EncryptedStorageError,
272
+ EncryptedStorageError: () => import_utils24.EncryptedStorageError,
273
273
  EncryptedStorageSecureStoreBackend: () => EncryptedStorageSecureStoreBackend,
274
- EncryptedTypedStorage: () => import_utils23.EncryptedTypedStorage,
274
+ EncryptedTypedStorage: () => import_utils24.EncryptedTypedStorage,
275
275
  EncryptionContextNotSetError: () => EncryptionContextNotSetError,
276
276
  EncryptionKeyNotConfiguredError: () => EncryptionKeyNotConfiguredError,
277
277
  FetchCredentialMiddleware: () => FetchCredentialMiddleware,
@@ -285,6 +285,8 @@ __export(index_exports, {
285
285
  InMemoryStoreRequiredError: () => InMemoryStoreRequiredError,
286
286
  InvalidClientIdUrlError: () => InvalidClientIdUrlError,
287
287
  JwksService: () => JwksService,
288
+ JwtSecretRequiredError: () => JwtSecretRequiredError,
289
+ JwtSecretWeakError: () => JwtSecretWeakError,
288
290
  LazyCredentialLoader: () => LazyCredentialLoader,
289
291
  NoProviderIdError: () => NoProviderIdError,
290
292
  NullOrchestratedAuthAccessor: () => NullOrchestratedAuthAccessor,
@@ -317,7 +319,7 @@ __export(index_exports, {
317
319
  TokenVault: () => TokenVault,
318
320
  TransparentAuthorization: () => TransparentAuthorization,
319
321
  TransportIdGenerator: () => TransportIdGenerator,
320
- TypedStorage: () => import_utils22.TypedStorage,
322
+ TypedStorage: () => import_utils23.TypedStorage,
321
323
  VaultEncryption: () => VaultEncryption,
322
324
  VaultLoadError: () => VaultLoadError,
323
325
  VaultNotFoundError: () => VaultNotFoundError,
@@ -399,9 +401,9 @@ __export(index_exports, {
399
401
  credentialTypeSchema: () => credentialTypeSchema,
400
402
  customCredentialSchema: () => customCredentialSchema,
401
403
  decodeJwtPayloadSafe: () => decodeJwtPayloadSafe,
402
- decryptAesGcm: () => import_utils33.decryptAesGcm,
404
+ decryptAesGcm: () => import_utils34.decryptAesGcm,
403
405
  decryptSessionJson: () => decryptSessionJson,
404
- decryptValue: () => import_utils33.decryptValue,
406
+ decryptValue: () => import_utils34.decryptValue,
405
407
  defaultSessionRateLimiter: () => defaultSessionRateLimiter,
406
408
  deriveAuthorizationId: () => deriveAuthorizationId,
407
409
  deriveExpectedAudience: () => deriveExpectedAudience,
@@ -409,13 +411,13 @@ __export(index_exports, {
409
411
  deriveTypedUser: () => deriveTypedUser,
410
412
  detectAuthProviders: () => detectAuthProviders,
411
413
  detectedAuthProviderSchema: () => detectedAuthProviderSchema,
412
- encryptAesGcm: () => import_utils33.encryptAesGcm,
414
+ encryptAesGcm: () => import_utils34.encryptAesGcm,
413
415
  encryptJson: () => encryptJson,
414
- encryptValue: () => import_utils33.encryptValue,
416
+ encryptValue: () => import_utils34.encryptValue,
415
417
  encryptedBlobSchema: () => encryptedBlobSchema,
416
418
  encryptedDataSchema: () => encryptedDataSchema,
417
419
  encryptedVaultEntrySchema: () => encryptedVaultEntrySchema,
418
- escapeHtml: () => import_utils3.escapeHtml,
420
+ escapeHtml: () => import_utils4.escapeHtml,
419
421
  extraWideLayout: () => extraWideLayout,
420
422
  extractBearerToken: () => extractBearerToken,
421
423
  extractCacheHeaders: () => extractCacheHeaders,
@@ -437,8 +439,9 @@ __export(index_exports, {
437
439
  getTokenSignatureFingerprint: () => getTokenSignatureFingerprint,
438
440
  hasOnlyLocalhostRedirectUris: () => hasOnlyLocalhostRedirectUris,
439
441
  headerApplier: () => headerApplier,
440
- hkdfSha256: () => import_utils33.hkdfSha256,
442
+ hkdfSha256: () => import_utils34.hkdfSha256,
441
443
  incrementalAuthConfigSchema: () => incrementalAuthConfigSchema,
444
+ isAnonymousSubject: () => isAnonymousSubject,
442
445
  isCimdClientId: () => isCimdClientId,
443
446
  isFrontMcpCredentials: () => isFrontMcpCredentials,
444
447
  isJwt: () => isJwt,
@@ -451,10 +454,11 @@ __export(index_exports, {
451
454
  isRedisTokenStorage: () => isRedisTokenStorage,
452
455
  isRemoteMode: () => isRemoteMode,
453
456
  isSessionComplete: () => isSessionComplete,
454
- isSignedSession: () => import_utils15.isSignedData,
457
+ isSignedSession: () => import_utils16.isSignedData,
455
458
  isSoonExpiring: () => isSoonExpiring,
456
459
  isSoonExpiringProvider: () => isSoonExpiringProvider,
457
460
  isSqliteTokenStorage: () => isSqliteTokenStorage,
461
+ isStaticMode: () => isStaticMode,
458
462
  isTransparentMode: () => isTransparentMode,
459
463
  jsonWebKeySetSchema: () => jsonWebKeySetSchema,
460
464
  jwkParametersSchema: () => jwkParametersSchema,
@@ -514,6 +518,7 @@ __export(index_exports, {
514
518
  startNextProvider: () => startNextProvider,
515
519
  statefulHttpTransportStateSchema: () => statefulHttpTransportStateSchema,
516
520
  statelessHttpTransportStateSchema: () => statelessHttpTransportStateSchema,
521
+ staticAuthOptionsSchema: () => staticAuthOptionsSchema,
517
522
  storedSessionSchema: () => storedSessionSchema,
518
523
  streamableHttpTransportStateSchema: () => streamableHttpTransportStateSchema,
519
524
  toEpochSeconds: () => toEpochSeconds,
@@ -545,6 +550,9 @@ module.exports = __toCommonJS(index_exports);
545
550
 
546
551
  // libs/auth/src/jwks/jwks.service.ts
547
552
  var import_jose = require("jose");
553
+ var import_utils2 = require("@frontmcp/utils");
554
+
555
+ // libs/auth/src/cimd/cimd.validator.ts
548
556
  var import_utils = require("@frontmcp/utils");
549
557
 
550
558
  // libs/auth/src/cimd/cimd.errors.ts
@@ -810,70 +818,38 @@ function isIpAddress(hostname) {
810
818
  }
811
819
  return false;
812
820
  }
821
+ var BLOCKED_RANGE_REASONS = /* @__PURE__ */ new Map([
822
+ ["0.0.0.0/8", "Current network addresses (0.x.x.x) are not allowed"],
823
+ ["10.0.0.0/8", "Private IP addresses (10.x.x.x) are not allowed"],
824
+ ["100.64.0.0/10", "Carrier-grade NAT addresses (100.64-127.x.x) are not allowed"],
825
+ ["127.0.0.0/8", "Loopback addresses (127.x.x.x) are not allowed"],
826
+ ["169.254.0.0/16", "Link-local addresses (169.254.x.x) are not allowed"],
827
+ ["172.16.0.0/12", "Private IP addresses (172.16-31.x.x) are not allowed"],
828
+ ["192.0.0.0/24", "IETF protocol-assignment addresses (192.0.0.0/24) are not allowed"],
829
+ ["192.168.0.0/16", "Private IP addresses (192.168.x.x) are not allowed"],
830
+ ["224.0.0.0/4", "Multicast addresses are not allowed"],
831
+ ["255.255.255.255/32", "Broadcast address is not allowed"],
832
+ ["::/128", "IPv6 unspecified address (::) is not allowed"],
833
+ ["::1/128", "IPv6 loopback address (::1) is not allowed"],
834
+ ["fc00::/7", "IPv6 unique local addresses (fc00::/7) are not allowed"],
835
+ ["fe80::/10", "IPv6 link-local addresses (fe80::/10) are not allowed"]
836
+ ]);
813
837
  function checkIpAddress(ip) {
814
- const cleanIp = ip.replace(/^\[|\]$/g, "");
815
- if (cleanIp.includes(".") && !cleanIp.includes(":")) {
816
- return checkIpv4(cleanIp);
817
- }
818
- return checkIpv6(cleanIp);
819
- }
820
- function checkIpv4(ip) {
821
- const parts = ip.split(".").map(Number);
822
- if (parts.length !== 4 || parts.some((p) => isNaN(p) || p < 0 || p > 255)) {
823
- return { allowed: false, reason: "Invalid IPv4 address" };
824
- }
825
- const [a, b, c, d] = parts;
826
- if (a === 127) {
827
- return { allowed: false, reason: "Loopback addresses (127.x.x.x) are not allowed" };
828
- }
829
- if (a === 10) {
830
- return { allowed: false, reason: "Private IP addresses (10.x.x.x) are not allowed" };
831
- }
832
- if (a === 172 && b >= 16 && b <= 31) {
833
- return { allowed: false, reason: "Private IP addresses (172.16-31.x.x) are not allowed" };
834
- }
835
- if (a === 192 && b === 168) {
836
- return { allowed: false, reason: "Private IP addresses (192.168.x.x) are not allowed" };
837
- }
838
- if (a === 169 && b === 254) {
839
- return { allowed: false, reason: "Link-local addresses (169.254.x.x) are not allowed" };
840
- }
841
- if (a === 100 && b >= 64 && b <= 127) {
842
- return { allowed: false, reason: "Carrier-grade NAT addresses (100.64-127.x.x) are not allowed" };
843
- }
844
- if (a === 192 && b === 0 && c === 0) {
845
- return { allowed: false, reason: "IETF protocol-assignment addresses (192.0.0.0/24) are not allowed" };
846
- }
847
- if (a === 0) {
848
- return { allowed: false, reason: "Current network addresses (0.x.x.x) are not allowed" };
849
- }
850
- if (a === 255 && b === 255 && c === 255 && d === 255) {
851
- return { allowed: false, reason: "Broadcast address is not allowed" };
852
- }
853
- if (a >= 224 && a <= 239) {
854
- return { allowed: false, reason: "Multicast addresses are not allowed" };
855
- }
856
- return { allowed: true, reason: "" };
857
- }
858
- function checkIpv6(ip) {
859
- const normalizedIp = ip.toLowerCase();
860
- if (normalizedIp === "::1") {
861
- return { allowed: false, reason: "IPv6 loopback address (::1) is not allowed" };
862
- }
863
- if (normalizedIp === "::" || normalizedIp === "0:0:0:0:0:0:0:0") {
864
- return { allowed: false, reason: "IPv6 unspecified address (::) is not allowed" };
865
- }
866
- if (normalizedIp.startsWith("fe8") || normalizedIp.startsWith("fe9") || normalizedIp.startsWith("fea") || normalizedIp.startsWith("feb")) {
867
- return { allowed: false, reason: "IPv6 link-local addresses (fe80::/10) are not allowed" };
868
- }
869
- if (normalizedIp.startsWith("fc") || normalizedIp.startsWith("fd")) {
870
- return { allowed: false, reason: "IPv6 unique local addresses (fc00::/7) are not allowed" };
838
+ const classification = (0, import_utils.classifyIpAddress)(ip);
839
+ if (!classification) {
840
+ const bareIp = ip.replace(/^\[|\]$/g, "");
841
+ return {
842
+ allowed: false,
843
+ reason: bareIp.includes(":") ? `Malformed IPv6 address: ${bareIp}` : "Invalid IPv4 address"
844
+ };
871
845
  }
872
- const ipv4MappedMatch = normalizedIp.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
873
- if (ipv4MappedMatch) {
874
- return checkIpv4(ipv4MappedMatch[1]);
846
+ if (classification.range === "public") {
847
+ return { allowed: true, reason: "" };
875
848
  }
876
- return { allowed: true, reason: "" };
849
+ return {
850
+ allowed: false,
851
+ reason: BLOCKED_RANGE_REASONS.get(classification.cidr) ?? `Addresses in the ${classification.range} range (${classification.cidr}) are not allowed`
852
+ };
877
853
  }
878
854
  function isDomainInList(hostname, domainList) {
879
855
  const lowerHostname = hostname.toLowerCase();
@@ -1004,9 +980,9 @@ var JwksService = class {
1004
980
  * Returns null if persistence is disabled (production).
1005
981
  */
1006
982
  async getKeyPersistence() {
1007
- if ((0, import_utils.isProduction)()) return null;
983
+ if ((0, import_utils2.isProduction)()) return null;
1008
984
  if (!this.keyPersistence) {
1009
- this.keyPersistence = await (0, import_utils.createKeyPersistence)({
985
+ this.keyPersistence = await (0, import_utils2.createKeyPersistence)({
1010
986
  baseDir: ".frontmcp/keys"
1011
987
  });
1012
988
  }
@@ -1125,7 +1101,7 @@ var JwksService = class {
1125
1101
  if (!jwtAlg) {
1126
1102
  return { ok: false, error: "missing_alg" };
1127
1103
  }
1128
- const isValid = await (0, import_utils.rsaVerify)(
1104
+ const isValid = await (0, import_utils2.rsaVerify)(
1129
1105
  jwtAlg,
1130
1106
  Buffer.from(signatureInput),
1131
1107
  matchingKey,
@@ -1268,10 +1244,10 @@ var JwksService = class {
1268
1244
  const parsed = new URL(currentUrl);
1269
1245
  const host = parsed.hostname.toLowerCase();
1270
1246
  const isLocalhost = host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]" || host.endsWith(".localhost");
1271
- if (parsed.protocol !== "https:" && !(parsed.protocol === "http:" && (isLocalhost || !(0, import_utils.isProduction)()))) {
1247
+ if (parsed.protocol !== "https:" && !(parsed.protocol === "http:" && (isLocalhost || !(0, import_utils2.isProduction)()))) {
1272
1248
  throw new Error(`insecure scheme "${parsed.protocol}"`);
1273
1249
  }
1274
- if (!(isLocalhost && !(0, import_utils.isProduction)())) {
1250
+ if (!(isLocalhost && !(0, import_utils2.isProduction)())) {
1275
1251
  const ssrf = await resolveAndCheckHostname(parsed.hostname);
1276
1252
  if (!ssrf.allowed) throw new Error(`blocked host: ${ssrf.reason}`);
1277
1253
  }
@@ -1282,11 +1258,10 @@ var JwksService = class {
1282
1258
  // Follow redirects manually so each hop is re-validated (scheme + SSRF).
1283
1259
  redirect: "manual"
1284
1260
  });
1285
- if (res.status >= 300 && res.status < 400) {
1261
+ if ((0, import_utils2.isRedirectResponse)(res)) {
1286
1262
  const location = res.headers.get("location");
1287
- if (!location || hop >= MAX_JWKS_FETCH_HOPS) {
1288
- throw new Error("too many redirects");
1289
- }
1263
+ if (!location) throw new Error("redirect without a readable Location header");
1264
+ if (hop >= MAX_JWKS_FETCH_HOPS) throw new Error("too many redirects");
1290
1265
  currentUrl = new URL(location, currentUrl).toString();
1291
1266
  continue;
1292
1267
  }
@@ -1379,13 +1354,13 @@ var JwksService = class {
1379
1354
  const { generateKeyPairSync } = require("node:crypto");
1380
1355
  if (alg === "RS256") {
1381
1356
  const { privateKey, publicKey } = generateKeyPairSync("rsa", { modulusLength: 2048 });
1382
- const kid = (0, import_utils.bytesToHex)((0, import_utils.randomBytes)(8));
1357
+ const kid = (0, import_utils2.bytesToHex)((0, import_utils2.randomBytes)(8));
1383
1358
  const publicJwk = publicKey.export({ format: "jwk" });
1384
1359
  Object.assign(publicJwk, { kid, alg: "RS256", use: "sig", kty: "RSA" });
1385
1360
  return { kid, privateKey, publicJwk: { keys: [publicJwk] }, createdAt: Date.now() };
1386
1361
  } else {
1387
1362
  const { privateKey, publicKey } = generateKeyPairSync("ec", { namedCurve: "P-256" });
1388
- const kid = (0, import_utils.bytesToHex)((0, import_utils.randomBytes)(8));
1363
+ const kid = (0, import_utils2.bytesToHex)((0, import_utils2.randomBytes)(8));
1389
1364
  const publicJwk = publicKey.export({ format: "jwk" });
1390
1365
  Object.assign(publicJwk, { kid, alg: "ES256", use: "sig", kty: "EC" });
1391
1366
  return { kid, privateKey, publicJwk: { keys: [publicJwk] }, createdAt: Date.now() };
@@ -1394,8 +1369,8 @@ var JwksService = class {
1394
1369
  };
1395
1370
 
1396
1371
  // libs/auth/src/ui/base-layout.ts
1397
- var import_utils2 = require("@frontmcp/utils");
1398
1372
  var import_utils3 = require("@frontmcp/utils");
1373
+ var import_utils4 = require("@frontmcp/utils");
1399
1374
  var CDN = {
1400
1375
  /** Tailwind CSS v4 Browser CDN - generates styles on-the-fly with @theme support */
1401
1376
  tailwind: "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4",
@@ -1474,13 +1449,13 @@ function baseLayout(content, options) {
1474
1449
  }
1475
1450
  ${customCss}
1476
1451
  </style>` : "";
1477
- const metaDescription = description ? `<meta name="description" content="${(0, import_utils2.escapeHtml)(description)}">` : "";
1452
+ const metaDescription = description ? `<meta name="description" content="${(0, import_utils3.escapeHtml)(description)}">` : "";
1478
1453
  return `<!DOCTYPE html>
1479
1454
  <html lang="en">
1480
1455
  <head>
1481
1456
  <meta charset="UTF-8">
1482
1457
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1483
- <title>${(0, import_utils2.escapeHtml)(title)} - FrontMCP</title>
1458
+ <title>${(0, import_utils3.escapeHtml)(title)} - FrontMCP</title>
1484
1459
  ${metaDescription}
1485
1460
 
1486
1461
  <!-- Google Fonts CDN - Inter (modern UI font) -->
@@ -1491,7 +1466,7 @@ function baseLayout(content, options) {
1491
1466
  ${tailwindBlock}
1492
1467
  ${headExtra}
1493
1468
  </head>
1494
- <body class="${(0, import_utils2.escapeHtml)(bodyClass)}">
1469
+ <body class="${(0, import_utils3.escapeHtml)(bodyClass)}">
1495
1470
  ${content}
1496
1471
  </body>
1497
1472
  </html>`;
@@ -1546,7 +1521,7 @@ function extraWideLayout(content, options) {
1546
1521
  }
1547
1522
 
1548
1523
  // libs/auth/src/ui/templates.ts
1549
- var escapeHtml3 = import_utils3.escapeHtml;
1524
+ var escapeHtml3 = import_utils4.escapeHtml;
1550
1525
  function buildConsentPage(params) {
1551
1526
  const { apps, clientName, pendingAuthId, csrfToken, callbackPath } = params;
1552
1527
  const appCards = apps.map((app) => buildAppCardHtml(app, pendingAuthId, csrfToken, callbackPath)).join("\n");
@@ -2048,7 +2023,7 @@ function renderLocalLoginPage(login, ctx, values) {
2048
2023
 
2049
2024
  // libs/auth/src/session/authorization.store.ts
2050
2025
  var import_lazy_zod = require("@frontmcp/lazy-zod");
2051
- var import_utils4 = require("@frontmcp/utils");
2026
+ var import_utils5 = require("@frontmcp/utils");
2052
2027
  var pkceChallengeSchema = import_lazy_zod.z.object({
2053
2028
  challenge: import_lazy_zod.z.string().min(43).max(128),
2054
2029
  method: import_lazy_zod.z.literal("S256")
@@ -2083,10 +2058,10 @@ var AUTH_CODE_TTL_MS = 60 * 1e3;
2083
2058
  var PENDING_AUTH_TTL_MS = 10 * 60 * 1e3;
2084
2059
  var REFRESH_TOKEN_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
2085
2060
  function generateAuthorizationCode() {
2086
- return (0, import_utils4.randomUUID)().replace(/-/g, "") + (0, import_utils4.randomUUID)().replace(/-/g, "");
2061
+ return (0, import_utils5.randomUUID)().replace(/-/g, "") + (0, import_utils5.randomUUID)().replace(/-/g, "");
2087
2062
  }
2088
2063
  function generateRefreshTokenValue() {
2089
- return (0, import_utils4.randomUUID)() + "-" + (0, import_utils4.randomUUID)();
2064
+ return (0, import_utils5.randomUUID)() + "-" + (0, import_utils5.randomUUID)();
2090
2065
  }
2091
2066
  function buildCodeRecord(params) {
2092
2067
  const now = Date.now();
@@ -2117,7 +2092,7 @@ function buildCodeRecord(params) {
2117
2092
  function buildPendingRecord(params) {
2118
2093
  const now = Date.now();
2119
2094
  return {
2120
- id: (0, import_utils4.randomUUID)(),
2095
+ id: (0, import_utils5.randomUUID)(),
2121
2096
  clientId: params.clientId,
2122
2097
  redirectUri: params.redirectUri,
2123
2098
  scopes: params.scopes,
@@ -2166,11 +2141,11 @@ function verifyPkce(codeVerifier, challenge) {
2166
2141
  if (challenge.method !== "S256") {
2167
2142
  return false;
2168
2143
  }
2169
- const hash = (0, import_utils4.sha256Base64url)(codeVerifier);
2144
+ const hash = (0, import_utils5.sha256Base64url)(codeVerifier);
2170
2145
  return hash === challenge.challenge;
2171
2146
  }
2172
2147
  function generatePkceChallenge(codeVerifier) {
2173
- const challenge = (0, import_utils4.sha256Base64url)(codeVerifier);
2148
+ const challenge = (0, import_utils5.sha256Base64url)(codeVerifier);
2174
2149
  return { challenge, method: "S256" };
2175
2150
  }
2176
2151
  var InMemoryAuthorizationStore = class {
@@ -2366,7 +2341,7 @@ var RedisAuthorizationStore = class {
2366
2341
  };
2367
2342
 
2368
2343
  // libs/auth/src/session/storage-authorization.store.ts
2369
- var import_utils5 = require("@frontmcp/utils");
2344
+ var import_utils6 = require("@frontmcp/utils");
2370
2345
  var StorageAuthorizationStore = class {
2371
2346
  codeStore;
2372
2347
  pendingStore;
@@ -2377,9 +2352,9 @@ var StorageAuthorizationStore = class {
2377
2352
  this.namespace = options.namespace ?? "oauth";
2378
2353
  this.storageIsNamespaced = this.isNamespacedStorage(storage);
2379
2354
  const base = this.storageIsNamespaced ? storage.namespace(this.namespace) : storage;
2380
- this.codeStore = new import_utils5.TypedStorage(base);
2381
- this.pendingStore = new import_utils5.TypedStorage(base);
2382
- this.refreshStore = new import_utils5.TypedStorage(base);
2355
+ this.codeStore = new import_utils6.TypedStorage(base);
2356
+ this.pendingStore = new import_utils6.TypedStorage(base);
2357
+ this.refreshStore = new import_utils6.TypedStorage(base);
2383
2358
  }
2384
2359
  // ============================================
2385
2360
  // Record builders (pure; shared with in-memory store)
@@ -2752,11 +2727,11 @@ var authorizationVaultEntrySchema = import_lazy_zod2.z.object({
2752
2727
  });
2753
2728
 
2754
2729
  // libs/auth/src/session/session-credential-vault.ts
2755
- var import_utils7 = require("@frontmcp/utils");
2730
+ var import_utils8 = require("@frontmcp/utils");
2756
2731
 
2757
2732
  // libs/auth/src/session/vault-encryption.ts
2758
2733
  var import_lazy_zod3 = require("@frontmcp/lazy-zod");
2759
- var import_utils6 = require("@frontmcp/utils");
2734
+ var import_utils7 = require("@frontmcp/utils");
2760
2735
  var encryptedDataSchema = import_lazy_zod3.z.object({
2761
2736
  /** Version for future algorithm changes */
2762
2737
  v: import_lazy_zod3.z.literal(1),
@@ -2796,7 +2771,7 @@ var VaultEncryption = class {
2796
2771
  ];
2797
2772
  const ikm = new TextEncoder().encode(ikmParts.join(""));
2798
2773
  const infoBytes = new TextEncoder().encode(this.hkdfInfo);
2799
- const key = await (0, import_utils6.hkdfSha256)(ikm, new Uint8Array(0), infoBytes, 32);
2774
+ const key = await (0, import_utils7.hkdfSha256)(ikm, new Uint8Array(0), infoBytes, 32);
2800
2775
  return key;
2801
2776
  }
2802
2777
  /**
@@ -2823,7 +2798,7 @@ var VaultEncryption = class {
2823
2798
  ];
2824
2799
  const ikm = new TextEncoder().encode(ikmParts.join(""));
2825
2800
  const infoBytes = new TextEncoder().encode(this.hkdfInfo);
2826
- const key = await (0, import_utils6.hkdfSha256)(ikm, new Uint8Array(0), infoBytes, 32);
2801
+ const key = await (0, import_utils7.hkdfSha256)(ikm, new Uint8Array(0), infoBytes, 32);
2827
2802
  return key;
2828
2803
  }
2829
2804
  /**
@@ -2837,14 +2812,14 @@ var VaultEncryption = class {
2837
2812
  if (key.length !== 32) {
2838
2813
  throw new Error("Encryption key must be 32 bytes");
2839
2814
  }
2840
- const iv = (0, import_utils6.randomBytes)(12);
2841
- const { ciphertext, tag } = await (0, import_utils6.encryptAesGcm)(key, new TextEncoder().encode(plaintext), iv);
2815
+ const iv = (0, import_utils7.randomBytes)(12);
2816
+ const { ciphertext, tag } = await (0, import_utils7.encryptAesGcm)(key, new TextEncoder().encode(plaintext), iv);
2842
2817
  return {
2843
2818
  v: 1,
2844
2819
  alg: "aes-256-gcm",
2845
- iv: (0, import_utils6.base64urlEncode)(iv),
2846
- ct: (0, import_utils6.base64urlEncode)(ciphertext),
2847
- tag: (0, import_utils6.base64urlEncode)(tag)
2820
+ iv: (0, import_utils7.base64urlEncode)(iv),
2821
+ ct: (0, import_utils7.base64urlEncode)(ciphertext),
2822
+ tag: (0, import_utils7.base64urlEncode)(tag)
2848
2823
  };
2849
2824
  }
2850
2825
  /**
@@ -2864,11 +2839,11 @@ var VaultEncryption = class {
2864
2839
  throw new Error("Invalid encrypted data format");
2865
2840
  }
2866
2841
  const { iv, ct, tag } = parsed.data;
2867
- const ivBuffer = (0, import_utils6.base64urlDecode)(iv);
2868
- const ciphertext = (0, import_utils6.base64urlDecode)(ct);
2869
- const tagBuffer = (0, import_utils6.base64urlDecode)(tag);
2842
+ const ivBuffer = (0, import_utils7.base64urlDecode)(iv);
2843
+ const ciphertext = (0, import_utils7.base64urlDecode)(ct);
2844
+ const tagBuffer = (0, import_utils7.base64urlDecode)(tag);
2870
2845
  try {
2871
- const plaintext = await (0, import_utils6.decryptAesGcm)(key, ciphertext, ivBuffer, tagBuffer);
2846
+ const plaintext = await (0, import_utils7.decryptAesGcm)(key, ciphertext, ivBuffer, tagBuffer);
2872
2847
  return new TextDecoder().decode(plaintext);
2873
2848
  } catch (_error) {
2874
2849
  throw new Error("Decryption failed: invalid key or corrupted data");
@@ -3008,7 +2983,7 @@ var SessionCredentialVault = class {
3008
2983
  * it expires via TTL when configured.
3009
2984
  */
3010
2985
  async rotateVault(sub) {
3011
- const vaultId = (0, import_utils7.randomUUID)();
2986
+ const vaultId = (0, import_utils8.randomUUID)();
3012
2987
  await this.storage.set(this.indexKey(sub), vaultId, this.credentialSetOpts);
3013
2988
  return vaultId;
3014
2989
  }
@@ -3157,19 +3132,19 @@ var SessionCredentialVault = class {
3157
3132
  }
3158
3133
  };
3159
3134
  function resolveVaultPepper(logger) {
3160
- const fromEnv = (0, import_utils7.getEnv)("VAULT_SECRET") ?? (0, import_utils7.getEnv)("JWT_SECRET");
3135
+ const fromEnv = (0, import_utils8.getEnv)("VAULT_SECRET") ?? (0, import_utils8.getEnv)("JWT_SECRET");
3161
3136
  if (fromEnv && fromEnv.trim().length > 0) return fromEnv;
3162
3137
  logger.warn(
3163
3138
  "SessionCredentialVault: neither VAULT_SECRET nor JWT_SECRET is set; using a random per-process pepper. Stored credentials will NOT survive a restart and cannot be shared across instances. Set VAULT_SECRET (or JWT_SECRET) for persistent, multi-instance credential storage."
3164
3139
  );
3165
- return (0, import_utils7.randomUUID)() + (0, import_utils7.randomUUID)();
3140
+ return (0, import_utils8.randomUUID)() + (0, import_utils8.randomUUID)();
3166
3141
  }
3167
3142
  function errMsg(err) {
3168
3143
  return err instanceof Error ? err.message : String(err);
3169
3144
  }
3170
3145
 
3171
3146
  // libs/auth/src/session/token-storage.factory.ts
3172
- var import_utils8 = require("@frontmcp/utils");
3147
+ var import_utils9 = require("@frontmcp/utils");
3173
3148
  function isRedisTokenStorage(config) {
3174
3149
  return typeof config === "object" && config !== null && "redis" in config && !!config.redis;
3175
3150
  }
@@ -3181,7 +3156,7 @@ function isPersistentTokenStorage(config) {
3181
3156
  }
3182
3157
  async function createTokenStorageAdapter(config) {
3183
3158
  if (config === void 0 || config === "memory") {
3184
- const adapter = new import_utils8.MemoryStorageAdapter();
3159
+ const adapter = new import_utils9.MemoryStorageAdapter();
3185
3160
  await adapter.connect();
3186
3161
  return adapter;
3187
3162
  }
@@ -3198,14 +3173,14 @@ async function createTokenStorageAdapter(config) {
3198
3173
  }
3199
3174
  if (isRedisTokenStorage(config)) {
3200
3175
  const { host, port, password, db, tls, keyPrefix } = config.redis;
3201
- const adapter = new import_utils8.RedisStorageAdapter({
3176
+ const adapter = new import_utils9.RedisStorageAdapter({
3202
3177
  config: { host, port, password, db, tls },
3203
3178
  keyPrefix: keyPrefix ?? ""
3204
3179
  });
3205
3180
  await adapter.connect();
3206
3181
  return adapter;
3207
3182
  }
3208
- const fallback = new import_utils8.MemoryStorageAdapter();
3183
+ const fallback = new import_utils9.MemoryStorageAdapter();
3209
3184
  await fallback.connect();
3210
3185
  return fallback;
3211
3186
  }
@@ -3225,7 +3200,7 @@ async function createSessionCredentialVault(options) {
3225
3200
  }
3226
3201
 
3227
3202
  // libs/auth/src/session/credential-resume-link.ts
3228
- var import_utils9 = require("@frontmcp/utils");
3203
+ var import_utils10 = require("@frontmcp/utils");
3229
3204
  var DEFAULT_RESUME_TTL_MS = 6e5;
3230
3205
  function signCredentialResumeToken(input, secret) {
3231
3206
  const payload = {
@@ -3234,7 +3209,7 @@ function signCredentialResumeToken(input, secret) {
3234
3209
  ...input.context !== void 0 ? { context: input.context } : {},
3235
3210
  exp: Date.now() + (input.ttlMs ?? DEFAULT_RESUME_TTL_MS)
3236
3211
  };
3237
- const signedJson = (0, import_utils9.signData)(payload, { secret });
3212
+ const signedJson = (0, import_utils10.signData)(payload, { secret });
3238
3213
  return Buffer.from(signedJson, "utf8").toString("base64url");
3239
3214
  }
3240
3215
  function verifyCredentialResumeToken(token, secret, now = Date.now()) {
@@ -3244,7 +3219,7 @@ function verifyCredentialResumeToken(token, secret, now = Date.now()) {
3244
3219
  } catch {
3245
3220
  return null;
3246
3221
  }
3247
- const payload = (0, import_utils9.verifyData)(signedJson, { secret });
3222
+ const payload = (0, import_utils10.verifyData)(signedJson, { secret });
3248
3223
  if (!payload) return null;
3249
3224
  if (typeof payload.sub !== "string" || typeof payload.key !== "string" || !Number.isFinite(payload.exp)) {
3250
3225
  return null;
@@ -3263,7 +3238,7 @@ function buildCredentialResumeUrl(basePath, token) {
3263
3238
  }
3264
3239
 
3265
3240
  // libs/auth/src/session/incremental-auth-ticket.ts
3266
- var import_utils10 = require("@frontmcp/utils");
3241
+ var import_utils11 = require("@frontmcp/utils");
3267
3242
  var DEFAULT_INCREMENTAL_TICKET_TTL_MS = 3e5;
3268
3243
  function signIncrementalAuthTicket(input, secret) {
3269
3244
  const payload = {
@@ -3271,10 +3246,10 @@ function signIncrementalAuthTicket(input, secret) {
3271
3246
  appId: input.appId,
3272
3247
  ...input.toolId !== void 0 ? { toolId: input.toolId } : {},
3273
3248
  ...input.priorAppIds !== void 0 ? { priorAppIds: input.priorAppIds } : {},
3274
- jti: (0, import_utils10.randomUUID)(),
3249
+ jti: (0, import_utils11.randomUUID)(),
3275
3250
  exp: Date.now() + (input.ttlMs ?? DEFAULT_INCREMENTAL_TICKET_TTL_MS)
3276
3251
  };
3277
- const signedJson = (0, import_utils10.signData)(payload, { secret });
3252
+ const signedJson = (0, import_utils11.signData)(payload, { secret });
3278
3253
  return Buffer.from(signedJson, "utf8").toString("base64url");
3279
3254
  }
3280
3255
  function verifyIncrementalAuthTicket(token, secret, now = Date.now()) {
@@ -3284,7 +3259,7 @@ function verifyIncrementalAuthTicket(token, secret, now = Date.now()) {
3284
3259
  } catch {
3285
3260
  return null;
3286
3261
  }
3287
- const payload = (0, import_utils10.verifyData)(signedJson, { secret });
3262
+ const payload = (0, import_utils11.verifyData)(signedJson, { secret });
3288
3263
  if (!payload) return null;
3289
3264
  if (typeof payload.sub !== "string" || payload.sub.length === 0) return null;
3290
3265
  if (typeof payload.appId !== "string" || payload.appId.length === 0) return null;
@@ -3464,7 +3439,7 @@ function errMsg2(err) {
3464
3439
  var SECURE_STORE_ACCESSOR = /* @__PURE__ */ Symbol.for("frontmcp:SECURE_STORE_ACCESSOR");
3465
3440
 
3466
3441
  // libs/auth/src/session/secure-store-accessor.impl.ts
3467
- var import_utils11 = require("@frontmcp/utils");
3442
+ var import_utils12 = require("@frontmcp/utils");
3468
3443
  var GLOBAL_NAMESPACE = "global";
3469
3444
  var SecureStoreAccessorImpl = class {
3470
3445
  backend;
@@ -3493,12 +3468,12 @@ var SecureStoreAccessorImpl = class {
3493
3468
  return GLOBAL_NAMESPACE;
3494
3469
  case "session": {
3495
3470
  const sid = this.resolveSessionId();
3496
- return sid ? `s:${(0, import_utils11.sha256Hex)(sid).slice(0, 32)}` : void 0;
3471
+ return sid ? `s:${(0, import_utils12.sha256Hex)(sid).slice(0, 32)}` : void 0;
3497
3472
  }
3498
3473
  case "user":
3499
3474
  default: {
3500
3475
  const sub = this.resolveSub();
3501
- return sub ? `u:${(0, import_utils11.sha256Hex)(sub).slice(0, 32)}` : void 0;
3476
+ return sub ? `u:${(0, import_utils12.sha256Hex)(sub).slice(0, 32)}` : void 0;
3502
3477
  }
3503
3478
  }
3504
3479
  }
@@ -3539,7 +3514,7 @@ function errMsg3(err) {
3539
3514
  }
3540
3515
 
3541
3516
  // libs/auth/src/session/secure-store.factory.ts
3542
- var import_utils12 = require("@frontmcp/utils");
3517
+ var import_utils13 = require("@frontmcp/utils");
3543
3518
  function isCustomBackendConfig(config) {
3544
3519
  return typeof config === "object" && config !== null && "backend" in config && !!config.backend;
3545
3520
  }
@@ -3588,7 +3563,7 @@ async function createSecureStore(options) {
3588
3563
  if (storage) {
3589
3564
  adapter = storage;
3590
3565
  } else if (kind === "memory") {
3591
- adapter = new import_utils12.MemoryStorageAdapter();
3566
+ adapter = new import_utils13.MemoryStorageAdapter();
3592
3567
  await adapter.connect();
3593
3568
  } else {
3594
3569
  adapter = await createTokenStorageAdapter(toTokenStorageConfig(config));
@@ -3602,7 +3577,7 @@ async function createSecureStore(options) {
3602
3577
  }
3603
3578
 
3604
3579
  // libs/auth/src/session/token.vault.ts
3605
- var import_utils13 = require("@frontmcp/utils");
3580
+ var import_utils14 = require("@frontmcp/utils");
3606
3581
  var TokenVault = class {
3607
3582
  /** Active key used for new encryptions */
3608
3583
  active;
@@ -3631,14 +3606,14 @@ var TokenVault = class {
3631
3606
  this.keys.set(k.kid, k.key);
3632
3607
  }
3633
3608
  async encrypt(plaintext, opts) {
3634
- const iv = (0, import_utils13.randomBytes)(12);
3635
- const { ciphertext, tag } = await (0, import_utils13.encryptAesGcm)(this.active.key, new TextEncoder().encode(plaintext), iv);
3609
+ const iv = (0, import_utils14.randomBytes)(12);
3610
+ const { ciphertext, tag } = await (0, import_utils14.encryptAesGcm)(this.active.key, new TextEncoder().encode(plaintext), iv);
3636
3611
  return {
3637
3612
  alg: "A256GCM",
3638
3613
  kid: this.active.kid,
3639
- iv: (0, import_utils13.base64urlEncode)(iv),
3640
- tag: (0, import_utils13.base64urlEncode)(tag),
3641
- data: (0, import_utils13.base64urlEncode)(ciphertext),
3614
+ iv: (0, import_utils14.base64urlEncode)(iv),
3615
+ tag: (0, import_utils14.base64urlEncode)(tag),
3616
+ data: (0, import_utils14.base64urlEncode)(ciphertext),
3642
3617
  exp: opts?.exp,
3643
3618
  meta: opts?.meta
3644
3619
  };
@@ -3652,16 +3627,16 @@ var TokenVault = class {
3652
3627
  }
3653
3628
  const key = this.keys.get(blob.kid);
3654
3629
  if (!key) throw new Error(`vault_unknown_kid:${blob.kid}`);
3655
- const iv = (0, import_utils13.base64urlDecode)(blob.iv);
3656
- const tag = (0, import_utils13.base64urlDecode)(blob.tag);
3657
- const data = (0, import_utils13.base64urlDecode)(blob.data);
3658
- const plaintext = await (0, import_utils13.decryptAesGcm)(key, data, iv, tag);
3630
+ const iv = (0, import_utils14.base64urlDecode)(blob.iv);
3631
+ const tag = (0, import_utils14.base64urlDecode)(blob.tag);
3632
+ const data = (0, import_utils14.base64urlDecode)(blob.data);
3633
+ const plaintext = await (0, import_utils14.decryptAesGcm)(key, data, iv, tag);
3659
3634
  return new TextDecoder().decode(plaintext);
3660
3635
  }
3661
3636
  };
3662
3637
 
3663
3638
  // libs/auth/src/session/index.ts
3664
- var import_utils33 = require("@frontmcp/utils");
3639
+ var import_utils34 = require("@frontmcp/utils");
3665
3640
 
3666
3641
  // libs/auth/src/session/transport-session.types.ts
3667
3642
  var import_lazy_zod4 = require("@frontmcp/lazy-zod");
@@ -3757,10 +3732,10 @@ var redisConfigSchema = import_lazy_zod4.z.object({
3757
3732
  });
3758
3733
 
3759
3734
  // libs/auth/src/session/session-crypto.ts
3760
- var import_utils15 = require("@frontmcp/utils");
3735
+ var import_utils16 = require("@frontmcp/utils");
3761
3736
 
3762
3737
  // libs/auth/src/errors/auth-internal.error.ts
3763
- var import_utils14 = require("@frontmcp/utils");
3738
+ var import_utils15 = require("@frontmcp/utils");
3764
3739
  var AuthInternalError = class extends Error {
3765
3740
  /**
3766
3741
  * Unique error ID for tracking in logs.
@@ -3782,7 +3757,7 @@ var AuthInternalError = class extends Error {
3782
3757
  super(message);
3783
3758
  this.name = this.constructor.name;
3784
3759
  this.code = code;
3785
- this.errorId = `err_${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(8))}`;
3760
+ this.errorId = `err_${(0, import_utils15.bytesToHex)((0, import_utils15.randomBytes)(8))}`;
3786
3761
  Error.captureStackTrace(this, this.constructor);
3787
3762
  }
3788
3763
  /**
@@ -3842,6 +3817,22 @@ var SessionSecretRequiredError = class extends AuthInternalError {
3842
3817
  super(`Session secret is required for ${component}`, "SESSION_SECRET_REQUIRED");
3843
3818
  }
3844
3819
  };
3820
+ var JwtSecretRequiredError = class extends AuthInternalError {
3821
+ constructor(mode) {
3822
+ super(
3823
+ `JWT_SECRET is required in production for auth.mode "${mode}". Without it the server signs tokens with a random per-process secret, so every restart invalidates outstanding tokens and any second instance or isolate rejects tokens the first one minted.`,
3824
+ "JWT_SECRET_REQUIRED"
3825
+ );
3826
+ }
3827
+ };
3828
+ var JwtSecretWeakError = class extends AuthInternalError {
3829
+ constructor(byteLength) {
3830
+ super(
3831
+ `JWT_SECRET is ${byteLength} bytes; HS256 requires at least 32 (RFC 7518 \xA73.2). A shorter secret is guessable, and whoever guesses it can forge tokens for this server. Generate one with \`openssl rand -hex 32\`.`,
3832
+ "JWT_SECRET_INVALID"
3833
+ );
3834
+ }
3835
+ };
3845
3836
  var CredentialProviderAlreadyRegisteredError = class extends AuthInternalError {
3846
3837
  constructor(name) {
3847
3838
  super(`Credential provider "${name}" is already registered`, "CREDENTIAL_PROVIDER_ALREADY_REGISTERED");
@@ -3905,9 +3896,9 @@ var AuthFlowError = class extends AuthInternalError {
3905
3896
 
3906
3897
  // libs/auth/src/session/session-crypto.ts
3907
3898
  function getSigningSecret(config) {
3908
- const secret = config?.secret || (0, import_utils15.getEnv)("MCP_SESSION_SECRET");
3899
+ const secret = config?.secret || (0, import_utils16.getEnv)("MCP_SESSION_SECRET");
3909
3900
  if (!secret) {
3910
- if ((0, import_utils15.isProduction)()) {
3901
+ if ((0, import_utils16.isProduction)()) {
3911
3902
  throw new SessionSecretRequiredError("session signing");
3912
3903
  }
3913
3904
  console.warn("[SessionCrypto] MCP_SESSION_SECRET not set. Using insecure default for development only.");
@@ -3919,13 +3910,13 @@ function resolveConfig(config) {
3919
3910
  return { secret: getSigningSecret(config) };
3920
3911
  }
3921
3912
  function signSession(session, config) {
3922
- return (0, import_utils15.signData)(session, resolveConfig(config));
3913
+ return (0, import_utils16.signData)(session, resolveConfig(config));
3923
3914
  }
3924
3915
  function verifySession(signedData, config) {
3925
- return (0, import_utils15.verifyData)(signedData, resolveConfig(config));
3916
+ return (0, import_utils16.verifyData)(signedData, resolveConfig(config));
3926
3917
  }
3927
3918
  function verifyOrParseSession(data, config) {
3928
- return (0, import_utils15.verifyOrParseData)(data, resolveConfig(config));
3919
+ return (0, import_utils16.verifyOrParseData)(data, resolveConfig(config));
3929
3920
  }
3930
3921
 
3931
3922
  // libs/auth/src/session/session-rate-limiter.ts
@@ -4052,7 +4043,7 @@ var SessionRateLimiter = class {
4052
4043
  var defaultSessionRateLimiter = new SessionRateLimiter();
4053
4044
 
4054
4045
  // libs/auth/src/session/session.transport.ts
4055
- var import_utils16 = require("@frontmcp/utils");
4046
+ var import_utils17 = require("@frontmcp/utils");
4056
4047
  var TransportIdGenerator = class {
4057
4048
  /**
4058
4049
  * Create a transport session ID.
@@ -4061,7 +4052,7 @@ var TransportIdGenerator = class {
4061
4052
  * @returns A transport session ID (UUID without dashes)
4062
4053
  */
4063
4054
  static createId() {
4064
- return (0, import_utils16.randomUUID)().replace(/-/g, "");
4055
+ return (0, import_utils17.randomUUID)().replace(/-/g, "");
4065
4056
  }
4066
4057
  };
4067
4058
 
@@ -4110,7 +4101,7 @@ var TinyTtlCache = class {
4110
4101
  };
4111
4102
 
4112
4103
  // libs/auth/src/session/utils/auth-token.utils.ts
4113
- var import_utils17 = require("@frontmcp/utils");
4104
+ var import_utils18 = require("@frontmcp/utils");
4114
4105
  function isJwt(token) {
4115
4106
  if (!token) return false;
4116
4107
  return token.split(".").length === 3;
@@ -4120,7 +4111,7 @@ function getTokenSignatureFingerprint(token) {
4120
4111
  const sig = token.split(".")[2];
4121
4112
  if (sig) return sig;
4122
4113
  }
4123
- return (0, import_utils17.sha256Base64url)(token);
4114
+ return (0, import_utils18.sha256Base64url)(token);
4124
4115
  }
4125
4116
  function extractClaimValue(claims, key, validator) {
4126
4117
  const value = claims[key];
@@ -4152,26 +4143,26 @@ function extractBearerToken(header) {
4152
4143
  }
4153
4144
 
4154
4145
  // libs/auth/src/session/utils/session-crypto.utils.ts
4155
- var import_utils18 = require("@frontmcp/utils");
4146
+ var import_utils19 = require("@frontmcp/utils");
4156
4147
  var cachedKey = null;
4157
4148
  function getKey() {
4158
4149
  if (cachedKey) return cachedKey;
4159
- const secret = (0, import_utils18.getEnv)("MCP_SESSION_SECRET");
4150
+ const secret = (0, import_utils19.getEnv)("MCP_SESSION_SECRET");
4160
4151
  if (!secret) {
4161
- if ((0, import_utils18.isProduction)()) {
4152
+ if ((0, import_utils19.isProduction)()) {
4162
4153
  throw new SessionSecretRequiredError("session ID encryption");
4163
4154
  }
4164
4155
  console.warn(
4165
4156
  "[SessionIdUtils] Using machine ID as session encryption secret - NOT SECURE FOR PRODUCTION. Set MCP_SESSION_SECRET environment variable for secure session encryption."
4166
4157
  );
4167
4158
  }
4168
- const base = secret || (0, import_utils18.getMachineId)();
4169
- cachedKey = (0, import_utils18.sha256)(new TextEncoder().encode(base));
4159
+ const base = secret || (0, import_utils19.getMachineId)();
4160
+ cachedKey = (0, import_utils19.sha256)(new TextEncoder().encode(base));
4170
4161
  return cachedKey;
4171
4162
  }
4172
4163
  function encryptJson(obj) {
4173
4164
  const key = getKey();
4174
- const encrypted = (0, import_utils18.encryptValue)(obj, key);
4165
+ const encrypted = (0, import_utils19.encryptValue)(obj, key);
4175
4166
  return `${encrypted.iv}.${encrypted.tag}.${encrypted.data}`;
4176
4167
  }
4177
4168
  function decryptSessionJson(sessionId) {
@@ -4180,7 +4171,7 @@ function decryptSessionJson(sessionId) {
4180
4171
  const [ivB64, tagB64, ctB64] = parts;
4181
4172
  if (!ivB64 || !tagB64 || !ctB64) return null;
4182
4173
  const key = getKey();
4183
- return (0, import_utils18.decryptValue)({ alg: "A256GCM", iv: ivB64, tag: tagB64, data: ctB64 }, key);
4174
+ return (0, import_utils19.decryptValue)({ alg: "A256GCM", iv: ivB64, tag: tagB64, data: ctB64 }, key);
4184
4175
  }
4185
4176
  function safeDecrypt(sessionId) {
4186
4177
  try {
@@ -4194,11 +4185,11 @@ function resetCachedKey() {
4194
4185
  }
4195
4186
 
4196
4187
  // libs/auth/src/session/storage/index.ts
4197
- var import_utils22 = require("@frontmcp/utils");
4198
4188
  var import_utils23 = require("@frontmcp/utils");
4189
+ var import_utils24 = require("@frontmcp/utils");
4199
4190
 
4200
4191
  // libs/auth/src/session/storage/storage-token-store.ts
4201
- var import_utils19 = require("@frontmcp/utils");
4192
+ var import_utils20 = require("@frontmcp/utils");
4202
4193
  var StorageTokenStore = class {
4203
4194
  storage;
4204
4195
  namespace;
@@ -4210,13 +4201,13 @@ var StorageTokenStore = class {
4210
4201
  this.defaultTtlSeconds = options.defaultTtlSeconds;
4211
4202
  this.storageIsNamespaced = "namespace" in storage && typeof storage.namespace === "function";
4212
4203
  const namespacedStorage = this.storageIsNamespaced ? storage.namespace(this.namespace) : storage;
4213
- this.storage = new import_utils19.TypedStorage(namespacedStorage);
4204
+ this.storage = new import_utils20.TypedStorage(namespacedStorage);
4214
4205
  }
4215
4206
  /**
4216
4207
  * Allocate a new unique ID for a token record.
4217
4208
  */
4218
4209
  allocId() {
4219
- return (0, import_utils19.randomUUID)();
4210
+ return (0, import_utils20.randomUUID)();
4220
4211
  }
4221
4212
  /**
4222
4213
  * Store an encrypted token blob.
@@ -4279,7 +4270,7 @@ var StorageTokenStore = class {
4279
4270
  };
4280
4271
 
4281
4272
  // libs/auth/src/session/storage/storage-authorization-vault.ts
4282
- var import_utils20 = require("@frontmcp/utils");
4273
+ var import_utils21 = require("@frontmcp/utils");
4283
4274
  var StorageAuthorizationVault = class {
4284
4275
  storage;
4285
4276
  namespace;
@@ -4288,7 +4279,7 @@ var StorageAuthorizationVault = class {
4288
4279
  this.namespace = options.namespace ?? "vault";
4289
4280
  this.pendingAuthTtlMs = options.pendingAuthTtlMs ?? 10 * 60 * 1e3;
4290
4281
  const namespacedStorage = this.isNamespacedStorage(storage) ? storage.namespace(this.namespace) : storage;
4291
- this.storage = new import_utils20.TypedStorage(namespacedStorage, {
4282
+ this.storage = new import_utils21.TypedStorage(namespacedStorage, {
4292
4283
  schema: options.validateOnRead ? authorizationVaultEntrySchema : void 0,
4293
4284
  throwOnInvalid: false
4294
4285
  });
@@ -4299,7 +4290,7 @@ var StorageAuthorizationVault = class {
4299
4290
  async create(params) {
4300
4291
  const now = Date.now();
4301
4292
  const entry = {
4302
- id: (0, import_utils20.randomUUID)(),
4293
+ id: (0, import_utils21.randomUUID)(),
4303
4294
  userSub: params.userSub,
4304
4295
  userEmail: params.userEmail,
4305
4296
  userName: params.userName,
@@ -4373,7 +4364,7 @@ var StorageAuthorizationVault = class {
4373
4364
  }
4374
4365
  const now = Date.now();
4375
4366
  const pendingAuth = {
4376
- id: (0, import_utils20.randomUUID)(),
4367
+ id: (0, import_utils21.randomUUID)(),
4377
4368
  appId: params.appId,
4378
4369
  toolId: params.toolId,
4379
4370
  authUrl: params.authUrl,
@@ -4577,11 +4568,11 @@ var StorageAuthorizationVault = class {
4577
4568
  };
4578
4569
 
4579
4570
  // libs/auth/src/session/storage/in-memory-authorization-vault.ts
4580
- var import_utils21 = require("@frontmcp/utils");
4571
+ var import_utils22 = require("@frontmcp/utils");
4581
4572
  var InMemoryAuthorizationVault = class extends StorageAuthorizationVault {
4582
4573
  memoryAdapter;
4583
4574
  constructor(options = {}) {
4584
- const memoryAdapter = new import_utils21.MemoryStorageAdapter();
4575
+ const memoryAdapter = new import_utils22.MemoryStorageAdapter();
4585
4576
  super(memoryAdapter, {
4586
4577
  namespace: options.namespace ?? "vault",
4587
4578
  pendingAuthTtlMs: options.pendingAuthTtlMs
@@ -4602,7 +4593,7 @@ var InMemoryAuthorizationVault = class extends StorageAuthorizationVault {
4602
4593
  };
4603
4594
 
4604
4595
  // libs/auth/src/session/redis-session.store.ts
4605
- var import_utils24 = require("@frontmcp/utils");
4596
+ var import_utils25 = require("@frontmcp/utils");
4606
4597
  var RedisSessionStore = class {
4607
4598
  storage;
4608
4599
  keyPrefix;
@@ -4624,14 +4615,14 @@ var RedisSessionStore = class {
4624
4615
  });
4625
4616
  }
4626
4617
  if ("redis" in config && config.redis) {
4627
- this.storage = new import_utils24.RedisStorageAdapter({
4618
+ this.storage = new import_utils25.RedisStorageAdapter({
4628
4619
  client: config.redis,
4629
4620
  keyPrefix: this.keyPrefix
4630
4621
  });
4631
4622
  this.externalInstance = true;
4632
4623
  } else {
4633
4624
  const redisConfig = config;
4634
- this.storage = new import_utils24.RedisStorageAdapter({
4625
+ this.storage = new import_utils25.RedisStorageAdapter({
4635
4626
  config: {
4636
4627
  host: redisConfig.host,
4637
4628
  port: redisConfig.port ?? 6379,
@@ -4813,7 +4804,7 @@ var RedisSessionStore = class {
4813
4804
  * Allocate a new session ID
4814
4805
  */
4815
4806
  allocId() {
4816
- return (0, import_utils24.randomUUID)();
4807
+ return (0, import_utils25.randomUUID)();
4817
4808
  }
4818
4809
  /**
4819
4810
  * Disconnect from Redis (only if we created the connection)
@@ -4849,7 +4840,7 @@ var RedisSessionStore = class {
4849
4840
  };
4850
4841
 
4851
4842
  // libs/auth/src/session/vercel-kv-session.store.ts
4852
- var import_utils25 = require("@frontmcp/utils");
4843
+ var import_utils26 = require("@frontmcp/utils");
4853
4844
  var VercelKvSessionStore = class {
4854
4845
  storage;
4855
4846
  keyPrefix;
@@ -4869,7 +4860,7 @@ var VercelKvSessionStore = class {
4869
4860
  maxRequests: this.security.rateLimiting?.maxRequests
4870
4861
  });
4871
4862
  }
4872
- this.storage = new import_utils25.VercelKvStorageAdapter({
4863
+ this.storage = new import_utils26.VercelKvStorageAdapter({
4873
4864
  url: config.url,
4874
4865
  token: config.token,
4875
4866
  keyPrefix: this.keyPrefix
@@ -5043,7 +5034,7 @@ var VercelKvSessionStore = class {
5043
5034
  * Allocate a new session ID
5044
5035
  */
5045
5036
  allocId() {
5046
- return (0, import_utils25.randomUUID)();
5037
+ return (0, import_utils26.randomUUID)();
5047
5038
  }
5048
5039
  /**
5049
5040
  * Disconnect from Vercel KV
@@ -5072,7 +5063,7 @@ var VercelKvSessionStore = class {
5072
5063
  };
5073
5064
 
5074
5065
  // libs/auth/src/session/orchestrated-token.store.ts
5075
- var import_utils26 = require("@frontmcp/utils");
5066
+ var import_utils27 = require("@frontmcp/utils");
5076
5067
  var InMemoryOrchestratedTokenStore = class {
5077
5068
  /** Token storage: Map<compositeKey, ProviderTokenRecord> */
5078
5069
  tokens = /* @__PURE__ */ new Map();
@@ -5114,7 +5105,7 @@ var InMemoryOrchestratedTokenStore = class {
5114
5105
  }
5115
5106
  const info = new TextEncoder().encode(`orchestrated-token:${compositeKey}`);
5116
5107
  const salt = new TextEncoder().encode("frontmcp-token-store");
5117
- const derivedKey = (0, import_utils26.hkdfSha256)(this.encryptionKey, salt, info, 32);
5108
+ const derivedKey = (0, import_utils27.hkdfSha256)(this.encryptionKey, salt, info, 32);
5118
5109
  this.derivedKeys.set(compositeKey, derivedKey);
5119
5110
  return derivedKey;
5120
5111
  }
@@ -5124,8 +5115,8 @@ var InMemoryOrchestratedTokenStore = class {
5124
5115
  async encryptRecord(compositeKey, record) {
5125
5116
  const key = await this.deriveKeyForRecord(compositeKey);
5126
5117
  const plaintext = JSON.stringify(record);
5127
- const iv = (0, import_utils26.randomBytes)(12);
5128
- const { ciphertext, tag } = (0, import_utils26.encryptAesGcm)(key, new TextEncoder().encode(plaintext), iv);
5118
+ const iv = (0, import_utils27.randomBytes)(12);
5119
+ const { ciphertext, tag } = (0, import_utils27.encryptAesGcm)(key, new TextEncoder().encode(plaintext), iv);
5129
5120
  return JSON.stringify({
5130
5121
  iv: Buffer.from(iv).toString("base64url"),
5131
5122
  tag: Buffer.from(tag).toString("base64url"),
@@ -5141,7 +5132,7 @@ var InMemoryOrchestratedTokenStore = class {
5141
5132
  const ivBytes = Buffer.from(iv, "base64url");
5142
5133
  const tagBytes = Buffer.from(tag, "base64url");
5143
5134
  const ciphertextBytes = Buffer.from(data, "base64url");
5144
- const plaintext = (0, import_utils26.decryptAesGcm)(key, ciphertextBytes, ivBytes, tagBytes);
5135
+ const plaintext = (0, import_utils27.decryptAesGcm)(key, ciphertextBytes, ivBytes, tagBytes);
5145
5136
  return JSON.parse(new TextDecoder().decode(plaintext));
5146
5137
  }
5147
5138
  /**
@@ -5343,7 +5334,7 @@ var InMemoryOrchestratedTokenStore = class {
5343
5334
  };
5344
5335
 
5345
5336
  // libs/auth/src/session/orchestrated-token.crypto.ts
5346
- var import_utils27 = require("@frontmcp/utils");
5337
+ var import_utils28 = require("@frontmcp/utils");
5347
5338
  var HKDF_SALT = new TextEncoder().encode("frontmcp-token-store");
5348
5339
  function deriveKeyForRecord(masterKey, compositeKey, cache) {
5349
5340
  const cached = cache.get(compositeKey);
@@ -5351,14 +5342,14 @@ function deriveKeyForRecord(masterKey, compositeKey, cache) {
5351
5342
  return cached;
5352
5343
  }
5353
5344
  const info = new TextEncoder().encode(`orchestrated-token:${compositeKey}`);
5354
- const derived = (0, import_utils27.hkdfSha256)(masterKey, HKDF_SALT, info, 32);
5345
+ const derived = (0, import_utils28.hkdfSha256)(masterKey, HKDF_SALT, info, 32);
5355
5346
  cache.set(compositeKey, derived);
5356
5347
  return derived;
5357
5348
  }
5358
5349
  function encryptRecord(key, record) {
5359
5350
  const plaintext = JSON.stringify(record);
5360
- const iv = (0, import_utils27.randomBytes)(12);
5361
- const { ciphertext, tag } = (0, import_utils27.encryptAesGcm)(key, new TextEncoder().encode(plaintext), iv);
5351
+ const iv = (0, import_utils28.randomBytes)(12);
5352
+ const { ciphertext, tag } = (0, import_utils28.encryptAesGcm)(key, new TextEncoder().encode(plaintext), iv);
5362
5353
  return JSON.stringify({
5363
5354
  iv: Buffer.from(iv).toString("base64url"),
5364
5355
  tag: Buffer.from(tag).toString("base64url"),
@@ -5370,7 +5361,7 @@ function decryptRecord(key, encrypted) {
5370
5361
  const ivBytes = Buffer.from(iv, "base64url");
5371
5362
  const tagBytes = Buffer.from(tag, "base64url");
5372
5363
  const ciphertextBytes = Buffer.from(data, "base64url");
5373
- const plaintext = (0, import_utils27.decryptAesGcm)(key, ciphertextBytes, ivBytes, tagBytes);
5364
+ const plaintext = (0, import_utils28.decryptAesGcm)(key, ciphertextBytes, ivBytes, tagBytes);
5374
5365
  return JSON.parse(new TextDecoder().decode(plaintext));
5375
5366
  }
5376
5367
 
@@ -5549,7 +5540,7 @@ var StorageOrchestratedTokenStore = class {
5549
5540
  };
5550
5541
 
5551
5542
  // libs/auth/src/session/federated-auth.session.ts
5552
- var import_utils28 = require("@frontmcp/utils");
5543
+ var import_utils29 = require("@frontmcp/utils");
5553
5544
  function toSessionRecord(session) {
5554
5545
  return {
5555
5546
  ...session,
@@ -5624,7 +5615,7 @@ var InMemoryFederatedAuthSessionStore = class {
5624
5615
  createSession(params) {
5625
5616
  const now = Date.now();
5626
5617
  return {
5627
- id: (0, import_utils28.randomUUID)(),
5618
+ id: (0, import_utils29.randomUUID)(),
5628
5619
  pendingAuthId: params.pendingAuthId,
5629
5620
  clientId: params.clientId,
5630
5621
  redirectUri: params.redirectUri,
@@ -5656,7 +5647,7 @@ var InMemoryFederatedAuthSessionStore = class {
5656
5647
  function createFederatedAuthSession(params, ttlMs = 15 * 60 * 1e3) {
5657
5648
  const now = Date.now();
5658
5649
  return {
5659
- id: (0, import_utils28.randomUUID)(),
5650
+ id: (0, import_utils29.randomUUID)(),
5660
5651
  pendingAuthId: params.pendingAuthId,
5661
5652
  clientId: params.clientId,
5662
5653
  redirectUri: params.redirectUri,
@@ -5713,7 +5704,7 @@ function startNextProvider(session, pkce, state) {
5713
5704
  }
5714
5705
 
5715
5706
  // libs/auth/src/session/storage-federated-auth.session.ts
5716
- var import_utils29 = require("@frontmcp/utils");
5707
+ var import_utils30 = require("@frontmcp/utils");
5717
5708
  var StorageFederatedAuthSessionStore = class {
5718
5709
  storage;
5719
5710
  namespace;
@@ -5722,7 +5713,7 @@ var StorageFederatedAuthSessionStore = class {
5722
5713
  this.namespace = options.namespace ?? "fed";
5723
5714
  this.storageIsNamespaced = this.isNamespacedStorage(storage);
5724
5715
  const namespacedStorage = this.storageIsNamespaced ? storage.namespace(this.namespace) : storage;
5725
- this.storage = new import_utils29.TypedStorage(namespacedStorage);
5716
+ this.storage = new import_utils30.TypedStorage(namespacedStorage);
5726
5717
  }
5727
5718
  async store(session) {
5728
5719
  await this.put(session);
@@ -5793,7 +5784,7 @@ var InMemoryConsentStore = class {
5793
5784
  };
5794
5785
 
5795
5786
  // libs/auth/src/session/storage-consent.store.ts
5796
- var import_utils30 = require("@frontmcp/utils");
5787
+ var import_utils31 = require("@frontmcp/utils");
5797
5788
  var StorageConsentStore = class {
5798
5789
  storage;
5799
5790
  namespace;
@@ -5802,7 +5793,7 @@ var StorageConsentStore = class {
5802
5793
  this.namespace = options.namespace ?? "remembered-consent";
5803
5794
  this.storageIsNamespaced = this.isNamespacedStorage(storage);
5804
5795
  const namespacedStorage = this.storageIsNamespaced ? storage.namespace(this.namespace) : storage;
5805
- this.storage = new import_utils30.TypedStorage(namespacedStorage);
5796
+ this.storage = new import_utils31.TypedStorage(namespacedStorage);
5806
5797
  }
5807
5798
  async get(userSub, clientId) {
5808
5799
  return this.storage.get(this.key(userSub, clientId));
@@ -5824,7 +5815,7 @@ var StorageConsentStore = class {
5824
5815
 
5825
5816
  // libs/auth/src/session/encrypted-authorization-vault.ts
5826
5817
  var import_lazy_zod5 = require("@frontmcp/lazy-zod");
5827
- var import_utils31 = require("@frontmcp/utils");
5818
+ var import_utils32 = require("@frontmcp/utils");
5828
5819
  var redisVaultEntrySchema = import_lazy_zod5.z.object({
5829
5820
  /** Vault ID */
5830
5821
  id: import_lazy_zod5.z.string(),
@@ -5849,7 +5840,7 @@ var redisVaultEntrySchema = import_lazy_zod5.z.object({
5849
5840
  /** Encrypted sensitive data blob */
5850
5841
  encrypted: encryptedDataSchema
5851
5842
  });
5852
- var encryptionContextStorage = new import_utils31.AsyncLocalStorage();
5843
+ var encryptionContextStorage = new import_utils32.AsyncLocalStorage();
5853
5844
  var EncryptedRedisVault = class {
5854
5845
  constructor(redis, encryption, namespace = "vault:") {
5855
5846
  this.redis = redis;
@@ -5985,7 +5976,7 @@ var EncryptedRedisVault = class {
5985
5976
  async create(params) {
5986
5977
  const now = Date.now();
5987
5978
  const entry = {
5988
- id: (0, import_utils31.randomUUID)(),
5979
+ id: (0, import_utils32.randomUUID)(),
5989
5980
  userSub: params.userSub,
5990
5981
  userEmail: params.userEmail,
5991
5982
  userName: params.userName,
@@ -6044,7 +6035,7 @@ var EncryptedRedisVault = class {
6044
6035
  }
6045
6036
  const now = Date.now();
6046
6037
  const pendingAuth = {
6047
- id: (0, import_utils31.randomUUID)(),
6038
+ id: (0, import_utils32.randomUUID)(),
6048
6039
  appId: params.appId,
6049
6040
  toolId: params.toolId,
6050
6041
  authUrl: params.authUrl,
@@ -6222,7 +6213,7 @@ function createEncryptedVault(redis, config = {}) {
6222
6213
  }
6223
6214
 
6224
6215
  // libs/auth/src/session/token.refresh.ts
6225
- var import_utils32 = require("@frontmcp/utils");
6216
+ var import_utils33 = require("@frontmcp/utils");
6226
6217
  function toEpochSeconds(exp) {
6227
6218
  if (exp == null) return void 0;
6228
6219
  if (exp instanceof Date) return Math.floor(exp.getTime() / 1e3);
@@ -6244,7 +6235,7 @@ function tryJwtExp(token) {
6244
6235
  const parts = token.split(".");
6245
6236
  if (parts.length < 2) return void 0;
6246
6237
  try {
6247
- const json = JSON.parse(new TextDecoder().decode((0, import_utils32.base64urlDecode)(parts[1])));
6238
+ const json = JSON.parse(new TextDecoder().decode((0, import_utils33.base64urlDecode)(parts[1])));
6248
6239
  const e = json?.exp;
6249
6240
  return typeof e === "number" ? toEpochSeconds(e) : void 0;
6250
6241
  } catch {
@@ -6307,7 +6298,7 @@ var progressiveAuthStateSchema = import_lazy_zod6.z.object({
6307
6298
  });
6308
6299
 
6309
6300
  // libs/auth/src/authorization/authorization.class.ts
6310
- var import_utils35 = require("@frontmcp/utils");
6301
+ var import_utils36 = require("@frontmcp/utils");
6311
6302
  var AuthorizationBase = class _AuthorizationBase {
6312
6303
  id;
6313
6304
  isAnonymous;
@@ -6355,14 +6346,14 @@ var AuthorizationBase = class _AuthorizationBase {
6355
6346
  * @param fingerprint - Optional client fingerprint for tracking
6356
6347
  */
6357
6348
  createTransportSession(protocol, fingerprint) {
6358
- const sessionId = (0, import_utils35.randomUUID)();
6349
+ const sessionId = (0, import_utils36.randomUUID)();
6359
6350
  const session = {
6360
6351
  id: sessionId,
6361
6352
  authorizationId: this.id,
6362
6353
  protocol,
6363
6354
  createdAt: Date.now(),
6364
6355
  expiresAt: this.expiresAt,
6365
- nodeId: (0, import_utils35.getMachineId)(),
6356
+ nodeId: (0, import_utils36.getMachineId)(),
6366
6357
  clientFingerprint: fingerprint
6367
6358
  };
6368
6359
  this.#sessions.set(session.id, session);
@@ -6503,7 +6494,7 @@ var AuthorizationBase = class _AuthorizationBase {
6503
6494
  */
6504
6495
  static isJwtHeader(segment) {
6505
6496
  try {
6506
- const bytes = (0, import_utils35.base64urlDecode)(segment);
6497
+ const bytes = (0, import_utils36.base64urlDecode)(segment);
6507
6498
  const text = new TextDecoder().decode(bytes);
6508
6499
  const parsed = JSON.parse(text);
6509
6500
  return typeof parsed === "object" && parsed !== null && typeof parsed.alg === "string";
@@ -6555,7 +6546,7 @@ var AuthorizationBase = class _AuthorizationBase {
6555
6546
  };
6556
6547
 
6557
6548
  // libs/auth/src/authorization/public.authorization.ts
6558
- var import_utils36 = require("@frontmcp/utils");
6549
+ var import_utils37 = require("@frontmcp/utils");
6559
6550
  var PublicAuthorization = class _PublicAuthorization extends AuthorizationBase {
6560
6551
  mode = "public";
6561
6552
  /**
@@ -6591,7 +6582,7 @@ var PublicAuthorization = class _PublicAuthorization extends AuthorizationBase {
6591
6582
  allowedTools = "all",
6592
6583
  allowedPrompts = "all"
6593
6584
  } = ctx;
6594
- const uuid = (0, import_utils36.randomUUID)();
6585
+ const uuid = (0, import_utils37.randomUUID)();
6595
6586
  const sub = `${prefix}:${uuid}`;
6596
6587
  const user = {
6597
6588
  sub,
@@ -6675,7 +6666,7 @@ var PublicAuthorization = class _PublicAuthorization extends AuthorizationBase {
6675
6666
  };
6676
6667
 
6677
6668
  // libs/auth/src/authorization/transparent.authorization.ts
6678
- var import_utils37 = require("@frontmcp/utils");
6669
+ var import_utils38 = require("@frontmcp/utils");
6679
6670
  var TransparentAuthorization = class _TransparentAuthorization extends AuthorizationBase {
6680
6671
  mode = "transparent";
6681
6672
  /**
@@ -6775,7 +6766,7 @@ var TransparentAuthorization = class _TransparentAuthorization extends Authoriza
6775
6766
  static generateAuthorizationId(token) {
6776
6767
  const parts = token.split(".");
6777
6768
  const signature = parts[2] || token;
6778
- return (0, import_utils37.sha256Hex)(signature).substring(0, 16);
6769
+ return (0, import_utils38.sha256Hex)(signature).substring(0, 16);
6779
6770
  }
6780
6771
  /**
6781
6772
  * Get the issuer from the token claims
@@ -6801,11 +6792,11 @@ var TransparentAuthorization = class _TransparentAuthorization extends Authoriza
6801
6792
  };
6802
6793
 
6803
6794
  // libs/auth/src/utils/authorization-id.utils.ts
6804
- var import_utils38 = require("@frontmcp/utils");
6795
+ var import_utils39 = require("@frontmcp/utils");
6805
6796
  function deriveAuthorizationId(token) {
6806
6797
  const parts = token.split(".");
6807
6798
  const signature = parts[2] || token;
6808
- return (0, import_utils38.sha256Hex)(signature).substring(0, 16);
6799
+ return (0, import_utils39.sha256Hex)(signature).substring(0, 16);
6809
6800
  }
6810
6801
 
6811
6802
  // libs/auth/src/authorization/orchestrated.authorization.ts
@@ -7174,7 +7165,7 @@ var OrchestratedAuthAccessorAdapter = class {
7174
7165
  };
7175
7166
 
7176
7167
  // libs/auth/src/authorization/dcr-client.registry.ts
7177
- var import_utils39 = require("@frontmcp/utils");
7168
+ var import_utils40 = require("@frontmcp/utils");
7178
7169
  var DEFAULT_MAX_DYNAMIC_CLIENTS = 1e3;
7179
7170
  function globMatch(pattern, input) {
7180
7171
  let p = 0;
@@ -7300,7 +7291,7 @@ var DcrClientRegistry = class {
7300
7291
  if (!isConfidential) return "ok";
7301
7292
  if (!client.client_secret) return "invalid";
7302
7293
  if (!presentedSecret) return "invalid";
7303
- return (0, import_utils39.timingSafeEqual)((0, import_utils39.sha256)(presentedSecret), (0, import_utils39.sha256)(client.client_secret)) ? "ok" : "invalid";
7294
+ return (0, import_utils40.timingSafeEqual)((0, import_utils40.sha256)(presentedSecret), (0, import_utils40.sha256)(client.client_secret)) ? "ok" : "invalid";
7304
7295
  }
7305
7296
  /** Whether a client id is known to the registry. */
7306
7297
  has(clientId) {
@@ -7388,7 +7379,7 @@ var DcrClientRegistry = class {
7388
7379
  if (typeof presented !== "string" || presented.length === 0) {
7389
7380
  return false;
7390
7381
  }
7391
- return (0, import_utils39.timingSafeEqual)((0, import_utils39.sha256)(presented), (0, import_utils39.sha256)(expected));
7382
+ return (0, import_utils40.timingSafeEqual)((0, import_utils40.sha256)(presented), (0, import_utils40.sha256)(expected));
7392
7383
  }
7393
7384
  };
7394
7385
 
@@ -7717,6 +7708,7 @@ var cimdConfigSchema = import_lazy_zod9.z.object({
7717
7708
  init_cimd_cache();
7718
7709
 
7719
7710
  // libs/auth/src/cimd/cimd.service.ts
7711
+ var import_utils41 = require("@frontmcp/utils");
7720
7712
  init_cimd_cache();
7721
7713
  var CimdService = class {
7722
7714
  config;
@@ -7891,7 +7883,7 @@ var CimdService = class {
7891
7883
  httpStatus: 304
7892
7884
  });
7893
7885
  }
7894
- if (response.status >= 300 && response.status < 400) {
7886
+ if ((0, import_utils41.isRedirectResponse)(response)) {
7895
7887
  const location = response.headers.get("location");
7896
7888
  if (!location) {
7897
7889
  throw new CimdFetchError(clientId, "Redirect response missing Location header", {
@@ -8508,10 +8500,48 @@ var publicAuthOptionsSchema = import_lazy_zod11.z.object({
8508
8500
  signKey: jwkSchema.or(import_lazy_zod11.z.instanceof(Uint8Array)).optional()
8509
8501
  });
8510
8502
 
8511
- // libs/auth/src/options/transparent.schema.ts
8503
+ // libs/auth/src/options/static.schema.ts
8512
8504
  var import_lazy_zod12 = require("@frontmcp/lazy-zod");
8513
- var transparentAuthOptionsSchema = import_lazy_zod12.z.object({
8514
- mode: import_lazy_zod12.z.literal("transparent"),
8505
+ var staticAuthOptionsSchema = import_lazy_zod12.z.object({
8506
+ mode: import_lazy_zod12.z.literal("static"),
8507
+ /**
8508
+ * Accepted credentials. Compared against the presented one in constant time,
8509
+ * over SHA-256 digests so neither the value nor its length leaks by timing.
8510
+ *
8511
+ * Read these from the environment — never commit them.
8512
+ */
8513
+ tokens: import_lazy_zod12.z.array(import_lazy_zod12.z.string().min(1)).min(1),
8514
+ /**
8515
+ * Request header carrying the credential.
8516
+ * @default 'authorization'
8517
+ */
8518
+ header: import_lazy_zod12.z.string().min(1).default("authorization"),
8519
+ /**
8520
+ * Scheme prefix to strip before comparing, matched case-insensitively. Set to
8521
+ * an empty string for headers that carry a bare token (e.g. `x-api-key`).
8522
+ * @default 'Bearer'
8523
+ */
8524
+ scheme: import_lazy_zod12.z.string().default("Bearer"),
8525
+ /**
8526
+ * Scopes granted to a request that presents a valid token.
8527
+ * @default ['static']
8528
+ */
8529
+ scopes: import_lazy_zod12.z.array(import_lazy_zod12.z.string()).default(["static"]),
8530
+ /**
8531
+ * Realm reported in the `WWW-Authenticate` challenge on failure.
8532
+ * @default 'mcp'
8533
+ */
8534
+ realm: import_lazy_zod12.z.string().default("mcp"),
8535
+ /**
8536
+ * Tool/prompt access configuration, same shape the other modes accept.
8537
+ */
8538
+ publicAccess: publicAccessConfigSchema.optional()
8539
+ });
8540
+
8541
+ // libs/auth/src/options/transparent.schema.ts
8542
+ var import_lazy_zod13 = require("@frontmcp/lazy-zod");
8543
+ var transparentAuthOptionsSchema = import_lazy_zod13.z.object({
8544
+ mode: import_lazy_zod13.z.literal("transparent"),
8515
8545
  /**
8516
8546
  * Flattened remote provider fields (provider, clientId, clientSecret, scopes, providerConfig)
8517
8547
  */
@@ -8520,28 +8550,28 @@ var transparentAuthOptionsSchema = import_lazy_zod12.z.object({
8520
8550
  * Expected token audience
8521
8551
  * If not set, defaults to the resource URL
8522
8552
  */
8523
- expectedAudience: import_lazy_zod12.z.union([import_lazy_zod12.z.string(), import_lazy_zod12.z.array(import_lazy_zod12.z.string())]).optional(),
8553
+ expectedAudience: import_lazy_zod13.z.union([import_lazy_zod13.z.string(), import_lazy_zod13.z.array(import_lazy_zod13.z.string())]).optional(),
8524
8554
  /**
8525
8555
  * Require an `aud` claim (reject audience-less tokens). Defaults to `false`
8526
8556
  * for IdP compatibility; set `true` to reject tokens with no audience.
8527
8557
  */
8528
- requireAudience: import_lazy_zod12.z.boolean().optional(),
8558
+ requireAudience: import_lazy_zod13.z.boolean().optional(),
8529
8559
  /**
8530
8560
  * Required scopes for access
8531
8561
  * Empty array means any valid token is accepted
8532
8562
  * @default []
8533
8563
  */
8534
- requiredScopes: import_lazy_zod12.z.array(import_lazy_zod12.z.string()).default([]),
8564
+ requiredScopes: import_lazy_zod13.z.array(import_lazy_zod13.z.string()).default([]),
8535
8565
  /**
8536
8566
  * Allow anonymous fallback when no token is provided
8537
8567
  * @default false
8538
8568
  */
8539
- allowAnonymous: import_lazy_zod12.z.boolean().default(false),
8569
+ allowAnonymous: import_lazy_zod13.z.boolean().default(false),
8540
8570
  /**
8541
8571
  * Scopes granted to anonymous sessions (when allowAnonymous=true)
8542
8572
  * @default ['anonymous']
8543
8573
  */
8544
- anonymousScopes: import_lazy_zod12.z.array(import_lazy_zod12.z.string()).default(["anonymous"]),
8574
+ anonymousScopes: import_lazy_zod13.z.array(import_lazy_zod13.z.string()).default(["anonymous"]),
8545
8575
  /**
8546
8576
  * Public access config for anonymous users (when allowAnonymous=true)
8547
8577
  */
@@ -8549,13 +8579,13 @@ var transparentAuthOptionsSchema = import_lazy_zod12.z.object({
8549
8579
  });
8550
8580
 
8551
8581
  // libs/auth/src/options/orchestrated.schema.ts
8552
- var import_lazy_zod13 = require("@frontmcp/lazy-zod");
8553
- var authSlotSchema = import_lazy_zod13.z.enum(["login", "consent", "incremental", "federated", "error"]);
8554
- var authUiMapSchema = import_lazy_zod13.z.partialRecord(authSlotSchema, import_lazy_zod13.z.string().min(1));
8555
- var authExtraHandlerSchema = import_lazy_zod13.z.custom((v) => typeof v === "function", {
8582
+ var import_lazy_zod14 = require("@frontmcp/lazy-zod");
8583
+ var authSlotSchema = import_lazy_zod14.z.enum(["login", "consent", "incremental", "federated", "error"]);
8584
+ var authUiMapSchema = import_lazy_zod14.z.partialRecord(authSlotSchema, import_lazy_zod14.z.string().min(1));
8585
+ var authExtraHandlerSchema = import_lazy_zod14.z.custom((v) => typeof v === "function", {
8556
8586
  message: "auth.extras entries must be handler functions (input, ctx) => AuthExtraResult."
8557
8587
  });
8558
- var authExtrasMapSchema = import_lazy_zod13.z.record(import_lazy_zod13.z.string().min(1), authExtraHandlerSchema);
8588
+ var authExtrasMapSchema = import_lazy_zod14.z.record(import_lazy_zod14.z.string().min(1), authExtraHandlerSchema);
8559
8589
  var sharedAuthFields = {
8560
8590
  local: localSigningConfigSchema.optional(),
8561
8591
  tokenStorage: tokenStorageConfigSchema.default("memory"),
@@ -8563,13 +8593,13 @@ var sharedAuthFields = {
8563
8593
  // Optional (no default) so an unset value resolves to the in-memory encrypted
8564
8594
  // default at runtime; existing configs are unaffected.
8565
8595
  secureStore: secureStoreConfigSchema.optional(),
8566
- allowDefaultPublic: import_lazy_zod13.z.boolean().default(false),
8567
- anonymousScopes: import_lazy_zod13.z.array(import_lazy_zod13.z.string()).default(["anonymous"]),
8596
+ allowDefaultPublic: import_lazy_zod14.z.boolean().default(false),
8597
+ anonymousScopes: import_lazy_zod14.z.array(import_lazy_zod14.z.string()).default(["anonymous"]),
8568
8598
  publicAccess: publicAccessConfigSchema.optional(),
8569
8599
  consent: consentConfigSchema.optional(),
8570
8600
  federatedAuth: federatedAuthConfigSchema.optional(),
8571
8601
  refresh: tokenRefreshConfigSchema.optional(),
8572
- expectedAudience: import_lazy_zod13.z.union([import_lazy_zod13.z.string(), import_lazy_zod13.z.array(import_lazy_zod13.z.string())]).optional(),
8602
+ expectedAudience: import_lazy_zod14.z.union([import_lazy_zod14.z.string(), import_lazy_zod14.z.array(import_lazy_zod14.z.string())]).optional(),
8573
8603
  incrementalAuth: incrementalAuthConfigSchema.optional(),
8574
8604
  /**
8575
8605
  * Require the OAuth client to be KNOWN (registered via DCR / pre-registered,
@@ -8585,46 +8615,46 @@ var sharedAuthFields = {
8585
8615
  * matching for every client. Clients on a configured
8586
8616
  * `dcr.allowedRedirectUris` allowlist still pass.
8587
8617
  */
8588
- requireRegisteredClients: import_lazy_zod13.z.boolean().default(false),
8618
+ requireRegisteredClients: import_lazy_zod14.z.boolean().default(false),
8589
8619
  cimd: cimdConfigSchema.optional(),
8590
8620
  // #469 — custom auth UI as a slot→file map + extras name→handler map (per-app
8591
8621
  // under splitByApp). Both optional; omitting them serves the built-in pages.
8592
8622
  ui: authUiMapSchema.optional(),
8593
8623
  extras: authExtrasMapSchema.optional()
8594
8624
  };
8595
- var loginFieldSchema = import_lazy_zod13.z.object({
8596
- type: import_lazy_zod13.z.enum(["text", "password", "email", "select", "hidden"]),
8597
- label: import_lazy_zod13.z.string().optional(),
8598
- required: import_lazy_zod13.z.boolean().optional(),
8599
- placeholder: import_lazy_zod13.z.string().optional(),
8600
- options: import_lazy_zod13.z.array(import_lazy_zod13.z.object({ value: import_lazy_zod13.z.string(), label: import_lazy_zod13.z.string() })).optional()
8625
+ var loginFieldSchema = import_lazy_zod14.z.object({
8626
+ type: import_lazy_zod14.z.enum(["text", "password", "email", "select", "hidden"]),
8627
+ label: import_lazy_zod14.z.string().optional(),
8628
+ required: import_lazy_zod14.z.boolean().optional(),
8629
+ placeholder: import_lazy_zod14.z.string().optional(),
8630
+ options: import_lazy_zod14.z.array(import_lazy_zod14.z.object({ value: import_lazy_zod14.z.string(), label: import_lazy_zod14.z.string() })).optional()
8601
8631
  });
8602
- var loginConfigSchema = import_lazy_zod13.z.object({
8603
- title: import_lazy_zod13.z.string().optional(),
8604
- subtitle: import_lazy_zod13.z.string().optional(),
8605
- logoUri: import_lazy_zod13.z.string().optional(),
8606
- fields: import_lazy_zod13.z.record(import_lazy_zod13.z.string(), loginFieldSchema).optional(),
8632
+ var loginConfigSchema = import_lazy_zod14.z.object({
8633
+ title: import_lazy_zod14.z.string().optional(),
8634
+ subtitle: import_lazy_zod14.z.string().optional(),
8635
+ logoUri: import_lazy_zod14.z.string().optional(),
8636
+ fields: import_lazy_zod14.z.record(import_lazy_zod14.z.string(), loginFieldSchema).optional(),
8607
8637
  // Full HTML override — a function, validated structurally like other callbacks
8608
8638
  // in the codebase (see http/cors handlers using z.custom<…>).
8609
- render: import_lazy_zod13.z.custom((v) => typeof v === "function", {
8639
+ render: import_lazy_zod14.z.custom((v) => typeof v === "function", {
8610
8640
  message: "login.render must be a function"
8611
8641
  }).optional(),
8612
- subject: import_lazy_zod13.z.object({
8613
- fromField: import_lazy_zod13.z.string().optional(),
8614
- strategy: import_lazy_zod13.z.enum(["per-session", "per-account"]).optional()
8642
+ subject: import_lazy_zod14.z.object({
8643
+ fromField: import_lazy_zod14.z.string().optional(),
8644
+ strategy: import_lazy_zod14.z.enum(["per-session", "per-account"]).optional()
8615
8645
  }).optional()
8616
8646
  });
8617
- var authenticateFnSchema = import_lazy_zod13.z.custom((v) => typeof v === "function", {
8647
+ var authenticateFnSchema = import_lazy_zod14.z.custom((v) => typeof v === "function", {
8618
8648
  message: "authenticate must be a function"
8619
8649
  });
8620
- var localAuthSchema = import_lazy_zod13.z.object({
8621
- mode: import_lazy_zod13.z.literal("local"),
8650
+ var localAuthSchema = import_lazy_zod14.z.object({
8651
+ mode: import_lazy_zod14.z.literal("local"),
8622
8652
  ...sharedAuthFields,
8623
8653
  // #468 — opt-out of the email requirement at /oauth/callback for
8624
8654
  // single-operator local setups. Defaults preserve the historical behavior
8625
8655
  // (email required) so existing configs are unaffected.
8626
- requireEmail: import_lazy_zod13.z.boolean().default(true),
8627
- anonymousSubject: import_lazy_zod13.z.string().min(1).default("local-operator"),
8656
+ requireEmail: import_lazy_zod14.z.boolean().default(true),
8657
+ anonymousSubject: import_lazy_zod14.z.string().min(1).default("local-operator"),
8628
8658
  // Checkpoint 3a — declarative login customization + custom verification.
8629
8659
  // Both optional; omitting them preserves the default login path exactly.
8630
8660
  login: loginConfigSchema.optional(),
@@ -8632,7 +8662,7 @@ var localAuthSchema = import_lazy_zod13.z.object({
8632
8662
  // Multi-OAuth-provider orchestration — declare upstream providers (GitHub,
8633
8663
  // Slack, Jira, …) to federate at /oauth/authorize. Optional; omitting it
8634
8664
  // preserves the default single-operator local login exactly.
8635
- providers: import_lazy_zod13.z.array(upstreamProviderSchema).optional(),
8665
+ providers: import_lazy_zod14.z.array(upstreamProviderSchema).optional(),
8636
8666
  // Local-AS Dynamic Client Registration control surface (#462) — gate
8637
8667
  // `POST /oauth/register`, allowlist redirect_uris/client_ids, require an
8638
8668
  // initial access token, and seed pre-registered trusted clients. Optional;
@@ -8640,8 +8670,8 @@ var localAuthSchema = import_lazy_zod13.z.object({
8640
8670
  // no allowlist; no initial access token).
8641
8671
  dcr: localDcrConfigSchema.optional()
8642
8672
  });
8643
- var remoteAuthSchema = import_lazy_zod13.z.object({
8644
- mode: import_lazy_zod13.z.literal("remote"),
8673
+ var remoteAuthSchema = import_lazy_zod14.z.object({
8674
+ mode: import_lazy_zod14.z.literal("remote"),
8645
8675
  ...flatRemoteProviderFields,
8646
8676
  ...sharedAuthFields
8647
8677
  });
@@ -8649,21 +8679,22 @@ var orchestratedLocalSchema = localAuthSchema;
8649
8679
  var orchestratedRemoteSchema = remoteAuthSchema;
8650
8680
 
8651
8681
  // libs/auth/src/options/schema.ts
8652
- var import_lazy_zod14 = require("@frontmcp/lazy-zod");
8653
- var authOptionsSchema = import_lazy_zod14.z.union([
8682
+ var import_lazy_zod15 = require("@frontmcp/lazy-zod");
8683
+ var authOptionsSchema = import_lazy_zod15.z.union([
8654
8684
  publicAuthOptionsSchema,
8685
+ staticAuthOptionsSchema,
8655
8686
  transparentAuthOptionsSchema,
8656
8687
  localAuthSchema,
8657
8688
  remoteAuthSchema
8658
8689
  ]);
8659
8690
 
8660
8691
  // libs/auth/src/options/app-auth.schema.ts
8661
- var import_lazy_zod15 = require("@frontmcp/lazy-zod");
8692
+ var import_lazy_zod16 = require("@frontmcp/lazy-zod");
8662
8693
  var standaloneOptionSchema = {
8663
- standalone: import_lazy_zod15.z.boolean().optional(),
8664
- excludeFromParent: import_lazy_zod15.z.boolean().optional()
8694
+ standalone: import_lazy_zod16.z.boolean().optional(),
8695
+ excludeFromParent: import_lazy_zod16.z.boolean().optional()
8665
8696
  };
8666
- var appAuthOptionsSchema = import_lazy_zod15.z.union([
8697
+ var appAuthOptionsSchema = import_lazy_zod16.z.union([
8667
8698
  publicAuthOptionsSchema.extend(standaloneOptionSchema),
8668
8699
  transparentAuthOptionsSchema.extend(standaloneOptionSchema),
8669
8700
  localAuthSchema.extend(standaloneOptionSchema),
@@ -8677,6 +8708,9 @@ function parseAuthOptions(input) {
8677
8708
  function isPublicMode(options) {
8678
8709
  return options.mode === "public";
8679
8710
  }
8711
+ function isStaticMode(options) {
8712
+ return options.mode === "static";
8713
+ }
8680
8714
  function isTransparentMode(options) {
8681
8715
  return options.mode === "transparent";
8682
8716
  }
@@ -8703,108 +8737,108 @@ function allowsPublicAccess(options) {
8703
8737
  }
8704
8738
 
8705
8739
  // libs/auth/src/consent/consent.types.ts
8706
- var import_lazy_zod16 = require("@frontmcp/lazy-zod");
8707
- var consentToolItemSchema = import_lazy_zod16.z.object({
8740
+ var import_lazy_zod17 = require("@frontmcp/lazy-zod");
8741
+ var consentToolItemSchema = import_lazy_zod17.z.object({
8708
8742
  /** Tool ID (e.g., 'slack:send_message') */
8709
- id: import_lazy_zod16.z.string().min(1),
8743
+ id: import_lazy_zod17.z.string().min(1),
8710
8744
  /** Tool name for display */
8711
- name: import_lazy_zod16.z.string().min(1),
8745
+ name: import_lazy_zod17.z.string().min(1),
8712
8746
  /** Tool description */
8713
- description: import_lazy_zod16.z.string().optional(),
8747
+ description: import_lazy_zod17.z.string().optional(),
8714
8748
  /** App ID this tool belongs to */
8715
- appId: import_lazy_zod16.z.string().min(1),
8749
+ appId: import_lazy_zod17.z.string().min(1),
8716
8750
  /** App name for display */
8717
- appName: import_lazy_zod16.z.string().min(1),
8751
+ appName: import_lazy_zod17.z.string().min(1),
8718
8752
  /** Whether the tool is selected by default */
8719
- defaultSelected: import_lazy_zod16.z.boolean().default(true),
8753
+ defaultSelected: import_lazy_zod17.z.boolean().default(true),
8720
8754
  /** Whether this tool requires specific scopes */
8721
- requiredScopes: import_lazy_zod16.z.array(import_lazy_zod16.z.string()).optional(),
8755
+ requiredScopes: import_lazy_zod17.z.array(import_lazy_zod17.z.string()).optional(),
8722
8756
  /** Category for grouping (e.g., 'read', 'write', 'admin') */
8723
- category: import_lazy_zod16.z.string().optional()
8757
+ category: import_lazy_zod17.z.string().optional()
8724
8758
  });
8725
- var consentSelectionSchema = import_lazy_zod16.z.object({
8759
+ var consentSelectionSchema = import_lazy_zod17.z.object({
8726
8760
  /** Selected tool IDs */
8727
- selectedTools: import_lazy_zod16.z.array(import_lazy_zod16.z.string()),
8761
+ selectedTools: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8728
8762
  /** Whether all tools were selected */
8729
- allSelected: import_lazy_zod16.z.boolean(),
8763
+ allSelected: import_lazy_zod17.z.boolean(),
8730
8764
  /** Timestamp when consent was given */
8731
- consentedAt: import_lazy_zod16.z.string().datetime(),
8765
+ consentedAt: import_lazy_zod17.z.string().datetime(),
8732
8766
  /** Consent version for tracking changes */
8733
- consentVersion: import_lazy_zod16.z.string().default("1.0")
8767
+ consentVersion: import_lazy_zod17.z.string().default("1.0")
8734
8768
  });
8735
- var consentStateSchema = import_lazy_zod16.z.object({
8769
+ var consentStateSchema = import_lazy_zod17.z.object({
8736
8770
  /** Whether consent flow is enabled */
8737
- enabled: import_lazy_zod16.z.boolean(),
8771
+ enabled: import_lazy_zod17.z.boolean(),
8738
8772
  /** Available tools for consent */
8739
- availableTools: import_lazy_zod16.z.array(consentToolItemSchema),
8773
+ availableTools: import_lazy_zod17.z.array(consentToolItemSchema),
8740
8774
  /** Pre-selected tools (from previous consent or defaults) */
8741
- preselectedTools: import_lazy_zod16.z.array(import_lazy_zod16.z.string()).optional(),
8775
+ preselectedTools: import_lazy_zod17.z.array(import_lazy_zod17.z.string()).optional(),
8742
8776
  /** Whether to show all tools or group by app */
8743
- groupByApp: import_lazy_zod16.z.boolean().default(true),
8777
+ groupByApp: import_lazy_zod17.z.boolean().default(true),
8744
8778
  /** Custom consent message */
8745
- customMessage: import_lazy_zod16.z.string().optional()
8779
+ customMessage: import_lazy_zod17.z.string().optional()
8746
8780
  });
8747
- var federatedProviderItemSchema = import_lazy_zod16.z.object({
8781
+ var federatedProviderItemSchema = import_lazy_zod17.z.object({
8748
8782
  /** Provider ID (derived or explicit) */
8749
- id: import_lazy_zod16.z.string().min(1),
8783
+ id: import_lazy_zod17.z.string().min(1),
8750
8784
  /** Provider display name */
8751
- name: import_lazy_zod16.z.string().min(1),
8785
+ name: import_lazy_zod17.z.string().min(1),
8752
8786
  /** Provider description */
8753
- description: import_lazy_zod16.z.string().optional(),
8787
+ description: import_lazy_zod17.z.string().optional(),
8754
8788
  /** Provider icon URL or emoji */
8755
- icon: import_lazy_zod16.z.string().optional(),
8789
+ icon: import_lazy_zod17.z.string().optional(),
8756
8790
  /** Provider type */
8757
- type: import_lazy_zod16.z.enum(["local", "remote", "transparent"]),
8791
+ type: import_lazy_zod17.z.enum(["local", "remote", "transparent"]),
8758
8792
  /** OAuth provider URL (for remote providers) */
8759
- providerUrl: import_lazy_zod16.z.string().url().optional(),
8793
+ providerUrl: import_lazy_zod17.z.string().url().optional(),
8760
8794
  /** Apps using this provider */
8761
- appIds: import_lazy_zod16.z.array(import_lazy_zod16.z.string()),
8795
+ appIds: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8762
8796
  /** App names using this provider */
8763
- appNames: import_lazy_zod16.z.array(import_lazy_zod16.z.string()),
8797
+ appNames: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8764
8798
  /** Scopes required by this provider */
8765
- scopes: import_lazy_zod16.z.array(import_lazy_zod16.z.string()),
8799
+ scopes: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8766
8800
  /** Whether this is the primary/parent provider */
8767
- isPrimary: import_lazy_zod16.z.boolean(),
8801
+ isPrimary: import_lazy_zod17.z.boolean(),
8768
8802
  /** Whether this provider is optional (can be skipped) */
8769
- isOptional: import_lazy_zod16.z.boolean().default(false)
8803
+ isOptional: import_lazy_zod17.z.boolean().default(false)
8770
8804
  });
8771
- var federatedLoginStateSchema = import_lazy_zod16.z.object({
8805
+ var federatedLoginStateSchema = import_lazy_zod17.z.object({
8772
8806
  /** All available providers */
8773
- providers: import_lazy_zod16.z.array(federatedProviderItemSchema),
8807
+ providers: import_lazy_zod17.z.array(federatedProviderItemSchema),
8774
8808
  /** Primary provider ID (if any) */
8775
- primaryProviderId: import_lazy_zod16.z.string().optional(),
8809
+ primaryProviderId: import_lazy_zod17.z.string().optional(),
8776
8810
  /** Whether user can skip optional providers */
8777
- allowSkip: import_lazy_zod16.z.boolean().default(true),
8811
+ allowSkip: import_lazy_zod17.z.boolean().default(true),
8778
8812
  /** Pre-selected provider IDs (from previous session) */
8779
- preselectedProviders: import_lazy_zod16.z.array(import_lazy_zod16.z.string()).optional()
8813
+ preselectedProviders: import_lazy_zod17.z.array(import_lazy_zod17.z.string()).optional()
8780
8814
  });
8781
- var federatedSelectionSchema = import_lazy_zod16.z.object({
8815
+ var federatedSelectionSchema = import_lazy_zod17.z.object({
8782
8816
  /** Selected provider IDs */
8783
- selectedProviders: import_lazy_zod16.z.array(import_lazy_zod16.z.string()),
8817
+ selectedProviders: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8784
8818
  /** Skipped provider IDs */
8785
- skippedProviders: import_lazy_zod16.z.array(import_lazy_zod16.z.string()),
8819
+ skippedProviders: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8786
8820
  /** Provider-specific metadata */
8787
- providerMetadata: import_lazy_zod16.z.record(import_lazy_zod16.z.string(), import_lazy_zod16.z.unknown()).optional()
8821
+ providerMetadata: import_lazy_zod17.z.record(import_lazy_zod17.z.string(), import_lazy_zod17.z.unknown()).optional()
8788
8822
  });
8789
8823
 
8790
8824
  // libs/auth/src/detection/auth-provider-detection.ts
8791
- var import_lazy_zod17 = require("@frontmcp/lazy-zod");
8792
- var detectedAuthProviderSchema = import_lazy_zod17.z.object({
8793
- id: import_lazy_zod17.z.string(),
8794
- providerUrl: import_lazy_zod17.z.string().optional(),
8795
- mode: import_lazy_zod17.z.enum(["public", "transparent", "local", "remote"]),
8796
- appIds: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8797
- scopes: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8798
- isParentProvider: import_lazy_zod17.z.boolean()
8825
+ var import_lazy_zod18 = require("@frontmcp/lazy-zod");
8826
+ var detectedAuthProviderSchema = import_lazy_zod18.z.object({
8827
+ id: import_lazy_zod18.z.string(),
8828
+ providerUrl: import_lazy_zod18.z.string().optional(),
8829
+ mode: import_lazy_zod18.z.enum(["public", "static", "transparent", "local", "remote"]),
8830
+ appIds: import_lazy_zod18.z.array(import_lazy_zod18.z.string()),
8831
+ scopes: import_lazy_zod18.z.array(import_lazy_zod18.z.string()),
8832
+ isParentProvider: import_lazy_zod18.z.boolean()
8799
8833
  });
8800
- var authProviderDetectionResultSchema = import_lazy_zod17.z.object({
8801
- providers: import_lazy_zod17.z.map(import_lazy_zod17.z.string(), detectedAuthProviderSchema),
8802
- requiresOrchestration: import_lazy_zod17.z.boolean(),
8803
- parentProviderId: import_lazy_zod17.z.string().optional(),
8804
- childProviderIds: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8805
- uniqueProviderCount: import_lazy_zod17.z.number(),
8806
- validationErrors: import_lazy_zod17.z.array(import_lazy_zod17.z.string()),
8807
- warnings: import_lazy_zod17.z.array(import_lazy_zod17.z.string())
8834
+ var authProviderDetectionResultSchema = import_lazy_zod18.z.object({
8835
+ providers: import_lazy_zod18.z.map(import_lazy_zod18.z.string(), detectedAuthProviderSchema),
8836
+ requiresOrchestration: import_lazy_zod18.z.boolean(),
8837
+ parentProviderId: import_lazy_zod18.z.string().optional(),
8838
+ childProviderIds: import_lazy_zod18.z.array(import_lazy_zod18.z.string()),
8839
+ uniqueProviderCount: import_lazy_zod18.z.number(),
8840
+ validationErrors: import_lazy_zod18.z.array(import_lazy_zod18.z.string()),
8841
+ warnings: import_lazy_zod18.z.array(import_lazy_zod18.z.string())
8808
8842
  });
8809
8843
  function deriveProviderId(options) {
8810
8844
  if (isPublicMode(options)) {
@@ -9193,43 +9227,43 @@ var AudienceValidator = class _AudienceValidator {
9193
9227
  };
9194
9228
 
9195
9229
  // libs/auth/src/vault/auth-providers.types.ts
9196
- var import_lazy_zod18 = require("@frontmcp/lazy-zod");
9197
- var credentialScopeSchema = import_lazy_zod18.z.enum(["global", "user", "session"]);
9198
- var loadingStrategySchema = import_lazy_zod18.z.enum(["eager", "lazy"]);
9199
- var getCredentialOptionsSchema = import_lazy_zod18.z.object({
9200
- forceRefresh: import_lazy_zod18.z.boolean().optional(),
9201
- scopes: import_lazy_zod18.z.array(import_lazy_zod18.z.string()).optional(),
9202
- timeout: import_lazy_zod18.z.number().positive().optional()
9230
+ var import_lazy_zod19 = require("@frontmcp/lazy-zod");
9231
+ var credentialScopeSchema = import_lazy_zod19.z.enum(["global", "user", "session"]);
9232
+ var loadingStrategySchema = import_lazy_zod19.z.enum(["eager", "lazy"]);
9233
+ var getCredentialOptionsSchema = import_lazy_zod19.z.object({
9234
+ forceRefresh: import_lazy_zod19.z.boolean().optional(),
9235
+ scopes: import_lazy_zod19.z.array(import_lazy_zod19.z.string()).optional(),
9236
+ timeout: import_lazy_zod19.z.number().positive().optional()
9203
9237
  }).strict();
9204
- var credentialProviderConfigSchema = import_lazy_zod18.z.object({
9205
- name: import_lazy_zod18.z.string().min(1),
9206
- description: import_lazy_zod18.z.string().optional(),
9238
+ var credentialProviderConfigSchema = import_lazy_zod19.z.object({
9239
+ name: import_lazy_zod19.z.string().min(1),
9240
+ description: import_lazy_zod19.z.string().optional(),
9207
9241
  scope: credentialScopeSchema,
9208
9242
  loading: loadingStrategySchema,
9209
- cacheTtl: import_lazy_zod18.z.number().nonnegative().optional(),
9243
+ cacheTtl: import_lazy_zod19.z.number().nonnegative().optional(),
9210
9244
  // Functions validated at runtime, not via Zod (Zod 4 compatibility)
9211
- factory: import_lazy_zod18.z.any(),
9212
- refresh: import_lazy_zod18.z.any().optional(),
9213
- toHeaders: import_lazy_zod18.z.any().optional(),
9214
- metadata: import_lazy_zod18.z.record(import_lazy_zod18.z.string(), import_lazy_zod18.z.unknown()).optional(),
9215
- required: import_lazy_zod18.z.boolean().optional()
9245
+ factory: import_lazy_zod19.z.any(),
9246
+ refresh: import_lazy_zod19.z.any().optional(),
9247
+ toHeaders: import_lazy_zod19.z.any().optional(),
9248
+ metadata: import_lazy_zod19.z.record(import_lazy_zod19.z.string(), import_lazy_zod19.z.unknown()).optional(),
9249
+ required: import_lazy_zod19.z.boolean().optional()
9216
9250
  }).strict();
9217
- var authProviderMappingSchema = import_lazy_zod18.z.union([
9218
- import_lazy_zod18.z.string(),
9219
- import_lazy_zod18.z.object({
9220
- name: import_lazy_zod18.z.string().min(1),
9221
- required: import_lazy_zod18.z.boolean().optional().default(true),
9222
- scopes: import_lazy_zod18.z.array(import_lazy_zod18.z.string()).optional(),
9223
- alias: import_lazy_zod18.z.string().optional()
9251
+ var authProviderMappingSchema = import_lazy_zod19.z.union([
9252
+ import_lazy_zod19.z.string(),
9253
+ import_lazy_zod19.z.object({
9254
+ name: import_lazy_zod19.z.string().min(1),
9255
+ required: import_lazy_zod19.z.boolean().optional().default(true),
9256
+ scopes: import_lazy_zod19.z.array(import_lazy_zod19.z.string()).optional(),
9257
+ alias: import_lazy_zod19.z.string().optional()
9224
9258
  }).strict()
9225
9259
  ]);
9226
- var authProvidersVaultOptionsSchema = import_lazy_zod18.z.object({
9227
- enabled: import_lazy_zod18.z.boolean().optional(),
9228
- useSharedStorage: import_lazy_zod18.z.boolean().optional().default(true),
9229
- namespace: import_lazy_zod18.z.string().optional().default("authproviders:"),
9230
- defaultCacheTtl: import_lazy_zod18.z.number().nonnegative().optional().default(36e5),
9231
- maxCredentialsPerSession: import_lazy_zod18.z.number().positive().optional().default(100),
9232
- providers: import_lazy_zod18.z.array(credentialProviderConfigSchema).optional()
9260
+ var authProvidersVaultOptionsSchema = import_lazy_zod19.z.object({
9261
+ enabled: import_lazy_zod19.z.boolean().optional(),
9262
+ useSharedStorage: import_lazy_zod19.z.boolean().optional().default(true),
9263
+ namespace: import_lazy_zod19.z.string().optional().default("authproviders:"),
9264
+ defaultCacheTtl: import_lazy_zod19.z.number().nonnegative().optional().default(36e5),
9265
+ maxCredentialsPerSession: import_lazy_zod19.z.number().positive().optional().default(100),
9266
+ providers: import_lazy_zod19.z.array(credentialProviderConfigSchema).optional()
9233
9267
  }).strict();
9234
9268
 
9235
9269
  // libs/auth/src/vault/credential-helpers.ts
@@ -9434,7 +9468,7 @@ var CredentialCache = class {
9434
9468
  var AUTH_PROVIDERS_ACCESSOR = /* @__PURE__ */ Symbol.for("frontmcp:AUTH_PROVIDERS_ACCESSOR");
9435
9469
 
9436
9470
  // libs/auth/src/vault/auth-providers.accessor.impl.ts
9437
- var import_utils42 = require("@frontmcp/utils");
9471
+ var import_utils44 = require("@frontmcp/utils");
9438
9472
  var AuthProvidersAccessorImpl = class {
9439
9473
  constructor(registry, vault, cache, loader, context, logger) {
9440
9474
  this.registry = registry;
@@ -9649,7 +9683,7 @@ var AuthProvidersAccessorImpl = class {
9649
9683
  return { [credential.headerName]: credential.key };
9650
9684
  case "basic": {
9651
9685
  const value = `${credential.username}:${credential.password}`;
9652
- const encoded = credential.encodedValue ?? (0, import_utils42.base64Encode)(new TextEncoder().encode(value));
9686
+ const encoded = credential.encodedValue ?? (0, import_utils44.base64Encode)(new TextEncoder().encode(value));
9653
9687
  return { Authorization: `Basic ${encoded}` };
9654
9688
  }
9655
9689
  case "custom":
@@ -10237,6 +10271,18 @@ var noopRelationshipResolver = {
10237
10271
  return false;
10238
10272
  }
10239
10273
  };
10274
+ function resolveAuthUser(authInfo) {
10275
+ const extraUser = authInfo?.extra?.["user"];
10276
+ if (authInfo?.user) return authInfo.user;
10277
+ return typeof extraUser === "object" && extraUser !== null ? extraUser : {};
10278
+ }
10279
+ function isAnonymousSubject(sub) {
10280
+ return typeof sub !== "string" || sub === "" || sub.startsWith("anon:");
10281
+ }
10282
+ function signedInSubject(rawSub, mappedSub) {
10283
+ if (rawSub !== void 0 && isAnonymousSubject(rawSub)) return void 0;
10284
+ return [mappedSub, rawSub].find((candidate) => !isAnonymousSubject(candidate));
10285
+ }
10240
10286
  var AuthoritiesContextBuilder = class {
10241
10287
  claimsMapping;
10242
10288
  claimsResolver;
@@ -10254,7 +10300,7 @@ var AuthoritiesContextBuilder = class {
10254
10300
  const resolved = this.claimsResolver(authInfo);
10255
10301
  return {
10256
10302
  user: {
10257
- sub: authInfo?.user?.sub ?? "",
10303
+ sub: signedInSubject(resolveAuthUser(authInfo).sub),
10258
10304
  roles: resolved.roles,
10259
10305
  permissions: resolved.permissions,
10260
10306
  claims: resolved.claims
@@ -10264,7 +10310,7 @@ var AuthoritiesContextBuilder = class {
10264
10310
  relationships: this.relationshipResolver
10265
10311
  };
10266
10312
  }
10267
- const user = authInfo?.user ?? {};
10313
+ const user = resolveAuthUser(authInfo);
10268
10314
  const authorization = authInfo?.extra?.["authorization"];
10269
10315
  const authorizationClaims = authorization?.["claims"] ?? {};
10270
10316
  const rawClaims = {
@@ -10285,10 +10331,10 @@ var AuthoritiesContextBuilder = class {
10285
10331
  } else {
10286
10332
  permissions = toStringArray(user["permissions"] ?? []);
10287
10333
  }
10288
- const sub = this.claimsMapping?.userId ? String(resolveDotPath(rawClaims, this.claimsMapping.userId) ?? "") : user.sub ?? "";
10334
+ const mappedSub = this.claimsMapping?.userId ? resolveDotPath(rawClaims, this.claimsMapping.userId) : void 0;
10289
10335
  return {
10290
10336
  user: {
10291
- sub,
10337
+ sub: signedInSubject(user.sub, mappedSub),
10292
10338
  roles,
10293
10339
  permissions,
10294
10340
  claims: rawClaims
@@ -10320,15 +10366,17 @@ var FrontMcpAuthContextImpl = class {
10320
10366
  roles;
10321
10367
  permissions;
10322
10368
  constructor(source, claimsMapping) {
10323
- const rawUser = source.user ?? {};
10324
- const sub = claimsMapping?.userId ? String(resolveDotPath(this.buildRawClaims(source), claimsMapping.userId) ?? rawUser.sub ?? "") : String(rawUser.sub ?? "");
10369
+ const rawUser = resolveAuthUser(source);
10370
+ const mappedSub = claimsMapping?.userId ? resolveDotPath(this.buildRawClaims(source), claimsMapping.userId) : void 0;
10371
+ const signedInSub = signedInSubject(rawUser.sub, mappedSub);
10372
+ const sub = signedInSub ?? (typeof rawUser.sub === "string" ? rawUser.sub : "");
10325
10373
  this.user = Object.freeze({
10326
10374
  sub,
10327
10375
  name: rawUser.name,
10328
10376
  email: rawUser.email,
10329
10377
  picture: rawUser.picture
10330
10378
  });
10331
- this.isAnonymous = sub === "" || sub.startsWith("anon:");
10379
+ this.isAnonymous = signedInSub === void 0;
10332
10380
  const extraAuth = source.extra?.["authorization"];
10333
10381
  this.mode = String(
10334
10382
  source.extra?.["authMode"] ?? extraAuth?.["mode"] ?? (source.extra?.["isPublic"] === true || rawUser["anonymous"] === true ? "public" : "authenticated")
@@ -10386,7 +10434,7 @@ var FrontMcpAuthContextImpl = class {
10386
10434
  * Mirrors the logic in AuthoritiesContextBuilder.build().
10387
10435
  */
10388
10436
  buildRawClaims(source) {
10389
- const rawUser = source.user ?? {};
10437
+ const rawUser = resolveAuthUser(source);
10390
10438
  const extraAuth = source.extra?.["authorization"];
10391
10439
  const authorizationClaims = extraAuth?.["claims"] ?? {};
10392
10440
  return {
@@ -10451,20 +10499,20 @@ function resolveRequiredScopes(denial, mapping, authorities) {
10451
10499
  }
10452
10500
 
10453
10501
  // libs/auth/src/authorities/authorities.schema.ts
10454
- var import_lazy_zod19 = require("@frontmcp/lazy-zod");
10455
- var rbacRolesPolicySchema = import_lazy_zod19.z.object({
10456
- all: import_lazy_zod19.z.array(import_lazy_zod19.z.string().min(1)).optional(),
10457
- any: import_lazy_zod19.z.array(import_lazy_zod19.z.string().min(1)).optional()
10502
+ var import_lazy_zod20 = require("@frontmcp/lazy-zod");
10503
+ var rbacRolesPolicySchema = import_lazy_zod20.z.object({
10504
+ all: import_lazy_zod20.z.array(import_lazy_zod20.z.string().min(1)).optional(),
10505
+ any: import_lazy_zod20.z.array(import_lazy_zod20.z.string().min(1)).optional()
10458
10506
  }).refine((data) => data.all !== void 0 || data.any !== void 0, {
10459
10507
  message: 'Roles policy must have at least "all" or "any"'
10460
10508
  });
10461
- var rbacPermissionsPolicySchema = import_lazy_zod19.z.object({
10462
- all: import_lazy_zod19.z.array(import_lazy_zod19.z.string().min(1)).optional(),
10463
- any: import_lazy_zod19.z.array(import_lazy_zod19.z.string().min(1)).optional()
10509
+ var rbacPermissionsPolicySchema = import_lazy_zod20.z.object({
10510
+ all: import_lazy_zod20.z.array(import_lazy_zod20.z.string().min(1)).optional(),
10511
+ any: import_lazy_zod20.z.array(import_lazy_zod20.z.string().min(1)).optional()
10464
10512
  }).refine((data) => data.all !== void 0 || data.any !== void 0, {
10465
10513
  message: 'Permissions policy must have at least "all" or "any"'
10466
10514
  });
10467
- var abacOperatorSchema = import_lazy_zod19.z.enum([
10515
+ var abacOperatorSchema = import_lazy_zod20.z.enum([
10468
10516
  "eq",
10469
10517
  "neq",
10470
10518
  "in",
@@ -10479,55 +10527,55 @@ var abacOperatorSchema = import_lazy_zod19.z.enum([
10479
10527
  "exists",
10480
10528
  "matches"
10481
10529
  ]);
10482
- var abacConditionSchema = import_lazy_zod19.z.object({
10483
- path: import_lazy_zod19.z.string().min(1),
10530
+ var abacConditionSchema = import_lazy_zod20.z.object({
10531
+ path: import_lazy_zod20.z.string().min(1),
10484
10532
  op: abacOperatorSchema,
10485
- value: import_lazy_zod19.z.unknown()
10533
+ value: import_lazy_zod20.z.unknown()
10486
10534
  });
10487
- var abacPolicySchema = import_lazy_zod19.z.object({
10488
- match: import_lazy_zod19.z.record(import_lazy_zod19.z.string(), import_lazy_zod19.z.unknown()).optional(),
10489
- conditions: import_lazy_zod19.z.array(abacConditionSchema).optional()
10535
+ var abacPolicySchema = import_lazy_zod20.z.object({
10536
+ match: import_lazy_zod20.z.record(import_lazy_zod20.z.string(), import_lazy_zod20.z.unknown()).optional(),
10537
+ conditions: import_lazy_zod20.z.array(abacConditionSchema).optional()
10490
10538
  }).refine((data) => data.match !== void 0 || data.conditions !== void 0, {
10491
10539
  message: 'Attributes policy must have at least "match" or "conditions"'
10492
10540
  });
10493
- var resourceIdRefSchema = import_lazy_zod19.z.union([
10494
- import_lazy_zod19.z.string().min(1),
10495
- import_lazy_zod19.z.object({ fromInput: import_lazy_zod19.z.string().min(1) }).strict(),
10496
- import_lazy_zod19.z.object({ fromClaims: import_lazy_zod19.z.string().min(1) }).strict()
10541
+ var resourceIdRefSchema = import_lazy_zod20.z.union([
10542
+ import_lazy_zod20.z.string().min(1),
10543
+ import_lazy_zod20.z.object({ fromInput: import_lazy_zod20.z.string().min(1) }).strict(),
10544
+ import_lazy_zod20.z.object({ fromClaims: import_lazy_zod20.z.string().min(1) }).strict()
10497
10545
  ]);
10498
- var rebacPolicySchema = import_lazy_zod19.z.object({
10499
- type: import_lazy_zod19.z.string().min(1),
10500
- resource: import_lazy_zod19.z.string().min(1),
10546
+ var rebacPolicySchema = import_lazy_zod20.z.object({
10547
+ type: import_lazy_zod20.z.string().min(1),
10548
+ resource: import_lazy_zod20.z.string().min(1),
10501
10549
  resourceId: resourceIdRefSchema
10502
10550
  });
10503
10551
  var basePolicyShape = {
10504
10552
  roles: rbacRolesPolicySchema.optional(),
10505
10553
  permissions: rbacPermissionsPolicySchema.optional(),
10506
10554
  attributes: abacPolicySchema.optional(),
10507
- relationships: import_lazy_zod19.z.union([rebacPolicySchema, import_lazy_zod19.z.array(rebacPolicySchema)]).optional(),
10508
- custom: import_lazy_zod19.z.record(import_lazy_zod19.z.string(), import_lazy_zod19.z.unknown()).optional(),
10509
- guards: import_lazy_zod19.z.array(import_lazy_zod19.z.instanceof(Function)).optional(),
10510
- operator: import_lazy_zod19.z.enum(["AND", "OR"]).optional()
10555
+ relationships: import_lazy_zod20.z.union([rebacPolicySchema, import_lazy_zod20.z.array(rebacPolicySchema)]).optional(),
10556
+ custom: import_lazy_zod20.z.record(import_lazy_zod20.z.string(), import_lazy_zod20.z.unknown()).optional(),
10557
+ guards: import_lazy_zod20.z.array(import_lazy_zod20.z.instanceof(Function)).optional(),
10558
+ operator: import_lazy_zod20.z.enum(["AND", "OR"]).optional()
10511
10559
  };
10512
- var authoritiesPolicySchema = import_lazy_zod19.z.lazy(
10513
- () => import_lazy_zod19.z.object({
10560
+ var authoritiesPolicySchema = import_lazy_zod20.z.lazy(
10561
+ () => import_lazy_zod20.z.object({
10514
10562
  ...basePolicyShape,
10515
10563
  not: authoritiesPolicySchema.optional(),
10516
- anyOf: import_lazy_zod19.z.array(authoritiesPolicySchema).optional(),
10517
- allOf: import_lazy_zod19.z.array(authoritiesPolicySchema).optional()
10564
+ anyOf: import_lazy_zod20.z.array(authoritiesPolicySchema).optional(),
10565
+ allOf: import_lazy_zod20.z.array(authoritiesPolicySchema).optional()
10518
10566
  })
10519
10567
  );
10520
- var authoritiesMetadataSchema = import_lazy_zod19.z.union([
10521
- import_lazy_zod19.z.string().min(1),
10522
- import_lazy_zod19.z.array(import_lazy_zod19.z.string().min(1)).min(1),
10568
+ var authoritiesMetadataSchema = import_lazy_zod20.z.union([
10569
+ import_lazy_zod20.z.string().min(1),
10570
+ import_lazy_zod20.z.array(import_lazy_zod20.z.string().min(1)).min(1),
10523
10571
  authoritiesPolicySchema
10524
10572
  ]);
10525
- var authoritiesClaimsMappingSchema = import_lazy_zod19.z.record(import_lazy_zod19.z.string(), import_lazy_zod19.z.string().optional()).refine((data) => Object.values(data).some((v) => v !== void 0), {
10573
+ var authoritiesClaimsMappingSchema = import_lazy_zod20.z.record(import_lazy_zod20.z.string(), import_lazy_zod20.z.string().optional()).refine((data) => Object.values(data).some((v) => v !== void 0), {
10526
10574
  message: "Claims mapping must have at least one mapping"
10527
10575
  });
10528
- var authoritiesConfigSchema = import_lazy_zod19.z.object({
10576
+ var authoritiesConfigSchema = import_lazy_zod20.z.object({
10529
10577
  claimsMapping: authoritiesClaimsMappingSchema.optional(),
10530
- profiles: import_lazy_zod19.z.record(import_lazy_zod19.z.string().min(1), authoritiesPolicySchema).optional()
10578
+ profiles: import_lazy_zod20.z.record(import_lazy_zod20.z.string().min(1), authoritiesPolicySchema).optional()
10531
10579
  });
10532
10580
 
10533
10581
  // libs/auth/src/authorities/authorities.evaluator.ts
@@ -10605,8 +10653,9 @@ function resolveValue(value, ctx) {
10605
10653
  }
10606
10654
  function applyOperator(actual, op, expected) {
10607
10655
  switch (op) {
10656
+ // A missing expected value (e.g. an absent fromInput) never matches, even an absent actual value
10608
10657
  case "eq":
10609
- return actual === expected;
10658
+ return expected !== void 0 && actual === expected;
10610
10659
  case "neq":
10611
10660
  return actual !== expected;
10612
10661
  case "in":
@@ -10655,7 +10704,7 @@ function evaluateAbac(policy, ctx) {
10655
10704
  for (const [path, expectedRaw] of Object.entries(policy.match)) {
10656
10705
  const actual = resolveDotPath(envelope, path);
10657
10706
  const expected = resolveValue(expectedRaw, ctx);
10658
- if (actual !== expected) {
10707
+ if (expected === void 0 || actual !== expected) {
10659
10708
  return {
10660
10709
  granted: false,
10661
10710
  deniedBy: `attributes.match: '${path}' expected '${String(expected)}' but got '${String(actual)}'`,
@@ -10695,6 +10744,15 @@ function resolveResourceId(ref, ctx) {
10695
10744
  return void 0;
10696
10745
  }
10697
10746
  async function evaluateSingleRebac(policy, ctx) {
10747
+ const userSub = ctx.user.sub;
10748
+ if (userSub === void 0 || isAnonymousSubject(userSub)) {
10749
+ return {
10750
+ granted: false,
10751
+ deniedBy: `relationships: an anonymous caller cannot be '${policy.type}' of ${policy.resource}`,
10752
+ denial: { kind: "relationships", path: "user.sub", expected: "a signed-in caller", actual: void 0 },
10753
+ evaluatedPolicies: ["relationships"]
10754
+ };
10755
+ }
10698
10756
  const resourceId = resolveResourceId(policy.resourceId, ctx);
10699
10757
  if (resourceId === void 0) {
10700
10758
  return {
@@ -10709,11 +10767,11 @@ async function evaluateSingleRebac(policy, ctx) {
10709
10767
  evaluatedPolicies: ["relationships"]
10710
10768
  };
10711
10769
  }
10712
- const hasRelationship = await ctx.relationships.check(policy.type, policy.resource, resourceId, ctx.user.sub, ctx);
10770
+ const hasRelationship = await ctx.relationships.check(policy.type, policy.resource, resourceId, userSub, ctx);
10713
10771
  if (!hasRelationship) {
10714
10772
  return {
10715
10773
  granted: false,
10716
- deniedBy: `relationships: user '${ctx.user.sub}' is not '${policy.type}' of ${policy.resource}:${resourceId}`,
10774
+ deniedBy: `relationships: user '${userSub}' is not '${policy.type}' of ${policy.resource}:${resourceId}`,
10717
10775
  denial: {
10718
10776
  kind: "relationships",
10719
10777
  path: "relationships",
@@ -11231,6 +11289,8 @@ var FetchCredentialMiddleware = class {
11231
11289
  InMemoryStoreRequiredError,
11232
11290
  InvalidClientIdUrlError,
11233
11291
  JwksService,
11292
+ JwtSecretRequiredError,
11293
+ JwtSecretWeakError,
11234
11294
  LazyCredentialLoader,
11235
11295
  NoProviderIdError,
11236
11296
  NullOrchestratedAuthAccessor,
@@ -11385,6 +11445,7 @@ var FetchCredentialMiddleware = class {
11385
11445
  headerApplier,
11386
11446
  hkdfSha256,
11387
11447
  incrementalAuthConfigSchema,
11448
+ isAnonymousSubject,
11388
11449
  isCimdClientId,
11389
11450
  isFrontMcpCredentials,
11390
11451
  isJwt,
@@ -11401,6 +11462,7 @@ var FetchCredentialMiddleware = class {
11401
11462
  isSoonExpiring,
11402
11463
  isSoonExpiringProvider,
11403
11464
  isSqliteTokenStorage,
11465
+ isStaticMode,
11404
11466
  isTransparentMode,
11405
11467
  jsonWebKeySetSchema,
11406
11468
  jwkParametersSchema,
@@ -11460,6 +11522,7 @@ var FetchCredentialMiddleware = class {
11460
11522
  startNextProvider,
11461
11523
  statefulHttpTransportStateSchema,
11462
11524
  statelessHttpTransportStateSchema,
11525
+ staticAuthOptionsSchema,
11463
11526
  storedSessionSchema,
11464
11527
  streamableHttpTransportStateSchema,
11465
11528
  toEpochSeconds,