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.
Prerequisites
Prerequisites
Deploy and configure the ReBAC engine first using the Entitlements setup guide. 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.
npm install @frontegg/e10s-clientimport { EntitlementsClientFactory, RequestContextType } from '@frontegg/e10s-client';
const e10sClient = EntitlementsClientFactory.create({
engineEndpoint: 'localhost:50051',
engineToken: 'your-engine-token',
});You can pass optional logging and fallback behavior:
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 describes who is acting (often derived from a Frontegg JWT). Import SubjectContext from @frontegg/e10s-client where your version exports it.
const subjectContext = {
tenantId: 'my-tenant-id',
userId: 'my-user-id',
permissions: ['read', 'write'],
attributes: { 'my-custom-attribute': 'some-value' },
};Use isEntitledTo with RequestContextType for feature, permission, or route checks.
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`);
}const e10sResult = await e10sClient.isEntitledTo(subjectContext, {
type: RequestContextType.Permission,
permissionKey: 'read',
});
if (!e10sResult.result) {
console.log(`User is not entitled to "read" permission`);
}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`);
}For relationships that use the active_at caveat, pass at as an ISO 8601 string:
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 strings (UTC, for example 2025-12-31T23:59:59Z, or with an offset). If omitted, evaluation uses the current UTC time.
Lookup APIs return relationships between entities (with optional at for time-based evaluation).
Find resources (for example documents) a subject may access for a given action:
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}`);
});Find subjects (for example users) allowed to act on a given resource:
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}`);
});When monitoring is enabled, responses include a monitoring flag while the entitlement outcome is still logged:
{
"result": true,
"monitoring": true
}- Run with SDK — full engine-focused walkthrough (same content scope as this page, under Entitlements setup)
- Java Entitlements — JVM client for the same engine
- npm: @frontegg/e10s-client