# Roles, members & seats (https://systemhub.com/docs/concepts/roles-and-seats)

> Part of systemHUB Docs · Connect: Settings → AI Gateway in systemHUB · Auth: OAuth (scoping is workspace-level today — see Getting started) · MCP tools: 48 · Full corpus: https://systemhub.com/llms-full.txt

systemHUB controls who can see and do what through **roles** and **member assignments**. This page explains the model an agent needs to reason about access — and where the current MCP boundary sits.

## The access model

A document's access is the union of two mechanisms:

- **Role-based access** — a document is assigned to one or more **roles** (e.g. a department or job function). Every member holding that role gets access.
- **Direct assignment** — an individual member is assigned to the document specifically, regardless of role.

A member can therefore have access that is **direct**, **role-based**, or **both**. The `get_document_members_and_roles` tool returns exactly this: the roles on a document, plus each member's name, email, role title(s), and access type.

Present an access picture as an audit: roles first, then members grouped by how they got in (direct vs role-based vs both).

## Document owners

Separate from access, every document carries a **primary owner** (mandatory — the person accountable for it) and an optional **secondary owner** (a backup). Owners are about accountability, not permission: owning a document is not what grants access to it.

Three behaviours to know before changing owners programmatically:

> **Changing the primary owner moves the outgoing owner into an empty secondary slot.** If the secondary slot is empty, the person you just replaced is automatically recorded as secondary owner — the intent being that a handover keeps the previous owner attached as backup. If a *distinct* secondary owner already occupies the slot, it is left untouched and the outgoing owner simply drops off. This fires on every owner change and is not reported in the response, so **re-read the document after reassigning** rather than assuming the secondary slot is unchanged.

- **A secondary owner equal to the primary owner is treated as no secondary owner.** It is returned as null and displayed as empty. This is why `list_documents_by_owner` describes matching a *distinct* secondary owner, and why a document can appear to gain a secondary owner the moment its primary changes.
- **To clear a secondary owner, pass `secondaryOwner: null`** on `edit_system` / `edit_policy` / `edit_training`. Omitting the field leaves it unchanged.

**Reassigning in bulk (e.g. someone leaving):** deleting a user in the app UI is the intended path — it asks for a replacement primary *and* secondary owner and swaps the departing person out of both slots across every document in one action, without triggering the auto-fill above. Reassigning documents one at a time instead means the auto-fill applies to each, so plan on a second pass to tidy the secondary slots.

## Seats

A **seat** is a licensed member of the workspace. Seat/member management — inviting people, allocating seats, changing who holds which role — is done in the **systemHUB app UI**.

> **MCP boundary (important for connecting agents):** the MCP can **read** the full access picture (members, roles, assignment type, agreement status, training progress) and can **write document-level access** — `manage_document_members` assigns or removes members and roles on a document, with `list_company_members` / `list_roles` to resolve names to UUIDs. What it can **not** do is seat provisioning: inviting new people to the workspace, allocating licences, or changing who holds which company role. That stays in the app UI — direct the user there.

## What agents can audit today

- `get_document_members_and_roles` — who can access a document, and how.
- `get_document_agreement_status` — who has agreed/signed off on a document (e.g. a policy acknowledgement).
- `get_document_training_progress` — for trainings, each assigned user's completion percentage and status.
- `get_document_activity_log` — who created and last modified a document, plus the event feed (`includeViews: true` to include views).
- `list_documents_by_owner` — everything a given person owns across systems, policies, and trainings, in one call.

> ⚠️ **`manage_document_members` with `action: "update"` REPLACES the document's assigned roles — it does not merge.** Passing a partial list silently removes every role you left out. To add or remove without collateral damage, use `action: "add"` / `"remove"`. Always confirm the result with `get_document_members_and_roles`.

> **Paginate deliberately.** The audit tools page their results. Pass `fetchAll: true` (the default on most) when you need a complete roster — a partial page will otherwise be reported as the whole answer, which is how an agent confidently states the wrong list of who has signed off.

Together these cover "who owns / can see / has completed what" — the read side of governance. The write side (provisioning) stays in the app for now.

Next: **[Authoring content →](/docs/concepts/authoring-content)**
