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 theapps/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();
}
}