@mastra/core
Version:
1 lines • 78.5 kB
Source Map (JSON)
{"version":3,"file":"ee-DXvSoTl7-C7miIhtq.cjs","names":[],"sources":["../../_internals/auth/dist/capabilities-ZXD8uYsD.js","../../_internals/auth/dist/ee-DXvSoTl7.js"],"sourcesContent":["import { createHash } from \"crypto\";\nimport os from \"os\";\n//#region src/ee/telemetry.ts\nfunction hashTelemetryValue(value) {\n\treturn createHash(\"sha256\").update(value).digest(\"hex\");\n}\nfunction getHashedHostname() {\n\treturn hashTelemetryValue(os.hostname() || \"unknown-host\").slice(0, 16);\n}\nfunction getEETelemetryFallbackDistinctId() {\n\treturn `mastra-${getHashedHostname()}`;\n}\nconst EE_TELEMETRY_BRIDGE = Symbol.for(\"mastra.eeTelemetryBridge\");\nfunction getTelemetryBridge() {\n\treturn globalThis[EE_TELEMETRY_BRIDGE];\n}\nfunction captureEEEvent(event, distinctId, properties) {\n\tgetTelemetryBridge()?.captureEEEvent?.(event, distinctId, properties);\n}\n//#endregion\n//#region src/ee/license.ts\n/**\n* License validation for EE features.\n*\n* Validation is delegated to the Mastra license server via `LicenseClient`\n* (POST {MASTRA_LICENSE_URL}/validate). The client validates in the\n* background and caches the result; the synchronous helpers in this module\n* read the cached state:\n*\n* - No license key configured → EE features disabled.\n* - Key configured, validation pending → fail open (features enabled) until\n* the first server response settles the state.\n* - Server says invalid/revoked/expired → EE features disabled.\n* - Server unreachable → fail open with a 72h grace period for previously\n* validated licenses.\n*\n* `MASTRA_LICENSE_KEY` is the primary env var; `MASTRA_EE_LICENSE` is a\n* supported legacy alias.\n*/\nvar LicenseClient = class LicenseClient {\n\tstatic instance;\n\tlogger;\n\tlicenseKey;\n\tlicenseUrl;\n\tmode = \"open-source\";\n\tstatus = \"pending\";\n\tcachedResult = null;\n\tcacheExpiry = 0;\n\tgracePeriodEnd = 0;\n\trevalidationTimeout = null;\n\tGRACE_PERIOD_MS = 4320 * 60 * 1e3;\n\tDEFAULT_TTL_MS = 1440 * 60 * 1e3;\n\tconstructor(logger) {\n\t\tthis.logger = logger;\n\t\tthis.licenseKey = process.env.MASTRA_LICENSE_KEY || process.env.MASTRA_EE_LICENSE;\n\t\tthis.licenseUrl = process.env.MASTRA_LICENSE_URL || \"https://license.mastra.ai\";\n\t\tif (this.licenseKey) this.mode = \"enterprise\";\n\t\telse this.mode = \"open-source\";\n\t}\n\tstatic getInstance(logger) {\n\t\tif (!LicenseClient.instance) LicenseClient.instance = new LicenseClient(logger);\n\t\telse if (logger) LicenseClient.instance.logger = logger;\n\t\treturn LicenseClient.instance;\n\t}\n\t/**\n\t* Reset the singleton so the next getInstance() re-reads env vars.\n\t* Intended for tests.\n\t*/\n\tstatic resetInstance() {\n\t\tif (LicenseClient.instance?.revalidationTimeout) clearTimeout(LicenseClient.instance.revalidationTimeout);\n\t\tLicenseClient.instance = void 0;\n\t}\n\tREQUEST_TIMEOUT_MS = 1e4;\n\tasync fetchWithRetry(url, options, retries = 3) {\n\t\tfor (let i = 0; i < retries; i++) {\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timer = setTimeout(() => controller.abort(), this.REQUEST_TIMEOUT_MS);\n\t\t\ttimer.unref?.();\n\t\t\ttry {\n\t\t\t\tconst signal = options.signal ? AbortSignal.any([options.signal, controller.signal]) : controller.signal;\n\t\t\t\tconst response = await fetch(url, {\n\t\t\t\t\t...options,\n\t\t\t\t\tsignal\n\t\t\t\t});\n\t\t\t\tif (response.status === 429 || response.status >= 500) {\n\t\t\t\t\tif (i === retries - 1) return response;\n\t\t\t\t} else return response;\n\t\t\t} catch (error) {\n\t\t\t\tif (i === retries - 1) throw error;\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tconst delay = Math.pow(2, i) * 1e3;\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay));\n\t\t}\n\t\tthrow new Error(\"Unreachable\");\n\t}\n\tvalidationPromise = null;\n\tasync validate() {\n\t\tif (this.mode === \"open-source\") return true;\n\t\tif (this.cachedResult && Date.now() < this.cacheExpiry) return true;\n\t\treturn this.revalidate();\n\t}\n\t/**\n\t* Contact the server regardless of cache freshness, coalescing concurrent\n\t* callers (e.g. the Mastra constructor and the auth/ee helpers both kicking\n\t* off validation at startup) into a single in-flight request so the server\n\t* is contacted — and the outcome logged — only once. Used directly by the\n\t* background revalidation timer, which must bypass the cache check.\n\t*/\n\trevalidate() {\n\t\tif (!this.validationPromise) this.validationPromise = this.performValidation().finally(() => {\n\t\t\tthis.validationPromise = null;\n\t\t});\n\t\treturn this.validationPromise;\n\t}\n\tasync performValidation() {\n\t\tconst now = Date.now();\n\t\ttry {\n\t\t\tif (!this.licenseUrl?.startsWith(\"https://\") && !this.licenseUrl?.includes(\"localhost\")) this.logger?.warn(\"License URL is not HTTPS. Proceeding, but this is insecure.\");\n\t\t\tconst response = await this.fetchWithRetry(`${this.licenseUrl}/validate`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({ licenseKey: this.licenseKey })\n\t\t\t});\n\t\t\tif (response.status === 429 || response.status >= 500) throw new Error(`License server responded with ${response.status}`);\n\t\t\tconst data = await response.json();\n\t\t\tif (data.valid) {\n\t\t\t\tthis.status = \"valid\";\n\t\t\t\tthis.logger?.info(`License validated: ${data.planTier} tier${data.expiresAt ? `, expires ${data.expiresAt.slice(0, 10)}` : \"\"}`);\n\t\t\t\tthis.cachedResult = data;\n\t\t\t\tconst ttlSeconds = data.leaseTtlSeconds || this.DEFAULT_TTL_MS / 1e3;\n\t\t\t\tthis.cacheExpiry = now + ttlSeconds * 1e3;\n\t\t\t\tthis.gracePeriodEnd = now + this.GRACE_PERIOD_MS;\n\t\t\t\tthis.scheduleRevalidation(ttlSeconds);\n\t\t\t\treturn true;\n\t\t\t} else if (data.code === \"RATE_LIMITED\") throw new Error(`License server rate limited: ${data.reason}`);\n\t\t\telse {\n\t\t\t\tthis.status = \"invalid\";\n\t\t\t\tthis.logger?.error(`License validation failed: ${data.code} - ${data.reason}`);\n\t\t\t\tthis.clearCache();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch {\n\t\t\tif (this.cachedResult && now < this.gracePeriodEnd) {\n\t\t\t\tthis.logger?.warn(\"License server unreachable. Using cached license (within grace period).\");\n\t\t\t\tthis.status = \"valid\";\n\t\t\t\tthis.scheduleRevalidation(this.DEFAULT_TTL_MS / 1e3);\n\t\t\t\treturn true;\n\t\t\t} else if (this.cachedResult) {\n\t\t\t\tthis.logger?.error(\"License server unreachable and grace period expired. Disabling enterprise features.\");\n\t\t\t\tthis.status = \"invalid\";\n\t\t\t\tthis.clearCache();\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tthis.logger?.warn(\"License server unreachable on startup. Failing open (allowing features) and will retry.\");\n\t\t\t\tthis.status = \"valid\";\n\t\t\t\tthis.cachedResult = {\n\t\t\t\t\tvalid: true,\n\t\t\t\t\tentitlements: [],\n\t\t\t\t\tplanTier: \"unknown\",\n\t\t\t\t\texpiresAt: null,\n\t\t\t\t\tleaseTtlSeconds: 300\n\t\t\t\t};\n\t\t\t\tthis.cacheExpiry = now + 300 * 1e3;\n\t\t\t\tthis.gracePeriodEnd = now + this.GRACE_PERIOD_MS;\n\t\t\t\tthis.scheduleRevalidation(300);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\tscheduleRevalidation(ttlSeconds) {\n\t\tif (this.revalidationTimeout) clearTimeout(this.revalidationTimeout);\n\t\tconst revalidateMs = ttlSeconds * 1e3 * .75;\n\t\tthis.revalidationTimeout = setTimeout(() => {\n\t\t\tthis.logger?.info(\"Performing background license revalidation...\");\n\t\t\tthis.revalidate().catch((err) => {\n\t\t\t\tthis.logger?.error(`Background license revalidation failed: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t});\n\t\t}, revalidateMs);\n\t\tthis.revalidationTimeout.unref();\n\t}\n\tclearCache() {\n\t\tthis.cachedResult = null;\n\t\tthis.cacheExpiry = 0;\n\t\tthis.gracePeriodEnd = 0;\n\t\tthis.status = \"invalid\";\n\t\tif (this.revalidationTimeout) {\n\t\t\tclearTimeout(this.revalidationTimeout);\n\t\t\tthis.revalidationTimeout = null;\n\t\t}\n\t}\n\thasFeature(featureName) {\n\t\tif (this.mode === \"open-source\") return true;\n\t\tif (this.status === \"pending\") return true;\n\t\tif (this.status === \"invalid\") return false;\n\t\tif (!this.cachedResult) return false;\n\t\tif (this.cachedResult.planTier === \"unknown\") return true;\n\t\treturn this.cachedResult.entitlements.includes(featureName);\n\t}\n\tgetEntitlements() {\n\t\tif (this.mode === \"open-source\") return null;\n\t\treturn this.cachedResult?.entitlements || null;\n\t}\n\tgetSnapshot() {\n\t\treturn {\n\t\t\tmode: this.mode,\n\t\t\tstatus: this.status,\n\t\t\tentitlements: this.cachedResult?.entitlements ?? null,\n\t\t\tplanTier: this.cachedResult?.planTier ?? null,\n\t\t\texpiresAt: this.cachedResult?.expiresAt ?? null\n\t\t};\n\t}\n};\n/**\n* Resolve the configured license key.\n* `MASTRA_LICENSE_KEY` is primary; `MASTRA_EE_LICENSE` is a supported legacy alias.\n*/\nfunction getLicenseKey() {\n\treturn process.env[\"MASTRA_LICENSE_KEY\"] || process.env[\"MASTRA_EE_LICENSE\"];\n}\nlet validationStarted = false;\nlet hasWarnedAboutDevLicense = false;\n/**\n* Get the shared LicenseClient and kick off background validation on first use.\n*/\nfunction getClient() {\n\tconst client = LicenseClient.getInstance();\n\tif (!validationStarted) {\n\t\tvalidationStarted = true;\n\t\tclient.validate().catch(() => {});\n\t}\n\treturn client;\n}\n/**\n* Start license validation against the license server.\n*\n* Safe to call multiple times — the underlying client caches results and\n* schedules its own background revalidation. Resolves to whether the license\n* is currently considered valid.\n*/\nfunction startLicenseValidation() {\n\tconst client = LicenseClient.getInstance();\n\tvalidationStarted = true;\n\treturn client.validate();\n}\n/**\n* Validate the configured license and return license information.\n*\n* Reflects the current server-backed validation state. The actual network\n* validation happens in the background via `LicenseClient`, and only the\n* configured key (env var) is ever validated — passing any other key\n* returns invalid.\n*\n* @param licenseKey - Optional key to check; must match the configured key.\n* @returns License information\n*/\nfunction validateLicense(licenseKey) {\n\tconst configuredKey = getLicenseKey();\n\tif (!(licenseKey ?? configuredKey)) return { valid: false };\n\tif (licenseKey !== void 0 && licenseKey !== configuredKey) return { valid: false };\n\tconst snap = getClient().getSnapshot();\n\treturn {\n\t\tvalid: snap.status !== \"invalid\",\n\t\tfeatures: snap.entitlements ?? void 0,\n\t\ttier: snap.planTier ?? void 0,\n\t\texpiresAt: snap.expiresAt ? new Date(snap.expiresAt) : void 0\n\t};\n}\n/**\n* Check if EE features are enabled (valid or pending server validation).\n*\n* @returns True if EE features should be enabled\n*/\nfunction isLicenseValid() {\n\tif (!getLicenseKey()) return false;\n\treturn getClient().getSnapshot().status !== \"invalid\";\n}\n/**\n* @deprecated Use `isLicenseValid()` instead. This alias is provided for backward compatibility.\n*/\nconst isEELicenseValid = isLicenseValid;\n/**\n* Check if a specific EE feature is enabled by the license entitlements.\n*\n* @param feature - Feature name to check (e.g. 'rbac', 'fga', 'sso')\n* @returns True if the feature is enabled\n*/\nfunction isFeatureEnabled(feature) {\n\tif (!getLicenseKey()) return false;\n\treturn getClient().hasFeature(feature);\n}\nfunction getSafeLicenseSummary() {\n\tconst key = getLicenseKey();\n\tconst info = validateLicense(key);\n\tconst licenseHash = key ? hashTelemetryValue(key) : void 0;\n\treturn {\n\t\tvalid: info.valid,\n\t\tisDevEnvironment: isDevEnvironment(),\n\t\tlicenseHash: licenseHash ? licenseHash.slice(0, 16) : void 0,\n\t\tanonymousId: licenseHash ? `${licenseHash.slice(0, 16)}-anonymous` : void 0,\n\t\tfeatures: info.features,\n\t\ttier: info.tier\n\t};\n}\nfunction warnIfDevEENeedsLicense() {\n\tif (hasWarnedAboutDevLicense || !isDevEnvironment() || isLicenseValid()) return;\n\thasWarnedAboutDevLicense = true;\n\tconsole.warn(\"[mastra/auth-ee] Mastra Enterprise features are enabled for local development, but no valid MASTRA_LICENSE_KEY is configured. These features will be disabled in production without a valid license. Contact us to get a production license: https://mastra.ai/contact\");\n}\n/**\n* Clear the license cache (useful for testing).\n* Resets the shared client so the next check re-reads env vars.\n*/\nfunction clearLicenseCache() {\n\tvalidationStarted = false;\n\thasWarnedAboutDevLicense = false;\n\tLicenseClient.resetInstance();\n}\n/**\n* Check if running in a development/testing environment.\n* In dev, EE features work without a license per the ee/LICENSE terms.\n*/\nfunction isDevEnvironment() {\n\treturn process.env[\"MASTRA_DEV\"] === \"true\" || process.env[\"MASTRA_DEV\"] === \"1\" || process.env[\"NODE_ENV\"] !== \"production\" && process.env[\"NODE_ENV\"] !== \"prod\";\n}\n/**\n* Check if EE features should be active.\n* Returns true if running in dev/test environment (always allowed) or if a valid license is present.\n*/\nfunction isEEEnabled() {\n\tif (isDevEnvironment()) {\n\t\twarnIfDevEENeedsLicense();\n\t\treturn true;\n\t}\n\treturn isLicenseValid();\n}\n//#endregion\n//#region src/ee/capabilities.ts\n/**\n* Type guard to check if response is authenticated.\n*/\nfunction isAuthenticated(caps) {\n\treturn \"user\" in caps && caps.user !== null;\n}\n/**\n* Check if an auth provider implements a specific interface.\n*/\nfunction implementsInterface(auth, method) {\n\treturn auth !== null && typeof auth === \"object\" && typeof auth[method] === \"function\";\n}\n/**\n* Check if auth provider is MastraCloudAuth (exempt from license requirement).\n*/\nfunction isMastraCloudAuth(auth) {\n\tif (!auth || typeof auth !== \"object\") return false;\n\treturn \"isMastraCloudAuth\" in auth && auth.isMastraCloudAuth === true;\n}\n/**\n* Check if auth provider is SimpleAuth (exempt from license requirement).\n* SimpleAuth is for development/testing and should work without a license.\n*/\nfunction isSimpleAuth(auth) {\n\tif (!auth || typeof auth !== \"object\") return false;\n\treturn \"isSimpleAuth\" in auth && auth.isSimpleAuth === true;\n}\n/**\n* Check if a set of permissions includes admin bypass (`*` or `*:*`).\n*/\nfunction hasAdminBypassPermissions(permissions) {\n\treturn permissions.some((p) => p === \"*\" || p === \"*:*\");\n}\nfunction getRequestIp(request) {\n\tconst forwardedFor = request.headers.get(\"x-forwarded-for\");\n\tif (forwardedFor) return forwardedFor.split(\",\")[0]?.trim();\n\treturn request.headers.get(\"x-real-ip\") ?? void 0;\n}\nfunction captureLicenseCheck({ request, user, hasLicense, isDev, isCloud, isSimple, capabilities }) {\n\tconst license = getSafeLicenseSummary();\n\ttry {\n\t\tconst ip = getRequestIp(request);\n\t\tcaptureEEEvent(\"ee_license_check\", user?.id || license.anonymousId || getEETelemetryFallbackDistinctId(), {\n\t\t\tlicense_valid: hasLicense,\n\t\t\tlicense_hash: license.licenseHash,\n\t\t\tis_dev_environment: isDev,\n\t\t\tis_cloud: isCloud,\n\t\t\tis_simple_auth: isSimple,\n\t\t\tcapabilities,\n\t\t\tuser_id: user?.id,\n\t\t\t$ip: ip,\n\t\t\tlicense_features: license.features,\n\t\t\tlicense_tier: license.tier\n\t\t});\n\t} catch {}\n}\n/**\n* Build capabilities response based on auth configuration and request state.\n*\n* This function determines what capabilities are available and, if the user\n* is authenticated, includes their user info and access permissions.\n*\n* @param auth - Auth provider (or null if no auth configured)\n* @param request - Incoming HTTP request\n* @param options - Optional configuration (roleMapping, etc.)\n* @returns Capabilities response (public or authenticated)\n*/\nasync function buildCapabilities(auth, request, options) {\n\tif (!auth) return {\n\t\tenabled: false,\n\t\tlogin: null\n\t};\n\tconst hasLicense = isLicenseValid();\n\tconst isCloud = isMastraCloudAuth(auth);\n\tconst isSimple = isSimpleAuth(auth);\n\tconst isDev = isDevEnvironment();\n\tif (isDev && !hasLicense) warnIfDevEENeedsLicense();\n\tconst isLicensedOrCloud = hasLicense || isCloud || isSimple || isDev;\n\tconst isFeatureLicensed = (feature) => isCloud || isSimple || isDev || hasLicense && isFeatureEnabled(feature);\n\tlet login = null;\n\tconst hasSSO = implementsInterface(auth, \"getLoginUrl\") && isLicensedOrCloud;\n\tconst hasCredentials = implementsInterface(auth, \"signIn\") && isLicensedOrCloud;\n\tconst raw = (options?.apiPrefix || \"/api\").trim();\n\tconst withSlash = raw.startsWith(\"/\") ? raw : `/${raw}`;\n\tconst ssoLoginUrl = `${withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash}/auth/sso/login`;\n\tlet signUpEnabled = true;\n\tif (implementsInterface(auth, \"signIn\")) {\n\t\tconst credentialsProvider = auth;\n\t\tif (typeof credentialsProvider.isSignUpEnabled === \"function\") signUpEnabled = credentialsProvider.isSignUpEnabled();\n\t}\n\tif (hasSSO && hasCredentials) {\n\t\tconst ssoConfig = auth.getLoginButtonConfig();\n\t\tlogin = {\n\t\t\ttype: \"both\",\n\t\t\tsignUpEnabled,\n\t\t\tdescription: ssoConfig.description,\n\t\t\tsso: {\n\t\t\t\t...ssoConfig,\n\t\t\t\turl: ssoLoginUrl\n\t\t\t}\n\t\t};\n\t} else if (hasSSO) {\n\t\tconst ssoConfig = auth.getLoginButtonConfig();\n\t\tlogin = {\n\t\t\ttype: \"sso\",\n\t\t\tdescription: ssoConfig.description,\n\t\t\tsso: {\n\t\t\t\t...ssoConfig,\n\t\t\t\turl: ssoLoginUrl\n\t\t\t}\n\t\t};\n\t} else if (hasCredentials) login = {\n\t\ttype: \"credentials\",\n\t\tsignUpEnabled\n\t};\n\tlet user = null;\n\tif (implementsInterface(auth, \"getCurrentUser\") && isLicensedOrCloud) try {\n\t\tuser = await auth.getCurrentUser(request);\n\t} catch {\n\t\tuser = null;\n\t}\n\tif (!user) {\n\t\tcaptureLicenseCheck({\n\t\t\trequest,\n\t\t\tuser,\n\t\t\thasLicense,\n\t\t\tisDev,\n\t\t\tisCloud,\n\t\t\tisSimple\n\t\t});\n\t\treturn {\n\t\t\tenabled: true,\n\t\t\tlogin\n\t\t};\n\t}\n\tconst rbacProvider = options?.rbac;\n\tconst hasRBAC = !!rbacProvider && isFeatureLicensed(\"rbac\");\n\tconst hasFGA = !!options?.fga && isFeatureLicensed(\"fga\");\n\tconst capabilities = {\n\t\tuser: implementsInterface(auth, \"getCurrentUser\") && isLicensedOrCloud,\n\t\tsession: implementsInterface(auth, \"createSession\") && isLicensedOrCloud,\n\t\tsso: implementsInterface(auth, \"getLoginUrl\") && isLicensedOrCloud,\n\t\trbac: hasRBAC,\n\t\tacl: implementsInterface(auth, \"canAccess\") && isFeatureLicensed(\"acl\"),\n\t\tfga: hasFGA\n\t};\n\tlet access = null;\n\tif (hasRBAC && rbacProvider) try {\n\t\tconst roles = await rbacProvider.getRoles(user);\n\t\tconst permissions = await rbacProvider.getPermissions(user);\n\t\taccess = {\n\t\t\troles,\n\t\t\tpermissions\n\t\t};\n\t\tconst license = getSafeLicenseSummary();\n\t\ttry {\n\t\t\tconst ip = getRequestIp(request);\n\t\t\tcaptureEEEvent(\"ee_feature_used\", user.id || license.anonymousId || getEETelemetryFallbackDistinctId(), {\n\t\t\t\tfeature: \"rbac\",\n\t\t\t\tuser_id: user.id,\n\t\t\t\torganization_membership_id: user.metadata?.[\"organizationMembershipId\"],\n\t\t\t\trole_count: roles.length,\n\t\t\t\tpermission_count: permissions.length,\n\t\t\t\t$ip: ip,\n\t\t\t\tlicense_valid: license.valid,\n\t\t\t\tlicense_hash: license.licenseHash,\n\t\t\t\tis_dev_environment: license.isDevEnvironment\n\t\t\t});\n\t\t} catch {}\n\t} catch {\n\t\taccess = null;\n\t}\n\tlet availableRoles;\n\tif (access && rbacProvider?.getAvailableRoles) {\n\t\tif (hasAdminBypassPermissions(access.permissions)) try {\n\t\t\tconst allRoles = await rbacProvider.getAvailableRoles();\n\t\t\tconst getPermissionsForRole = rbacProvider.getPermissionsForRole?.bind(rbacProvider);\n\t\t\tif (getPermissionsForRole) availableRoles = (await Promise.allSettled(allRoles.map(async (role) => ({\n\t\t\t\trole,\n\t\t\t\tperms: await getPermissionsForRole(role.id)\n\t\t\t})))).flatMap((result) => {\n\t\t\t\tif (result.status !== \"fulfilled\") {\n\t\t\t\t\tconsole.warn(\"[auth/ee] failed to list permissions for role:\", result.reason);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\treturn hasAdminBypassPermissions(result.value.perms) ? [] : [result.value.role];\n\t\t\t});\n\t\t\telse availableRoles = allRoles;\n\t\t} catch (error) {\n\t\t\tconsole.warn(\"[auth/ee] failed to list available roles for admin user:\", error);\n\t\t}\n\t}\n\tcaptureLicenseCheck({\n\t\trequest,\n\t\tuser,\n\t\thasLicense,\n\t\tisDev,\n\t\tisCloud,\n\t\tisSimple,\n\t\tcapabilities\n\t});\n\treturn {\n\t\tenabled: true,\n\t\tlogin,\n\t\tuser: {\n\t\t\tid: user.id,\n\t\t\temail: user.email,\n\t\t\tname: user.name,\n\t\t\tavatarUrl: user.avatarUrl\n\t\t},\n\t\tcapabilities,\n\t\taccess,\n\t\tavailableRoles\n\t};\n}\n//#endregion\nexport { isDevEnvironment as a, isFeatureEnabled as c, validateLicense as d, warnIfDevEENeedsLicense as f, getSafeLicenseSummary as i, isLicenseValid as l, getEETelemetryFallbackDistinctId as m, isAuthenticated as n, isEEEnabled as o, captureEEEvent as p, clearLicenseCache as r, isEELicenseValid as s, buildCapabilities as t, startLicenseValidation as u };\n\n//# sourceMappingURL=capabilities-ZXD8uYsD.js.map","import { i as getSafeLicenseSummary, m as getEETelemetryFallbackDistinctId, p as captureEEEvent } from \"./capabilities-ZXD8uYsD.js\";\n//#region src/ee/interfaces/permissions.generated.ts\n/**\n* AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n*\n* This file is generated by packages/server/scripts/generate-permissions.ts\n* Run `pnpm generate:permissions` from packages/server to regenerate.\n*\n* Source of truth: SERVER_ROUTES in @mastra/server\n*/\n/**\n* All known API resources.\n* Derived from SERVER_ROUTES paths in @mastra/server.\n*/\nconst RESOURCES = [\n\t\"a2a\",\n\t\"agent-builder\",\n\t\"agent-controller\",\n\t\"agents\",\n\t\"auth\",\n\t\"background-tasks\",\n\t\"channels\",\n\t\"datasets\",\n\t\"embedders\",\n\t\"experiments\",\n\t\"infrastructure\",\n\t\"logs\",\n\t\"mcp\",\n\t\"memory\",\n\t\"observability\",\n\t\"processor-providers\",\n\t\"processors\",\n\t\"schedules\",\n\t\"scores\",\n\t\"stored-agents\",\n\t\"stored-mcp-clients\",\n\t\"stored-prompt-blocks\",\n\t\"stored-scorers\",\n\t\"stored-skills\",\n\t\"stored-workflows\",\n\t\"stored-workspaces\",\n\t\"system\",\n\t\"tool-providers\",\n\t\"tools\",\n\t\"vector\",\n\t\"vectors\",\n\t\"workflows\",\n\t\"workspaces\"\n];\n/**\n* All permission actions.\n* Derived from HTTP methods and route overrides:\n* - GET → read\n* - POST → write or execute (context-dependent)\n* - PUT/PATCH → write\n* - DELETE → delete\n* - Additional actions from explicit requiresPermission overrides\n*/\nconst ACTIONS = [\n\t\"create\",\n\t\"delete\",\n\t\"execute\",\n\t\"publish\",\n\t\"read\",\n\t\"share\",\n\t\"write\"\n];\n/**\n* All valid permission patterns.\n* Use `keyof typeof PERMISSION_PATTERNS` or the `PermissionPattern` type.\n*/\nconst PERMISSION_PATTERNS = {\n\t/** Full access to all resources and actions */\n\t\"*\": \"*\",\n\t/** Create all resources */\n\t\"*:create\": \"*:create\",\n\t/** Delete all resources */\n\t\"*:delete\": \"*:delete\",\n\t/** Execute all resources */\n\t\"*:execute\": \"*:execute\",\n\t/** Publish, activate, or restore all resources */\n\t\"*:publish\": \"*:publish\",\n\t/** View all resources */\n\t\"*:read\": \"*:read\",\n\t/** Change visibility/audience all resources */\n\t\"*:share\": \"*:share\",\n\t/** Create and modify all resources */\n\t\"*:write\": \"*:write\",\n\t/** Full access to agent-to-agent communication */\n\t\"a2a:*\": \"a2a:*\",\n\t/** Full access to agent builder */\n\t\"agent-builder:*\": \"agent-builder:*\",\n\t/** Full access to agent controller sessions */\n\t\"agent-controller:*\": \"agent-controller:*\",\n\t/** Full access to agents */\n\t\"agents:*\": \"agents:*\",\n\t/** Full access to auth */\n\t\"auth:*\": \"auth:*\",\n\t/** Full access to background tasks */\n\t\"background-tasks:*\": \"background-tasks:*\",\n\t/** Full access to channels */\n\t\"channels:*\": \"channels:*\",\n\t/** Full access to datasets */\n\t\"datasets:*\": \"datasets:*\",\n\t/** Full access to embedders */\n\t\"embedders:*\": \"embedders:*\",\n\t/** Full access to experiments */\n\t\"experiments:*\": \"experiments:*\",\n\t/** Full access to infrastructure */\n\t\"infrastructure:*\": \"infrastructure:*\",\n\t/** Full access to logs */\n\t\"logs:*\": \"logs:*\",\n\t/** Full access to MCP servers */\n\t\"mcp:*\": \"mcp:*\",\n\t/** Full access to memory and threads */\n\t\"memory:*\": \"memory:*\",\n\t/** Full access to traces and spans */\n\t\"observability:*\": \"observability:*\",\n\t/** Full access to processor-providers */\n\t\"processor-providers:*\": \"processor-providers:*\",\n\t/** Full access to processors */\n\t\"processors:*\": \"processors:*\",\n\t/** Full access to schedules */\n\t\"schedules:*\": \"schedules:*\",\n\t/** Full access to evaluation scores */\n\t\"scores:*\": \"scores:*\",\n\t/** Full access to stored agents */\n\t\"stored-agents:*\": \"stored-agents:*\",\n\t/** Full access to stored MCP clients */\n\t\"stored-mcp-clients:*\": \"stored-mcp-clients:*\",\n\t/** Full access to stored prompt blocks */\n\t\"stored-prompt-blocks:*\": \"stored-prompt-blocks:*\",\n\t/** Full access to stored scorers */\n\t\"stored-scorers:*\": \"stored-scorers:*\",\n\t/** Full access to stored skills */\n\t\"stored-skills:*\": \"stored-skills:*\",\n\t/** Full access to stored workflows */\n\t\"stored-workflows:*\": \"stored-workflows:*\",\n\t/** Full access to stored workspaces */\n\t\"stored-workspaces:*\": \"stored-workspaces:*\",\n\t/** Full access to system info */\n\t\"system:*\": \"system:*\",\n\t/** Full access to tool-providers */\n\t\"tool-providers:*\": \"tool-providers:*\",\n\t/** Full access to tools */\n\t\"tools:*\": \"tools:*\",\n\t/** Full access to vector stores */\n\t\"vector:*\": \"vector:*\",\n\t/** Full access to vectors */\n\t\"vectors:*\": \"vectors:*\",\n\t/** Full access to workflows */\n\t\"workflows:*\": \"workflows:*\",\n\t/** Full access to workspaces */\n\t\"workspaces:*\": \"workspaces:*\",\n\t/** View agent-to-agent communication */\n\t\"a2a:read\": \"a2a:read\",\n\t/** Create and modify agent-to-agent communication */\n\t\"a2a:write\": \"a2a:write\",\n\t/** Execute agent builder */\n\t\"agent-builder:execute\": \"agent-builder:execute\",\n\t/** View agent builder */\n\t\"agent-builder:read\": \"agent-builder:read\",\n\t/** Create and modify agent builder */\n\t\"agent-builder:write\": \"agent-builder:write\",\n\t/** Execute agent controller sessions */\n\t\"agent-controller:execute\": \"agent-controller:execute\",\n\t/** View agent controller sessions */\n\t\"agent-controller:read\": \"agent-controller:read\",\n\t/** Create agents */\n\t\"agents:create\": \"agents:create\",\n\t/** Delete agents */\n\t\"agents:delete\": \"agents:delete\",\n\t/** Execute agents */\n\t\"agents:execute\": \"agents:execute\",\n\t/** View agents */\n\t\"agents:read\": \"agents:read\",\n\t/** Create and modify agents */\n\t\"agents:write\": \"agents:write\",\n\t/** View auth */\n\t\"auth:read\": \"auth:read\",\n\t/** View background tasks */\n\t\"background-tasks:read\": \"background-tasks:read\",\n\t/** View channels */\n\t\"channels:read\": \"channels:read\",\n\t/** Create and modify channels */\n\t\"channels:write\": \"channels:write\",\n\t/** Delete datasets */\n\t\"datasets:delete\": \"datasets:delete\",\n\t/** Execute datasets */\n\t\"datasets:execute\": \"datasets:execute\",\n\t/** View datasets */\n\t\"datasets:read\": \"datasets:read\",\n\t/** Create and modify datasets */\n\t\"datasets:write\": \"datasets:write\",\n\t/** View embedders */\n\t\"embedders:read\": \"embedders:read\",\n\t/** View experiments */\n\t\"experiments:read\": \"experiments:read\",\n\t/** View infrastructure */\n\t\"infrastructure:read\": \"infrastructure:read\",\n\t/** View logs */\n\t\"logs:read\": \"logs:read\",\n\t/** Execute MCP servers */\n\t\"mcp:execute\": \"mcp:execute\",\n\t/** View MCP servers */\n\t\"mcp:read\": \"mcp:read\",\n\t/** Create and modify MCP servers */\n\t\"mcp:write\": \"mcp:write\",\n\t/** Delete memory and threads */\n\t\"memory:delete\": \"memory:delete\",\n\t/** Execute memory and threads */\n\t\"memory:execute\": \"memory:execute\",\n\t/** View memory and threads */\n\t\"memory:read\": \"memory:read\",\n\t/** Create and modify memory and threads */\n\t\"memory:write\": \"memory:write\",\n\t/** View traces and spans */\n\t\"observability:read\": \"observability:read\",\n\t/** Create and modify traces and spans */\n\t\"observability:write\": \"observability:write\",\n\t/** View processor-providers */\n\t\"processor-providers:read\": \"processor-providers:read\",\n\t/** Execute processors */\n\t\"processors:execute\": \"processors:execute\",\n\t/** View processors */\n\t\"processors:read\": \"processors:read\",\n\t/** Delete schedules */\n\t\"schedules:delete\": \"schedules:delete\",\n\t/** Execute schedules */\n\t\"schedules:execute\": \"schedules:execute\",\n\t/** View schedules */\n\t\"schedules:read\": \"schedules:read\",\n\t/** Create and modify schedules */\n\t\"schedules:write\": \"schedules:write\",\n\t/** View evaluation scores */\n\t\"scores:read\": \"scores:read\",\n\t/** Create and modify evaluation scores */\n\t\"scores:write\": \"scores:write\",\n\t/** Delete stored agents */\n\t\"stored-agents:delete\": \"stored-agents:delete\",\n\t/** Publish, activate, or restore stored agents */\n\t\"stored-agents:publish\": \"stored-agents:publish\",\n\t/** View stored agents */\n\t\"stored-agents:read\": \"stored-agents:read\",\n\t/** Create and modify stored agents */\n\t\"stored-agents:write\": \"stored-agents:write\",\n\t/** Delete stored MCP clients */\n\t\"stored-mcp-clients:delete\": \"stored-mcp-clients:delete\",\n\t/** Publish, activate, or restore stored MCP clients */\n\t\"stored-mcp-clients:publish\": \"stored-mcp-clients:publish\",\n\t/** View stored MCP clients */\n\t\"stored-mcp-clients:read\": \"stored-mcp-clients:read\",\n\t/** Create and modify stored MCP clients */\n\t\"stored-mcp-clients:write\": \"stored-mcp-clients:write\",\n\t/** Delete stored prompt blocks */\n\t\"stored-prompt-blocks:delete\": \"stored-prompt-blocks:delete\",\n\t/** Publish, activate, or restore stored prompt blocks */\n\t\"stored-prompt-blocks:publish\": \"stored-prompt-blocks:publish\",\n\t/** View stored prompt blocks */\n\t\"stored-prompt-blocks:read\": \"stored-prompt-blocks:read\",\n\t/** Create and modify stored prompt blocks */\n\t\"stored-prompt-blocks:write\": \"stored-prompt-blocks:write\",\n\t/** Delete stored scorers */\n\t\"stored-scorers:delete\": \"stored-scorers:delete\",\n\t/** Publish, activate, or restore stored scorers */\n\t\"stored-scorers:publish\": \"stored-scorers:publish\",\n\t/** View stored scorers */\n\t\"stored-scorers:read\": \"stored-scorers:read\",\n\t/** Create and modify stored scorers */\n\t\"stored-scorers:write\": \"stored-scorers:write\",\n\t/** Delete stored skills */\n\t\"stored-skills:delete\": \"stored-skills:delete\",\n\t/** Publish, activate, or restore stored skills */\n\t\"stored-skills:publish\": \"stored-skills:publish\",\n\t/** View stored skills */\n\t\"stored-skills:read\": \"stored-skills:read\",\n\t/** Create and modify stored skills */\n\t\"stored-skills:write\": \"stored-skills:write\",\n\t/** View stored workflows */\n\t\"stored-workflows:read\": \"stored-workflows:read\",\n\t/** Create and modify stored workflows */\n\t\"stored-workflows:write\": \"stored-workflows:write\",\n\t/** Delete stored workspaces */\n\t\"stored-workspaces:delete\": \"stored-workspaces:delete\",\n\t/** View stored workspaces */\n\t\"stored-workspaces:read\": \"stored-workspaces:read\",\n\t/** Create and modify stored workspaces */\n\t\"stored-workspaces:write\": \"stored-workspaces:write\",\n\t/** View system info */\n\t\"system:read\": \"system:read\",\n\t/** Delete tool-providers */\n\t\"tool-providers:delete\": \"tool-providers:delete\",\n\t/** View tool-providers */\n\t\"tool-providers:read\": \"tool-providers:read\",\n\t/** Create and modify tool-providers */\n\t\"tool-providers:write\": \"tool-providers:write\",\n\t/** Execute tools */\n\t\"tools:execute\": \"tools:execute\",\n\t/** View tools */\n\t\"tools:read\": \"tools:read\",\n\t/** Delete vector stores */\n\t\"vector:delete\": \"vector:delete\",\n\t/** Execute vector stores */\n\t\"vector:execute\": \"vector:execute\",\n\t/** View vector stores */\n\t\"vector:read\": \"vector:read\",\n\t/** Create and modify vector stores */\n\t\"vector:write\": \"vector:write\",\n\t/** View vectors */\n\t\"vectors:read\": \"vectors:read\",\n\t/** Delete workflows */\n\t\"workflows:delete\": \"workflows:delete\",\n\t/** Execute workflows */\n\t\"workflows:execute\": \"workflows:execute\",\n\t/** View workflows */\n\t\"workflows:read\": \"workflows:read\",\n\t/** Create and modify workflows */\n\t\"workflows:write\": \"workflows:write\",\n\t/** Delete workspaces */\n\t\"workspaces:delete\": \"workspaces:delete\",\n\t/** View workspaces */\n\t\"workspaces:read\": \"workspaces:read\",\n\t/** Create and modify workspaces */\n\t\"workspaces:write\": \"workspaces:write\",\n\t/** Full access to all stored resource families */\n\t\"stored:*\": \"stored:*\",\n\t/** View all stored resource families */\n\t\"stored:read\": \"stored:read\",\n\t/** Create and modify all stored resource families */\n\t\"stored:write\": \"stored:write\",\n\t/** Delete all stored resource families */\n\t\"stored:delete\": \"stored:delete\",\n\t/** Change visibility/audience stored agents */\n\t\"stored-agents:share\": \"stored-agents:share\",\n\t/** Change visibility/audience stored skills */\n\t\"stored-skills:share\": \"stored-skills:share\"\n};\n/**\n* All valid resource:action permission combinations (excludes wildcards).\n*/\nconst PERMISSIONS = [\n\t\"a2a:read\",\n\t\"a2a:write\",\n\t\"agent-builder:execute\",\n\t\"agent-builder:read\",\n\t\"agent-builder:write\",\n\t\"agent-controller:execute\",\n\t\"agent-controller:read\",\n\t\"agents:create\",\n\t\"agents:delete\",\n\t\"agents:execute\",\n\t\"agents:read\",\n\t\"agents:write\",\n\t\"auth:read\",\n\t\"background-tasks:read\",\n\t\"channels:read\",\n\t\"channels:write\",\n\t\"datasets:delete\",\n\t\"datasets:execute\",\n\t\"datasets:read\",\n\t\"datasets:write\",\n\t\"embedders:read\",\n\t\"experiments:read\",\n\t\"infrastructure:read\",\n\t\"logs:read\",\n\t\"mcp:execute\",\n\t\"mcp:read\",\n\t\"mcp:write\",\n\t\"memory:delete\",\n\t\"memory:execute\",\n\t\"memory:read\",\n\t\"memory:write\",\n\t\"observability:read\",\n\t\"observability:write\",\n\t\"processor-providers:read\",\n\t\"processors:execute\",\n\t\"processors:read\",\n\t\"schedules:delete\",\n\t\"schedules:execute\",\n\t\"schedules:read\",\n\t\"schedules:write\",\n\t\"scores:read\",\n\t\"scores:write\",\n\t\"stored-agents:delete\",\n\t\"stored-agents:publish\",\n\t\"stored-agents:read\",\n\t\"stored-agents:write\",\n\t\"stored-mcp-clients:delete\",\n\t\"stored-mcp-clients:publish\",\n\t\"stored-mcp-clients:read\",\n\t\"stored-mcp-clients:write\",\n\t\"stored-prompt-blocks:delete\",\n\t\"stored-prompt-blocks:publish\",\n\t\"stored-prompt-blocks:read\",\n\t\"stored-prompt-blocks:write\",\n\t\"stored-scorers:delete\",\n\t\"stored-scorers:publish\",\n\t\"stored-scorers:read\",\n\t\"stored-scorers:write\",\n\t\"stored-skills:delete\",\n\t\"stored-skills:publish\",\n\t\"stored-skills:read\",\n\t\"stored-skills:write\",\n\t\"stored-workflows:read\",\n\t\"stored-workflows:write\",\n\t\"stored-workspaces:delete\",\n\t\"stored-workspaces:read\",\n\t\"stored-workspaces:write\",\n\t\"system:read\",\n\t\"tool-providers:delete\",\n\t\"tool-providers:read\",\n\t\"tool-providers:write\",\n\t\"tools:execute\",\n\t\"tools:read\",\n\t\"vector:delete\",\n\t\"vector:execute\",\n\t\"vector:read\",\n\t\"vector:write\",\n\t\"vectors:read\",\n\t\"workflows:delete\",\n\t\"workflows:execute\",\n\t\"workflows:read\",\n\t\"workflows:write\",\n\t\"workspaces:delete\",\n\t\"workspaces:read\",\n\t\"workspaces:write\"\n];\n/**\n* Type-safe constants for Mastra-owned FGA permissions.\n*\n* These values are generated from server routes and can be used wherever\n* Mastra checks or maps FGA permissions.\n*/\nconst MastraFGAPermissions = {\n\t/** View agent-to-agent communication */\n\tA2A_READ: \"a2a:read\",\n\t/** Create and modify agent-to-agent communication */\n\tA2A_WRITE: \"a2a:write\",\n\t/** Execute agent builder */\n\tAGENT_BUILDER_EXECUTE: \"agent-builder:execute\",\n\t/** View agent builder */\n\tAGENT_BUILDER_READ: \"agent-builder:read\",\n\t/** Create and modify agent builder */\n\tAGENT_BUILDER_WRITE: \"agent-builder:write\",\n\t/** Execute agent controller sessions */\n\tAGENT_CONTROLLER_EXECUTE: \"agent-controller:execute\",\n\t/** View agent controller sessions */\n\tAGENT_CONTROLLER_READ: \"agent-controller:read\",\n\t/** Create agents */\n\tAGENTS_CREATE: \"agents:create\",\n\t/** Delete agents */\n\tAGENTS_DELETE: \"agents:delete\",\n\t/** Execute agents */\n\tAGENTS_EXECUTE: \"agents:execute\",\n\t/** View agents */\n\tAGENTS_READ: \"agents:read\",\n\t/** Create and modify agents */\n\tAGENTS_WRITE: \"agents:write\",\n\t/** View auth */\n\tAUTH_READ: \"auth:read\",\n\t/** View background tasks */\n\tBACKGROUND_TASKS_READ: \"background-tasks:read\",\n\t/** View channels */\n\tCHANNELS_READ: \"channels:read\",\n\t/** Create and modify channels */\n\tCHANNELS_WRITE: \"channels:write\",\n\t/** Delete datasets */\n\tDATASETS_DELETE: \"datasets:delete\",\n\t/** Execute datasets */\n\tDATASETS_EXECUTE: \"datasets:execute\",\n\t/** View datasets */\n\tDATASETS_READ: \"datasets:read\",\n\t/** Create and modify datasets */\n\tDATASETS_WRITE: \"datasets:write\",\n\t/** View embedders */\n\tEMBEDDERS_READ: \"embedders:read\",\n\t/** View experiments */\n\tEXPERIMENTS_READ: \"experiments:read\",\n\t/** View infrastructure */\n\tINFRASTRUCTURE_READ: \"infrastructure:read\",\n\t/** View logs */\n\tLOGS_READ: \"logs:read\",\n\t/** Execute MCP servers */\n\tMCP_EXECUTE: \"mcp:execute\",\n\t/** View MCP servers */\n\tMCP_READ: \"mcp:read\",\n\t/** Create and modify MCP servers */\n\tMCP_WRITE: \"mcp:write\",\n\t/** Delete memory and threads */\n\tMEMORY_DELETE: \"memory:delete\",\n\t/** Execute memory and threads */\n\tMEMORY_EXECUTE: \"memory:execute\",\n\t/** View memory and threads */\n\tMEMORY_READ: \"memory:read\",\n\t/** Create and modify memory and threads */\n\tMEMORY_WRITE: \"memory:write\",\n\t/** View traces and spans */\n\tOBSERVABILITY_READ: \"observability:read\",\n\t/** Create and modify traces and spans */\n\tOBSERVABILITY_WRITE: \"observability:write\",\n\t/** View processor-providers */\n\tPROCESSOR_PROVIDERS_READ: \"processor-providers:read\",\n\t/** Execute processors */\n\tPROCESSORS_EXECUTE: \"processors:execute\",\n\t/** View processors */\n\tPROCESSORS_READ: \"processors:read\",\n\t/** Delete schedules */\n\tSCHEDULES_DELETE: \"schedules:delete\",\n\t/** Execute schedules */\n\tSCHEDULES_EXECUTE: \"schedules:execute\",\n\t/** View schedules */\n\tSCHEDULES_READ: \"schedules:read\",\n\t/** Create and modify schedules */\n\tSCHEDULES_WRITE: \"schedules:write\",\n\t/** View evaluation scores */\n\tSCORES_READ: \"scores:read\",\n\t/** Create and modify evaluation scores */\n\tSCORES_WRITE: \"scores:write\",\n\t/** Delete stored agents */\n\tSTORED_AGENTS_DELETE: \"stored-agents:delete\",\n\t/** Publish, activate, or restore stored agents */\n\tSTORED_AGENTS_PUBLISH: \"stored-agents:publish\",\n\t/** View stored agents */\n\tSTORED_AGENTS_READ: \"stored-agents:read\",\n\t/** Create and modify stored agents */\n\tSTORED_AGENTS_WRITE: \"stored-agents:write\",\n\t/** Delete stored MCP clients */\n\tSTORED_MCP_CLIENTS_DELETE: \"stored-mcp-clients:delete\",\n\t/** Publish, activate, or restore stored MCP clients */\n\tSTORED_MCP_CLIENTS_PUBLISH: \"stored-mcp-clients:publish\",\n\t/** View stored MCP clients */\n\tSTORED_MCP_CLIENTS_READ: \"stored-mcp-clients:read\",\n\t/** Create and modify stored MCP clients */\n\tSTORED_MCP_CLIENTS_WRITE: \"stored-mcp-clients:write\",\n\t/** Delete stored prompt blocks */\n\tSTORED_PROMPT_BLOCKS_DELETE: \"stored-prompt-blocks:delete\",\n\t/** Publish, activate, or restore stored prompt blocks */\n\tSTORED_PROMPT_BLOCKS_PUBLISH: \"stored-prompt-blocks:publish\",\n\t/** View stored prompt blocks */\n\tSTORED_PROMPT_BLOCKS_READ: \"stored-prompt-blocks:read\",\n\t/** Create and modify stored prompt blocks */\n\tSTORED_PROMPT_BLOCKS_WRITE: \"stored-prompt-blocks:write\",\n\t/** Delete stored scorers */\n\tSTORED_SCORERS_DELETE: \"stored-scorers:delete\",\n\t/** Publish, activate, or restore stored scorers */\n\tSTORED_SCORERS_PUBLISH: \"stored-scorers:publish\",\n\t/** View stored scorers */\n\tSTORED_SCORERS_READ: \"stored-scorers:read\",\n\t/** Create and modify stored scorers */\n\tSTORED_SCORERS_WRITE: \"stored-scorers:write\",\n\t/** Delete stored skills */\n\tSTORED_SKILLS_DELETE: \"stored-skills:delete\",\n\t/** Publish, activate, or restore stored skills */\n\tSTORED_SKILLS_PUBLISH: \"stored-skills:publish\",\n\t/** View stored skills */\n\tSTORED_SKILLS_READ: \"stored-skills:read\",\n\t/** Create and modify stored skills */\n\tSTORED_SKILLS_WRITE: \"stored-skills:write\",\n\t/** View stored workflows */\n\tSTORED_WORKFLOWS_READ: \"stored-workflows:read\",\n\t/** Create and modify stored workflows */\n\tSTORED_WORKFLOWS_WRITE: \"stored-workflows:write\",\n\t/** Delete stored workspaces */\n\tSTORED_WORKSPACES_DELETE: \"stored-workspaces:delete\",\n\t/** View stored workspaces */\n\tSTORED_WORKSPACES_READ: \"stored-workspaces:read\",\n\t/** Create and modify stored workspaces */\n\tSTORED_WORKSPACES_WRITE: \"stored-workspaces:write\",\n\t/** View system info */\n\tSYSTEM_READ: \"system:read\",\n\t/** Delete tool-providers */\n\tTOOL_PROVIDERS_DELETE: \"tool-providers:delete\",\n\t/** View tool-providers */\n\tTOOL_PROVIDERS_READ: \"tool-providers:read\",\n\t/** Create and modify tool-providers */\n\tTOOL_PROVIDERS_WRITE: \"tool-providers:write\",\n\t/** Execute tools */\n\tTOOLS_EXECUTE: \"tools:execute\",\n\t/** View tools */\n\tTOOLS_READ: \"tools:read\",\n\t/** Delete vector stores */\n\tVECTOR_DELETE: \"vector:delete\",\n\t/** Execute vector stores */\n\tVECTOR_EXECUTE: \"vector:execute\",\n\t/** View vector stores */\n\tVECTOR_READ: \"vector:read\",\n\t/** Create and modify vector stores */\n\tVECTOR_WRITE: \"vector:write\",\n\t/** View vectors */\n\tVECTORS_READ: \"vectors:read\",\n\t/** Delete workflows */\n\tWORKFLOWS_DELETE: \"workflows:delete\",\n\t/** Execute workflows */\n\tWORKFLOWS_EXECUTE: \"workflows:execute\",\n\t/** View workflows */\n\tWORKFLOWS_READ: \"workflows:read\",\n\t/** Create and modify workflows */\n\tWORKFLOWS_WRITE: \"workflows:write\",\n\t/** Delete workspaces */\n\tWORKSPACES_DELETE: \"workspaces:delete\",\n\t/** View workspaces */\n\tWORKSPACES_READ: \"workspaces:read\",\n\t/** Create and modify workspaces */\n\tWORKSPACES_WRITE: \"workspaces:write\"\n};\n/**\n* Validates that a string is a valid permission pattern.\n* Useful for runtime validation of permission strings.\n*/\nfunction isValidPermissionPattern(pattern) {\n\treturn pattern in PERMISSION_PATTERNS;\n}\n/**\n* Validates that all permissions in an array are valid patterns.\n*/\nfunction validatePermissions(permissions) {\n\treturn permissions.every(isValidPermissionPattern);\n}\n//#endregion\n//#region src/ee/fga-check.ts\n/**\n* FGA enforcement utility for checking fine-grained authorization.\n*\n* @license Mastra Enterprise License - see ee/LICENSE\n*/\nfunction mergeFGAContext({ context, requestContext, metadata }) {\n\tconst mergedContext = { ...context };\n\tif (requestContext) mergedContext.requestContext = requestContext;\n\tif (metadata || context?.metadata) mergedContext.metadata = {\n\t\t...context?.metadata ?? {},\n\t\t...metadata ?? {}\n\t};\n\treturn Object.keys(mergedContext).length > 0 ? mergedContext : void 0;\n}\nfunction isActorSignal(actor) {\n\tif (actor === true) return true;\n\tif (typeof actor !== \"object\" || actor === null) return false;\n\tconst candidate = actor;\n\treturn candidate.actorKind === \"system\" && (candidate.sourceWorkflow === void 0 || typeof candidate.sourceWorkflow === \"string\");\n}\nfunction getAgentFGAResourceId(agentId) {\n\treturn agentId;\n}\nfunction getWorkflowFGAResourceId(workflowId) {\n\treturn workflowId;\n}\nfunction getStandaloneToolFGAResourceId(toolName) {\n\treturn toolName;\n}\nfunction getAgentToolFGAResourceId(agentId, toolName) {\n\treturn `${agentId}:${toolName}`;\n}\nfunction getMCPToolFGAResourceId(serverName, toolName) {\n\treturn JSON.stringify([serverName, toolName]);\n}\n/**\n* Check fine-grained authorization for a resource.\n*\n* No-op if no FGA provider is configured (backward compatibility).\n* Delegates to fgaProvider.require() which throws FGADeniedError if denied.\n*/\nasync function checkFGA(options) {\n\tawait requireFGA(options);\n}\n/**\n* Require fine-grained authorization for a resource.\n*\n* No-op if no FGA provider is configured. When FGA is configured, a missing\n* user fails closed.\n*/\nasync function requireFGA(options) {\n\tconst { fgaProvider, user, resource, permission, context, requestContext, metadata, actor } = options;\n\tif (!fgaProvider) return;\n\tconst fgaContext = mergeFGAContext({\n\t\tcontext,\n\t\trequestContext,\n\t\tmetadata\n\t});\n\tconst license = getSafeLicenseSummary();\n\tif (isActorSignal(actor)) {\n\t\tconst tenantOrganizationId = fgaContext?.requestContext?.get(\"organizationId\");\n\t\tif (typeof tenantOrganizationId !== \"string\" || tenantOrganizationId.length === 0) throw new FGADeniedError(user, resource, permission, \"trusted actor requires organizationId / tenant scope\");\n\t\tconst sourceWorkflow = (actor === true ? void 0 : actor.sourceWorkflow) ?? (typeof fgaContext?.metadata?.[\"sourceWorkflow\"] === \"string\" ? fgaContext.metadata[\"sourceWorkflow\"] : void 0);\n\t\tconst providerEnforced = typeof fgaProvider.requireActor === \"function\";\n\t\tif (providerEnforced) await fgaProvider.requireActor(actor, {\n\t\t\tresource,\n\t\t\tpermission,\n\t\t\t...fgaContext ? { context: fgaContext } : {}\n\t\t});\n\t\ttry {\n\t\t\tcaptureEEEvent(\"ee_feature_used\", license.anonymousId || getEETelemetryFallbackDistinctId(), {\n\t\t\t\tfeature: \"fga\",\n\t\t\t\tactor_kind: \"system\",\n\t\t\t\tactor_authorized_by: providerEnforced ? \"provider\" : \"bypass\",\n\t\t\t\tresource_type: resource.type,\n\t\t\t\tresource_id: resource.id,\n\t\t\t\tpermission,\n\t\t\t\tuser_id: null,\n\t\t\t\torganization_membership_id: null,\n\t\t\t\tsource_workflow: sourceWorkflow,\n\t\t\t\tlicense_valid: license.valid,\n\t\t\t\tlicense_hash: license.licenseHash,\n\t\t\t\tis_dev_environment: license.isDevEnvironment\n\t\t\t});\n\t\t} catch {}\n\t\treturn;\n\t}\n\tif (!user) throw new FGADeniedError(user, resource, permission, \"authenticated user is required\");\n\tawait fgaProvider.require(user, fgaContext ? {\n\t\tresource,\n\t\tpermission,\n\t\tcontext: fgaContext\n\t} : {\n\t\tresource,\n\t\tpermission\n\t});\n\ttry {\n\t\tcaptureEEEvent(\"ee_feature_used\", user?.id || license.anonymousId || getEETelemetryFallbackDistinctId(), {\n\t\t\tfeature: \"fga\",\n\t\t\tactor_kind: \"user\",\n\t\t\tresource_type: resource.type,\n\t\t\tresource_id: resource.id,\n\t\t\tpermission,\n\t\t\tuser_id: user?.id ?? null,\n\t\t\torganization_membership_id: user?.organizationMembershipId ?? null,\n\t\t\tlicense_valid: license.valid,\n\t\t\tlicense_hash: license.licenseHash,\n\t\t\tis_dev_environment: license.isDevEnvironment\n\t\t});\n\t} catch {}\n}\n/**\n* Error thrown when an FGA authorization check is denied.\n*/\nvar FGADeniedError = class extends Error {\n\tuser;\n\tresource;\n\tpermission;\n\tstatus;\n\tconstructor(user, resource, permission, reason) {\n\t\tconst userId = user?.id || user?.workosId || \"unknown\";\n\t\tconst permissionLabel = Array.isArray(permission) ? `any of [${permission.join(\", \")}]` : permission;\n\t\tsuper(reason ? `FGA authorization denied: ${reason}` : `FGA authorization denied: user ${userId} cannot ${permissionLabel} on ${resource.type}:${resource.id}`);\n\t\tthis.name = \"FGADeniedError\";\n\t\tthis.user = user;\n\t\tthis.resource = resource;\n\t\tthis.permission = permission;\n\t\tthis.status = 403;\n\t}\n};\n//#endregion\n//#region src/ee/defaults/roles.ts\n/**\n* Default role definitions for Studio.\n*\n* These roles provide a sensible starting point for most applications:\n* - **owner**: Full access to everything\n* - **admin**: Manage agents, workflows, and users\n* - **member**: Execute agents and workflows, read-only settings\n* - **viewer**: Read-only access\n*\n* Permission patterns:\n* - `*` - Full access to everything\n* - `resource:*` - All actions on a specific resource\n* - `*:action` - An action across all resources (e.g., `*:read` for read-only)\n*/\nconst DEFAULT_ROLES = [\n\t{\n\t\tid: \"owner\",\n\t\tname: \"Owner\",\n\t\tdescription: \"Full access to all features and settings\",\n\t\tpermissions: [\"*\"]\n\t},\n\t{\n\t\tid: \"admin\",\n\t\tname: \"Admin\",\n\t\tdescription: \"Manage agents, workflows, and team members\",\n\t\tpermissions: [\n\t\t\t\"*:read\",\n\t\t\t\"*:write\",\n\t\t\t\"*:execute\",\n\t\t\t\"*:publish\",\n\t\t\t\"*:share\"\n\t\t]\n\t},\n\t{\n\t\tid: \"member\",\n\t\tname: \"Member\",\n\t\tdescription: \"Execute agents and workflows\",\n\t\tpermissions: [\"*:read\", \"*:execute\"]\n\t},\n\t{\n\t\tid: \"viewer\",\n\t\tname: \"Viewer\",\n\t\tdescription: \"Read-only access\",\n\t\tpermissions: [\"*:read\"]\n\t}\n];\n/**\n* Get role by ID from default roles.\n*\n* @param roleId - Role ID to find\n* @returns Role definition or undefined\n*/\nfunction getDefaultRole(roleId) {\n\treturn DEFAULT_ROLES.find((role) => role.id === roleId);\n}\n/**\n* Resolve all permissions for a set of role IDs.\n*\n* Handles role inheritance and deduplication.\n*\n* @param roleIds - Role IDs to resolve\n* @param roles - Role definitions (defaults to DEFAULT_ROLES)\n* @returns Array of resolved permissions\n*/\nfunc