## 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](/ciam/guides/authorization/entitlements/agent/setup) is a prerequisite for completing the SDK installation. To get started, select your technology from the following link: [SDKs Overview](/ciam/sdks/overview), and navigate to the **Entitlements** section. br ### Installation with Node.js To install the package using npm, run the following command: ```node $ npm install @frontegg/e10s-client ``` ### Initializing the client br ```typescript import { EntitlementsClientFactory, RequestContextType } from '@frontegg/e10s-client'; const e10sClient = EntitlementsClientFactory.create({ engineEndpoint: 'localhost:50051', engineToken: 'your-engine-token' }); ``` ### Configuration options br ```typescript 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. ```typescript 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 ```typescript 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 ```typescript 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 ```typescript 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. ```typescript 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`); } ``` br 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. ```typescript 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) ```typescript 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'): ```json { "result": true, "monitoring": true } ```