Roles and permissions
Five roles, and per-site overrides
Edit this pageOn this page
Five organisation roles, plus per-site overrides that can only raise access, never lower it.
The roles
| Role | Rank | Can do |
|---|---|---|
owner | 3 | Everything, including destructive actions and transferring ownership |
admin | 2 | Manage members, sites, credentials, integrations and daemons |
editor | 1 | Add networks, enqueue scans, triage findings, edit hosts |
auditor | 0 | Read everything in scope, including the audit log |
viewer | 0 | Read everything in scope |
viewer and auditor are the same rank deliberately: an auditor is not more
powerful than a viewer, only differently scoped. Neither can change anything.
An owner is an owner everywhere, unaffected by any site scoping.
Per-site overrides
A site scope raises somebody's role for one location:
| Organisation role | Override at site X | Effective at site X | Effective elsewhere |
|---|---|---|---|
viewer | editor | editor | viewer |
viewer | admin | admin | viewer |
admin | viewer | admin | admin |
owner | anything | owner | owner |
Your organisation role is the floor. An override that appeared to lower
access would give the permission model two answers to the same question, and
the one people would rely on is whichever they happened to test. So the
resolution is simply max(org role, override).
When an override is in effect, a scoped: badge appears next to the site
picker. A permission you hold and cannot see is a permission that will
surprise you.
Manage overrides at Sites → site → Scopes.
Where roles are enforced
Not in the interface. Every page that gates a privileged action resolves the effective role on the server, against the specific site, before doing anything — so a hidden button is a convenience, not the control.
Underneath that, PostgreSQL row-level security scopes every query to the
organisation with FORCE enabled, so a query that forgets its tenant filter
returns nothing rather than returning another organisation's estate. Role
checks decide what you may do; RLS decides what exists as far as your session
is concerned.
Adding people
Settings → People → Invite. An invitation is a single-use link with an expiry, shown once — the same treatment as a daemon key, and for the same reason: only its hash is stored.
Where a directory owns your user list, use SCIM instead and stop inviting people by hand.
Removing people
Removing a member revokes their access immediately and ends the sessions they already hold. Without that, removal stops the next sign-in and leaves the current one running, which is the difference between removing access and scheduling it.
The membership record is retained rather than deleted, so the audit trail of who had access, and when it was removed, survives the removal.
Roles from a directory
Both OIDC and SCIM can set roles:
- OIDC maps a groups claim to a role at each sign-in.
- SCIM maps group membership to a role as the directory pushes it.
Both use the same rule when somebody is in several mapped groups: the strongest wins. The order a directory lists groups in is not something an operator can see or control, so a first-match rule would make the answer arbitrary.
Both also refuse to demote on an empty result. Somebody whose groups map to
nothing keeps the role they have, rather than being reset to viewer —
otherwise a directory reorganising its groups silently strips a role an
operator set by hand, and the person finds out by losing access.
Superadmin and cross-organisation access
There is no ambient superadmin. Cross-organisation access requires an explicit scope and writes an audit entry — a deployment holding several customers should not have a role that quietly reads all of them.