Roles and policies
Who may see and do what is decided by Cerbos policies, read on every request. The image ships default policies. You add your own beside them in files, with a test for each, and you never touch the core’s code.
The shipped roles
Section titled “The shipped roles”| Role | May |
|---|---|
viewer |
Read, search, run queries on what Power BI lets them see, ask questions, comment, upvote, and read the query log. |
curator |
Everything a viewer may, and change the book (curate), verify, approve, accept answers and archive threads. |
admin |
Everything a curator may, and settings, secrets, conventions, people, service accounts, sync and audit. |
pii_reader |
Read and query marked personal data within the person’s Power BI rights. Add it to the person’s normal role. |
Admins do not receive pii_reader automatically. Assign it only to a person or group; service accounts never read PII. See PII for rules and a worked check.
What a person may see in the first place is a separate rule, access.metadata_visibility: powerbi (the default, what Power BI lets them reach), everyone (anyone signed in), or policy (only what your own policy allows). Power BI then applies the person’s own rights again on every query, so a role never gives access to data Power BI refuses.
Assign roles
Section titled “Assign roles”Roles are kept in the database and read on every request. Assign them in the admin section or with the CLI:
pbmb admin roles listpbmb admin roles assign curator --person ada@sample.examplepbmb admin roles assign viewer --domain sample.examplepbmb admin roles assign curator --group <group id> --provider microsoftpbmb admin roles revoke <assignment id>Give one of --person (an email), --domain (an email domain) or --group (the id the sign-in provider puts in the token, with --provider, which defaults to microsoft). The last admin cannot be revoked.
The default after setup is that everyone in your Power BI tenant is a viewer (the setting access.default_role: viewer, curator or none, where none lets in only people who are assigned) and the person who ran the setup is an admin. Change the default with pbmb admin settings set access.default_role none. pbmb admin export writes the assignments into book.yml for git.
Add a role
Section titled “Add a role”A role exists when a policy names it. Say a team of metric stewards should curate and verify the book, but leave approval to curators. Three steps: the policy, its test, the assignment.
pbmb init made two folders in your deployment directory, access/policies/ and access/tests/. Put the policy in access/policies/book.yaml:
# Metric stewards may curate and verify the book, but not approve.apiVersion: api.cerbos.dev/v1resourcePolicy: resource: book version: default scope: deployment scopePermissions: SCOPE_PERMISSIONS_OVERRIDE_PARENT rules: - actions: [curate, verify] effect: EFFECT_ALLOW roles: [metric_steward]Put its test in access/tests/book_test.yaml. Cerbos expects a refusal for every combination the test lists and expected leaves out, so the test checks what a steward may not do as well:
name: metric_stewarddescription: A steward curates and verifies; a viewer and the shipped curator keep what the defaults give them.options: lenientScopeSearch: trueprincipals: steward: id: steward roles: [viewer, metric_steward] viewer: id: viewer roles: [viewer] curator: id: curator roles: [curator]resources: book: kind: book id: book scope: deploymenttests: - name: who may do what to the book input: principals: [steward, viewer, curator] resources: [book] actions: [curate, verify, approve] expected: - principal: steward resource: book actions: { curate: EFFECT_ALLOW, verify: EFFECT_ALLOW } - principal: curator resource: book actions: { curate: EFFECT_ALLOW, verify: EFFECT_ALLOW, approve: EFFECT_ALLOW }Run the tests before you start anything:
pbmb checkpbmb check validates book.yml when there is one, checks that .env holds every bootstrap value and is readable only by you, and runs your policy tests in the pinned Cerbos image through Docker, with the default policies underneath. Run it from the deployment directory, or pass the directory. It exits 1 when a step fails, and prints the last lines of Cerbos’s output so you can see which test failed.
Cerbos reads policies once at start. Load the new policy, then assign the role. Because the api does not know your role, assigning it takes --custom, which says you mean a role your own policies define:
docker compose restart cerbospbmb admin roles assign metric_steward --person grace@sample.example --customThe person keeps viewer from the default assignment, and gains metric_steward.
What a policy can decide
Section titled “What a policy can decide”Every request that reads or changes data asks Cerbos about a resource and an action:
| Resource | Attributes | Actions |
|---|---|---|
dataset |
workspace_id, workspace_name, app_ids, app_names, has_row_level_security, endorsement, sensitivity_label, custom |
describe, query |
book |
none | curate, verify, approve, edit_conventions |
thread |
author_id, kind, status |
create, reply, upvote, accept, archive |
query_log |
principal_id |
read |
result |
owner_id |
read |
admin |
none | manage_settings, manage_secrets, manage_people, manage_service_accounts, run_sync, read_audit, revoke_connection, read_sync_events, read_status |
The principal carries its roles, its kind (person or service_account), and what Power BI says it can reach: powerbi_workspace_ids, powerbi_app_ids and powerbi_dataset_ids. Read the default policies in access/policies/ of the repository: they are short, and they are the best examples.
Lists and search apply describe inside their SQL, using Cerbos’s query plan. A describe rule may therefore use only workspace_id, has_row_level_security, endorsement, sensitivity_label, the dataset id and app_ids, with and, or, not, ==, in and hasIntersection. A condition the api cannot translate fails every list loudly instead of showing too much. A query rule is checked for one dataset at a time and may use any attribute, including custom.
How your policies layer on the defaults
Section titled “How your policies layer on the defaults”The defaults sit at the root scope. The api asks every question at the scope deployment. A resource you write no policy for falls back to the default. For one you do write, a rule of yours that matches decides, and where none matches the defaults decide.
Your policies must use scope: deployment. Cerbos makes every policy in one scope share one scopePermissions, so you make one choice for all of them:
scopePermissions |
Your rules | Use it to |
|---|---|---|
SCOPE_PERMISSIONS_OVERRIDE_PARENT |
Replace a default. An ALLOW widens and a DENY narrows. | Add a role, open or close a dataset. |
SCOPE_PERMISSIONS_REQUIRE_PARENTAL_CONSENT_FOR_ALLOWS |
An ALLOW counts only where a default allows too. Only DENY rules take effect. | Narrow the defaults and be sure nothing widens. |
Both are shown with their tests in access/layering_tests/ in the repository. In override/, a deployment policy opens certified datasets to everyone signed in, and the defaults decide the rest. In narrowing/, the book policy denies approve to curators, so only admins approve, and its ALLOW for everyone to curate changes nothing:
resourcePolicy: resource: book version: default scope: deployment scopePermissions: SCOPE_PERMISSIONS_REQUIRE_PARENTAL_CONSENT_FOR_ALLOWS rules: - actions: [approve] effect: EFFECT_DENY roles: [curator]The PII widening in override/ has no effect for anyone who is not a person holding pii_reader; the api refuses it in code.
Copy the one you want into access/policies/ and its test into access/tests/, then run pbmb check.
What no policy can widen
Section titled “What no policy can widen”The api holds some rules in code, because a policy cannot see how a request arrived. They apply whatever your policies say:
- A service account’s workspace and app grant can never be widened. A policy that allows a service account a dataset outside its grant is overridden by the api.
- The api refuses every admin action to a service account, except reading the status.
- A result can be read only by the caller who ran the query.
- Only a person in a browser session approves a metric, unless the conventions’
trust.human_verify_fromsaysany.
These are listed again in What is not a setting.
pbmb checkpbmb admin roles listpbmb whoamipbmb check prints ok policy tests (and ok .env, ok book.yml) and exits 0. roles list shows the assignment you made. Run pbmb whoami as that person: it lists metric_steward among their roles.