## Entitlements quickstart Use Frontegg’s **`@frontegg/e10s-client`** package from Node.js to call your ReBAC (SpiceDB) entitlements engine: evaluate feature and permission checks, route access, fine-grained entity checks, and lookup APIs. br Check out the repo on GitHub br Prerequisites Deploy and configure the ReBAC engine first using the [Entitlements setup guide](/ciam/guides/authorization/entitlements/agent/setup). You need a reachable **gRPC** endpoint (for example SpiceDB on port `50051`) and an **engine token**. Use **Node.js v18+** and `@frontegg/e10s-client` **v3.0.0+**. For conceptual flow and engine operations, see [Run with SDK](/ciam/guides/authorization/entitlements/agent/nodejs). ### Install the client ``` npm install @frontegg/e10s-client ``` ### Initialize the client ```typescript import { EntitlementsClientFactory, RequestContextType } from '@frontegg/e10s-client'; const e10sClient = EntitlementsClientFactory.create({ engineEndpoint: 'localhost:50051', engineToken: 'your-engine-token', }); ``` ### Configuration options You can pass optional logging and fallback behavior: ```typescript import { EntitlementsClientFactory } from '@frontegg/e10s-client'; const e10sClient = EntitlementsClientFactory.create({ engineEndpoint: 'localhost:50051', engineToken: 'your-engine-token', logging: { client: customLoggingClient, logResults: true, }, fallbackConfiguration: { defaultFallback: false, }, }); ``` ### Subject context Subject context describes who is acting (often derived from a Frontegg JWT). Import `SubjectContext` from `@frontegg/e10s-client` where your version exports it. ```typescript const subjectContext = { tenantId: 'my-tenant-id', userId: 'my-user-id', permissions: ['read', 'write'], attributes: { 'my-custom-attribute': 'some-value' }, }; ``` ### Query entitlements Use `isEntitledTo` with `RequestContextType` for **feature**, **permission**, or **route** checks. #### 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`); } ``` #### 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`); } ``` #### 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`); } ``` #### Fine-grained authorization with time-based access For relationships that use the `active_at` caveat, pass `at` as an ISO 8601 string: ```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`); } ``` Note The `at` parameter accepts ISO 8601 strings (UTC, for example `2025-12-31T23:59:59Z`, or with an offset). If omitted, evaluation uses the current UTC time. ### Lookup operations Lookup APIs return relationships between entities (with optional `at` for time-based evaluation). #### Lookup target entities Find resources (for example documents) a subject may access for a given action: ```typescript const response = await e10sClient.lookupTargetEntities({ entityType: 'user', entityId: 'user-123', TargetEntityType: 'document', action: 'read', limit: 100, cursor: undefined, at: '2026-01-15T12:00:00Z', }); console.log(`Found ${response.totalReturned} target entities`); response.targets.forEach((target) => { console.log(`${target.TargetEntityType}:${target.TargetEntityId}`); }); ``` #### Lookup entities Find subjects (for example users) allowed to act on a given resource: ```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}`); }); ``` ### Monitoring mode When monitoring is enabled, responses include a `monitoring` flag while the entitlement outcome is still logged: ```json { "result": true, "monitoring": true } ``` ### Related documentation - [Run with SDK](/ciam/guides/authorization/entitlements/agent/nodejs) — full engine-focused walkthrough (same content scope as this page, under Entitlements setup) - [Java Entitlements](/ciam/sdks/backend/java/entitlements) — JVM client for the same engine - [npm: @frontegg/e10s-client](https://www.npmjs.com/package/@frontegg/e10s-client)