@frontmcp/auth 1.10.15 → 1.11.0-rc.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 (175) hide show
  1. package/browser/authorities/authorities.context.mjs +115 -0
  2. package/browser/authorities/authorities.engine.mjs +272 -0
  3. package/browser/authorities/authorities.errors.mjs +59 -0
  4. package/browser/authorities/authorities.evaluator.mjs +225 -0
  5. package/browser/authorities/authorities.metadata-augment.mjs +18 -0
  6. package/browser/authorities/authorities.registry.mjs +112 -0
  7. package/browser/authorities/authorities.schema.mjs +92 -0
  8. package/browser/authorities/authorities.scope-mapping.mjs +30 -0
  9. package/browser/authorities/authorities.validation.mjs +208 -0
  10. package/browser/authorities/index.mjs +43 -0
  11. package/browser/authorization/authorization.class.mjs +252 -0
  12. package/browser/authorization/authorization.types.mjs +64 -0
  13. package/browser/authorization/dcr-client.registry.mjs +222 -0
  14. package/browser/authorization/index.mjs +41 -0
  15. package/browser/authorization/orchestrated.accessor.mjs +86 -0
  16. package/browser/authorization/orchestrated.authorization.mjs +289 -0
  17. package/browser/authorization/public.authorization.mjs +124 -0
  18. package/browser/authorization/transparent.authorization.mjs +130 -0
  19. package/browser/cimd/cimd-redis.cache.mjs +231 -0
  20. package/browser/cimd/cimd.cache.mjs +215 -0
  21. package/browser/cimd/cimd.errors.mjs +142 -0
  22. package/browser/cimd/cimd.logger.mjs +15 -0
  23. package/browser/cimd/cimd.service.mjs +376 -0
  24. package/browser/cimd/cimd.types.mjs +228 -0
  25. package/browser/cimd/cimd.validator.mjs +217 -0
  26. package/browser/cimd/index.mjs +63 -0
  27. package/browser/common/auth-logger.interface.mjs +14 -0
  28. package/browser/common/index.mjs +6 -0
  29. package/browser/common/jwt.types.mjs +38 -0
  30. package/browser/common/session-user.types.mjs +0 -0
  31. package/browser/common/session.types.mjs +58 -0
  32. package/browser/common/zod-utils.mjs +0 -0
  33. package/browser/consent/consent.types.mjs +94 -0
  34. package/browser/consent/index.mjs +17 -0
  35. package/browser/context/frontmcp-auth-context.factory.mjs +29 -0
  36. package/browser/context/frontmcp-auth-context.impl.mjs +112 -0
  37. package/browser/context/index.mjs +7 -0
  38. package/browser/detection/auth-provider-detection.mjs +176 -0
  39. package/browser/detection/index.mjs +19 -0
  40. package/browser/errors/auth-internal.error.mjs +42 -0
  41. package/browser/errors/auth-internal.errors.mjs +150 -0
  42. package/browser/errors/index.mjs +53 -0
  43. package/browser/fetch/fetch-credential-middleware.mjs +91 -0
  44. package/browser/fetch/index.mjs +19 -0
  45. package/browser/index.mjs +573 -0
  46. package/browser/jwks/index.mjs +9 -0
  47. package/browser/jwks/jose.loader.mjs +28 -0
  48. package/browser/jwks/jwks.service.mjs +521 -0
  49. package/browser/jwks/jwks.utils.mjs +33 -0
  50. package/browser/options/app-auth.schema.mjs +18 -0
  51. package/browser/options/index.mjs +89 -0
  52. package/browser/options/orchestrated.schema.mjs +128 -0
  53. package/browser/options/public.schema.mjs +39 -0
  54. package/browser/options/schema.mjs +16 -0
  55. package/browser/options/shared.schemas.mjs +506 -0
  56. package/browser/options/static.schema.mjs +41 -0
  57. package/browser/options/transparent.schema.mjs +43 -0
  58. package/browser/options/utils.mjs +47 -0
  59. package/browser/people/index.mjs +15 -0
  60. package/browser/people/loopback-token.auth.mjs +115 -0
  61. package/browser/people/people-auth.options.mjs +37 -0
  62. package/browser/session/authorization-vault.mjs +279 -0
  63. package/browser/session/authorization.store.mjs +336 -0
  64. package/browser/session/consent.store.mjs +34 -0
  65. package/browser/session/credential-resume-link.mjs +43 -0
  66. package/browser/session/credentials-accessor.impl.mjs +54 -0
  67. package/browser/session/credentials-accessor.mjs +5 -0
  68. package/browser/session/encrypted-authorization-vault.mjs +405 -0
  69. package/browser/session/federated-auth.session.mjs +176 -0
  70. package/browser/session/incremental-auth-ticket.mjs +42 -0
  71. package/browser/session/index.mjs +266 -0
  72. package/browser/session/orchestrated-token.crypto.mjs +47 -0
  73. package/browser/session/orchestrated-token.store.mjs +286 -0
  74. package/browser/session/pending-login.mjs +37 -0
  75. package/browser/session/redis-session.store.mjs +255 -0
  76. package/browser/session/secure-store-accessor.impl.mjs +78 -0
  77. package/browser/session/secure-store-accessor.mjs +5 -0
  78. package/browser/session/secure-store-backends.mjs +111 -0
  79. package/browser/session/secure-store.factory.mjs +77 -0
  80. package/browser/session/session-credential-vault.factory.mjs +18 -0
  81. package/browser/session/session-credential-vault.mjs +243 -0
  82. package/browser/session/session-crypto.mjs +39 -0
  83. package/browser/session/session-rate-limiter.mjs +126 -0
  84. package/browser/session/session.transport.mjs +16 -0
  85. package/browser/session/signin-binding.mjs +30 -0
  86. package/browser/session/storage/in-memory-authorization-vault.mjs +28 -0
  87. package/browser/session/storage/index.mjs +14 -0
  88. package/browser/session/storage/storage-authorization-vault.mjs +301 -0
  89. package/browser/session/storage/storage-token-store.mjs +83 -0
  90. package/browser/session/storage-authorization.store.mjs +134 -0
  91. package/browser/session/storage-consent.store.mjs +33 -0
  92. package/browser/session/storage-federated-auth.session.mjs +55 -0
  93. package/browser/session/storage-orchestrated-token.store.mjs +197 -0
  94. package/browser/session/token-storage.factory.mjs +58 -0
  95. package/browser/session/token.refresh.mjs +36 -0
  96. package/browser/session/token.vault.mjs +61 -0
  97. package/browser/session/transport-session.types.mjs +108 -0
  98. package/browser/session/utils/auth-token.utils.mjs +58 -0
  99. package/browser/session/utils/index.mjs +23 -0
  100. package/browser/session/utils/session-crypto.utils.mjs +49 -0
  101. package/browser/session/utils/tiny-ttl-cache.mjs +46 -0
  102. package/browser/session/vault-encryption.mjs +187 -0
  103. package/browser/session/vercel-kv-session.store.mjs +230 -0
  104. package/browser/shared-server/index.mjs +17 -0
  105. package/browser/shared-server/shared-server-identity.mjs +55 -0
  106. package/browser/ui/base-layout.mjs +184 -0
  107. package/browser/ui/index.mjs +51 -0
  108. package/browser/ui/local-login.helper.mjs +46 -0
  109. package/browser/ui/templates.mjs +482 -0
  110. package/browser/utils/audience.validator.mjs +110 -0
  111. package/browser/utils/authorization-id.utils.mjs +10 -0
  112. package/browser/utils/index.mjs +45 -0
  113. package/browser/utils/redirect-uri.utils.mjs +22 -0
  114. package/browser/utils/scope-grant.utils.mjs +36 -0
  115. package/browser/utils/token-scopes.utils.mjs +12 -0
  116. package/browser/utils/www-authenticate.utils.mjs +164 -0
  117. package/browser/vault/auth-providers.accessor.impl.mjs +236 -0
  118. package/browser/vault/auth-providers.accessor.mjs +5 -0
  119. package/browser/vault/auth-providers.registry.mjs +140 -0
  120. package/browser/vault/auth-providers.types.mjs +47 -0
  121. package/browser/vault/auth-providers.vault.mjs +206 -0
  122. package/browser/vault/credential-cache.mjs +187 -0
  123. package/browser/vault/credential-helpers.mjs +15 -0
  124. package/browser/vault/credential-loaders/eager-loader.mjs +91 -0
  125. package/browser/vault/credential-loaders/lazy-loader.mjs +120 -0
  126. package/browser/vault/index.mjs +35 -0
  127. package/cimd/cimd.types.d.ts +1 -1
  128. package/cimd/cimd.types.d.ts.map +1 -1
  129. package/common/jwt.types.d.ts +1 -1
  130. package/common/jwt.types.d.ts.map +1 -1
  131. package/common/session.types.d.ts +9 -1
  132. package/common/session.types.d.ts.map +1 -1
  133. package/consent/consent.types.d.ts +1 -1
  134. package/consent/consent.types.d.ts.map +1 -1
  135. package/detection/auth-provider-detection.d.ts +1 -1
  136. package/detection/auth-provider-detection.d.ts.map +1 -1
  137. package/errors/auth-internal.errors.d.ts +6 -0
  138. package/errors/auth-internal.errors.d.ts.map +1 -1
  139. package/errors/index.d.ts +1 -1
  140. package/errors/index.d.ts.map +1 -1
  141. package/esm/index.mjs +2 -2
  142. package/esm/package.json +21 -5
  143. package/index.d.ts +5 -1
  144. package/index.d.ts.map +1 -1
  145. package/index.js +2 -2
  146. package/options/app-auth.schema.d.ts +19 -1
  147. package/options/app-auth.schema.d.ts.map +1 -1
  148. package/options/orchestrated.schema.d.ts +37 -1
  149. package/options/orchestrated.schema.d.ts.map +1 -1
  150. package/options/public.schema.d.ts +1 -1
  151. package/options/public.schema.d.ts.map +1 -1
  152. package/options/schema.d.ts +19 -1
  153. package/options/schema.d.ts.map +1 -1
  154. package/options/shared.schemas.d.ts +10 -14
  155. package/options/shared.schemas.d.ts.map +1 -1
  156. package/options/static.schema.d.ts +1 -1
  157. package/options/static.schema.d.ts.map +1 -1
  158. package/options/transparent.schema.d.ts +1 -1
  159. package/options/transparent.schema.d.ts.map +1 -1
  160. package/package.json +21 -5
  161. package/people/index.d.ts +3 -0
  162. package/people/index.d.ts.map +1 -0
  163. package/people/loopback-token.auth.d.ts +75 -0
  164. package/people/loopback-token.auth.d.ts.map +1 -0
  165. package/people/people-auth.options.d.ts +36 -0
  166. package/people/people-auth.options.d.ts.map +1 -0
  167. package/session/authorization-vault.d.ts +1 -1
  168. package/session/authorization-vault.d.ts.map +1 -1
  169. package/session/encrypted-authorization-vault.d.ts +1 -1
  170. package/session/encrypted-authorization-vault.d.ts.map +1 -1
  171. package/session/secure-store.factory.d.ts.map +1 -1
  172. package/shared-server/index.d.ts +3 -0
  173. package/shared-server/index.d.ts.map +1 -0
  174. package/shared-server/shared-server-identity.d.ts +26 -0
  175. package/shared-server/shared-server-identity.d.ts.map +1 -0
