@mastra/core
Version:
1,453 lines (1,450 loc) • 48 kB
JavaScript
import { createHash } from 'crypto';
import os from 'os';
// ../_internals/auth/dist/chunk-BHFQZXOC.js
function hashTelemetryValue(value) {
return createHash("sha256").update(value).digest("hex");
}
function getHashedHostname() {
return hashTelemetryValue(os.hostname() || "unknown-host").slice(0, 16);
}
function getEETelemetryFallbackDistinctId() {
return `mastra-${getHashedHostname()}`;
}
var EE_TELEMETRY_BRIDGE = /* @__PURE__ */ Symbol.for("mastra.eeTelemetryBridge");
function getTelemetryBridge() {
return globalThis[EE_TELEMETRY_BRIDGE];
}
function captureEEEvent(event, distinctId, properties) {
getTelemetryBridge()?.captureEEEvent?.(event, distinctId, properties);
}
var LicenseClient = class _LicenseClient {
static instance;
logger;
licenseKey;
licenseUrl;
mode = "open-source";
status = "pending";
cachedResult = null;
cacheExpiry = 0;
gracePeriodEnd = 0;
revalidationTimeout = null;
GRACE_PERIOD_MS = 72 * 60 * 60 * 1e3;
// 72 hours
DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
// 24 hours
constructor(logger) {
this.logger = logger;
this.licenseKey = process.env.MASTRA_LICENSE_KEY || process.env.MASTRA_EE_LICENSE;
this.licenseUrl = process.env.MASTRA_LICENSE_URL || "https://license.mastra.ai";
if (this.licenseKey) {
this.mode = "enterprise";
} else {
this.mode = "open-source";
}
}
static getInstance(logger) {
if (!_LicenseClient.instance) {
_LicenseClient.instance = new _LicenseClient(logger);
} else if (logger) {
_LicenseClient.instance.logger = logger;
}
return _LicenseClient.instance;
}
/**
* Reset the singleton so the next getInstance() re-reads env vars.
* Intended for tests.
*/
static resetInstance() {
if (_LicenseClient.instance?.revalidationTimeout) {
clearTimeout(_LicenseClient.instance.revalidationTimeout);
}
_LicenseClient.instance = void 0;
}
REQUEST_TIMEOUT_MS = 1e4;
async fetchWithRetry(url, options, retries = 3) {
for (let i = 0; i < retries; i++) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), this.REQUEST_TIMEOUT_MS);
timer.unref?.();
try {
const signal = options.signal ? AbortSignal.any([options.signal, controller.signal]) : controller.signal;
const response = await fetch(url, { ...options, signal });
if (response.status === 429 || response.status >= 500) {
if (i === retries - 1) return response;
} else {
return response;
}
} catch (error) {
if (i === retries - 1) throw error;
} finally {
clearTimeout(timer);
}
const delay = Math.pow(2, i) * 1e3;
await new Promise((resolve) => setTimeout(resolve, delay));
}
throw new Error("Unreachable");
}
validationPromise = null;
async validate() {
if (this.mode === "open-source") {
return true;
}
if (this.cachedResult && Date.now() < this.cacheExpiry) {
return true;
}
return this.revalidate();
}
/**
* Contact the server regardless of cache freshness, coalescing concurrent
* callers (e.g. the Mastra constructor and the auth/ee helpers both kicking
* off validation at startup) into a single in-flight request so the server
* is contacted — and the outcome logged — only once. Used directly by the
* background revalidation timer, which must bypass the cache check.
*/
revalidate() {
if (!this.validationPromise) {
this.validationPromise = this.performValidation().finally(() => {
this.validationPromise = null;
});
}
return this.validationPromise;
}
async performValidation() {
const now = Date.now();
try {
if (!this.licenseUrl?.startsWith("https://") && !this.licenseUrl?.includes("localhost")) {
this.logger?.warn("License URL is not HTTPS. Proceeding, but this is insecure.");
}
const response = await this.fetchWithRetry(`${this.licenseUrl}/validate`, {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify({ licenseKey: this.licenseKey })
});
if (response.status === 429 || response.status >= 500) {
throw new Error(`License server responded with ${response.status}`);
}
const data = await response.json();
if (data.valid) {
this.status = "valid";
this.logger?.info(
`License validated: ${data.planTier} tier${data.expiresAt ? `, expires ${data.expiresAt.slice(0, 10)}` : ""}`
);
this.cachedResult = data;
const ttlSeconds = data.leaseTtlSeconds || this.DEFAULT_TTL_MS / 1e3;
this.cacheExpiry = now + ttlSeconds * 1e3;
this.gracePeriodEnd = now + this.GRACE_PERIOD_MS;
this.scheduleRevalidation(ttlSeconds);
return true;
} else if (data.code === "RATE_LIMITED") {
throw new Error(`License server rate limited: ${data.reason}`);
} else {
this.status = "invalid";
this.logger?.error(`License validation failed: ${data.code} - ${data.reason}`);
this.clearCache();
return false;
}
} catch {
if (this.cachedResult && now < this.gracePeriodEnd) {
this.logger?.warn("License server unreachable. Using cached license (within grace period).");
this.status = "valid";
this.scheduleRevalidation(this.DEFAULT_TTL_MS / 1e3);
return true;
} else if (this.cachedResult) {
this.logger?.error("License server unreachable and grace period expired. Disabling enterprise features.");
this.status = "invalid";
this.clearCache();
return false;
} else {
this.logger?.warn("License server unreachable on startup. Failing open (allowing features) and will retry.");
this.status = "valid";
this.cachedResult = {
valid: true,
entitlements: [],
planTier: "unknown",
expiresAt: null,
leaseTtlSeconds: 300
// 5 minutes
};
this.cacheExpiry = now + 300 * 1e3;
this.gracePeriodEnd = now + this.GRACE_PERIOD_MS;
this.scheduleRevalidation(300);
return true;
}
}
}
scheduleRevalidation(ttlSeconds) {
if (this.revalidationTimeout) {
clearTimeout(this.revalidationTimeout);
}
const revalidateMs = ttlSeconds * 1e3 * 0.75;
this.revalidationTimeout = setTimeout(() => {
this.logger?.info("Performing background license revalidation...");
this.revalidate().catch((err) => {
this.logger?.error(
`Background license revalidation failed: ${err instanceof Error ? err.message : String(err)}`
);
});
}, revalidateMs);
this.revalidationTimeout.unref();
}
clearCache() {
this.cachedResult = null;
this.cacheExpiry = 0;
this.gracePeriodEnd = 0;
this.status = "invalid";
if (this.revalidationTimeout) {
clearTimeout(this.revalidationTimeout);
this.revalidationTimeout = null;
}
}
hasFeature(featureName) {
if (this.mode === "open-source") return true;
if (this.status === "pending") return true;
if (this.status === "invalid") return false;
if (!this.cachedResult) return false;
if (this.cachedResult.planTier === "unknown") return true;
return this.cachedResult.entitlements.includes(featureName);
}
getEntitlements() {
if (this.mode === "open-source") return null;
return this.cachedResult?.entitlements || null;
}
getSnapshot() {
return {
mode: this.mode,
status: this.status,
entitlements: this.cachedResult?.entitlements ?? null,
planTier: this.cachedResult?.planTier ?? null,
expiresAt: this.cachedResult?.expiresAt ?? null
};
}
};
function getLicenseKey() {
return process.env["MASTRA_LICENSE_KEY"] || process.env["MASTRA_EE_LICENSE"];
}
var validationStarted = false;
var hasWarnedAboutDevLicense = false;
function getClient() {
const client = LicenseClient.getInstance();
if (!validationStarted) {
validationStarted = true;
void client.validate().catch(() => {
});
}
return client;
}
function startLicenseValidation() {
const client = LicenseClient.getInstance();
validationStarted = true;
return client.validate();
}
function validateLicense(licenseKey) {
const configuredKey = getLicenseKey();
const key = licenseKey ?? configuredKey;
if (!key) {
return { valid: false };
}
if (licenseKey !== void 0 && licenseKey !== configuredKey) {
return { valid: false };
}
const snap = getClient().getSnapshot();
return {
valid: snap.status !== "invalid",
features: snap.entitlements ?? void 0,
tier: snap.planTier ?? void 0,
expiresAt: snap.expiresAt ? new Date(snap.expiresAt) : void 0
};
}
function isLicenseValid() {
if (!getLicenseKey()) {
return false;
}
return getClient().getSnapshot().status !== "invalid";
}
var isEELicenseValid = isLicenseValid;
function isFeatureEnabled(feature) {
if (!getLicenseKey()) {
return false;
}
return getClient().hasFeature(feature);
}
function getSafeLicenseSummary() {
const key = getLicenseKey();
const info = validateLicense(key);
const licenseHash = key ? hashTelemetryValue(key) : void 0;
return {
valid: info.valid,
isDevEnvironment: isDevEnvironment(),
licenseHash: licenseHash ? licenseHash.slice(0, 16) : void 0,
anonymousId: licenseHash ? `${licenseHash.slice(0, 16)}-anonymous` : void 0,
features: info.features,
tier: info.tier
};
}
function warnIfDevEENeedsLicense() {
if (hasWarnedAboutDevLicense || !isDevEnvironment() || isLicenseValid()) {
return;
}
hasWarnedAboutDevLicense = true;
console.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"
);
}
function clearLicenseCache() {
validationStarted = false;
hasWarnedAboutDevLicense = false;
LicenseClient.resetInstance();
}
function isDevEnvironment() {
return process.env["MASTRA_DEV"] === "true" || process.env["MASTRA_DEV"] === "1" || process.env["NODE_ENV"] !== "production" && process.env["NODE_ENV"] !== "prod";
}
function isEEEnabled() {
if (isDevEnvironment()) {
warnIfDevEENeedsLicense();
return true;
}
return isLicenseValid();
}
function isAuthenticated(caps) {
return "user" in caps && caps.user !== null;
}
function implementsInterface(auth, method) {
return auth !== null && typeof auth === "object" && typeof auth[method] === "function";
}
function isMastraCloudAuth(auth) {
if (!auth || typeof auth !== "object") return false;
return "isMastraCloudAuth" in auth && auth.isMastraCloudAuth === true;
}
function isSimpleAuth(auth) {
if (!auth || typeof auth !== "object") return false;
return "isSimpleAuth" in auth && auth.isSimpleAuth === true;
}
function hasAdminBypassPermissions(permissions) {
return permissions.some((p) => p === "*" || p === "*:*");
}
function getRequestIp(request) {
const forwardedFor = request.headers.get("x-forwarded-for");
if (forwardedFor) {
return forwardedFor.split(",")[0]?.trim();
}
return request.headers.get("x-real-ip") ?? void 0;
}
function captureLicenseCheck({
request,
user,
hasLicense,
isDev,
isCloud,
isSimple,
capabilities
}) {
const license = getSafeLicenseSummary();
try {
const ip = getRequestIp(request);
captureEEEvent("ee_license_check", user?.id || license.anonymousId || getEETelemetryFallbackDistinctId(), {
license_valid: hasLicense,
license_hash: license.licenseHash,
is_dev_environment: isDev,
is_cloud: isCloud,
is_simple_auth: isSimple,
capabilities,
user_id: user?.id,
$ip: ip,
license_features: license.features,
license_tier: license.tier
});
} catch {
}
}
async function buildCapabilities(auth, request, options) {
if (!auth) {
return { enabled: false, login: null };
}
const hasLicense = isLicenseValid();
const isCloud = isMastraCloudAuth(auth);
const isSimple = isSimpleAuth(auth);
const isDev = isDevEnvironment();
if (isDev && !hasLicense) {
warnIfDevEENeedsLicense();
}
const isLicensedOrCloud = hasLicense || isCloud || isSimple || isDev;
const isFeatureLicensed = (feature) => isCloud || isSimple || isDev || hasLicense && isFeatureEnabled(feature);
let login = null;
const hasSSO = implementsInterface(auth, "getLoginUrl") && isLicensedOrCloud;
const hasCredentials = implementsInterface(auth, "signIn") && isLicensedOrCloud;
const raw = (options?.apiPrefix || "/api").trim();
const withSlash = raw.startsWith("/") ? raw : `/${raw}`;
const prefix = withSlash.endsWith("/") ? withSlash.slice(0, -1) : withSlash;
const ssoLoginUrl = `${prefix}/auth/sso/login`;
let signUpEnabled = true;
if (implementsInterface(auth, "signIn")) {
const credentialsProvider = auth;
if (typeof credentialsProvider.isSignUpEnabled === "function") {
signUpEnabled = credentialsProvider.isSignUpEnabled();
}
}
if (hasSSO && hasCredentials) {
const ssoConfig = auth.getLoginButtonConfig();
login = {
type: "both",
signUpEnabled,
description: ssoConfig.description,
sso: {
...ssoConfig,
url: ssoLoginUrl
}
};
} else if (hasSSO) {
const ssoConfig = auth.getLoginButtonConfig();
login = {
type: "sso",
description: ssoConfig.description,
sso: {
...ssoConfig,
url: ssoLoginUrl
}
};
} else if (hasCredentials) {
login = {
type: "credentials",
signUpEnabled
};
}
let user = null;
if (implementsInterface(auth, "getCurrentUser") && isLicensedOrCloud) {
try {
user = await auth.getCurrentUser(request);
} catch {
user = null;
}
}
if (!user) {
captureLicenseCheck({ request, user, hasLicense, isDev, isCloud, isSimple });
return { enabled: true, login };
}
const rbacProvider = options?.rbac;
const hasRBAC = !!rbacProvider && isFeatureLicensed("rbac");
const hasFGA = !!options?.fga && isFeatureLicensed("fga");
const capabilities = {
user: implementsInterface(auth, "getCurrentUser") && isLicensedOrCloud,
session: implementsInterface(auth, "createSession") && isLicensedOrCloud,
sso: implementsInterface(auth, "getLoginUrl") && isLicensedOrCloud,
rbac: hasRBAC,
acl: implementsInterface(auth, "canAccess") && isFeatureLicensed("acl"),
fga: hasFGA
};
let access = null;
if (hasRBAC && rbacProvider) {
try {
const roles = await rbacProvider.getRoles(user);
const permissions = await rbacProvider.getPermissions(user);
access = { roles, permissions };
const license = getSafeLicenseSummary();
try {
const ip = getRequestIp(request);
captureEEEvent("ee_feature_used", user.id || license.anonymousId || getEETelemetryFallbackDistinctId(), {
feature: "rbac",
user_id: user.id,
organization_membership_id: user.metadata?.["organizationMembershipId"],
role_count: roles.length,
permission_count: permissions.length,
$ip: ip,
license_valid: license.valid,
license_hash: license.licenseHash,
is_dev_environment: license.isDevEnvironment
});
} catch {
}
} catch {
access = null;
}
}
let availableRoles;
if (access && rbacProvider?.getAvailableRoles) {
if (hasAdminBypassPermissions(access.permissions)) {
try {
const allRoles = await rbacProvider.getAvailableRoles();
const getPermissionsForRole = rbacProvider.getPermissionsForRole?.bind(rbacProvider);
if (getPermissionsForRole) {
const rolePermissions = await Promise.allSettled(
allRoles.map(async (role) => ({
role,
perms: await getPermissionsForRole(role.id)
}))
);
availableRoles = rolePermissions.flatMap((result) => {
if (result.status !== "fulfilled") {
console.warn("[auth/ee] failed to list permissions for role:", result.reason);
return [];
}
return hasAdminBypassPermissions(result.value.perms) ? [] : [result.value.role];
});
} else {
availableRoles = allRoles;
}
} catch (error) {
console.warn("[auth/ee] failed to list available roles for admin user:", error);
}
}
}
captureLicenseCheck({ request, user, hasLicense, isDev, isCloud, isSimple, capabilities });
return {
enabled: true,
login,
user: {
id: user.id,
email: user.email,
name: user.name,
avatarUrl: user.avatarUrl
},
capabilities,
access,
availableRoles
};
}
// ../_internals/auth/dist/chunk-H3EJ4GVJ.js
var RESOURCES = [
"a2a",
"agent-builder",
"agent-controller",
"agents",
"auth",
"background-tasks",
"channels",
"datasets",
"embedders",
"experiments",
"infrastructure",
"logs",
"mcp",
"memory",
"observability",
"processor-providers",
"processors",
"schedules",
"scores",
"stored-agents",
"stored-mcp-clients",
"stored-prompt-blocks",
"stored-scorers",
"stored-skills",
"stored-workspaces",
"system",
"tool-providers",
"tools",
"vector",
"vectors",
"workflows",
"workspaces"
];
var ACTIONS = ["create", "delete", "execute", "publish", "read", "share", "write"];
var PERMISSION_PATTERNS = {
/** Full access to all resources and actions */
"*": "*",
/** Create all resources */
"*:create": "*:create",
/** Delete all resources */
"*:delete": "*:delete",
/** Execute all resources */
"*:execute": "*:execute",
/** Publish, activate, or restore all resources */
"*:publish": "*:publish",
/** View all resources */
"*:read": "*:read",
/** Change visibility/audience all resources */
"*:share": "*:share",
/** Create and modify all resources */
"*:write": "*:write",
/** Full access to agent-to-agent communication */
"a2a:*": "a2a:*",
/** Full access to agent builder */
"agent-builder:*": "agent-builder:*",
/** Full access to agent controller sessions */
"agent-controller:*": "agent-controller:*",
/** Full access to agents */
"agents:*": "agents:*",
/** Full access to auth */
"auth:*": "auth:*",
/** Full access to background tasks */
"background-tasks:*": "background-tasks:*",
/** Full access to channels */
"channels:*": "channels:*",
/** Full access to datasets */
"datasets:*": "datasets:*",
/** Full access to embedders */
"embedders:*": "embedders:*",
/** Full access to experiments */
"experiments:*": "experiments:*",
/** Full access to infrastructure */
"infrastructure:*": "infrastructure:*",
/** Full access to logs */
"logs:*": "logs:*",
/** Full access to MCP servers */
"mcp:*": "mcp:*",
/** Full access to memory and threads */
"memory:*": "memory:*",
/** Full access to traces and spans */
"observability:*": "observability:*",
/** Full access to processor-providers */
"processor-providers:*": "processor-providers:*",
/** Full access to processors */
"processors:*": "processors:*",
/** Full access to schedules */
"schedules:*": "schedules:*",
/** Full access to evaluation scores */
"scores:*": "scores:*",
/** Full access to stored agents */
"stored-agents:*": "stored-agents:*",
/** Full access to stored MCP clients */
"stored-mcp-clients:*": "stored-mcp-clients:*",
/** Full access to stored prompt blocks */
"stored-prompt-blocks:*": "stored-prompt-blocks:*",
/** Full access to stored scorers */
"stored-scorers:*": "stored-scorers:*",
/** Full access to stored skills */
"stored-skills:*": "stored-skills:*",
/** Full access to stored workspaces */
"stored-workspaces:*": "stored-workspaces:*",
/** Full access to system info */
"system:*": "system:*",
/** Full access to tool-providers */
"tool-providers:*": "tool-providers:*",
/** Full access to tools */
"tools:*": "tools:*",
/** Full access to vector stores */
"vector:*": "vector:*",
/** Full access to vectors */
"vectors:*": "vectors:*",
/** Full access to workflows */
"workflows:*": "workflows:*",
/** Full access to workspaces */
"workspaces:*": "workspaces:*",
/** View agent-to-agent communication */
"a2a:read": "a2a:read",
/** Create and modify agent-to-agent communication */
"a2a:write": "a2a:write",
/** Execute agent builder */
"agent-builder:execute": "agent-builder:execute",
/** View agent builder */
"agent-builder:read": "agent-builder:read",
/** Create and modify agent builder */
"agent-builder:write": "agent-builder:write",
/** Execute agent controller sessions */
"agent-controller:execute": "agent-controller:execute",
/** View agent controller sessions */
"agent-controller:read": "agent-controller:read",
/** Create agents */
"agents:create": "agents:create",
/** Delete agents */
"agents:delete": "agents:delete",
/** Execute agents */
"agents:execute": "agents:execute",
/** View agents */
"agents:read": "agents:read",
/** Create and modify agents */
"agents:write": "agents:write",
/** View auth */
"auth:read": "auth:read",
/** View background tasks */
"background-tasks:read": "background-tasks:read",
/** View channels */
"channels:read": "channels:read",
/** Create and modify channels */
"channels:write": "channels:write",
/** Delete datasets */
"datasets:delete": "datasets:delete",
/** Execute datasets */
"datasets:execute": "datasets:execute",
/** View datasets */
"datasets:read": "datasets:read",
/** Create and modify datasets */
"datasets:write": "datasets:write",
/** View embedders */
"embedders:read": "embedders:read",
/** View experiments */
"experiments:read": "experiments:read",
/** View infrastructure */
"infrastructure:read": "infrastructure:read",
/** View logs */
"logs:read": "logs:read",
/** Execute MCP servers */
"mcp:execute": "mcp:execute",
/** View MCP servers */
"mcp:read": "mcp:read",
/** Create and modify MCP servers */
"mcp:write": "mcp:write",
/** Delete memory and threads */
"memory:delete": "memory:delete",
/** Execute memory and threads */
"memory:execute": "memory:execute",
/** View memory and threads */
"memory:read": "memory:read",
/** Create and modify memory and threads */
"memory:write": "memory:write",
/** View traces and spans */
"observability:read": "observability:read",
/** Create and modify traces and spans */
"observability:write": "observability:write",
/** View processor-providers */
"processor-providers:read": "processor-providers:read",
/** Execute processors */
"processors:execute": "processors:execute",
/** View processors */
"processors:read": "processors:read",
/** Delete schedules */
"schedules:delete": "schedules:delete",
/** Execute schedules */
"schedules:execute": "schedules:execute",
/** View schedules */
"schedules:read": "schedules:read",
/** Create and modify schedules */
"schedules:write": "schedules:write",
/** View evaluation scores */
"scores:read": "scores:read",
/** Create and modify evaluation scores */
"scores:write": "scores:write",
/** Delete stored agents */
"stored-agents:delete": "stored-agents:delete",
/** Publish, activate, or restore stored agents */
"stored-agents:publish": "stored-agents:publish",
/** View stored agents */
"stored-agents:read": "stored-agents:read",
/** Create and modify stored agents */
"stored-agents:write": "stored-agents:write",
/** Delete stored MCP clients */
"stored-mcp-clients:delete": "stored-mcp-clients:delete",
/** Publish, activate, or restore stored MCP clients */
"stored-mcp-clients:publish": "stored-mcp-clients:publish",
/** View stored MCP clients */
"stored-mcp-clients:read": "stored-mcp-clients:read",
/** Create and modify stored MCP clients */
"stored-mcp-clients:write": "stored-mcp-clients:write",
/** Delete stored prompt blocks */
"stored-prompt-blocks:delete": "stored-prompt-blocks:delete",
/** Publish, activate, or restore stored prompt blocks */
"stored-prompt-blocks:publish": "stored-prompt-blocks:publish",
/** View stored prompt blocks */
"stored-prompt-blocks:read": "stored-prompt-blocks:read",
/** Create and modify stored prompt blocks */
"stored-prompt-blocks:write": "stored-prompt-blocks:write",
/** Delete stored scorers */
"stored-scorers:delete": "stored-scorers:delete",
/** Publish, activate, or restore stored scorers */
"stored-scorers:publish": "stored-scorers:publish",
/** View stored scorers */
"stored-scorers:read": "stored-scorers:read",
/** Create and modify stored scorers */
"stored-scorers:write": "stored-scorers:write",
/** Delete stored skills */
"stored-skills:delete": "stored-skills:delete",
/** Publish, activate, or restore stored skills */
"stored-skills:publish": "stored-skills:publish",
/** View stored skills */
"stored-skills:read": "stored-skills:read",
/** Create and modify stored skills */
"stored-skills:write": "stored-skills:write",
/** Delete stored workspaces */
"stored-workspaces:delete": "stored-workspaces:delete",
/** View stored workspaces */
"stored-workspaces:read": "stored-workspaces:read",
/** Create and modify stored workspaces */
"stored-workspaces:write": "stored-workspaces:write",
/** View system info */
"system:read": "system:read",
/** Delete tool-providers */
"tool-providers:delete": "tool-providers:delete",
/** View tool-providers */
"tool-providers:read": "tool-providers:read",
/** Create and modify tool-providers */
"tool-providers:write": "tool-providers:write",
/** Execute tools */
"tools:execute": "tools:execute",
/** View tools */
"tools:read": "tools:read",
/** Delete vector stores */
"vector:delete": "vector:delete",
/** Execute vector stores */
"vector:execute": "vector:execute",
/** View vector stores */
"vector:read": "vector:read",
/** Create and modify vector stores */
"vector:write": "vector:write",
/** View vectors */
"vectors:read": "vectors:read",
/** Delete workflows */
"workflows:delete": "workflows:delete",
/** Execute workflows */
"workflows:execute": "workflows:execute",
/** View workflows */
"workflows:read": "workflows:read",
/** Create and modify workflows */
"workflows:write": "workflows:write",
/** Delete workspaces */
"workspaces:delete": "workspaces:delete",
/** View workspaces */
"workspaces:read": "workspaces:read",
/** Create and modify workspaces */
"workspaces:write": "workspaces:write",
/** Full access to all stored resource families */
"stored:*": "stored:*",
/** View all stored resource families */
"stored:read": "stored:read",
/** Create and modify all stored resource families */
"stored:write": "stored:write",
/** Delete all stored resource families */
"stored:delete": "stored:delete",
/** Change visibility/audience stored agents */
"stored-agents:share": "stored-agents:share",
/** Change visibility/audience stored skills */
"stored-skills:share": "stored-skills:share"
};
var PERMISSIONS = [
"a2a:read",
"a2a:write",
"agent-builder:execute",
"agent-builder:read",
"agent-builder:write",
"agent-controller:execute",
"agent-controller:read",
"agents:create",
"agents:delete",
"agents:execute",
"agents:read",
"agents:write",
"auth:read",
"background-tasks:read",
"channels:read",
"channels:write",
"datasets:delete",
"datasets:execute",
"datasets:read",
"datasets:write",
"embedders:read",
"experiments:read",
"infrastructure:read",
"logs:read",
"mcp:execute",
"mcp:read",
"mcp:write",
"memory:delete",
"memory:execute",
"memory:read",
"memory:write",
"observability:read",
"observability:write",
"processor-providers:read",
"processors:execute",
"processors:read",
"schedules:delete",
"schedules:execute",
"schedules:read",
"schedules:write",
"scores:read",
"scores:write",
"stored-agents:delete",
"stored-agents:publish",
"stored-agents:read",
"stored-agents:write",
"stored-mcp-clients:delete",
"stored-mcp-clients:publish",
"stored-mcp-clients:read",
"stored-mcp-clients:write",
"stored-prompt-blocks:delete",
"stored-prompt-blocks:publish",
"stored-prompt-blocks:read",
"stored-prompt-blocks:write",
"stored-scorers:delete",
"stored-scorers:publish",
"stored-scorers:read",
"stored-scorers:write",
"stored-skills:delete",
"stored-skills:publish",
"stored-skills:read",
"stored-skills:write",
"stored-workspaces:delete",
"stored-workspaces:read",
"stored-workspaces:write",
"system:read",
"tool-providers:delete",
"tool-providers:read",
"tool-providers:write",
"tools:execute",
"tools:read",
"vector:delete",
"vector:execute",
"vector:read",
"vector:write",
"vectors:read",
"workflows:delete",
"workflows:execute",
"workflows:read",
"workflows:write",
"workspaces:delete",
"workspaces:read",
"workspaces:write"
];
var MastraFGAPermissions = {
/** View agent-to-agent communication */
A2A_READ: "a2a:read",
/** Create and modify agent-to-agent communication */
A2A_WRITE: "a2a:write",
/** Execute agent builder */
AGENT_BUILDER_EXECUTE: "agent-builder:execute",
/** View agent builder */
AGENT_BUILDER_READ: "agent-builder:read",
/** Create and modify agent builder */
AGENT_BUILDER_WRITE: "agent-builder:write",
/** Execute agent controller sessions */
AGENT_CONTROLLER_EXECUTE: "agent-controller:execute",
/** View agent controller sessions */
AGENT_CONTROLLER_READ: "agent-controller:read",
/** Create agents */
AGENTS_CREATE: "agents:create",
/** Delete agents */
AGENTS_DELETE: "agents:delete",
/** Execute agents */
AGENTS_EXECUTE: "agents:execute",
/** View agents */
AGENTS_READ: "agents:read",
/** Create and modify agents */
AGENTS_WRITE: "agents:write",
/** View auth */
AUTH_READ: "auth:read",
/** View background tasks */
BACKGROUND_TASKS_READ: "background-tasks:read",
/** View channels */
CHANNELS_READ: "channels:read",
/** Create and modify channels */
CHANNELS_WRITE: "channels:write",
/** Delete datasets */
DATASETS_DELETE: "datasets:delete",
/** Execute datasets */
DATASETS_EXECUTE: "datasets:execute",
/** View datasets */
DATASETS_READ: "datasets:read",
/** Create and modify datasets */
DATASETS_WRITE: "datasets:write",
/** View embedders */
EMBEDDERS_READ: "embedders:read",
/** View experiments */
EXPERIMENTS_READ: "experiments:read",
/** View infrastructure */
INFRASTRUCTURE_READ: "infrastructure:read",
/** View logs */
LOGS_READ: "logs:read",
/** Execute MCP servers */
MCP_EXECUTE: "mcp:execute",
/** View MCP servers */
MCP_READ: "mcp:read",
/** Create and modify MCP servers */
MCP_WRITE: "mcp:write",
/** Delete memory and threads */
MEMORY_DELETE: "memory:delete",
/** Execute memory and threads */
MEMORY_EXECUTE: "memory:execute",
/** View memory and threads */
MEMORY_READ: "memory:read",
/** Create and modify memory and threads */
MEMORY_WRITE: "memory:write",
/** View traces and spans */
OBSERVABILITY_READ: "observability:read",
/** Create and modify traces and spans */
OBSERVABILITY_WRITE: "observability:write",
/** View processor-providers */
PROCESSOR_PROVIDERS_READ: "processor-providers:read",
/** Execute processors */
PROCESSORS_EXECUTE: "processors:execute",
/** View processors */
PROCESSORS_READ: "processors:read",
/** Delete schedules */
SCHEDULES_DELETE: "schedules:delete",
/** Execute schedules */
SCHEDULES_EXECUTE: "schedules:execute",
/** View schedules */
SCHEDULES_READ: "schedules:read",
/** Create and modify schedules */
SCHEDULES_WRITE: "schedules:write",
/** View evaluation scores */
SCORES_READ: "scores:read",
/** Create and modify evaluation scores */
SCORES_WRITE: "scores:write",
/** Delete stored agents */
STORED_AGENTS_DELETE: "stored-agents:delete",
/** Publish, activate, or restore stored agents */
STORED_AGENTS_PUBLISH: "stored-agents:publish",
/** View stored agents */
STORED_AGENTS_READ: "stored-agents:read",
/** Create and modify stored agents */
STORED_AGENTS_WRITE: "stored-agents:write",
/** Delete stored MCP clients */
STORED_MCP_CLIENTS_DELETE: "stored-mcp-clients:delete",
/** Publish, activate, or restore stored MCP clients */
STORED_MCP_CLIENTS_PUBLISH: "stored-mcp-clients:publish",
/** View stored MCP clients */
STORED_MCP_CLIENTS_READ: "stored-mcp-clients:read",
/** Create and modify stored MCP clients */
STORED_MCP_CLIENTS_WRITE: "stored-mcp-clients:write",
/** Delete stored prompt blocks */
STORED_PROMPT_BLOCKS_DELETE: "stored-prompt-blocks:delete",
/** Publish, activate, or restore stored prompt blocks */
STORED_PROMPT_BLOCKS_PUBLISH: "stored-prompt-blocks:publish",
/** View stored prompt blocks */
STORED_PROMPT_BLOCKS_READ: "stored-prompt-blocks:read",
/** Create and modify stored prompt blocks */
STORED_PROMPT_BLOCKS_WRITE: "stored-prompt-blocks:write",
/** Delete stored scorers */
STORED_SCORERS_DELETE: "stored-scorers:delete",
/** Publish, activate, or restore stored scorers */
STORED_SCORERS_PUBLISH: "stored-scorers:publish",
/** View stored scorers */
STORED_SCORERS_READ: "stored-scorers:read",
/** Create and modify stored scorers */
STORED_SCORERS_WRITE: "stored-scorers:write",
/** Delete stored skills */
STORED_SKILLS_DELETE: "stored-skills:delete",
/** Publish, activate, or restore stored skills */
STORED_SKILLS_PUBLISH: "stored-skills:publish",
/** View stored skills */
STORED_SKILLS_READ: "stored-skills:read",
/** Create and modify stored skills */
STORED_SKILLS_WRITE: "stored-skills:write",
/** Delete stored workspaces */
STORED_WORKSPACES_DELETE: "stored-workspaces:delete",
/** View stored workspaces */
STORED_WORKSPACES_READ: "stored-workspaces:read",
/** Create and modify stored workspaces */
STORED_WORKSPACES_WRITE: "stored-workspaces:write",
/** View system info */
SYSTEM_READ: "system:read",
/** Delete tool-providers */
TOOL_PROVIDERS_DELETE: "tool-providers:delete",
/** View tool-providers */
TOOL_PROVIDERS_READ: "tool-providers:read",
/** Create and modify tool-providers */
TOOL_PROVIDERS_WRITE: "tool-providers:write",
/** Execute tools */
TOOLS_EXECUTE: "tools:execute",
/** View tools */
TOOLS_READ: "tools:read",
/** Delete vector stores */
VECTOR_DELETE: "vector:delete",
/** Execute vector stores */
VECTOR_EXECUTE: "vector:execute",
/** View vector stores */
VECTOR_READ: "vector:read",
/** Create and modify vector stores */
VECTOR_WRITE: "vector:write",
/** View vectors */
VECTORS_READ: "vectors:read",
/** Delete workflows */
WORKFLOWS_DELETE: "workflows:delete",
/** Execute workflows */
WORKFLOWS_EXECUTE: "workflows:execute",
/** View workflows */
WORKFLOWS_READ: "workflows:read",
/** Create and modify workflows */
WORKFLOWS_WRITE: "workflows:write",
/** Delete workspaces */
WORKSPACES_DELETE: "workspaces:delete",
/** View workspaces */
WORKSPACES_READ: "workspaces:read",
/** Create and modify workspaces */
WORKSPACES_WRITE: "workspaces:write"
};
function isValidPermissionPattern(pattern) {
return pattern in PERMISSION_PATTERNS;
}
function validatePermissions(permissions) {
return permissions.every(isValidPermissionPattern);
}
function mergeFGAContext({
context,
requestContext,
metadata
}) {
const mergedContext = {
...context
};
if (requestContext) {
mergedContext.requestContext = requestContext;
}
if (metadata || context?.metadata) {
mergedContext.metadata = {
...context?.metadata ?? {},
...metadata ?? {}
};
}
return Object.keys(mergedContext).length > 0 ? mergedContext : void 0;
}
function isActorSignal(actor) {
if (actor === true) {
return true;
}
if (typeof actor !== "object" || actor === null) {
return false;
}
const candidate = actor;
return candidate.actorKind === "system" && (candidate.sourceWorkflow === void 0 || typeof candidate.sourceWorkflow === "string");
}
function getAgentFGAResourceId(agentId) {
return agentId;
}
function getWorkflowFGAResourceId(workflowId) {
return workflowId;
}
function getStandaloneToolFGAResourceId(toolName) {
return toolName;
}
function getAgentToolFGAResourceId(agentId, toolName) {
return `${agentId}:${toolName}`;
}
function getMCPToolFGAResourceId(serverName, toolName) {
return JSON.stringify([serverName, toolName]);
}
async function checkFGA(options) {
await requireFGA(options);
}
async function requireFGA(options) {
const { fgaProvider, user, resource, permission, context, requestContext, metadata, actor } = options;
if (!fgaProvider) {
return;
}
const fgaContext = mergeFGAContext({ context, requestContext, metadata });
const license = getSafeLicenseSummary();
if (isActorSignal(actor)) {
const tenantOrganizationId = fgaContext?.requestContext?.get("organizationId");
if (typeof tenantOrganizationId !== "string" || tenantOrganizationId.length === 0) {
throw new FGADeniedError(user, resource, permission, "trusted actor requires organizationId / tenant scope");
}
const sourceWorkflow = (actor === true ? void 0 : actor.sourceWorkflow) ?? (typeof fgaContext?.metadata?.["sourceWorkflow"] === "string" ? fgaContext.metadata["sourceWorkflow"] : void 0);
try {
captureEEEvent("ee_feature_used", license.anonymousId || getEETelemetryFallbackDistinctId(), {
feature: "fga",
actor_kind: "system",
resource_type: resource.type,
resource_id: resource.id,
permission,
user_id: null,
organization_membership_id: null,
source_workflow: sourceWorkflow,
license_valid: license.valid,
license_hash: license.licenseHash,
is_dev_environment: license.isDevEnvironment
});
} catch {
}
return;
}
if (!user) {
throw new FGADeniedError(user, resource, permission, "authenticated user is required");
}
await fgaProvider.require(
user,
fgaContext ? { resource, permission, context: fgaContext } : { resource, permission }
);
try {
captureEEEvent("ee_feature_used", user?.id || license.anonymousId || getEETelemetryFallbackDistinctId(), {
feature: "fga",
actor_kind: "user",
resource_type: resource.type,
resource_id: resource.id,
permission,
user_id: user?.id ?? null,
organization_membership_id: user?.organizationMembershipId ?? null,
license_valid: license.valid,
license_hash: license.licenseHash,
is_dev_environment: license.isDevEnvironment
});
} catch {
}
}
var FGADeniedError = class extends Error {
user;
resource;
permission;
status;
constructor(user, resource, permission, reason) {
const userId = user?.id || user?.workosId || "unknown";
const permissionLabel = Array.isArray(permission) ? `any of [${permission.join(", ")}]` : permission;
super(
reason ? `FGA authorization denied: ${reason}` : `FGA authorization denied: user ${userId} cannot ${permissionLabel} on ${resource.type}:${resource.id}`
);
this.name = "FGADeniedError";
this.user = user;
this.resource = resource;
this.permission = permission;
this.status = 403;
}
};
var DEFAULT_ROLES = [
{
id: "owner",
name: "Owner",
description: "Full access to all features and settings",
permissions: ["*"]
},
{
id: "admin",
name: "Admin",
description: "Manage agents, workflows, and team members",
permissions: [
"*:read",
"*:write",
"*:execute",
"*:publish",
"*:share"
// Note: admins cannot delete resources
]
},
{
id: "member",
name: "Member",
description: "Execute agents and workflows",
permissions: ["*:read", "*:execute"]
},
{
id: "viewer",
name: "Viewer",
description: "Read-only access",
permissions: ["*:read"]
}
];
function getDefaultRole(roleId) {
return DEFAULT_ROLES.find((role) => role.id === roleId);
}
function resolvePermissions(roleIds, roles = DEFAULT_ROLES) {
const permissions = /* @__PURE__ */ new Set();
const visited = /* @__PURE__ */ new Set();
function resolveRole(roleId) {
if (visited.has(roleId)) return;
visited.add(roleId);
const role = roles.find((r) => r.id === roleId);
if (!role) return;
for (const permission of role.permissions) {
permissions.add(permission);
}
if (role.inherits) {
for (const inheritedRoleId of role.inherits) {
resolveRole(inheritedRoleId);
}
}
}
for (const roleId of roleIds) {
resolveRole(roleId);
}
return Array.from(permissions);
}
var RESOURCE_EXPANSIONS = {
stored: [
"stored-agents",
"stored-mcp-clients",
"stored-prompt-blocks",
"stored-scorers",
"stored-skills",
"stored-workspaces"
]
};
function matchesPermission(userPermission, requiredPermission) {
if (userPermission === "*") {
return true;
}
const grantedParts = userPermission.split(":");
const requiredParts = requiredPermission.split(":");
const expandedFamilies = RESOURCE_EXPANSIONS[grantedParts[0] ?? ""];
if (expandedFamilies && expandedFamilies.includes(requiredParts[0] ?? "")) {
const aliased = [requiredParts[0], ...grantedParts.slice(1)].join(":");
return matchesPermission(aliased, requiredPermission);
}
if (grantedParts.length < 2 || requiredParts.length < 2) {
return userPermission === requiredPermission;
}
const [grantedResource, grantedAction, grantedId] = grantedParts;
const [requiredResource, requiredAction, requiredId] = requiredParts;
if (grantedResource === "*") {
if (grantedAction === "*") {
if (grantedId === void 0) {
return true;
}
return grantedId === requiredId;
}
if (grantedAction !== requiredAction) {
return false;
}
if (grantedId === void 0) {
return true;
}
return grantedId === requiredId;
}
if (grantedResource !== requiredResource) {
return false;
}
if (grantedAction === "*") {
if (grantedId === void 0) {
return true;
}
return grantedId === requiredId;
}
if (grantedAction !== requiredAction) {
return false;
}
if (grantedId === void 0) {
return true;
}
return grantedId === requiredId;
}
function hasPermission(userPermissions, requiredPermission) {
return userPermissions.some((p) => matchesPermission(p, requiredPermission));
}
function resolvePermissionsFromMapping(roles, mapping) {
const permissions = /* @__PURE__ */ new Set();
const defaultPerms = mapping["_default"] ?? [];
for (const role of roles) {
const rolePerms = mapping[role];
if (rolePerms) {
for (const perm of rolePerms) {
permissions.add(perm);
}
} else {
for (const perm of defaultPerms) {
permissions.add(perm);
}
}
}
return Array.from(permissions);
}
var StaticRBACProvider = class {
roles;
_roleMapping;
getUserRolesFn;
permissionCache = /* @__PURE__ */ new Map();
/** Expose roleMapping for middleware access */
get roleMapping() {
return this._roleMapping;
}
constructor(options) {
if ("roles" in options && options.roles) {
this.roles = options.roles;
}
if ("roleMapping" in options && options.roleMapping) {
this._roleMapping = options.roleMapping;
}
this.getUserRolesFn = options.getUserRoles;
}
async getRoles(user) {
const roleIds = await this.getUserRolesFn(user);
return roleIds;
}
async hasRole(user, role) {
const roles = await this.getRoles(user);
return roles.includes(role);
}
async getPermissions(user) {
const roleIds = await this.getRoles(user);
const cacheKey = roleIds.sort().join(",");
const cached = this.permissionCache.get(cacheKey);
if (cached) return cached;
let permissions;
if (this._roleMapping) {
permissions = resolvePermissionsFromMapping(roleIds, this._roleMapping);
} else if (this.roles) {
permissions = resolvePermissions(roleIds, this.roles);
} else {
permissions = [];
}
this.permissionCache.set(cacheKey, permissions);
return permissions;
}
async hasPermission(user, permission) {
const permissions = await this.getPermissions(user);
return permissions.some((p) => matchesPermission(p, permission));
}
async hasAllPermissions(user, permissions) {
const userPermissions = await this.getPermissions(user);
return permissions.every((required) => userPermissions.some((p) => matchesPermission(p, required)));
}
async hasAnyPermission(user, permissions) {
const userPermissions = await this.getPermissions(user);
return permissions.some((required) => userPermissions.some((p) => matchesPermission(p, required)));
}
/**
* Clear the permission cache.
*/
clearCache() {
this.permissionCache.clear();
}
/**
* Get all role definitions.
* Only available when using role definitions mode (not role mapping).
*/
getRoleDefinitions() {
return this.roles ?? [];
}
/**
* Get a specific role definition.
* Only available when using role definitions mode (not role mapping).
*/
getRoleDefinition(roleId) {
return this.roles?.find((r) => r.id === roleId);
}
/**
* Get all available roles in the system.
*/
async getAvailableRoles() {
if (this.roles) {
return this.roles.map((r) => ({ id: r.id, name: r.name }));
}
if (this._roleMapping) {
return Object.keys(this._roleMapping).filter((k) => k !== "_default").map((k) => ({ id: k, name: k }));
}
return [];
}
/**
* Get the resolved permissions for a specific role.
*/
async getPermissionsForRole(roleId) {
if (this._roleMapping) {
return resolvePermissionsFromMapping([roleId], this._roleMapping);
}
if (this.roles) {
return resolvePermissions([roleId], this.roles);
}
return [];
}
};
/**
* EE Authentication Interfaces
*
* Enterprise interfaces for RBAC, ACL, and advanced authorization.
*
* @license Mastra Enterprise License - see ee/LICENSE
* @packageDocumentation
*/
/**
* FGA enforcement utility for checking fine-grained authorization.
*
* @license Mastra Enterprise License - see ee/LICENSE
*/
/**
* RBAC provider implementations.
*
* @license Mastra Enterprise License - see ee/LICENSE
*/
/**
* Default implementations for EE authentication.
*
* @license Mastra Enterprise License - see ee/LICENSE
*/
/**
* @mastra/core/auth/ee
*
* Enterprise authentication capabilities for Mastra.
* This code is licensed under the Mastra Enterprise License - see ee/LICENSE.
*
* @license Mastra Enterprise License - see ee/LICENSE
* @packageDocumentation
*/
export { ACTIONS, DEFAULT_ROLES, FGADeniedError, MastraFGAPermissions, PERMISSIONS, PERMISSION_PATTERNS, RESOURCES, StaticRBACProvider, buildCapabilities, checkFGA, clearLicenseCache, getAgentFGAResourceId, getAgentToolFGAResourceId, getDefaultRole, getMCPToolFGAResourceId, getSafeLicenseSummary, getStandaloneToolFGAResourceId, getWorkflowFGAResourceId, hasPermission, isAuthenticated, isDevEnvironment, isEEEnabled, isEELicenseValid, isFeatureEnabled, isLicenseValid, isValidPermissionPattern, matchesPermission, requireFGA, resolvePermissions, resolvePermissionsFromMapping, startLicenseValidation, validateLicense, validatePermissions, warnIfDevEENeedsLicense };
//# sourceMappingURL=chunk-HIW7BSXS.js.map
//# sourceMappingURL=chunk-HIW7BSXS.js.map