How to use Cerbos effectively

Published by Charith Ellawala on April 04, 2023
How to use Cerbos effectively

So you have done your research and you’re convinced that decoupling authorization logic from your applications and services is a good idea. You have looked through the Cerbos documentation and it seems simple and intuitive. But, you are a veteran of many technology-integration battles and have the scars to prove it. You're feeling a little bit sceptical: "Is Cerbos really as painless as they claim?", you find yourself asking. Well, fear not. Cerbos is a product developed by developers who have had to deal with similar painful problems themselves. We are committed to making Cerbos a delightful piece of software to use, and, in this article, we aim to showcase all the (free!) developer productivity tools and features that we have built to achieve that goal.

Try Cerbos without downloading anything

Ultimately, Cerbos is a self-hosted service that you'd deploy on your own private infrastructure. However, you can get a taste of Cerbos and how it works without downloading or installing anything. Simply head over to the online playground and you can try your hand at writing a Cerbos policy using an interactive web IDE with syntax highlighting, code suggestions, automatic test runs and much more. You can even share your work with others by sending the unique URL to them. For example, https://play.cerbos.dev/p/IJxlK6131f642ND65F1EhPmiT18Ap1A5 is an instance that we created to demonstrate how to model multi-tenant SaaS permissions.

image

If you are someone who likes to get closer to the metal to see how things really work, the Playground integrates with a public, demo instance of Cerbos hosted on the cloud. You can try out the actual Cerbos API using cURL or any programming language of your choice by following the instructions provided when you click on Try the API button from your playground instance. Please bear in mind that this is purely a demo instance on the cloud with no availability or latency guarantees. When the time comes, your actual production Cerbos deployment will be on your internal network using your own infrastructure where you have full control over everything.

Get more hands-on

Now that the Playground has whetted your appetite, let's go deeper. You probably don't want to develop your real policies out in public using the Playground. Also, one of the defining features of Cerbos is its statelessness – which means that with every request, you need to provide all the data it needs to make a decision. You certainly don't want to send your precious data over the internet to some server running somewhere that you have no control over.

At the time of writing, you can't run the Cerbos Playground yourself. But, that doesn't mean that you have to miss out on all those sweet IDE-like features. In fact, the good news is that you can use your own favourite IDE as long as it has support for the Language Server Protocol (LSP). The Cerbos documentation site has instructions for configuring LSP on popular editors. Even if you're using an editor that doesn't have LSP support, chances are that it will still have pretty good support for editing YAML/JSON files – which is what Cerbos policies ultimately are.

OK, that's editing sorted out. How do you run Cerbos? There are many options to choose from, including Homebrew bottles, DEB or RPM packages, tarballs, Docker containers, Helm charts and even a GitHub Action. The Docker container is the easiest way to get started because it's just a single command:

docker run --rm --name cerbos -p 3592:3592 -v $(pwd):/policies ghcr.io/cerbos/cerbos:latest

If you had any policy files in the current working directory, Cerbos would have loaded them already and they're ready for use right away. You can drop any new files in or edit existing ones in the current directory and Cerbos will automatically update itself. Remember what we said earlier about Cerbos being painless?

Although the Cerbos container is all you need to get everything done, it's handy to have the cerbos and cerbosctlbinaries installed on your developer machines. Use brew, apt, dnf or simply extract the tarballs to your $PATH to install them.

Import existing policies from the Playground

If you have been tinkering with some policies on the Cerbos Playground and want to use them as the base for developing more policies on your own machine, you can simply hit the Export button to download a zip archive containing them.

If you're using the disk storage driver with Cerbos, simply extract the files to the configured policy directory. With the Cerbos container, it's only a matter of mounting the directory under /policies inside the container (-v /path/to/extracted/policies:/policies). With the other Cerbos installation methods, you either need to edit the configuration file or add--set=storage.disk.directory=/path/to/extracted/policies to the set of command line arguments passed to Cerbos.

If you're using one of the mutable storage drivers such as mysql, postgres, sqlite3 or sqlserver and have the Admin API enabled, you don't even have to extract the zip file. The `cerbosctl put` utility is capable of loading policies and schemas into Cerbos directly from a zip archive.

Manage Cerbos with cerbosctl

