{"version":3,"sources":["../src/auth/ee/license.ts","../src/auth/ee/fga-check.ts"],"names":["LicenseClient","hashTelemetryValue","captureEEEvent","getEETelemetryFallbackDistinctId"],"mappings":"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","file":"chunk-TKFSM674.cjs","sourcesContent":["/**\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 */\n\nimport { LicenseClient } from '../../license';\nimport { hashTelemetryValue } from '../../telemetry/posthog';\n\n/**\n * License information.\n */\nexport interface LicenseInfo {\n /** Whether the license is valid */\n valid: boolean;\n /** License expiration date */\n expiresAt?: Date;\n /** Features enabled by this license */\n features?: string[];\n /** Organization name */\n organization?: string;\n /** License plan tier (e.g. 'teams', 'enterprise') */\n tier?: string;\n}\n\nexport interface SafeLicenseSummary {\n valid: boolean;\n isDevEnvironment: boolean;\n licenseHash?: string;\n anonymousId?: string;\n features?: string[];\n tier?: string;\n}\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(): string | undefined {\n return process.env['MASTRA_LICENSE_KEY'] || process.env['MASTRA_EE_LICENSE'];\n}\n\nlet validationStarted = false;\nlet hasWarnedAboutDevLicense = false;\n\n/**\n * Get the shared LicenseClient and kick off background validation on first use.\n */\nfunction getClient(): LicenseClient {\n const client = LicenseClient.getInstance();\n if (!validationStarted) {\n validationStarted = true;\n void client.validate().catch(() => {\n // Background validation failures are handled inside LicenseClient\n // (grace period / fail-open). Never let them surface here.\n });\n }\n return client;\n}\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 */\nexport function startLicenseValidation(): Promise {\n const client = LicenseClient.getInstance();\n validationStarted = true;\n return client.validate();\n}\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 */\nexport function validateLicense(licenseKey?: string): LicenseInfo {\n const configuredKey = getLicenseKey();\n const key = licenseKey ?? configuredKey;\n\n if (!key) {\n return { valid: false };\n }\n\n // The client only ever validates the configured key, so its snapshot can't\n // vouch for any other key the caller supplies.\n if (licenseKey !== undefined && licenseKey !== configuredKey) {\n return { valid: false };\n }\n\n const snap = getClient().getSnapshot();\n\n return {\n valid: snap.status !== 'invalid',\n features: snap.entitlements ?? undefined,\n tier: snap.planTier ?? undefined,\n expiresAt: snap.expiresAt ? new Date(snap.expiresAt) : undefined,\n };\n}\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 */\nexport function isLicenseValid(): boolean {\n if (!getLicenseKey()) {\n return false;\n }\n\n // 'valid' or 'pending' (fail open until the first server response).\n // LicenseClient logs the failure reason when the server rejects the key.\n return getClient().getSnapshot().status !== 'invalid';\n}\n\n/**\n * @deprecated Use `isLicenseValid()` instead. This alias is provided for backward compatibility.\n */\nexport const isEELicenseValid = isLicenseValid;\n\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 */\nexport function isFeatureEnabled(feature: string): boolean {\n if (!getLicenseKey()) {\n return false;\n }\n\n return getClient().hasFeature(feature);\n}\n\n/**\n * Get the current license information.\n *\n * @returns License info or null if no license key is configured\n */\nexport function getLicenseInfo(): LicenseInfo | null {\n if (!getLicenseKey()) {\n return null;\n }\n\n return validateLicense();\n}\n\nexport function getSafeLicenseSummary(): SafeLicenseSummary {\n const key = getLicenseKey();\n const info = validateLicense(key);\n const licenseHash = key ? hashTelemetryValue(key) : undefined;\n\n return {\n valid: info.valid,\n isDevEnvironment: isDevEnvironment(),\n licenseHash: licenseHash ? licenseHash.slice(0, 16) : undefined,\n anonymousId: licenseHash ? `${licenseHash.slice(0, 16)}-anonymous` : undefined,\n features: info.features,\n tier: info.tier,\n };\n}\n\nexport function warnIfDevEENeedsLicense(): void {\n if (hasWarnedAboutDevLicense || !isDevEnvironment() || isLicenseValid()) {\n return;\n }\n\n hasWarnedAboutDevLicense = true;\n console.warn(\n '[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\n/**\n * Clear the license cache (useful for testing).\n * Resets the shared client so the next check re-reads env vars.\n */\nexport function clearLicenseCache(): void {\n validationStarted = false;\n hasWarnedAboutDevLicense = false;\n LicenseClient.resetInstance();\n}\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 */\nexport function isDevEnvironment(): boolean {\n return (\n process.env['MASTRA_DEV'] === 'true' ||\n process.env['MASTRA_DEV'] === '1' ||\n (process.env['NODE_ENV'] !== 'production' && process.env['NODE_ENV'] !== 'prod')\n );\n}\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 */\nexport function isEEEnabled(): boolean {\n if (isDevEnvironment()) {\n warnIfDevEENeedsLicense();\n return true;\n }\n return isLicenseValid();\n}\n","/**\n * FGA enforcement utility for checking fine-grained authorization.\n *\n * @license Mastra Enterprise License - see ee/LICENSE\n */\n\nimport { captureEEEvent, getEETelemetryFallbackDistinctId } from '../../telemetry/posthog';\nimport type { FGACheckContext, IFGAProvider } from './interfaces/fga';\nimport type { MastraFGAPermissionInput } from './interfaces/permissions.generated';\nimport { getSafeLicenseSummary } from './license';\n\nexport type ActorSignal =\n | true\n | {\n actorKind: 'system';\n sourceWorkflow?: string;\n };\n\nexport interface CheckFGAOptions {\n fgaProvider: IFGAProvider | undefined;\n user: any;\n resource: { type: string; id: string };\n permission: MastraFGAPermissionInput | MastraFGAPermissionInput[];\n context?: FGACheckContext;\n requestContext?: FGACheckContext['requestContext'];\n actor?: ActorSignal;\n}\n\nexport interface RequireFGAOptions extends CheckFGAOptions {\n metadata?: Record;\n}\n\nfunction mergeFGAContext({\n context,\n requestContext,\n metadata,\n}: Pick): FGACheckContext | undefined {\n const mergedContext: FGACheckContext = {\n ...context,\n };\n\n if (requestContext) {\n mergedContext.requestContext = requestContext;\n }\n\n if (metadata || context?.metadata) {\n mergedContext.metadata = {\n ...(context?.metadata ?? {}),\n ...(metadata ?? {}),\n };\n }\n\n return Object.keys(mergedContext).length > 0 ? mergedContext : undefined;\n}\n\nfunction isActorSignal(actor: unknown): actor is ActorSignal {\n if (actor === true) {\n return true;\n }\n\n if (typeof actor !== 'object' || actor === null) {\n return false;\n }\n\n const candidate = actor as { actorKind?: unknown; sourceWorkflow?: unknown };\n return (\n candidate.actorKind === 'system' &&\n (candidate.sourceWorkflow === undefined || typeof candidate.sourceWorkflow === 'string')\n );\n}\n\nexport function getAgentFGAResourceId(agentId: string): string {\n return agentId;\n}\n\nexport function getWorkflowFGAResourceId(workflowId: string): string {\n return workflowId;\n}\n\nexport function getStandaloneToolFGAResourceId(toolName: string): string {\n return toolName;\n}\n\nexport function getAgentToolFGAResourceId(agentId: string, toolName: string): string {\n return `${agentId}:${toolName}`;\n}\n\nexport function getMCPToolFGAResourceId(serverName: string, toolName: string): string {\n return JSON.stringify([serverName, toolName]);\n}\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 */\nexport async function checkFGA(options: CheckFGAOptions): Promise {\n await requireFGA(options);\n}\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 */\nexport async function requireFGA(options: RequireFGAOptions): Promise {\n const { fgaProvider, user, resource, permission, context, requestContext, metadata, actor } = options;\n\n if (!fgaProvider) {\n return;\n }\n\n const fgaContext = mergeFGAContext({ context, requestContext, metadata });\n const license = getSafeLicenseSummary();\n\n if (isActorSignal(actor)) {\n const tenantOrganizationId = fgaContext?.requestContext?.get('organizationId');\n if (typeof tenantOrganizationId !== 'string' || tenantOrganizationId.length === 0) {\n throw new FGADeniedError(user, resource, permission, 'trusted actor requires organizationId / tenant scope');\n }\n\n const sourceWorkflow =\n (actor === true ? undefined : actor.sourceWorkflow) ??\n (typeof fgaContext?.metadata?.['sourceWorkflow'] === 'string'\n ? fgaContext.metadata['sourceWorkflow']\n : undefined);\n\n try {\n captureEEEvent('ee_feature_used', license.anonymousId || getEETelemetryFallbackDistinctId(), {\n feature: 'fga',\n actor_kind: 'system',\n resource_type: resource.type,\n resource_id: resource.id,\n permission,\n user_id: null,\n organization_membership_id: null,\n source_workflow: sourceWorkflow,\n license_valid: license.valid,\n license_hash: license.licenseHash,\n is_dev_environment: license.isDevEnvironment,\n });\n } catch {\n // Telemetry must never affect auth or EE feature behavior.\n }\n return;\n }\n\n if (!user) {\n throw new FGADeniedError(user, resource, permission, 'authenticated user is required');\n }\n\n await fgaProvider.require(\n user,\n fgaContext ? { resource, permission, context: fgaContext } : { resource, permission },\n );\n\n try {\n captureEEEvent('ee_feature_used', user?.id || license.anonymousId || getEETelemetryFallbackDistinctId(), {\n feature: 'fga',\n actor_kind: 'user',\n resource_type: resource.type,\n resource_id: resource.id,\n permission,\n user_id: user?.id ?? null,\n organization_membership_id: user?.organizationMembershipId ?? null,\n license_valid: license.valid,\n license_hash: license.licenseHash,\n is_dev_environment: license.isDevEnvironment,\n });\n } catch {\n // Telemetry must never affect auth or EE feature behavior.\n }\n}\n\n/**\n * Error thrown when an FGA authorization check is denied.\n */\nexport class FGADeniedError extends Error {\n public readonly user: any;\n public readonly resource: { type: string; id: string };\n public readonly permission: MastraFGAPermissionInput | MastraFGAPermissionInput[];\n public readonly status: number;\n\n constructor(\n user: any,\n resource: { type: string; id: string },\n permission: MastraFGAPermissionInput | MastraFGAPermissionInput[],\n reason?: string,\n ) {\n const userId = user?.id || user?.workosId || 'unknown';\n const permissionLabel = Array.isArray(permission) ? `any of [${permission.join(', ')}]` : permission;\n super(\n reason\n ? `FGA authorization denied: ${reason}`\n : `FGA authorization denied: user ${userId} cannot ${permissionLabel} on ${resource.type}:${resource.id}`,\n );\n this.name = 'FGADeniedError';\n this.user = user;\n this.resource = resource;\n this.permission = permission;\n this.status = 403;\n }\n}\n"]}