Skip to main content

How To Call a Policy Plan from Code

This page will run through how you can directly contact Cerbos to prospecively grant access to a resource based on a policy plan.

We assume the following:

  • The app is named death-star and sits under the apps/death-star

1. Create a New Policy If Required

See How to Create a Cerbos Policy.

2. Create a Representation of Your Policies in Code

./apps/death-star/src/infrastructure/Cerbos/Resources.ts
import { Resource } from '@tsm/nest/cerbos';

export class DeathStarPlans implements Resource {
public readonly kind = 'death-star-plans';
public actions: ['view', 'create', 'destroy'];
public attributes: {
locationOfDeathStarWeakSpot: string;
};
}

2. Add the Policy Plan to Your Repository Queries

In your application, you can now call the Cerbos API to check if a user can perform an action on a resource. Note the user is set by the ingress guards based on the access token in the request. For worker processes, the principal will be the service account.

./apps/death-star/src/infrastructure/TypeORM/Repository/DeathStarPlanRepository.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { QueryPlanner } from '@tsm/nest/cerbos';
import { Pagination, paginate } from 'nestjs-typeorm-paginate';
import { Repository, type SelectQueryBuilder } from 'typeorm';
import { DeathStarPlan } from '../../../domain/Entity/DeathStarPlan';
import { DeathStarPlan as DeathStarPlanResource } from '../../Cerbos/Resources';

@Injectable()
export class DeathStarPlanRepository {
public constructor(
@InjectRepository(DeathStarPlan) private readonly repository: Repository<DeathStarPlan>,
private readonly cerbos: QueryPlanner,
) {}

private async attachPolicy(queryBuilder: SelectQueryBuilder<DeathStarPlan>) {
return await this.cerbos.attach(queryBuilder, DeathStarPlanResource, {
'request.resource.id': 'id',
'request.resource.attr.locationOfDeathStarWeakSpot': 'locationOfDeathStarWeakSpot',
});
}

public async findOne(planId: string): Promise<DeathStarPlan> {
const queryBuilder = this.repository.createQueryBuilder().andWhere({
id: planId,
});

await this.attachPolicy(queryBuilder);

return await queryBuilder.getOneOrFail();
}
}