Nested fields support with Prisma Query Plans

Published by Alex Olivier on July 17, 2023
Nested fields support with Prisma Query Plans

Cerbos Query Plans address a significant challenge in separating authorization logic from application code. They offer a dynamic solution by generating a set of conditions from policies. These conditions are then used to filter data retrieval, ensuring that only the instances of a resource that a user has permission to access are returned.

To enhance the usability of Query Plans, several adapters have been developed. These adapters take a plan as input and produce filters in formats compatible with popular Object-Relational Mapping (ORM) systems. For example, in the case of Prisma, the adapters support increasingly complex filters over time, including the recent addition of support for related fields.

If you take a simple Prisma schema like below, you have a parent model which includes a related (nested) model and internally the database joins these two based on the ID field:

model Resource {
  id               String         @id @default(cuid())
  nested           NestedResource @relation(fields: [nestedResourceId], references: [id])
  nestedResourceId String
}

model NestedResource {
  id       String     @id @default(cuid())
  aBool    Boolean
  Resource Resource[]
}

When there is a related model it is a common scenario where you want to query the parent model, based on the value in a child relation field:

const results = await prisma.resource.find({
  where: {
   "nested": {
     "aBool": {
         "equal": true
     }
   }
})

With the latest release of the Prisma Query Plan Adapter any nested attributes in policy will be converted into nested filter conditions also - for example providing a field mapper such a below:

const result = queryPlanToPrisma({
   queryPlan,
   fieldNameMapper: {
     "request.resource.attr.nested.aBool": "nested.aBool",
   },
});

and the Cerbos policy contains a condition such as:

condition:
  match:
    expr: request.resource.attr.nested.aBool == true

the adapter will produce a Prisma filter snippet which will now query the nested relational field which can then be passed to Prisma and work as expected.

{
   "nested": {
     "aBool": {
         "equal": true
     }
}

You can find out more about Query Plans in the documentation and our suite of adapters is available on GitHub.

DOCUMENTATION
INTEGRATION

Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team