Cerbos has continuously evolved to provide you with cool features. Variables were first introduced experimentally in v0.8, offering a way to reduce duplication in policy conditions. Building on this foundation, they were further refined and stabilized in v0.9, making them even more valuable for crafting robust access control rules.
However, there was one limitation - variables were restricted to each individual policy, making it impossible to reuse them across multiple policies. When there was a need to use the same variable across the configuration, this led to repetition and sub-optimal policy maintainability. But with the latest release of Cerbos v0.29, this limitation has been overcome with the introduction of
exportVariables - an enabler to share variables across the configuration. This enhancement empowers policy authors to define variables in a dedicated file and effortlessly import them into multiple policies. Not only does this reduce duplication within policies, but it also streamlines policy management across the entire access control system.
In this piece, we'll explore how to leverage Cerbos' new
exportVariables feature and compare it with the old approach of using local variables within policies.
The first thing you need to do is update your version of Cerbos accordingly. The feature we’re covering is available since v0.29 so that is the lowest you should aim for in order to be able to use
exportVariables. See installation instructions for more information.
In earlier versions of Cerbos, only local variables existed, and were accessible from the policy they are defined in. Note that variables were defined in a top-level
variables field in the policy file.
Let’s say you had resource policy file named
leave_request_policies.yaml, structured like this:
--- apiVersion: api.cerbos.dev/v1 variables: pending_approval: ("PENDING_APPROVAL") principal_location: (P.attr.ip_address.inIPAddrRange("10.20.0.0/16") ? "GB" : "") resourcePolicy: # ...
Whenever you wanted to use any of these variables, there was no option other than to redefine them in every file you’d be using them in. Which, we admit, was not the smoothest way to go around it.
From Cerbos v0.29 onwards, variables can now be defined in a separate file known as the
exportVariables policy and effortlessly imported into other policies. Let's see how this is done. You’ll need define a file named for example
common_variables.yaml in which you will define variables you want to be able to import across your configuration:
--- apiVersion: api.cerbos.dev/v1 description: Common variables used within our app exportVariables: name: our_common_variables definitions: pending_approval: ("PENDING_APPROVAL") principal_location: (P.attr.ip_address.inIPAddrRange("10.20.0.0/16") ? "GB" : "")
In the snippet above you see how the
exportVariable keyword is being used, and nested below it are
definitions, which respectively represent the name to use when importing this set of variables, and the map of variable name to expression.
With this approach, our
leave_request_policies.yaml (and any other policy file) can simply import the
our_common_variables anywhere you need them, like this:
--- apiVersion: api.cerbos.dev/v1 resourcePolicy: variables: import: - our_common_variables # ...
And that’s it! Usage of the variables within policy conditions stays unchanged.
--- apiVersion: api.cerbos.dev/v1 variables: import: - our_common_variables resourcePolicy: version: "default" scope: "our.app.uk" resource: leave_request rules: - actions: ["delete"] condition: match: expr: request.resource.attr.geography == variables.principal_location effect: EFFECT_ALLOW
There still might be a lot of cases where you’d prefer to keep (some of) your variables local to the policy.
From Cerbos v0.29 onwards, the previously-used top-level
variables approach is deprecated and replaced with a
variables.local section within the policy definition.
--- apiVersion: api.cerbos.dev/v1 resourcePolicy: variables: local: pending_approval: ("PENDING_APPROVAL") principal_location: (P.attr.ip_address.inIPAddrRange("10.20.0.0/16") ? "GB" : "") # ...
You can define local variables as well as importing variables in the same policy, but you can’t define the same variable in multiple places.
In order to ensure backwards compatibility, the deprecated top-level field is merged with the
variables.local section in derived roles, resource, and principal policies.
With the introduction of
exportVariables in Cerbos v0.29, managing access control policies becomes more straightforward and flexible. By transitioning from the old approach of using local variables to the new method of importing exported variables, policy authors can streamline their policies, reduce duplication, and further improve overall readability. If you still have a case for using local variables, don’t forget to update to a
variables.local approach as shown above.
Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team