You can install the Entitlements SDK via Node.js. The Entitlements Client interacts with Frontegg’s ReBAC authorization engine to evaluate permissions and query access relationships.
Prerequisites
Prerequisites
Configuring the entitlements engine at Entitlement Setup guide is a prerequisite for completing the SDK installation.
To get started, select your technology from the following link: SDKs Overview, and navigate to the Entitlements section.
To install the package using npm, run the following command:
$ npm install @frontegg/e10s-client
import { EntitlementsClientFactory, RequestContextType } from '@frontegg/e10s-client';
const e10sClient = EntitlementsClientFactory.create({
engineEndpoint: 'localhost:50051',
engineToken: 'your-engine-token'
});
import { EntitlementsClientFactory } from '@frontegg/e10s-client';
const e10sClient = EntitlementsClientFactory.create({
engineEndpoint: 'localhost:50051',
engineToken: 'your-engine-token',
logging: {
client: customLoggingClient, // Optional: custom logging client
logResults: true // Optional: log all query results
},
fallbackConfiguration: {
// Optional: fallback behavior on errors
defaultFallback: false
}
});Subject context describes the user who performs the action; these can be taken from Frontegg JWT if authenticating with Frontegg.
const subjectContext: SubjectContext = {
tenantId: 'my-tenant-id',
userId: 'my-user-id', // Optional
permissions: ['read', 'write'], // Optional
attributes: { 'my-custom-attribute': 'some-value' } // Optional
};
The Entitlements client allows you to query for a feature, permission, or route entitlement, each requiring different context information.
const e10sResult = await e10sClient.isEntitledTo(
subjectContext,
{
type: RequestContextType.Feature,
featureKey: 'my-cool-feature'
}
);
if (!e10sResult.result) {
console.log(`User is not entitled to "my-cool-feature" feature, reason: ${e10sResult.justification}`);
}const e10sResult = await e10sClient.isEntitledTo(
subjectContext,
{
type: RequestContextType.Permission,
permissionKey: 'read'
}
);
if (!e10sResult.result) {
console.log(`User is not entitled to "read" permission, reason: ${e10sResult.justification}`);
}const e10sResult = await e10sClient.isEntitledTo(
subjectContext,
{
type: RequestContextType.Route,
method: "GET",
path: "/users"
}
);
if (!e10sResult.result) {
console.log(`User is not entitled to "GET /users" route, reason: ${e10sResult.justification}`);
}For relationships that use the active_at caveat to control time-based access, you can specify the at parameter to evaluate access at a specific point in time.
const e10sResult = await e10sClient.isEntitledTo(
{
entityType: 'user',
key: 'some@user.com'
},
{
type: RequestContextType.Entity,
entityType: 'document',
key: 'README.md',
action: 'read',
at: '2026-01-15T12:00:00Z'
}
);
if (!e10sResult.result) {
console.log(`User is not allowed to read document at the specified time`);
}Note
Note
The at parameter accepts ISO 8601 format strings:
- UTC format: 2025-12-31T23:59:59Z
- Timezone offset: 2025-12-31T23:59:59+02:00 (If
atnot provided, it defaults to the current UTC time).
The client provides lookup operations that query the ReBAC authorization model to discover access relationships between entities. All lookup operations support the optional at parameter for time-based access control.
Find all TargetEntity instances (i.e. documents) of a given type that a entity (i.e user) is entitled to perform a specific action on.
const response = await e10sClient.lookupTargetEntities({
entityType: 'user',
entityId: 'user-123',
TargetEntityType: 'document',
action: 'read',
limit: 100, // Optional: limit number of results (default: 50, max: 1000)
cursor: undefined, // Optional: pagination cursor
at: '2026-01-15T12:00:00Z' // Optional: ISO 8601 timestamp for active_at caveat
});
console.log(`Found ${response.totalReturned} Target Entities`);
response.targets.forEach((target) => {
console.log(`${target.TargetEntityType}:${target.TargetEntityId}`);
// target.permissionship: 'HAS_PERMISSION' | 'CONDITIONAL_PERMISSION' | 'NO_PERMISSION'
});
// For pagination, use the returned cursor
if (response.cursor) {
const nextPage = await e10sClient.lookupTargetEntities({
// ... same params
cursor: response.cursor
});
}Find all entities (i.e. users) of a given type that are entitled to perform a specific action on a given entity instance (i.e. documents)
const response = await e10sClient.lookupEntities({
TargetEntityType: 'document',
TargetEntityId: 'doc-456',
entityType: 'user',
action: 'read',
at: '2026-01-15T12:00:00Z'
});
console.log(`Found ${response.totalReturned} entities`);
response.entities.forEach((entity) => {
console.log(`${entity.entityType}:${entity.entityId}`);
// entity.permissionship: 'HAS_PERMISSION' | 'CONDITIONAL_PERMISSION' | 'NO_PERMISSION'
});In case monitoring mode is enabled, the result object will always return as follows (and in which the Entitlement check result will be 'logged'):
{
"result": true,
"monitoring": true
}