Skip to content
Last updated

Migration Guide: Legacy Agent to e10s-engine

This guide helps you migrate from the legacy Entitlements Agent to the new e10s-engine.


Why Migrate?

The new ReBac Engine provides:

  • Fine-grained authorization with advanced relationship-based access control, with advanced features, Hierarchical authorization, listing (lookup queries), and time-based access
  • Better performance with optimized queries
  • Scalable architecture with Kubernetes-native deployment

Architecture Comparison

AspectLegacy AgentNew ReBac Engine
SDK Version@frontegg/e10s-client v2.x@frontegg/e10s-client v3.x
Data SyncPolling-based bundlesContinuous sync job
Query EngineOPA queriesSpiceDB queries
ProtocolHTTP/RESTgRPC
Default Port818150051

Major Version Change

The migration from v2 to v3 of @frontegg/e10s-client is a major version change. Review the breaking changes and updated APIs before upgrading.


Migration Steps

Step 1: Review Current Implementation

Identify how you're currently using the legacy agent:

// Legacy OPA-based implementation
import { EntitlementsClient, RequestContextType } from '@frontegg/e10s-client';

const client = new EntitlementsClient({
  pdpHost: 'http://localhost:8181'  // OPA endpoint
});

// Feature check
const result = await client.isEntitledTo(
  { tenantId: 'tenant-123', userId: 'user-456' },
  { type: RequestContextType.Feature, featureKey: 'premium-feature' }
);

Step 2: Deploy New ReBac Engine

Follow the Setup Guide to deploy the new ReBac Engine alongside your existing agent.

Parallel Deployment

Run both systems in parallel during migration to ensure zero downtime. The new engine can be deployed on different ports without affecting the legacy agent.

Step 3: Update SDK Configuration

Update your SDK initialization to use the new SpiceDB endpoint:

// New SpiceDB-based implementation
import { EntitlementsClientFactory, RequestContextType } from '@frontegg/e10s-client';

const client = EntitlementsClientFactory.create({
  engineEndpoint: 'localhost:50051',  // SpiceDB gRPC endpoint
  engineToken: 'your-preshared-key'
});

Step 4: Update Permission Checks

The new ReBac engine uses entity-based subjects instead of user/tenant context for fine-grained checks:

// Before: Legacy feature check
const legacyResult = await legacyClient.isEntitledTo(
  { tenantId: 'tenant-123', userId: 'user-456' },
  { type: RequestContextType.Feature, featureKey: 'premium-feature' }
);

// After: New ReBac entity check
const newResult = await newClient.isEntitledTo(
  { entityType: 'user', key: 'user-456' },
  {
    type: RequestContextType.Entity,
    entityType: 'document',
    key: 'doc-789',
    action: 'read'
  }
);

Backwards Compatibility

The new SDK still supports tenantId and userId context for feature, permission, and route checks. You only need to use entityType and key for fine-grained ReBac queries.

Step 5: Migrate Relation Data

If you have existing authorization relationships, ensure they are configured in Frontegg:

  1. Define Entity Types in the Frontegg Portal or using Frontegg APIs
  2. Configure Relations between entity types
  3. Create Assignments via the Relations API

The sync job will automatically synchronize these to your SpiceDB instance.

Step 6: Validate and Test

Test both systems return consistent results:

async function validateMigration() {
  // Test the same permission on both systems
  const legacyResult = await legacyClient.isEntitledTo(/*...*/);
  const newResult = await newClient.isEntitledTo(/*...*/);
  
  if (legacyResult.result !== newResult.result) {
    console.error('Migration validation failed!');
  }
}

Step 7: Switch Traffic

Once validated, update your application to use the new client:

// Feature flag for gradual rollout
const USE_NEW_REBAC = process.env.USE_NEW_REBAC === 'true';

const client = USE_NEW_REBAC
  ? EntitlementsClientFactory.create({
      spiceDBEndpoint: 'localhost:50051',
      spiceDBToken: 'your-preshared-key'
    })
  : new EntitlementsClient({ pdpHost: 'http://localhost:8181' });

Step 8: Decommission Legacy Agent

After successful migration:

  1. Stop the legacy Entitlements Agent container
  2. Remove legacy environment variables
  3. Update documentation and runbooks
# Stop legacy agent
docker stop frontegg-entitlements-agent
docker rm frontegg-entitlements-agent

Environment Variables Mapping

Legacy VariableNew VariableNotes
FRONTEGG_CLIENT_IDFRONTEGG_CLIENT_IDSame
FRONTEGG_CLIENT_CREDENTIALS_OAUTH_CLIENT_IDFRONTEGG_CLIENT_IDConsolidated
FRONTEGG_CLIENT_CREDENTIALS_OAUTH_SECRETFRONTEGG_CLIENT_SECRETRenamed
FRONTEGG_REGIONFRONTEGG_URLUse full URL
POLLING_MIN_DELAY-Replaced by continuous sync
POLLING_MAX_DELAY-Replaced by continuous sync
-SPICEDB_ADDRESSNew: SpiceDB endpoint
-SPICEDB_GRPC_PRESHARED_KEYNew: Auth token

SDK Method Changes

Legacy MethodNew MethodNotes
isEntitledTo()isEntitledTo()Same interface, new engine
-lookupTargetEntities()New: Find accessible resources
-lookupEntities()New: Find subjects with access

Rollback Plan

If issues occur, you can quickly rollback:

  1. Revert SDK initialization to use legacy client
  2. Restart legacy Entitlements Agent
  3. Update environment variables as needed
// Rollback to legacy
const client = new EntitlementsClient({
  pdpHost: 'http://localhost:8181'
});

Next Steps