Roles and permissions

How Reader, Writer and Owner roles map to document actions, and why the person who submits a document can never approve it.

<!-- Reviewed 2026-09-08 (no default team; team codes capped at three): the covered code lost one payload field (`isDefault` on `GET /api/teams?mine=true`, which no surface this page describes ever showed), renamed the team-less fallback helper, and had its comments corrected — the fallback itself is now the workspace's OLDEST team rather than its flagged one, which resolves to the same team on every workspace the app has made. New team codes are 2–3 characters; existing longer codes are untouched and keep numbering, because the numbers already issued cite them. Nothing this page states about behaviour changes. --> <!-- Reviewed 2026-09-05 (a request with no body is an empty object): the covered src/lib/server/withApi.ts now hands an ABSENT request body to the route's own schema as `{}` instead of refusing it as malformed JSON, so a route that grows an all-optional body no longer breaks callers that send none. Who may call what is untouched — the roles, the gates and their refusals are exactly as this page describes; only the wording of one malformed-input error changed, and it names the missing field now rather than blaming the JSON. --> <!-- Reviewed 2026-09-02 (an archived document is a start): the covered archive route keeps its gate (doc.propose, control-backed refusal); after an archive commits it now dispatches the record event the governing procedures start on. No permission moved. --> <!-- Reviewed 2026-08-27 (document clause audit retired): this page's covered code changed only where the audit touched it — `teams.ts` no longer lists `audit_reports` among a team's owned tables, and `withApi.ts` lost the `auditReports` resource gate. Nothing this page describes to a reader moved: a team still owns its documents and risks, and the permission rungs are unchanged. Confirmed rather than rewritten. -->

Who may edit, approve and publish a controlled document is decided by the role you hold, and every one of those decisions is made on the server rather than in the browser. This page is the full rule.

Two kinds of role

Alchex uses two independent sets of roles, and it helps to keep them apart.

Workspace rolesOwner, Admin, Member — decide who runs the workspace: inviting people, changing workspace settings, billing, creating and deleting teams. You pick a workspace role when you invite someone.

Team rolesReader, Writer, Owner — decide what someone can do to the controlled documents belonging to that team. You pick a team role when you add a person to a team, and you can give the same person different roles on different teams.

One shortcut connects them: a workspace Admin or workspace Owner counts as a team Owner on every team, without being added to it. Everyone else has exactly the team role you gave them — and someone who is on no team at all cannot see that team's documents, even to read.

What each role can do

The table below is the live rule, not a summary of it. Every row is enforced on the server, so a role can never do something through a shortcut, a link, or a stale browser tab that it could not do through the normal screens.

ActionReaderWriterOwner
View the published document and its version historyYesYesYes
Create a documentNoYesYes
Edit the draftNoYesYes
Start a comment thread, reply, resolveNoYesYes
Submit a draft for reviewNoYesYes
Withdraw a submissionNoYesYes
Remove a record (archive it) — document or registerNoYesYes
Restore an archived recordNoYesYes
Permanently delete a recordNoNoYes
Approve or send back a submitted draftNoNoYes*
Publish the current draft directlyNoNoYes
Add or remove team members, change their team roleNoNoYes

* Subject to the separation-of-duties rule below.

A few things worth spelling out:

  • Reader really is read-only. A Reader cannot create, edit, comment, submit or archive anything. There is no "just this once" exception.
  • Commenting is a Writer action. Leaving review feedback counts as contributing to the document, so it sits on the same rung as editing.
  • Removing a document is archiving it, and that is a Writer action. It takes the document out of circulation but does not destroy it: every version, approval and stored file is kept, and Restore on the archived document's banner brings it back. Removal sits on the same rung as proposing a change, which is what makes it safe: it is reversible. Permanent delete is a separate, Owner-only door on the Governance list, and it refuses a document that ever published — its versions and approvals are a record somebody may hold — so what it is for is the draft that never became one. A control's definition document is not an exception any more: archiving it archives the control with it (a Writer action, the same rung), permanently deleting it removes the control, its wiring and the definition together (an Owner action, the same rung), and moving it takes the pair to the new team. If the control carries an audit verdict you are asked before it is cleared — see Activity and archive.
  • Nothing about removal depends on what cites the document. A record other documents point at can still be removed by anyone whose role reaches it; the citing chips pick up a red dot and can be re-pointed. Removal is never refused on that account, so there is no admin-only way around a refusal either. That holds for the permanent door too, and for every kind of record — deleting a cited register is not refused either. See References and Activity and archive.
  • The two rungs are the same for every kind of record. Archiving and restoring a document or a register is a Writer action; permanently deleting either of them is an Owner action. There is one rule to learn, not one per kind.
  • Publishing and approving are the two Owner-only powers — the moments where content becomes official.

Editing is governed by your role and by the document's state — archived documents are read-only for everyone, and so is any record while its review is pending: from submit until the decision or a withdrawal, the record is locked for every role, the submitter's included. See Drafts and Submit and approve.

Separation of duties

The single most important rule in the whole permission model:

Whoever submitted a document for review cannot approve that same review — not even a workspace Owner.

There is no role that lifts this. If you submitted the draft, the approve and send-back buttons are unavailable to you on that review, and the request is refused by the server if it arrives anyway. Someone else with Owner rights on that team has to make the call.

The check does not rely on anything your browser sends. When a decision arrives, Alchex reads the submitter from the approval record itself and compares it with your signed-in identity. That is why the rule survives page refreshes, shared links, and copied requests.

Two clarifications that come up often:

  • The rule keys on the submitter, not on who typed the words. An Owner who helped edit a draft that someone else submitted may still approve it. If you need contribution-level separation, use the activity trail to show who touched what.
  • Publishing directly is the one sanctioned self-approval — and it is a server verb, not a button. The publish verb, at the Owner rung, can issue the current draft without a second pair of eyes; the app itself offers no way to press it. It is recorded explicitly as a direct publish, so it is always visible in the history, and it is refused while somebody else's review is still pending, so it cannot be used to jump a queue. See Publishing.

Choosing roles in practice

A workable default for most teams:

  • Reader for people who need to follow the rules but never write them.
  • Writer for the people who draft and maintain documents, and for anyone whose feedback you want in comment threads.
  • Owner for the small group accountable for what the team publishes. Keep it to at least two people — with only one Owner, that person's own submissions can never be approved by anyone else, and separation of duties collapses into direct publishing.

Reserve workspace Admin for people who genuinely administer the workspace, and remember it silently grants team Owner everywhere.

Where to change roles

Workspace roles and invitations live in workspace settings, under Members. Inviting someone sets their workspace role, their starting team, and their role on that team in one step; the invitation link expires after seven days and works once.

Team roles live on the team itself, under Members. Only a team Owner (or a workspace Admin/Owner) can add people or change their role there, and you cannot remove your own Owner access from that screen.

Changes take effect immediately. If you are new to the workspace model, start with the Overview; to see how these roles play out across a document's life, read Submit and approve and Comments.

<!-- Reviewed 2026-08-26 (workflow manager P2 — the executor): the covered record routes gained post-commit workflow dispatch hooks (record created / submitted → runs; decisions → resume). No editor can place a workflow chip yet, so no published document declares a trigger and every documented flow behaves exactly as before. Nothing this page documents changed. -->