Using Clerk with Cerbos

Published by Alex Olivier on March 17, 2022
Using Clerk with Cerbos

Far too often, poor user management stands between users and products. From forgotten passwords and failed account de-duplication, to broken and out-of-sync vendor integrations — there's a lot that can go wrong. Clerk solves user management so developers can stop reinventing the wheel and focus on their core business - the same mission Cerbos has for authorization.

As identity is such a key part to authorization, today we released a starter project that connects Clerk and Cerbos in a Next.js application. It demonstrates how an identity object, passed from Clerk, can be mapped into the principal information in the call to Cerbos. By doing this, all the profile information can be used, regardless of the source, to define policies and conditions.

The benefit of integrating an authentication and identity provider with Cerbos is that the rich context about the user can be used in policy conditions. It enables role-based access controls (RBAC) as well as more advanced attribute-based access controls (ABAC) without the need to have complicated logic written directly in your code.

Cerbos integrates with many authentication providers. Our Clerk integration works with the same principle that all of our other Authentication integrations (Okta, Auth0, WorkOS etc). It relies on getting the identity object and combining it with the resource that user is trying to access and ask the question whether that user is allowed to do that action on the said principal. For example, “can a user who is a manager in the northeast region approve an expense report that belongs to an employee from the south region in the amount of $5000?” or perhaps $10,000, and $50,000 for different groups of users: the point being without having to create a whole new user group for each threshold.

Clerk with Cerbos

Following is an example of what this may look like in your application code. It simply grabs the profile from Clerk and passes it over to Cerbos in the principal object. You can see a full example on GitHub which showcases how to use it in a Next.js project..

import { requireSession, users } from "@clerk/nextjs/api";
import { GRPC as Cerbos } from "@cerbo/grpc";
const cerbos = new Cerbos("PDP_HOSTNAME"); //The Cerbos PDP Instance

export default requireSession(async (req, res) => {
 // get the profile from Clerk.dev
 const user = await users.getUser(req.session.userId);

 const roles = user.publicMetadata.role
   ? [user.publicMetadata.role]
   : ["user"];

 // check access
 const authorized = await cerbos.checkResource({
   principal: {
     id: req.session.userId,
     roles, //roles from Clerk profile
     attributes: {
       email: user.email,
     },
   },
   resource: ...,
   actions: [...]
 })

 // ...handle the response
});

You can find out more about Clerk on their site, our integration, as well as our other integrations such as Auth0, Okta and WorkOS and more on the Ecosystem page.

DOCUMENTATION
GUIDE
INTEGRATION

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