Policy authoring

Policy structure

  • The policy header is common for all policy types:

    • apiVersion: Required. Must be api.cerbos.dev/v1.

    • description: Optional. Description of the policy.

    • disabled: Optional. Set to true to make the Cerbos engine ignore this policy file.

    • metadata.sourceFile: Optional. Set to the source of the policy data for auditing purposes.

    • metadata.annotations: Optional. Key-value pairs of strings holding free-form data for auditing purposes.

  • Resource names, actions, and principal names can be hierarchical. Use : as the delimiter. For example: app:component:resource.

  • Wildcard matches are allowed on certain fields. Wildcards respect the hierarchy delimiter :.

  • Scoped policies (optional) are handy for use cases like multi-tenancy where you may want to override particular rules for some tenants.

  • See Conditions to learn how to write conditions in policy rules.

  • See Schemas to learn how you can define schemas for validating requests.

  • See Best practices to check out a growing collection of snippets detailing the optimal way to write policies.

Editing policies

The quickest and the easiest way to get familiar with Cerbos policies is to use the online playground. It provides an IDE-like experience with an interactive editor, examples, code snippets, test cases and other useful utilities to help you design policies.

Editor configurations

Editors with support for the Language Server Protocol (LSP) can make use of the YAML language server implementation when working with Cerbos policies. Simply add the following line at the beginning of your policy file to get context-sensitive code suggestions and validation messages from the editor.

# yaml-language-server: $schema=https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json

The same method can be used for tests:

# yaml-language-server: $schema=https://api.cerbos.dev/latest/cerbos/policy/v1/TestSuite.schema.json

Resource fixtures for tests:

# yaml-language-server: $schema=https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Resources.schema.json

Principal fixtures for tests:

# yaml-language-server: $schema=https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Principals.schema.json
# yaml-language-server: $schema=https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/AuxData.schema.json

YAML language server also supports per-directory settings. If all your Cerbos policies are contained in a specific directory, you can configure the editor to always use the correct schema for the YAML files in that directory. Refer to the YAML language server documentation for more information.

Example: Apply the schema to all files in the /cerbos directory
yaml.schemas: {
    "https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json": "/cerbos/*",
    "https://api.cerbos.dev/latest/cerbos/policy/v1/TestSuite.schema.json": "/cerbos/**/*_test.yaml",
    "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Resources.schema.json": "/cerbos/**/testdata/resources.yaml",
    "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Principals.schema.json": "/cerbos/**/testdata/principals.yaml",
    "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/AuxData.schema.json": "/cerbos/**/testdata/auxdata.yaml"
}

JSON files can specify the schema using the $schema top-level property.

"$schema": "https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json",

Neovim

Refer to your plugin manager documentation to figure out how to install nvim-lspconfig and configure the yaml-language-server. Plugins such as mason-lspconfig can automatically download and install language servers as well.

The following is an example of using lazy.nvim and mason.nvim to install and configure yaml-language-server. It follows the recommended way of configuring lazy plugins.

~/.config/nvim/lua/plugins/lspconfig.lua
return {
    {
        "neovim/nvim-lspconfig",
        dependencies = {
            {
                "williamboman/mason.nvim",
            },
            {
                "williamboman/mason-lspconfig.nvim",
                opts = {
                    ensure_installed = { "yamlls" },
                },
            },
        },
        opts = {
            servers = {
                yamlls = {
                    settings = {
                        yaml = {
                            schemas = {
                                "https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json": "/cerbos/*",
                                "https://api.cerbos.dev/latest/cerbos/policy/v1/TestSuite.schema.json": "/cerbos/**/*_test.yaml",
                                "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Resources.schema.json": "/cerbos/**/testdata/resources.yaml",
                                "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Principals.schema.json": "/cerbos/**/testdata/principals.yaml",
                                "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/AuxData.schema.json": "/cerbos/**/testdata/auxdata.yaml"
                            },
                        },
                    },
                },
            },
        },
    }
}

JetBrains IDEs

Navigate to the Preferences  Languages & Frameworks  Schemas and DTDs  JSON Schema Mappings in JetBrains IDE of your choice.

Add an entry with the following configuration:

Name: Cerbos
Schema file or URL: https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json
Schema version: JSON Schema Version 7
File path pattern: cerbos/*

JetBrains JSON Schema Mappings menu

In the example above, the schema is applied to all files in the cerbos directory.

Visual Studio Code

If you are new to Visual Studio Code, refer to the documentation for more information about how to change settings.

Install the YAML language server extension from https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml

After the extension is installed, hit Ctrl+, or File  Preferences  Settings to edit settings. Expand Extensions  YAML, click Edit in settings.json under Yaml: Schemas. and add the following snippet:

{
  "yaml.schemas": {
    "https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json": "cerbos/*",
    "https://api.cerbos.dev/latest/cerbos/policy/v1/TestSuite.schema.json": "/cerbos/**/*_test.yaml",
    "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Resources.schema.json": "/cerbos/**/testdata/resources.yaml",
    "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Principals.schema.json": "/cerbos/**/testdata/principals.yaml",
    "https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/AuxData.schema.json": "/cerbos/**/testdata/auxdata.yaml"
  }
}
In the example above, the schema is applied to all files in the cerbos directory.