Skip to content

Commit bf08402

Browse files
junydaniaclaude
andauthored
feat(core): validate EE licenses against the Mastra license server (#17859)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent dfe9bfe commit bf08402

9 files changed

Lines changed: 688 additions & 119 deletions

File tree

.changeset/thin-goats-trade.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@mastra/core': patch
3+
---
4+
5+
License validation for EE features (RBAC, ACL, FGA, SSO) now checks your license key against the Mastra license server instead of validating it locally.
6+
7+
**What changes for you**
8+
9+
- Set `MASTRA_LICENSE_KEY` to your license key. `MASTRA_EE_LICENSE` continues to work as a supported legacy alias, so existing deployments are unaffected.
10+
- RBAC, ACL, and FGA are now enabled per-feature based on the entitlements your license plan includes, rather than a single blanket license check.
11+
- If the license server is briefly unreachable, previously validated licenses keep working (72-hour grace period), and validation never blocks startup — it runs in the background.
12+
- Development environments (`NODE_ENV` not set to production) are unaffected and keep full EE access without a license.

packages/core/package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,16 @@
281281
"default": "./dist/integration/index.cjs"
282282
}
283283
},
284+
"./license": {
285+
"import": {
286+
"types": "./dist/license/index.d.ts",
287+
"default": "./dist/license/index.js"
288+
},
289+
"require": {
290+
"types": "./dist/license/index.d.ts",
291+
"default": "./dist/license/index.cjs"
292+
}
293+
},
284294
"./llm": {
285295
"import": {
286296
"types": "./dist/llm/index.d.ts",

packages/core/src/auth/ee/__tests__/capabilities-fga.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ describe('FGA Capability Detection', () => {
103103

104104
expect('capabilities' in result && result.capabilities.fga).toBe(true);
105105
expect(warn).toHaveBeenCalledWith(
106-
'[mastra/auth-ee] Mastra Enterprise features are enabled for local development, but no valid MASTRA_EE_LICENSE is configured. These features will be disabled in production without a valid license. Contact us to get a production license: https://mastra.ai/contact',
106+
'[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',
107107
);
108108
});
109109
});

packages/core/src/auth/ee/capabilities.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ import type { IACLProvider } from './interfaces/acl';
99
import type { IFGAProvider } from './interfaces/fga';
1010
import type { IRBACProvider } from './interfaces/rbac';
1111
import type { EEUser } from './interfaces/user';
12-
import { isLicenseValid, isDevEnvironment, getSafeLicenseSummary, warnIfDevEENeedsLicense } from './license';
12+
import {
13+
isLicenseValid,
14+
isDevEnvironment,
15+
isFeatureEnabled,
16+
getSafeLicenseSummary,
17+
warnIfDevEENeedsLicense,
18+
} from './license';
1319

1420
/**
1521
* Public capabilities response (no authentication required).
@@ -254,6 +260,11 @@ export async function buildCapabilities(
254260
}
255261
const isLicensedOrCloud = hasLicense || isCloud || isSimple || isDev;
256262

263+
// Per-feature license gating: rbac/acl/fga additionally require the license
264+
// entitlement (e.g. enterprise tier). Cloud, SimpleAuth and dev are exempt.
265+
const isFeatureLicensed = (feature: string) =>
266+
isCloud || isSimple || isDev || (hasLicense && isFeatureEnabled(feature));
267+
257268
// Build login configuration (always public)
258269
let login: PublicAuthCapabilities['login'] = null;
259270

@@ -323,18 +334,18 @@ export async function buildCapabilities(
323334

324335
// Get RBAC provider from options (if configured)
325336
const rbacProvider = options?.rbac;
326-
const hasRBAC = !!rbacProvider && isLicensedOrCloud;
337+
const hasRBAC = !!rbacProvider && isFeatureLicensed('rbac');
327338

328339
// Get FGA provider from options (if configured)
329-
const hasFGA = !!options?.fga && isLicensedOrCloud;
340+
const hasFGA = !!options?.fga && isFeatureLicensed('fga');
330341

331342
// Build capability flags
332343
const capabilities: CapabilityFlags = {
333344
user: implementsInterface<IUserProvider>(auth, 'getCurrentUser') && isLicensedOrCloud,
334345
session: implementsInterface<ISessionProvider>(auth, 'createSession') && isLicensedOrCloud,
335346
sso: implementsInterface<ISSOProvider>(auth, 'getLoginUrl') && isLicensedOrCloud,
336347
rbac: hasRBAC,
337-
acl: implementsInterface<IACLProvider>(auth, 'canAccess') && isLicensedOrCloud,
348+
acl: implementsInterface<IACLProvider>(auth, 'canAccess') && isFeatureLicensed('acl'),
338349
fga: hasFGA,
339350
};
340351

packages/core/src/auth/ee/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export * from './capabilities';
1717
// License
1818
export {
1919
validateLicense,
20+
startLicenseValidation,
2021
isLicenseValid,
2122
isEELicenseValid,
2223
isFeatureEnabled,

0 commit comments

Comments
 (0)