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.9.1 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. Make sure that your tests are in a separate directory from the policies to avoid confusion. We recommend storing them in a top-level directory named
tests. A test file must have
_test suffix in the name and one of the following file extensions: 'yaml', 'yml', or 'json'. For example,
--- name: AlbumObjectTestSuite (1) description: Tests for verifying the album:object resource policy (2) resources: (3) alicia_album: kind: "album:object", attr: owner: aliciaID, id: XX125, public: false, flagged: false principals: (4) bradley: id: bradleyID roles: - user alicia: id: aliciaID roles: - user tests: (5) - name: Alicia tries to view her own private album (6) input: (7) requestId: "test" actions: ["view", "delete"] resource: "alicia_album" expected: (8) - principal: alicia actions: view: EFFECT_ALLOW delete: EFFECT_ALLOW - principal: bradley actions: view: EFFECT_DENY delete: EFFECT_DENY
|1||Name of the test suite|
|2||Description of the test suite|
|3||Map of resources. A key is a string that can be used to refer to the associated resource|
|4||Map of principals. A key is a string that can be used to refer to the associated principal|
|5||List of tests in this suite|
|6||Name of the test|
|7||Input to the policy engine|
|8||List of outcomes expected for a specified principal and a given action.|
It is possible to share principals and resources between test suites stored in the same directory. Create a
testdata directory in the directory containing your test suite files, then define shared resources and principals in
testdata\principals.yml respectively (
json extensions are also supported).
tests ├── album_object_test.yaml ├── gallery_object_test.yaml ├── slideshow_object_test.yaml └── testdata ├── principals.yaml └── resources.yaml
--- principals: john: id: johnID roles: - user - moderator
--- resources: alicia_album: kind: "album:object", attr: owner: aliciaID, id: XX125, public: false, flagged: false
YAML anchors and overrides are a great way to reduce repetition and reuse definitions in test cases.
For example, the following definitions are equivalent:
To run the tests, provide the path to the tests directory using the
docker run -i -t \ -v /path/to/policy/dir:/policies \ -v /path/to/test/dir:/tests \ ghcr.io/cerbos/cerbos:0.9.1 compile --tests=/tests /policies
Machine readable output can be produced by passing
--format=json flag to the command.
By default, all discovered tests are run. To run just some of the tests, provide a regular expression that matches the test using the
docker run -i -t \ -v /path/to/policy/dir:/policies \ -v /path/to/test/dir:/tests \ ghcr.io/cerbos/cerbos:0.9.1 compile --tests=/tests --run=Delete /policies
You can also skip entire suites or individual tests in a suite by adding
skip: true to the test definition.
--- name: AlbumObjectTestSuite description: Tests for verifying the album:object resource policy tests: - name: View private album skip: true skipReason: "Policy under review" input: requestId: "test01" actions: ["view"] resource: alicia_private_album expected: - principal: alicia 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 testDir: tests
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.9.1/cerbos_0.9.1_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 --tests ./tests