Checking Relations

Now that you've created your definitions and relations, you can check them to determine access control.

Most of our SDKs provide a check function, which is the primary method for checking relations. This function checks if the given relations are satisfied and returns detailed results.

Check if relation exists

The check function checks if the given relations are satisfied. Pass in an array of FGARelation objects and the function returns an array of FGACheck results indicating whether each relation is allowed.

const relations = [
  {
    resource: 'some-doc',
    resourceType: 'doc',
    relation: 'can_view',
    target: 'u1',
    targetType: 'user',
  },
];

const checks = await descopeClient.management.fga.check(relations);
// checks[0].allowed indicates if the relation is satisfied

Check a relation with a condition

If the relation or permission being checked has a condition attached via with, you can supply the values that condition's CEL expression should evaluate against.

const relations = [
  {
    resource: 'doc-123',
    resourceType: 'doc',
    relation: 'viewer',
    target: 'u1',
    targetType: 'user',
  },
];

const context = { role: 'admin' };

const checks = await descopeClient.management.fga.checkWithContext(relations, context);
// checks[0].allowed indicates if the relation is satisfied given this context

Even if a parameter is missing, the condition can still evaluate to true as long as short-circuit evaluation prevents that parameter from being evaluated. For example, in an inclusive OR (||) expression, if any operand evaluates to true, the remaining operands don't need to be evaluated, including ones with missing values. In that case, a missing parameter has no effect on the result.

Check who can access a particular resource

The whoCanAccess function takes in a resource, a relation definition, and a namespace corresponding to the relation definition and returns an array of users with the given relation definitions to the resource.

const resource: string = "The resource of a relation";
const relationDefinition: string = "The relation definition name";
const namespace: string = "The relation definition namespace";

const users: string[] = await descopeClient.management.authz.whoCanAccess(resource, relationDefinition, namespace);

Check what relations a resource has

The resourceRelations function returns an array of relations for a given resource.

const resource: string = "The resource for the relations";

const relations: AuthzRelation[] = descopeClient.management.authz.resourceRelations(resource);

Check what relations a resource has (with target set filter)

const resource: string = "The resource for the relations";

// Get relations including target set relations (default)
const relations: AuthzRelation[] = await descopeClient.management.authz.resourceRelations(resource);

// Get relations excluding target set relations
const relationsWithoutTargetSets: AuthzRelation[] = await descopeClient.management.authz.resourceRelations(resource, true);

Check what relations a target has directly

The targetsRelations function takes an array of targets (eg. users) and returns an array of relations that exist for the target directly.

This will NOT return relations that exist for the target implicitly, such as through a parent node with a matching relation definition.

const targets: string[] = ["The targets to check relations for directly."];

const relations: AuthzRelation[] = descopeClient.management.authz.targetsRelations(targets);

Check what relations a target has directly (with target set filter)

const targets: string[] = ["The targets to check relations for directly."];

// Get relations excluding target set relations (default)
const relations: AuthzRelation[] = await descopeClient.management.authz.targetsRelations(targets);

// Get relations including target set relations
const relationsWithTargetSets: AuthzRelation[] = await descopeClient.management.authz.targetsRelations(targets, true);

Check what relations a target has directly and implicitly (recursive)

The whatCanTargetAccess function is similar to the targetsRelations function in that it takes a single target and returns an array of relations that exist for it, but instead of simply including direct relations, it returns implicit ones as well, traversing the tree of relations recursively.

const target: string = "The target to check relations for directly and implicitly.";


const relations: AuthzRelation[] = descopeClient.management.authz.whatCanTargetAccess(target);

Check what resources a target can access through a particular relation definition

The whatCanTargetAccessWithRelation function is similar to whatCanTargetAccess, but instead of returning all relations for a given target, it specifically finds resources that the target can access through relation paths ending in a given relation definition.

const target: string = "The target to check relations for directly and implicitly.";


const resources: AuthzResource[] = await descopeClient.management.authz.whatCanTargetAccessWithRelation(
  target,
  relationDefinition,
  namespace,
);

Get Modified Resources and Targets

The getModified function returns a list of targets and resources that have changed since a given date. This is useful for invalidating local caches and keeping your application's authorization data in sync.

Note

getModified returns changes for up to 1,000 modified targets and resources. If more changes exist since the given date, the call fails with an error instead of returning a partial or paginated result. Treat that error as a signal to do a full resync rather than retrying with the same since value.

// Get all changes since a specific date
const since = new Date('2024-01-01T00:00:00Z');


const modified = await descopeClient.management.authz.getModified(since);
// Returns: { resources: string[], targets: string[], schemaChanged: boolean }
Was this helpful?

On this page