Drizzle adapter :: Cerbos Authorization Management Platform // Documentation

Drizzle adapter

This documentation is for
an as-yet unreleased
version of Cerbos PDP. Choose 0.53.0 from the version picker at the top right or navigate to https://docs.cerbos.dev for the latest version.

The @cerbos/orm-drizzle package converts a Cerbos PlanResources response into a Drizzle ORM SQL expression. The resulting filter can be composed with your existing query builder chain.

Requirements

Installation

npm install @cerbos/orm-drizzle

Supported operators

Usage

import { queryPlanToDrizzle, PlanKind } from "@cerbos/orm-drizzle";
import { eq, and } from "drizzle-orm";
import { resources } from "./schema";

const plan = await cerbos.planResources({
  principal,
  resource: { kind: "document" },
  action: "view",
});

const result = queryPlanToDrizzle({
  queryPlan: plan,
  mapper: {
    "request.resource.attr.status": resources.status,
    "request.resource.attr.owner": resources.ownerId,
  },
});

switch (result.kind) {
  case PlanKind.ALWAYS_DENIED:
    return [];
  case PlanKind.ALWAYS_ALLOWED:
    return await db.select().from(resources);
  case PlanKind.CONDITIONAL:
    return await db
      .select()
      .from(resources)
      .where(result.filter);
}

Field mapper

The mapper associates Cerbos attribute references with Drizzle columns. It accepts:

const result = queryPlanToDrizzle({
  queryPlan,
  mapper: {
    "request.resource.attr.custom": {
      column: sql`lower(${resources.title})`,
      transform: ({ operator, value }) => {
        if (operator !== "eq") throw new Error("Unsupported");
        return eq(sql`lower(${resources.title})`, value.toLowerCase());
      },
    },
  },
});

Relation mapping

The adapter wraps relation comparisons in EXISTS subqueries, automatically inferring relation fields when they match column names on the related table.

const result = queryPlanToDrizzle({
  queryPlan,
  mapper: {
    "request.resource.attr.owner": {
      relation: {
        type: "one",
        table: owners,
        sourceColumn: resources.ownerId,
        targetColumn: owners.id,
        fields: {
          email: owners.email,
        },
      },
    },
    "request.resource.attr.tags": {
      relation: {
        type: "many",
        table: resourceTags,
        sourceColumn: resources.id,
        targetColumn: resourceTags.resourceId,
        fields: {
          name: {
            relation: {
              type: "one",
              table: tags,
              sourceColumn: resourceTags.tagId,
              targetColumn: tags.id,
              field: tags.name,
            },
          },
        },
      },
    },
  },
});

Collection operators

Source code

cerbos/query-plan-adapters/drizzle