@frontegg/e10s-client
v3.0.1
Published
<br />
Downloads
35,819
Readme
Table of Contents
Installation
To install the package using npm, run the following
$ npm install @frontegg/e10s-clientPrerequisite
The Entitlements Client interacts with Frontegg’s ReBAC authorization engine to evaluate permissions and query access relationships.
Look for instructions here
Usage
Initialize 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 which 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 a route entitlement, each requires different context information.
Query for Feature
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`);
}Query for Permission
const e10sResult = await e10sClient.isEntitledTo(subjectContext, {
type: RequestContextType.Permission,
permissionKey: 'read'
});
if (!e10sResult.result) {
console.log(`User is not entitled to "read" permission`);
}Query for Route
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`);
}Query for FGA (Fine-Grained Authorization)
const e10sResult = await e10sClient.isEntitledTo(
{
entityType: 'user',
key: '[email protected]'
},
{
type: RequestContextType.Entity,
entityType: 'document',
key: 'README.md',
action: 'read'
}
);
if (!e10sResult.result) {
console.log(`User is not allowed to read document`);
}Query for FGA with Time-Based Access (active_at caveat)
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: '[email protected]'
},
{
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`);
}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.
Note: The
atparameter is also supported in Lookup Operations with the same format and behavior.
Examples
Runnable demos live in examples/. They use a separate package.json and are not installed when you run yarn at the repo root.
cd examples
yarn install # pulls @frontegg/e10s-client@latest from npmSee examples/Readme.md for Docker/SpiceDB setup and demo scripts.
Lookup Operations
The client provides lookup operations that query the ReBAC authorization model to discover access relationships between entities.
FGA lookup operations support the optional at parameter for time-based access control (see Time-Based Access).
Lookup Entitlements
Find all entitlement feature keys granted to a tenant or user.
This lookup returns effective feature entitlements for the requested subject:
- When only
tenantIdis provided, the response contains feature grants available to that tenant. - When both
tenantIdanduserIdare provided, the response contains the user's effective feature grants: tenant-inherited grants plus user-direct grants. - If
userIdis provided but the user is not a member of the tenant, the response is empty. - If the same feature key is granted through both the tenant and the user, it is returned once in the page response.
Use a tenant-only subject when you need tenant-level entitlements. Use a subject with userId when you need the feature set that should apply to a specific user.
Pagination note: For user lookups, tenant and user grants are looked up and paginated independently. A feature key that is reachable through both streams may appear on different pages, so callers that aggregate multiple pages should deduplicate feature keys across pages if needed.
const response = await e10sClient.lookupEntitlements({
subject: {
tenantId: 'tenant-123',
userId: 'user-456', // Optional: include for effective user entitlements
attributes: { plan: 'pro' } // Optional: evaluated by targeting rules
},
criteria: {
type: RequestContextType.Feature
},
limit: 100, // Optional: default 50
cursor: undefined // Optional: pagination cursor
});
console.log(`Found ${response.totalReturned} entitlement features`);
response.entitlements.forEach((entitlement) => {
console.log(`${entitlement.type}:${entitlement.key}`);
// entitlement.permissionship: 'HAS_PERMISSION' | 'CONDITIONAL_PERMISSION' | 'NO_PERMISSION'
});
if (response.cursor) {
const nextPage = await e10sClient.lookupEntitlements({
// ... same params
cursor: response.cursor
});
}Lookup Target Entities
Find all TargetEntity instances (i.e. documents) of a given type that an 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 real results will only be logged, and the following payload will always return
{
"result": true,
"monitoring": true
}