@@ -0,0 +1,128 @@
1
+ var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
2
+ const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
3
+ // __frontmcpCreateRequire
4
+ // libs/auth/src/options/orchestrated.schema.ts
5
+ import { internalZ as z } from "@frontmcp/lazy-zod";
6
+ import {
7
+ cimdConfigSchema,
8
+ consentConfigSchema,
9
+ federatedAuthConfigSchema,
10
+ flatRemoteProviderFields,
11
+ incrementalAuthConfigSchema,
12
+ localDcrConfigSchema,
13
+ localSigningConfigSchema,
14
+ publicAccessConfigSchema,
15
+ secureStoreConfigSchema,
16
+ tokenRefreshConfigSchema,
17
+ tokenStorageConfigSchema,
18
+ upstreamProviderSchema
19
+ } from "./shared.schemas.mjs";
20
+ var authSlotSchema = z.enum(["login", "consent", "incremental", "federated", "error"]);
21
+ var authUiMapSchema = z.partialRecord(authSlotSchema, z.string().min(1));
22
+ var authExtraHandlerSchema = z.custom((v) => typeof v === "function", {
23
+ message: "auth.extras entries must be handler functions (input, ctx) => AuthExtraResult."
24
+ });
25
+ var authExtrasMapSchema = z.record(z.string().min(1), authExtraHandlerSchema);
26
+ var sharedAuthFields = {
27
+ local: localSigningConfigSchema.optional(),
28
+ tokenStorage: tokenStorageConfigSchema.default("memory"),
29
+ // #470 \u2014 backing for the general session secure-secret store (`this.secureStore`).
30
+ // Optional (no default) so an unset value resolves to the in-memory encrypted
31
+ // default at runtime; existing configs are unaffected.
32
+ secureStore: secureStoreConfigSchema.optional(),
33
+ allowDefaultPublic: z.boolean().default(false),
34
+ anonymousScopes: z.array(z.string()).default(["anonymous"]),
35
+ publicAccess: publicAccessConfigSchema.optional(),
36
+ consent: consentConfigSchema.optional(),
37
+ federatedAuth: federatedAuthConfigSchema.optional(),
38
+ refresh: tokenRefreshConfigSchema.optional(),
39
+ expectedAudience: z.union([z.string(), z.array(z.string())]).optional(),
40
+ incrementalAuth: incrementalAuthConfigSchema.optional(),
41
+ /**
42
+ * Require the OAuth client to be KNOWN (registered via DCR / pre-registered,
43
+ * or a CIMD client-id URL) before an authorization request is accepted.
44
+ *
45
+ * @default true
46
+ *
47
+ * SECURITY: an unregistered client id has no trusted `redirect_uris` to
48
+ * validate against, so accepting it lets anyone start a sign-in whose
49
+ * authorization code is delivered to a redirect_uri of their choosing
50
+ * (auth-code interception). `false` is for local development only; a
51
+ * `dcr.allowedRedirectUris` allowlist still constrains such clients.
52
+ */
53
+ requireRegisteredClients: z.boolean().default(true),
54
+ /**
55
+ * Scopes the server may grant (exact values or `*` globs). Requested scopes
56
+ * outside this list are dropped from the grant. Unset \u2192 the standard OpenID
57
+ * scopes only (see `DEFAULT_ALLOWED_SCOPES`).
58
+ */
59
+ allowedScopes: z.array(z.string().trim().min(1, "allowedScopes entries must be non-empty")).optional(),
60
+ cimd: cimdConfigSchema.optional(),
61
+ // #469 \u2014 custom auth UI as a slot\u2192file map + extras name\u2192handler map (per-app
62
+ // under splitByApp). Both optional; omitting them serves the built-in pages.
63
+ ui: authUiMapSchema.optional(),
64
+ extras: authExtrasMapSchema.optional()
65
+ };
66
+ var loginFieldSchema = z.object({
67
+ type: z.enum(["text", "password", "email", "select", "hidden"]),
68
+ label: z.string().optional(),
69
+ required: z.boolean().optional(),
70
+ placeholder: z.string().optional(),
71
+ options: z.array(z.object({ value: z.string(), label: z.string() })).optional()
72
+ });
73
+ var loginConfigSchema = z.object({
74
+ title: z.string().optional(),
75
+ subtitle: z.string().optional(),
76
+ logoUri: z.string().optional(),
77
+ fields: z.record(z.string(), loginFieldSchema).optional(),
78
+ // Full HTML override \u2014 a function, validated structurally like other callbacks
79
+ // in the codebase (see http/cors handlers using z.custom<\u2026>).
80
+ render: z.custom((v) => typeof v === "function", {
81
+ message: "login.render must be a function"
82
+ }).optional(),
83
+ subject: z.object({
84
+ fromField: z.string().optional(),
85
+ strategy: z.enum(["per-session", "per-account"]).optional()
86
+ }).optional()
87
+ });
88
+ var authenticateFnSchema = z.custom((v) => typeof v === "function", {
89
+ message: "authenticate must be a function"
90
+ });
91
+ var localAuthSchema = z.object({
92
+ mode: z.literal("local"),
93
+ ...sharedAuthFields,
94
+ // #468 \u2014 opt-out of the email requirement at /oauth/callback for
95
+ // single-operator local setups. Defaults preserve the historical behavior
96
+ // (email required) so existing configs are unaffected.
97
+ requireEmail: z.boolean().default(true),
98
+ anonymousSubject: z.string().min(1).default("local-operator"),
99
+ // Checkpoint 3a \u2014 declarative login customization + custom verification.
100
+ // Both optional; omitting them preserves the default login path exactly.
101
+ login: loginConfigSchema.optional(),
102
+ authenticate: authenticateFnSchema.optional(),
103
+ // Multi-OAuth-provider orchestration \u2014 declare upstream providers (GitHub,
104
+ // Slack, Jira, \u2026) to federate at /oauth/authorize. Optional; omitting it
105
+ // preserves the default single-operator local login exactly.
106
+ providers: z.array(upstreamProviderSchema).optional(),
107
+ // Local-AS Dynamic Client Registration control surface (#462) \u2014 gate
108
+ // `POST /oauth/register`, allowlist redirect_uris/client_ids, require an
109
+ // initial access token, and seed pre-registered trusted clients. Optional;
110
+ // omitting it preserves today's behavior exactly (DCR on in dev, off in prod;
111
+ // no allowlist; no initial access token).
112
+ dcr: localDcrConfigSchema.optional()
113
+ });
114
+ var remoteAuthSchema = z.object({
115
+ mode: z.literal("remote"),
116
+ ...flatRemoteProviderFields,
117
+ ...sharedAuthFields
118
+ });
119
+ var orchestratedLocalSchema = localAuthSchema;
120
+ var orchestratedRemoteSchema = remoteAuthSchema;
121
+ export {
122
+ authenticateFnSchema,
123
+ localAuthSchema,
124
+ loginConfigSchema,
125
+ orchestratedLocalSchema,
126
+ orchestratedRemoteSchema,
127
+ remoteAuthSchema
128
+ };
@@ -0,0 +1,39 @@
1
+ // libs/auth/src/options/public.schema.ts
2
+ import { internalZ as z } from "@frontmcp/lazy-zod";
3
+ import { jsonWebKeySetSchema, jwkSchema } from "../common/jwt.types.mjs";
4
+ import { publicAccessConfigSchema } from "./shared.schemas.mjs";
5
+ var publicAuthOptionsSchema = z.object({
6
+ mode: z.literal("public"),
7
+ /**
8
+ * Issuer identifier for anonymous JWTs
9
+ * @default auto-derived from server URL
10
+ */
11
+ issuer: z.string().optional(),
12
+ /**
13
+ * Anonymous session TTL in seconds
14
+ * @default 3600 (1 hour)
15
+ */
16
+ sessionTtl: z.number().int().positive().default(3600),
17
+ /**
18
+ * Scopes granted to anonymous sessions
19
+ * @default ['anonymous']
20
+ */
21
+ anonymousScopes: z.array(z.string()).default(["anonymous"]),
22
+ /**
23
+ * Tool/prompt access configuration for anonymous users
24
+ */
25
+ publicAccess: publicAccessConfigSchema.optional(),
26
+ /**
27
+ * JWKS for token verification
28
+ * @default auto-generated
29
+ */
30
+ jwks: jsonWebKeySetSchema.optional(),
31
+ /**
32
+ * Private key for signing anonymous tokens
33
+ * @default auto-generated
34
+ */
35
+ signKey: jwkSchema.or(z.instanceof(Uint8Array)).optional()
36
+ });
37
+ export {
38
+ publicAuthOptionsSchema
39
+ };
@@ -0,0 +1,16 @@
1
+ // libs/auth/src/options/schema.ts
2
+ import { internalZ as z } from "@frontmcp/lazy-zod";
3
+ import { localAuthSchema, remoteAuthSchema } from "./orchestrated.schema.mjs";
4
+ import { publicAuthOptionsSchema } from "./public.schema.mjs";
5
+ import { staticAuthOptionsSchema } from "./static.schema.mjs";
6
+ import { transparentAuthOptionsSchema } from "./transparent.schema.mjs";
7
+ var authOptionsSchema = z.union([
8
+ publicAuthOptionsSchema,
9
+ staticAuthOptionsSchema,
10
+ transparentAuthOptionsSchema,
11
+ localAuthSchema,
12
+ remoteAuthSchema
13
+ ]);
14
+ export {
15
+ authOptionsSchema
16
+ };
@@ -0,0 +1,506 @@
1
+ var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
2
+ const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
3
+ // __frontmcpCreateRequire
4
+ // libs/auth/src/options/shared.schemas.ts
5
+ import { internalZ as z } from "@frontmcp/lazy-zod";
6
+ import { jsonWebKeySetSchema, jwkSchema } from "../common/jwt.types.mjs";
7
+ import { redisConfigSchema } from "../session/transport-session.types.mjs";
8
+ import {
9
+ cimdCacheConfigSchema,
10
+ cimdSecurityConfigSchema,
11
+ cimdNetworkConfigSchema,
12
+ cimdConfigSchema
13
+ } from "../cimd/index.mjs";
14
+ var publicAccessConfigSchema = z.object({
15
+ /**
16
+ * Allow all tools or explicit whitelist
17
+ * @default 'all'
18
+ */
19
+ tools: z.union([z.literal("all"), z.array(z.string())]).default("all"),
20
+ /**
21
+ * Allow all prompts or explicit whitelist
22
+ * @default 'all'
23
+ */
24
+ prompts: z.union([z.literal("all"), z.array(z.string())]).default("all"),
25
+ /**
26
+ * Rate limit per IP per minute
27
+ * @default 60
28
+ */
29
+ rateLimit: z.number().default(60)
30
+ });
31
+ var localSigningConfigSchema = z.object({
32
+ /**
33
+ * Private key for signing tokens
34
+ * @default auto-generated
35
+ */
36
+ signKey: jwkSchema.or(z.instanceof(Uint8Array)).optional(),
37
+ /**
38
+ * JWKS for token verification
39
+ * @default auto-generated
40
+ */
41
+ jwks: jsonWebKeySetSchema.optional(),
42
+ /**
43
+ * Issuer identifier for tokens
44
+ * @default auto-derived from server URL
45
+ */
46
+ issuer: z.string().optional()
47
+ });
48
+ var providerConfigSchema = z.object({
49
+ /** Provider display name */
50
+ name: z.string().optional(),
51
+ /**
52
+ * Unique identifier for this provider
53
+ * @default derived from provider URL
54
+ */
55
+ id: z.string().optional(),
56
+ /**
57
+ * Inline JWKS for offline token verification
58
+ * Falls back to fetching from provider's /.well-known/jwks.json
59
+ */
60
+ jwks: jsonWebKeySetSchema.optional(),
61
+ /** Custom JWKS URI if not at standard path */
62
+ jwksUri: z.string().url().optional(),
63
+ /**
64
+ * Additional `iss` values to trust beyond the provider issuer URL.
65
+ *
66
+ * SECURITY: trusted verbatim \u2014 set only to issuers you control (e.g. a
67
+ * gateway that re-mints tokens), never derived from request or token data.
68
+ * Entries are trimmed and blank values are rejected (a blank issuer would
69
+ * otherwise be trusted as `''`/`'/'`).
70
+ */
71
+ additionalIssuers: z.array(z.string().trim().min(1, "additionalIssuers entries must be non-empty")).optional(),
72
+ /**
73
+ * Validate the token's `iss` claim against the provider issuer (and
74
+ * {@link additionalIssuers}). Defaults to `true`.
75
+ *
76
+ * SECURITY: `false` disables issuer verification entirely \u2014 any token signed
77
+ * by a provider JWKS key is accepted regardless of issuer. Only for a trusted
78
+ * gateway whose re-minted issuer cannot be enumerated; prefer
79
+ * `additionalIssuers` when the issuer set is known.
80
+ */
81
+ verifyIssuer: z.boolean().optional(),
82
+ /**
83
+ * Enable Dynamic Client Registration (DCR)
84
+ * @default false
85
+ */
86
+ dcrEnabled: z.boolean().default(false),
87
+ /** Authorization endpoint override */
88
+ authEndpoint: z.string().url().optional(),
89
+ /** Token endpoint override */
90
+ tokenEndpoint: z.string().url().optional(),
91
+ /** Registration endpoint override (for DCR) */
92
+ registrationEndpoint: z.string().url().optional(),
93
+ /** User info endpoint override */
94
+ userInfoEndpoint: z.string().url().optional()
95
+ });
96
+ var remoteProviderConfigSchema = z.object({
97
+ /**
98
+ * OAuth provider base URL
99
+ * @example 'https://auth.example.com'
100
+ */
101
+ provider: z.string().url(),
102
+ /**
103
+ * Provider display name
104
+ */
105
+ name: z.string().optional(),
106
+ /**
107
+ * Unique identifier for this provider
108
+ * @default derived from provider URL
109
+ */
110
+ id: z.string().optional(),
111
+ /**
112
+ * Inline JWKS for offline token verification
113
+ * Falls back to fetching from provider's /.well-known/jwks.json
114
+ */
115
+ jwks: jsonWebKeySetSchema.optional(),
116
+ /**
117
+ * Custom JWKS URI if not at standard path
118
+ */
119
+ jwksUri: z.string().url().optional(),
120
+ /**
121
+ * Client ID for this MCP server
122
+ */
123
+ clientId: z.string().optional(),
124
+ /**
125
+ * Client secret (for confidential clients)
126
+ */
127
+ clientSecret: z.string().optional(),
128
+ /**
129
+ * Scopes to request from the upstream provider
130
+ */
131
+ scopes: z.array(z.string()).optional(),
132
+ /**
133
+ * Enable Dynamic Client Registration (DCR)
134
+ * @default false
135
+ */
136
+ dcrEnabled: z.boolean().default(false),
137
+ /**
138
+ * Authorization endpoint override
139
+ */
140
+ authEndpoint: z.string().url().optional(),
141
+ /**
142
+ * Token endpoint override
143
+ */
144
+ tokenEndpoint: z.string().url().optional(),
145
+ /**
146
+ * Registration endpoint override (for DCR)
147
+ */
148
+ registrationEndpoint: z.string().url().optional(),
149
+ /**
150
+ * User info endpoint override
151
+ */
152
+ userInfoEndpoint: z.string().url().optional()
153
+ });
154
+ var upstreamProviderSchema = z.object({
155
+ /** Stable provider id (e.g. `'github'`). Used in `this.orchestration.getToken(id)`. */
156
+ id: z.string().min(1),
157
+ /** Human-readable display name. Defaults to `id` when omitted. */
158
+ name: z.string().optional(),
159
+ /** Authorization endpoint (canonical name). */
160
+ authorizationEndpoint: z.string().url().optional(),
161
+ /** Authorization endpoint (alias for {@link authorizationEndpoint}). */
162
+ authorizeUrl: z.string().url().optional(),
163
+ /** Token endpoint (canonical name). */
164
+ tokenEndpoint: z.string().url().optional(),
165
+ /** Token endpoint (alias for {@link tokenEndpoint}). */
166
+ tokenUrl: z.string().url().optional(),
167
+ /** OAuth client id issued by the upstream provider. */
168
+ clientId: z.string().min(1),
169
+ /** OAuth client secret (confidential clients). */
170
+ clientSecret: z.string().optional(),
171
+ /** Scopes to request from the upstream provider. */
172
+ scopes: z.array(z.string()).optional(),
173
+ /** User info endpoint (optional, used to enrich the session identity). */
174
+ userInfoEndpoint: z.string().url().optional(),
175
+ /** JWKS URI for upstream id_token validation (optional). */
176
+ jwksUri: z.string().url().optional(),
177
+ /**
178
+ * The provider's issuer identifier (its OIDC `iss`). When set, an RFC 9207
179
+ * `iss` on the provider's callback and the `iss` of its `id_token` must name
180
+ * it (or one of {@link additionalIssuers}). Without it the provider's
181
+ * `id_token` is not used for identity; `userInfoEndpoint` is asked instead.
182
+ */
183
+ issuer: z.string().url().optional(),
184
+ /** Other issuer values this provider legitimately uses. */
185
+ additionalIssuers: z.array(z.string().trim().min(1, "additionalIssuers entries must be non-empty")).optional()
186
+ }).refine((p) => !!(p.authorizationEndpoint ?? p.authorizeUrl), {
187
+ message: "authorizationEndpoint (or authorizeUrl) is required",
188
+ path: ["authorizationEndpoint"]
189
+ }).refine((p) => !!(p.tokenEndpoint ?? p.tokenUrl), {
190
+ message: "tokenEndpoint (or tokenUrl) is required",
191
+ path: ["tokenEndpoint"]
192
+ }).refine((p) => !(p.authorizationEndpoint && p.authorizeUrl), {
193
+ message: "provide only one of authorizationEndpoint or authorizeUrl",
194
+ path: ["authorizationEndpoint"]
195
+ }).refine((p) => !(p.tokenEndpoint && p.tokenUrl), {
196
+ message: "provide only one of tokenEndpoint or tokenUrl",
197
+ path: ["tokenEndpoint"]
198
+ });
199
+ var localDcrClientSchema = z.object({
200
+ /** Stable, pre-assigned client identifier the client authenticates with. */
201
+ clientId: z.string().min(1),
202
+ /**
203
+ * Confidential-client secret. Omit for public clients
204
+ * (`token_endpoint_auth_method: 'none'`, the default).
205
+ */
206
+ clientSecret: z.string().min(1).optional(),
207
+ /** Exact redirect URIs this client is allowed to use (at least one). */
208
+ redirectUris: z.array(z.string().url()).min(1, "At least one redirect_uri is required"),
209
+ /** Human-readable name shown on consent/login screens. */
210
+ clientName: z.string().optional(),
211
+ /**
212
+ * Token-endpoint auth method. Defaults to `'none'` (public PKCE client).
213
+ */
214
+ tokenEndpointAuthMethod: z.enum(["none", "client_secret_basic", "client_secret_post"]).default("none"),
215
+ /** Allowed grant types. Defaults to `['authorization_code']`. */
216
+ grantTypes: z.array(z.enum(["authorization_code", "refresh_token"])).default(["authorization_code"]),
217
+ /** Allowed response types. Defaults to `['code']`. */
218
+ responseTypes: z.array(z.enum(["code"])).default(["code"]),
219
+ /** Optional space-delimited default scope string. */
220
+ scope: z.string().optional()
221
+ });
222
+ var localDcrConfigSchema = z.object({
223
+ /**
224
+ * Whether `POST /oauth/register` is mounted/active and whether
225
+ * `registration_endpoint` is advertised in AS metadata.
226
+ *
227
+ * When unset (default), the historical guard applies: enabled in
228
+ * development, disabled in production. Set explicitly to force it on or off
229
+ * regardless of `NODE_ENV`.
230
+ */
231
+ enabled: z.boolean().optional(),
232
+ /**
233
+ * Allowlist of redirect URIs. Each entry is matched EXACTLY or as a simple
234
+ * glob (`*` matches any run of characters). When set, both DCR registrations
235
+ * and `/oauth/authorize` requests are rejected unless their `redirect_uri`
236
+ * matches an entry. When unset, no redirect_uri allowlist is enforced.
237
+ */
238
+ allowedRedirectUris: z.array(z.string().min(1)).optional(),
239
+ /**
240
+ * Allowlist of client ids. When set, only these `client_id`s may register
241
+ * (DCR registrations are forced to one of these ids) or be used at
242
+ * `/oauth/authorize`. When unset, any client id is accepted (subject to the
243
+ * other checks). CIMD URL client ids are validated by the CIMD layer and are
244
+ * exempt from this allowlist.
245
+ */
246
+ allowedClientIds: z.array(z.string().min(1)).optional(),
247
+ /**
248
+ * Initial Access Token (RFC 7591 \u00a73). When set, `POST /oauth/register`
249
+ * requires an `Authorization: Bearer <token>` header that matches this value
250
+ * (constant-time compared); requests without it (or with a wrong value) are
251
+ * rejected `401 invalid_token`. When unset, registration is unauthenticated
252
+ * (the historical behavior).
253
+ */
254
+ initialAccessToken: z.string().min(1).optional(),
255
+ /**
256
+ * Pre-registered trusted clients seeded into the registry at startup. These
257
+ * are accepted by the authorize/token flows WITHOUT a DCR round-trip, which
258
+ * lets you disable DCR entirely while still shipping known clients.
259
+ */
260
+ clients: z.array(localDcrClientSchema).optional(),
261
+ /**
262
+ * Maximum number of DYNAMICALLY-registered (DCR) clients kept in memory.
263
+ * Once reached, further dynamic registrations are REJECTED (existing clients,
264
+ * including confidential ones, are preserved \u2014 never evicted). A cap of `0`
265
+ * disables dynamic registration entirely. Pre-registered / declarative
266
+ * `clients` never count toward this cap. Defaults to 1000; guards against
267
+ * unbounded memory growth from unauthenticated DCR.
268
+ */
269
+ maxDynamicClients: z.number().int().min(0).optional()
270
+ });
271
+ var flatRemoteProviderFields = {
272
+ /**
273
+ * OAuth provider base URL (required)
274
+ * @example 'https://auth.example.com'
275
+ */
276
+ provider: z.string().url(),
277
+ /** Client ID for this MCP server */
278
+ clientId: z.string().optional(),
279
+ /** Client secret (for confidential clients) */
280
+ clientSecret: z.string().optional(),
281
+ /** Scopes to request from the upstream provider */
282
+ scopes: z.array(z.string()).optional(),
283
+ /** Advanced provider configuration */
284
+ providerConfig: providerConfigSchema.optional()
285
+ };
286
+ var tokenStorageSqliteSchema = z.object({
287
+ /** Path to the `.sqlite` database file used for auth persistence. */
288
+ path: z.string().min(1),
289
+ /**
290
+ * Encryption configuration for at-rest encryption of stored values.
291
+ * Independent of the AES-GCM blob encryption already applied to upstream
292
+ * provider tokens by the orchestrated-token store.
293
+ */
294
+ encryption: z.object({
295
+ secret: z.string().min(1)
296
+ }).optional(),
297
+ /**
298
+ * Interval in milliseconds for purging expired keys.
299
+ * @default 60000
300
+ */
301
+ ttlCleanupIntervalMs: z.number().int().nonnegative().optional(),
302
+ /**
303
+ * Enable WAL mode for better read concurrency.
304
+ * @default true
305
+ */
306
+ walMode: z.boolean().optional(),
307
+ /**
308
+ * Milliseconds to wait for a lock held by another process before a write
309
+ * fails with `SQLITE_BUSY`.
310
+ * @default 5000
311
+ */
312
+ busyTimeoutMs: z.number().int().nonnegative().optional()
313
+ });
314
+ var tokenStorageConfigSchema = z.union([
315
+ z.literal("memory"),
316
+ z.object({ redis: redisConfigSchema }),
317
+ z.object({ sqlite: tokenStorageSqliteSchema })
318
+ ]);
319
+ var secureStoreScopeSchema = z.enum(["user", "session", "global"]);
320
+ var secureStoreEncryptionSchema = z.object({
321
+ /**
322
+ * Server pepper mixed into HKDF key derivation (defense-in-depth). Defaults to
323
+ * `VAULT_SECRET ?? JWT_SECRET` at runtime when omitted.
324
+ */
325
+ pepper: z.string().min(1).optional()
326
+ });
327
+ var secureStoreCustomBackendSchema = z.custom(
328
+ (v) => typeof v === "object" && v !== null && typeof v.get === "function" && typeof v.set === "function" && typeof v.delete === "function" && typeof v.list === "function",
329
+ { message: "secureStore.backend must implement get/set/delete/list (SecureStoreBackend)" }
330
+ );
331
+ var secureStoreCommonFields = {
332
+ /** Namespace scope. @default 'user' */
333
+ scope: secureStoreScopeSchema.optional(),
334
+ /** Default TTL (ms) for stored secrets. @default undefined (no expiry) */
335
+ ttlMs: z.number().int().positive().optional(),
336
+ /** At-rest encryption settings (built-in backings only). */
337
+ encryption: secureStoreEncryptionSchema.optional()
338
+ };
339
+ var secureStoreBackingSchemas = {
340
+ sqlite: tokenStorageSqliteSchema,
341
+ redis: redisConfigSchema,
342
+ backend: secureStoreCustomBackendSchema
343
+ };
344
+ function secureStoreBackingError(issue) {
345
+ if (typeof issue.input !== "object" || issue.input === null) return void 0;
346
+ const config = issue.input;
347
+ const named = Object.keys(secureStoreBackingSchemas).filter((backing) => config[backing] !== void 0);
348
+ if (named.length > 1) return `secureStore takes one backing, not ${named.join(" and ")}`;
349
+ for (const [backing, schema] of Object.entries(secureStoreBackingSchemas)) {
350
+ if (config[backing] === void 0) continue;
351
+ const nested = schema.safeParse(config[backing]).error?.issues[0];
352
+ if (!nested) continue;
353
+ const where = ["secureStore", backing, ...nested.path.map(String)].join(".");
354
+ return nested.message.startsWith(where) ? nested.message : `${where}: ${nested.message}`;
355
+ }
356
+ return void 0;
357
+ }
358
+ var noBacking = {
359
+ sqlite: z.undefined().optional(),
360
+ redis: z.undefined().optional(),
361
+ backend: z.undefined().optional()
362
+ };
363
+ var secureStoreConfigSchema = z.union(
364
+ [
365
+ z.literal("memory"),
366
+ z.object({ ...noBacking, sqlite: secureStoreBackingSchemas.sqlite, ...secureStoreCommonFields }),
367
+ z.object({ ...noBacking, redis: secureStoreBackingSchemas.redis, ...secureStoreCommonFields }),
368
+ z.object({ ...noBacking, backend: secureStoreBackingSchemas.backend, ...secureStoreCommonFields }),
369
+ z.object({ ...noBacking, ...secureStoreCommonFields })
370
+ ],
371
+ { error: secureStoreBackingError }
372
+ );
373
+ var tokenRefreshConfigSchema = z.object({
374
+ /**
375
+ * Enable automatic token refresh
376
+ * @default true
377
+ */
378
+ enabled: z.boolean().default(true),
379
+ /**
380
+ * Refresh token before expiry by this many seconds
381
+ * @default 60
382
+ */
383
+ skewSeconds: z.number().nonnegative().default(60)
384
+ });
385
+ var skippedAppBehaviorSchema = z.enum(["anonymous", "require-auth"]);
386
+ var consentConfigSchema = z.object({
387
+ /**
388
+ * Enable consent flow for tool selection
389
+ * When enabled, users can choose which tools to expose to the LLM
390
+ * @default false
391
+ */
392
+ enabled: z.boolean().default(false),
393
+ /**
394
+ * Group tools by app in the consent UI
395
+ * @default true
396
+ */
397
+ groupByApp: z.boolean().default(true),
398
+ /**
399
+ * Show tool descriptions in consent UI
400
+ * @default true
401
+ */
402
+ showDescriptions: z.boolean().default(true),
403
+ /**
404
+ * Allow selecting all tools at once
405
+ * @default true
406
+ */
407
+ allowSelectAll: z.boolean().default(true),
408
+ /**
409
+ * Require at least one tool to be selected
410
+ * @default true
411
+ */
412
+ requireSelection: z.boolean().default(true),
413
+ /**
414
+ * Custom message to display on consent page
415
+ */
416
+ customMessage: z.string().optional(),
417
+ /**
418
+ * Remember consent for future sessions
419
+ * @default true
420
+ */
421
+ rememberConsent: z.boolean().default(true),
422
+ /**
423
+ * Tools to exclude from consent (always available)
424
+ * Useful for essential tools that should always be accessible
425
+ */
426
+ excludedTools: z.array(z.string()).optional(),
427
+ /**
428
+ * Tools to always include in consent (pre-selected)
429
+ */
430
+ defaultSelectedTools: z.array(z.string()).optional()
431
+ });
432
+ var federatedAuthConfigSchema = z.object({
433
+ /**
434
+ * How strictly to validate the OAuth state parameter on provider callbacks.
435
+ * - 'strict': require exact match to stored state (default, safest)
436
+ * - 'format': validate only "federated:{sessionId}:{nonce}" format
437
+ * @default 'strict'
438
+ */
439
+ stateValidation: z.enum(["strict", "format"]).default("strict"),
440
+ /**
441
+ * Minimum number of upstream providers a user must link before a FrontMCP JWT
442
+ * is minted. The federated callback refuses to issue a token until at least
443
+ * this many providers have been authorized. Defaults to `1` at runtime when
444
+ * `providers` are configured (i.e. "no JWT until \u22651 linked"). Left optional
445
+ * here so existing configs without `providers` are completely unaffected.
446
+ */
447
+ minProviders: z.number().int().positive().optional(),
448
+ /**
449
+ * Provider ids that MUST be among the linked providers before a JWT is minted.
450
+ * The federated callback rejects the login unless every id listed here is in
451
+ * the user's selected providers. Optional \u2014 omit to allow any combination that
452
+ * satisfies {@link minProviders}.
453
+ */
454
+ requiredProviders: z.array(z.string()).optional()
455
+ });
456
+ var incrementalAuthConfigSchema = z.object({
457
+ /**
458
+ * Enable incremental (progressive) authorization
459
+ * When enabled, users can skip app authorizations during initial auth
460
+ * and authorize individual apps later when needed
461
+ * @default true
462
+ */
463
+ enabled: z.boolean().default(true),
464
+ /**
465
+ * Behavior when a tool from a skipped app is called
466
+ * - 'anonymous': If app supports anonymous access, use it; otherwise require auth
467
+ * - 'require-auth': Always require authorization (return auth_url)
468
+ * @default 'anonymous'
469
+ */
470
+ skippedAppBehavior: skippedAppBehaviorSchema.default("anonymous"),
471
+ /**
472
+ * Allow users to skip app authorization during initial auth flow
473
+ * @default true
474
+ */
475
+ allowSkip: z.boolean().default(true),
476
+ /**
477
+ * Show all apps in a single authorization page (vs step-by-step)
478
+ * @default true
479
+ */
480
+ showAllAppsAtOnce: z.boolean().default(true)
481
+ });
482
+ export {
483
+ cimdCacheConfigSchema,
484
+ cimdConfigSchema,
485
+ cimdNetworkConfigSchema,
486
+ cimdSecurityConfigSchema,
487
+ consentConfigSchema,
488
+ federatedAuthConfigSchema,
489
+ flatRemoteProviderFields,
490
+ incrementalAuthConfigSchema,
491
+ localDcrClientSchema,
492
+ localDcrConfigSchema,
493
+ localSigningConfigSchema,
494
+ providerConfigSchema,
495
+ publicAccessConfigSchema,
496
+ remoteProviderConfigSchema,
497
+ secureStoreConfigSchema,
498
+ secureStoreCustomBackendSchema,
499
+ secureStoreEncryptionSchema,
500
+ secureStoreScopeSchema,
501
+ skippedAppBehaviorSchema,
502
+ tokenRefreshConfigSchema,
503
+ tokenStorageConfigSchema,
504
+ tokenStorageSqliteSchema,
505
+ upstreamProviderSchema
506
+ };