Validating and testing policies
You can use the Cerbos compiler to make sure that your policies are valid before pushing them to a production Cerbos instance. We recommend setting up a git hook or a CI step to run the Cerbos compiler before you push any policy changes to production.
docker run -i -t -v /path/to/policy/dir:/policies ghcr.io/cerbos/cerbos:0.30.0 compile /policies
You can write optional tests for policies and run them as part of the compilation stage to make sure that the policies do exactly what you expect.
Tests are defined using the familiar YAML format as well. A test file must have
_test suffix in the name and one of the following file extensions:
json. For example,
--- name: AlbumObjectTestSuite (1) description: Tests for verifying the album:object resource policy (2) options: now: "2022-08-02T15:00:00Z" (3) principals: (4) alicia: id: aliciaID roles: - user bradley: id: bradleyID roles: - user resources: (5) alicia_album: id: XX125 kind: album:object policyVersion: default attr: owner: aliciaID public: false flagged: false bradley_album: id: XX250 kind: album:object policyVersion: staging attr: owner: bradleyID public: false flagged: false auxData: (6) validJWT: jwt: iss: my.domain aud: ["x", "y"] myField: value tests: (7) - name: Accessing an album (8) options: now: "2022-08-03T15:00:00Z" (9) input: (10) principals: (11) - alicia - bradley resources: (12) - alicia_album - bradley_album actions: (13) - view - delete auxData: validJWT (14) expected: (15) - principal: alicia (16) resource: alicia_album (17) actions: (18) view: EFFECT_ALLOW delete: EFFECT_ALLOW outputs: (19) - action: view (20) expected: (21) - src: resource.album.vdefault#view-rule val: key1: value1 key2: ["value2", "value3"] - src: resource.album.vdefault#token-lifetime val: 1h - principal: bradley resource: bradley_album actions: view: EFFECT_ALLOW delete: EFFECT_ALLOW
|1||Name of the test suite|
|2||Description of the test suite|
|3||Optional RFC3339 timestamp to be used as the return value of the
|4||Map of principal fixtures. The key is a string that can be used to refer to the associated principal.|
|5||Map of resource fixtures. The key is a string that can be used to refer to the associated resource.|
|6||Map of (optional) auxiliary data fixtures required to evaluate some requests. The key is a string that can be used to refer to the associated auxData.|
|7||List of tests in this suite|
|8||Name of the test|
|9||Optional RFC3339 timestamp to be used as the return value of the
|10||Input to the policy engine|
|11||List of keys of principal fixtures to test|
|12||List of keys of resource fixtures to test|
|13||List of actions to test|
|14||Key of auxiliary data fixture to test (optional)|
|15||List of outcomes expected for each principal and resource. If a principal+resource pair specified in
|16||Key of the principal fixture under test|
|17||Key of the resource fixture under test|
|18||Expected outcomes for each action for the principal+resource pair|
|19||Optional list of output values to match|
|20||Name of the action that would produce the output|
|21||List of expected output values|
It is possible to share principals, resources and auxData blocks between test suites stored in the same directory. Create a
testdata directory in the directory containing your test suite files, then define shared resources, principals and auxData in
testdata/auxdata.yml respectively (
json extensions are also supported).
tests ├── album_object_test.yaml ├── gallery_object_test.yaml ├── slideshow_object_test.yaml └── testdata ├── auxdata.yaml ├── principals.yaml └── resources.yaml
--- principals: john: id: johnID roles: - user - moderator
--- resources: alicia_album: id: XX125 kind: "album:object" attr: owner: aliciaID public: false flagged: false
--- auxData: validJWT: jwt: iss: my.domain aud: ["x", "y"] myField: value
YAML anchors and overrides are a great way to reduce repetition and reuse definitions in test cases.
For example, the following definitions are equivalent:
compile command automatically discovers test files in the policy repository.
docker run -i -t \ -v /path/to/policy/dir:/policies \ ghcr.io/cerbos/cerbos:0.30.0 compile /policies
The output format can be controlled using the
--output flag, which accepts the values
--color flag controls the coloring of the output. To produce machine readable output from the tests, pass
--output=json --color=never to the command.
By default, all discovered tests are run. Use the
--skip-tests flag to skip all tests or use the
--run flag to run a set of tests that match a regular expression.
docker run -i -t \ -v /path/to/policy/dir:/policies \ ghcr.io/cerbos/cerbos:0.30.0 compile --run=Delete /policies
You can mark entire suites or individual tests in a suite with
skip: true to skip them during test runs.
--- name: AlbumObjectTestSuite description: Tests for verifying the album:object resource policy tests: - name: View private album skip: true skipReason: "Policy under review" input: principals: ["alicia"] resources: ["alicia_private_album"] actions: ["view"] expected: - principal: alicia resource: alicia_private_album actions: view: EFFECT_ALLOW
Because Cerbos artefacts are distributed as self-contained containers and binaries, you should be able to easily integrate Cerbos into any CI environment. Simply configure your workflow to execute the commands described in the sections above using either the Cerbos container (you may need to configure mount points to suit your repo structure) or the binary.
--- name: PR Check on: pull_request: branches: - main jobs: cerbosCheck: name: Check Cerbos policies runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Setup Cerbos uses: cerbos/cerbos-setup-action@v1 with: version: latest - name: Compile and test policies uses: cerbos/cerbos-compile-action@v1 with: policyDir: policies
See https://github.com/cerbos/photo-share-tutorial for an example of Cerbos GitHub Actions being used in a workflow.
--- stages: - prepare - compile download-cerbos: stage: prepare script: - curl https://github.com/cerbos/cerbos/releases/download/v0.30.0/cerbos_0.30.0_Linux_x86_64.tar.gz -L --output /tmp/cerbos.tar.gz - tar -xf /tmp/cerbos.tar.gz -C ./ - chmod +x ./cerbos artifacts: paths: - cerbos compile-job: stage: compile dependencies: ["download-cerbos"] script: - ./cerbos compile ./policies