Permissions
Vizier Central has 22 actions and four roles. The whole policy is one table in one file, deliberately: a permission model you cannot read in a single sitting is a permission model nobody audits.
Enforced on the server
Every refusal below happens in the control plane, not in a client. That matters for an audit: a check inside the binary somebody runs is a linter, because they can edit it. A check on a server they do not control is a control.
The four roles
viewer
Reads everything, changes nothing. Cannot run.
Somebody who needs to see the estate but not touch it: a manager, an auditor, a new joiner in their first week.
operator
Plans and applies. Raises changes for review. Cannot destroy, and cannot configure the estate.
The engineers doing the work.
admin
Destroys, configures projects and environments, decides which publisher keys the company trusts, reviews changes, reads the audit log.
Team leads and platform owners.
owner
Manages people, renames the organisation, and is the only role that may WEAKEN an environment.
Whoever is accountable for the account.
Each role subsumes the ones above it: an admin can do everything an operator can. The table below lists each action once, against the least role that may perform it.
Every action
viewer and above
The floor. Somebody with an account can see the estate they belong to, which is the point of having an account.
| org.read | The organisation itself |
| projects.read | Which projects exist |
| environments.read | Environments and the evidence each one demands |
| accounts.read | Cloud account pointers (never a credential; there are none) |
| keys.read | Which publisher keys the company trusts |
| runs.read | Run history |
| runs.receipt.read | The receipt a run emitted, verbatim |
| changes.read | The review queue and any change in it |
operator and above
The engineer’s job. Note what is NOT here: destroy, and every form of configuration.
| run.plan | Plan against an environment |
| run.apply | Apply to an environment |
| changes.propose | Raise a change for somebody else to review |
admin and above
Running the estate, and deciding what the company trusts.
| run.destroy | Tear down. Split from apply deliberately: they are the same mechanism and not the same decision |
| lease.break | Force a stuck lease open. Admin because the failure it causes - two runners on one state - is what leases prevent |
| changes.review | Approve or reject somebody else’s change |
| projects.write | Create and configure projects |
| environments.write | Create and configure environments (raising the floor, never lowering it) |
| accounts.write | Register the identities environments deploy through |
| keys.write | Decide whose signatures this company accepts. The most consequential thing an admin can do: it is the root of every proof below it |
| audit.read | Read the audit log. Admin rather than owner, because a log only one person can read is not much of a control |
owner and above
The acts that decide who else can act, and the one act that makes the estate less safe.
| environments.lower_floor | WEAKEN an environment: a lower status floor, signatures or pinning off, warn instead of enforce, or fewer approvals |
| users.manage | Add people, change roles, disable accounts |
| org.manage | Rename the organisation |
The rules that make it fail closed
Each of these is a real failure mode rather than defensive habit.
An action with no entry is denied
Not defaulted, not warned about: denied. The way this goes wrong in practice is a new route whose author forgets the table entry, and denying turns that into a visible 403 during development instead of an invisible hole in production.
A role this build does not recognise ranks zero
A database row that says "superadmin" because somebody edited it by hand, or because it was written by a newer version, can do nothing at all. It must never out-rank owner.
A disabled user is refused before any role is consulted
Disabling somebody is one act, not "remember to also change their role".
Nobody may change their own membership
It is what guarantees an organisation is never left without an owner. Another owner changes yours.
The author of a change cannot approve it
Enforced in the database, not in a handler. An admin who raised a change still cannot pass it: without this, four-eyes is true on the org chart and false in the room.
What an assessor gets from this
Role separation and an append-only trail are what a SOC 2 or ISO 27001 assessor asks to see, and Central produces both as a by-product of working normally. Every run keeps the receipt it emitted, verbatim, alongside who started it and what evidence it was held to. Every configuration change is written to the audit log with its before and after. Nobody can approve their own change, and lowering an environment's bar is a separate permission from editing it.
The console has a Permissions screen that reads the server's own policy table rather than repeating it, so what it shows cannot describe a system that no longer exists. This page is the version you can send to somebody before they have an account.
Roles and review come with Vizier Central, from the Team tier.