# Policy authoring

|     |     |
| --- | --- |
|  | This documentation is for<br>an as-yet unreleased<br>version of Cerbos PDP. Choose 0.53.0 from the version picker at the top right or navigate to [https://docs.cerbos.dev](https://docs.cerbos.dev/) for the latest version. |

## Tips for working with policies

- Policies can be in either YAML or JSON formats. Accepted file extensions are `.yml`, `.yaml` or `.json`. All other extensions are ignored.

- The JSON schemas for Cerbos files are available at:

- Policy  
    - `https://api.cerbos.dev/v0.54.0-prerelease/cerbos/policy/v1/Policy.schema.json`
  - [Test suite](https://docs.cerbos.dev/cerbos/prerelease/policies/compile#testing)  
    - `https://api.cerbos.dev/v0.54.0-prerelease/cerbos/policy/v1/TestSuite.schema.json`
  - [Principal test fixtures](https://docs.cerbos.dev/cerbos/prerelease/policies/compile#fixtures)  
    - `https://api.cerbos.dev/v0.54.0-prerelease/cerbos/policy/v1/TestFixture/Principals.schema.json`
  - [Resources test fixtures](https://docs.cerbos.dev/cerbos/prerelease/policies/compile#fixtures)  
    - `https://api.cerbos.dev/v0.54.0-prerelease/cerbos/policy/v1/TestFixture/Resources.schema.json`
  - [Auxiliary data test fixtures](https://docs.cerbos.dev/cerbos/prerelease/policies/compile#fixtures)  
    - `https://api.cerbos.dev/v0.54.0-prerelease/cerbos/policy/v1/TestFixture/AuxData.schema.json`

- If you prefer to always use the latest version, they can be accessed at:
  - `https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json`
  - `https://api.cerbos.dev/latest/cerbos/policy/v1/TestSuite.schema.json`
  - `https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Principals.schema.json`
  - `https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/Resources.schema.json`
  - `https://api.cerbos.dev/latest/cerbos/policy/v1/TestFixture/AuxData.schema.json`

## 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](https://docs.cerbos.dev/cerbos/prerelease/policies/scoped_policies) (optional) are handy for use cases like multi-tenancy where you may want to override particular rules for some tenants.

- See [Conditions](https://docs.cerbos.dev/cerbos/prerelease/policies/conditions) to learn how to write conditions in policy rules.

- See [Schemas](https://docs.cerbos.dev/cerbos/prerelease/policies/schemas) to learn how you can define schemas for validating requests.

- See [Best practices](https://docs.cerbos.dev/cerbos/prerelease/policies/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](https://play.cerbos.dev/). 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)](https://microsoft.github.io/language-server-protocol/) can make use of the [YAML language server](https://github.com/redhat-developer/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
# yaml-language-server: $schema=https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json
```

The same method can be used for [tests](https://docs.cerbos.dev/cerbos/prerelease/policies/compile#testing):

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

[Resource fixtures](https://docs.cerbos.dev/cerbos/prerelease/policies/compile#fixtures) for tests:

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

[Principal fixtures](https://docs.cerbos.dev/cerbos/prerelease/policies/compile#fixtures) for tests:

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

[Auxiliary data fixtures](https://docs.cerbos.dev/cerbos/prerelease/policies/compile#fixtures) for tests:

```yaml
# 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](https://github.com/redhat-developer/yaml-language-server#language-server-settings=) for more information.

Example: Apply the schema to all files in the /cerbos directory

```yaml
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.

```json
"$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](https://github.com/neovim/nvim-lspconfig/tree/master) and [configure the yaml-language-server](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#yamlls). Plugins such as [mason-lspconfig](https://github.com/williamboman/mason-lspconfig.nvim) can automatically download and install language servers as well.

The following is an example of using [lazy.nvim](https://github.com/folke/lazy.nvim) and [mason.nvim](https://github.com/williamboman/mason.nvim) to install and configure yaml-language-server. It follows the [recommended way of configuring lazy plugins](https://github.com/folke/lazy.nvim#-structuring-your-plugins).

~/.config/nvim/lua/plugins/lspconfig.lua

```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 **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/*
```

|     |     |
| --- | --- |
|  | 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](https://code.visualstudio.com/docs/getstarted/settings) for more information about how to change settings.

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

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

```json
{
  "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.
