Skip to content
Last updated

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.



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.

Install the client

npm install @frontegg/e10s-client

Initialize the client

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:

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.

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

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

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

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:

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:

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:

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:

{
  "result": true,
  "monitoring": true
}