# Organisations and roles

Four roles, each a minimum rather than a set. Tenancy is enforced on every query, and an unauthorised object reads as missing rather than forbidden.

Source: https://opafra.com/docs/access/organisations-and-roles

---

Work in Opafra belongs to an **organisation**, or to a personal workspace for someone
working alone. Servers, plans, environments, secrets, keys and run history all belong to
one tenant and are invisible to every other.

## The four roles

Roles are hierarchical. Each one is a minimum, so an Admin can do everything an Operator
can.

| Role | Can |
|---|---|
| **Viewer** | Read. See inventory, plans, environments and run history. |
| **Operator** | Everything above, plus run plans, edit them, manage inventory, and resolve approvals. |
| **Admin** | Everything above, plus manage members and invitations, grant environment access, change org settings, and read the audit log. |
| **Owner** | Everything above, plus delete the organisation. |

The split worth knowing is **Operator to Admin**. An Operator changes production; an
Admin changes who may change production. Those are different jobs, and the second is the
one that needs fewer holders.

> **Note**
>
> Approving a gated run requires Operator or above. A Viewer cannot approve, which keeps
> the approval a decision by someone who could have made the change themselves.

## What Admin exclusively controls

Worth listing, because these are the levers that change everyone else's reach:

- Inviting, removing, and re-roling members
- Granting and revoking access to protected environments
- Approving or denying environment access requests
- Reading the audit log
- Organisation settings

Only an Owner can delete the organisation.

## Personal workspaces

Working alone gives you a personal workspace rather than an organisation. It behaves the
same way and is scoped just as strictly: your servers, plans and secrets are yours, and no
organisation can see them.

## How isolation is enforced

Tenancy is applied at the query, not at the screen. Every read is scoped to the caller's
tenant, and every change by id checks ownership before proceeding.

**An object you may not see reports as missing, not as forbidden.** That is deliberate.
"Forbidden" confirms the object exists, which turns an id into something worth guessing
at. "Not found" tells a prober nothing at all.

> **Important**
>
> The same rule applies to references. A `secret://` reference pointing outside your
> tenant's namespace is rejected rather than followed, so a hand-written reference is not a
> way around the boundary.

Defaults fail closed. Where a check cannot be resolved, access is refused rather than
assumed.

## Environment access is separate

Roles apply across the tenant. A **protected** environment narrows that further: even an
Operator needs an explicit grant to see it, run against it, or manage it.

A grant can carry an expiry, so temporary access is genuinely temporary rather than
permanent access someone intended to revoke. Someone without access can request it, and
the request records who asked, for what, and who decided.

See [environments](/docs/inventory/environments) for how that interacts with approval
gates, which are a separate flag with a separate purpose.

## Choosing roles for a team

A workable default:

- **Viewer** for anyone who needs to see what happened but does not run anything, which
  includes most people who are only ever reading a run record
- **Operator** for the people doing the work
- **Admin** for the small number who manage the team and read the audit log
- **Owner** for whoever owns the account

Granting Operator broadly and Admin narrowly is the shape that matches how the roles are
actually split.

## Next steps

- [Environments](/docs/inventory/environments) for grants and protected environments
- [Audit log](/docs/governance/audit-log) for what is recorded and who can read it
