Skip to content
Last updated

Running the service

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

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.


Installation with Node.js

To install the package using npm, run the following command:


$ npm install @frontegg/e10s-client

Initializing the client


import { EntitlementsClientFactory, RequestContextType } from '@frontegg/e10s-client';

const e10sClient = EntitlementsClientFactory.create({
	engineEndpoint: 'localhost:50051',
	engineToken: 'your-engine-token' 
});

Configuration options


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
	}
});

Setting up the subject context

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
};

Query

The Entitlements client allows you to query for a feature, permission, or route entitlement, each requiring different context information.

Querying for feature entitlement

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}`);
}

Query for permission entitlement

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}`);
}

Querying for a route entitlement

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}`);
}

Querying for FGA (Fine-Grained Authorization) with time-based access

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

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 at not provided, it defaults to the current UTC time).

Lookup operations

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.

Lookup target entites

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
	});
}

Lookup entities

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'
});

Monitoring

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
}