Validating and testing policies :: Cerbos Authorization Management Platform // Documentation

Validating and testing policies

Validating 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.53.0 compile /policies

Testing 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: yaml, yml, or json. For example, album_test.yml, album_test.yaml or album_test.json.

Test suite definition

---
name: AlbumObjectTestSuite (1)
description: Tests for verifying the album:object resource policy (2)
options:
  now: "2022-08-02T15:00:00Z" (3)
defaultPolicyVersion: staging (4)
defaultScope: "" (5)
lenientScopeSearch: true (6)
globals: (7)
  my_global_var: foo

principals: (8)
  alicia:
    id: aliciaID
    roles:
      - user

bradley:
    id: bradleyID
    roles:
      - user

principalGroups: (9)
  everyone:
    principals:
      - alicia
      - bradley

resources: (10)
  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

resourceGroups: (11)
  all_albums:
    resources:
      - alicia_album
      - bradley_album

auxData: (12)
  validJWT:
    jwt:
      iss: my.domain
      aud: ["x", "y"]
      myField: value

tests: (13)
  - name: Accessing an album (14)
    options: (15)
      now: "2022-08-03T15:00:00Z" (16)
      defaultPolicyVersion: production (17)
      defaultScope: "" (18)
      lenientScopeSearch: false (19)
      globals: (20)
        my_global_var: bar

input: (21)
      principals: (22)
        - alicia
        - bradley
      resources: (23)
        - alicia_album
        - bradley_album
      actions: (24)
        - view
        - delete
      auxData: validJWT (25)

expected: (26)
      - principal: alicia (27)
        resource: alicia_album (28)
        actions: (29)
          view: EFFECT_ALLOW
          delete: EFFECT_ALLOW
        outputs: (30)
          - action: view (31)
            expected: (32)
              - 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

- name: Using groups
    input:
      principalGroups: (33)
        - everyone
      resourceGroups: (34)
        - all_albums
      actions:
        - download

expected:
      - principalGroups: (35)
          - everyone
        resourceGroups: (36)
          - all_albums
        actions:
          download: EFFECT_DENY

Sharing test fixtures

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/resources.yml, testdata/principals.yml, testdata/auxdata.yml respectively (yaml and 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

An example of testdata/principals.yml

---
principals: # required
  john:
    id: johnID
    roles:
      - user
      - moderator

principalGroups: # optional
  moderators:
    principals:
      - john

An example of testdata/resources.yml

---
resources: # required
  alicia_album:
    id: XX125
    kind: "album:object"
    attr:
      owner: aliciaID
      public: false
      flagged: false

resourceGroups: # optional
  all_albums:
    resources:
      - alicia_album

An example of testdata/auxdata.yml

---
auxData: # required
  validJWT:
    jwt:
      iss: my.domain
      aud: ["x", "y"]
      myField: value

Running tests

The 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.53.0 compile /policies

The output format can be controlled using the --output flag, which accepts the values tree (default), list and json. The --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 --test-filter to run only tests matching specific criteria.

CI Integration

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.