The [cerbosctl](https://docs.cerbos.dev/cerbos/latest/cli/cerbosctl.html) utility ships with several handy utilities for interacting with Cerbos instances that have the Admin API enabled. You can view the policies and schemas available in the store, add or update policies and schemas (if the store is mutable), and reload the store.

If you have enabled local audit logs on the Cerbos instance, [cerbosctl audit](https://docs.cerbos.dev/cerbos/latest/cli/cerbosctl.html#audit) lets you filter and view the audit log entries on your terminal. The output can be exported as JSON for further processing with other analytics tools of your choice. There’s even a text user interface (TUI) for browsing the audit entries using the keyboard.

Write code to interact with Cerbos

Things are going well so far. You've written some simple policies, and you’ve written some integration code using one of the many SDKs to call the Cerbos API to make authorization decisions. Now you want to share that code with your colleagues for experimentation or try to get your CI system to test it. You want to make it easy but it's way too early to bust out the heavyweights like Docker Compose or Podman. Then, how do you get the Cerbos "sidecar" process to run alongside your app? We have got you covered there too with `cerbos run`. To illustrate, let's say you have been writing a Python script named awesome_cerbos_poc.py to try out Cerbos. You have your Cerbos policies stored in a subdirectory named policies alongside your script. Now all you need to do is to run the following command:

cerbos run -- python awesome_cerbos_poc.py

The above command will start a Cerbos instance and then launch a Python interpreter to run the awesome_cerbos_poc.py script. The script can access Cerbos using the values of CERBOS_HTTP or CERBOS_GRPC variables that are automatically injected into the process environment. When the script exits, the Cerbos instance shuts down as well. Easy!

Writing advanced policy expressions

You can use the Common Expression Language (CEL) to write conditional rules in Cerbos policies. This is one of the most powerful features of Cerbos because it allows the business logic associated with authorization to be externalized from your application code. When business requirements inevitably change, in most cases you can get away with just modifying the Cerbos policy instead of changing and deploying your application. In a monolithic application, this might not be too difficult (although, you still have to develop, test and rollout to production -- which can be quite intensive depending on the nature of the system). However, if you have multiple services or systems (usually developed in different languages or by different teams) that need to follow these business logic changes, then the benefit of Cerbos is quite obvious. With a single, non-intrusive Cerbos policy rollout (essentially a Git push), all of those systems will be automatically in compliance without any manual intervention.

CEL is a very simple language and its syntax would be familiar to anyone who has worked with C-family languages such as Java, Javascript, Go, Rust and so on. Cerbos supports all the built-in CEL functions with some extra functions built by us to support common authorization use cases. Even though most of these functions are easy to understand and use by just reading the documentation, sometimes the best way to figure out how something works is to just try it out. This is even more important when developing a pipeline of function calls that feed their results to other functions. You can do that with the Cerbos REPL. You can start it by running the cerbos repl command (or, docker run -it ghcr.io/cerbos/cerbos:latest repl).

You can evaluate CEL expressions on the REPL. For example, if you type in 1 + 1, it will output 2. The result of the last successfully evaluated expression is stored in the special ___ variable. So, if you type in_ + 2 now, the result would be 4. You can even define your own variables and assign values to them to be used later.

The REPL is more than a glorified calculator though. You may recall that Cerbos policy conditions work on the request object which contains all the contextual data required for evaluating the rules. You can define what request is by providing the JSON representation of it. If you are only interested in a particular part of the request such as request.resource, R, request.principal, P, V and other special variables, that can be done as well to save you some typing.

image

One of the really cool features of the REPL is that you can load a policy file and have all its rules available at your fingertips to experiment with. This is quite handy when you're trying to debug a policy because you can quickly change the inputs and see what the rule outputs.

image

Debugging with tests

Cerbos comes with its own testing framework for writing policy tests. They can serve as canaries to detect any policy changes that accidentally (or intentionally) break the invariants you have defined for your authorization system. The Cerbos test runner is part of the core distribution and you can integrate it into any CI workflow that supports running containers or binaries. For GitHub users, we even provide a GitHub Action that they can simply drop into their workflow definition.

Even though tests are not mandatory, we highly recommend writing them so that you have peace of mind when working with your access control policies. If you have a CI/CD pipeline, you can even automate your policy rollouts when the tests are green. There's really no downside to writing tests and the initial investment in effort will pay-off very quickly.

One of the lesser known features of the Cerbos test runner is that you can use it as a handy debugging tool that gives you an insight into how the Cerbos decision engine arrived at a particular decision. If you append the --verbose flag to the test invoker, it will print out an execution trace of the decision tree for every failed test.

image

Cerbos: not just a pretty face decoupled authorization layer

That was a whirlwind tour of all the developer productivity tools that you have access to with the free and open source distribution of Cerbos. If you had any concerns about how much “hidden” work there would be while trying to adopt Cerbos into your stack, we hope that this article helped dispel that worry. Go forth and authorize!

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