From 423681e8b755d84bf63e03112629a41852e56f42 Mon Sep 17 00:00:00 2001 From: joshunrau Date: Tue, 10 Nov 2026 15:42:09 -0500 Subject: [PATCH 1/2] docs: add a guide to configuring permissions Explains how base levels, permission sets and custom permissions combine, walks admins through granting each, and lists the permissions every page needs, with the Data Hub broken down per tab. Linked from the Security reference and the getting-started guide. Co-Authored-By: Claude Opus 5.5 --- .../3.4-how-to-get-started-with-odc.mdx | 2 +- .../3.5-how-to-configure-permissions.mdx | 143 ++++++++++++++++++ docs/en/5-reference/5.1-security.md | 2 +- 3 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 docs/en/3-guides/3.5-how-to-configure-permissions.mdx diff --git a/docs/en/3-guides/3.4-how-to-get-started-with-odc.mdx b/docs/en/3-guides/3.4-how-to-get-started-with-odc.mdx index e7886073a..3ecb7ee8b 100644 --- a/docs/en/3-guides/3.4-how-to-get-started-with-odc.mdx +++ b/docs/en/3-guides/3.4-how-to-get-started-with-odc.mdx @@ -17,7 +17,7 @@ ODC has three roles: - **Group Manager**: manages one or more groups and the data collected by those groups. - **Standard User**: starts sessions and administers instruments. -For the complete permission model, see the [Security reference](/en/docs/reference/security/). +For the complete permission model, see the [Security reference](/en/docs/reference/security/). For the permissions each page needs, see [How to Configure Permissions](/en/docs/guides/how-to-configure-permissions/). ## Before You Start diff --git a/docs/en/3-guides/3.5-how-to-configure-permissions.mdx b/docs/en/3-guides/3.5-how-to-configure-permissions.mdx new file mode 100644 index 000000000..419a1e8c5 --- /dev/null +++ b/docs/en/3-guides/3.5-how-to-configure-permissions.mdx @@ -0,0 +1,143 @@ +--- +title: How to Configure Permissions +slug: en/docs/guides/how-to-configure-permissions +sidebar: + order: 5 +--- + +import { Steps } from '@astrojs/starlight/components'; + +This guide is for admins. It explains how to give users access beyond their role, and lists the permissions each page needs, with the Data Hub in detail. For the security model behind it, see the [Security reference](/en/docs/reference/security/). + +## How a User's Permissions Are Made Up + +A user's permissions come from two layers: + +1. Their **base permission level** (Admin, Group Manager or Standard), chosen when the user is created. Each level grants a fixed set of permissions, listed under [Default Permissions](#default-permissions). +2. Either a **permission set** or **custom permissions**, added on top of the base level. A permission set is a named list of rules that several users can share. Custom permissions belong to one user. A user has one or the other, never both. + +Permissions only add access. Nothing you configure removes what the base level grants. Only an admin can change permissions, and a change takes effect the next time the user signs in. + +Admins already hold every permission, so there is nothing to add for them. + +## Permissions + +A permission is an **action** on a **resource**, within a **scope**. + +- **Action:** Read, Create, Update, Delete, or Manage (All), which allows every action on the resource. +- **Resource:** Assignment, Group, Instrument, Instrument Record, Instrument Repository, Session, Subject, User, or All. +- **Scope:** the groups the permission applies to. A custom permission applies to one of the user's groups or to **All Groups**. A permission set rule applies to **Every group** or to the **Holder's groups**, meaning the groups each user holding the set belongs to when they sign in. + +Some combinations are restricted: + +- An Instrument permission has no scope. It always applies to every group. +- On User, only Read has any effect, since only an admin can create, modify or delete users. +- Manage (All) on All makes the user an admin. A permission set cannot contain it. +- A custom permission scoped to a group is removed when the user leaves that group. + +Choose the narrowest scope that works. The Data Hub shows one group at a time, the one selected in the group switcher, and a user who is not an admin can only select groups they belong to. A permission scoped to the user's own group is therefore usually enough for the Data Hub. + +## Give a User Custom Permissions + + + +1. **Open the user** + + Go to **Admin Panel** > **Access** > **Users** and select the user. + +2. **Choose Custom** + + In the **Permissions** card, select the **Custom** tab. If the user holds a permission set, saving custom permissions removes it. + +3. **Add each permission** + + In the empty row at the bottom of the table, choose the **Action**, **Resource** and **Scope**. Select **+** to add another row. + +4. **Save** + + Select **Save Changes**. The user gets the new permissions the next time they sign in. + + + +## Share Permissions with a Permission Set + +Use a permission set when several users need the same additional permissions. Editing the set later changes the permissions of every user who holds it. + + + +1. **Create the set** + + Go to **Admin Panel** > **Access** > **Permission Sets** and select **Add Permission Set**. Give it a **Name**, then add its **Rules**, choosing the action, resource and scope for each. Select **Create**. + +2. **Give it to users** + + Open each user under **Admin Panel** > **Access** > **Users**. In the **Permissions** card, select the **Permission set** tab, choose the set, and select **Save Changes**. You can also choose a set when creating a user. + + + +## What Each Page Needs + +### Navigation + +Each item appears in the navigation only when the user has the permissions listed. Some items also depend on how the instance is configured. + +| Item | Permissions | Also requires | +| ------------------------------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| **Dashboard** | Read Instrument, Read Instrument Record, Read Subject and Read User | Its figures also need Read Session | +| **Data Hub** > **Subjects** | Read Subject and Read Instrument Record | | +| **Data Hub** > **Instruments** | Read Subject, Read Instrument Record and Read Instrument | | +| **Upload Data** | Read Subject and Create Instrument Record | **Enable Uploader** under **Admin Panel** > **Instance** > **Settings** | +| **Manage Group** | Manage (All) on Group | A group selected in the group switcher | +| **Email Templates** | Manage (All) on Group | A configured mail server, gateway support, and a group selected | +| **Remote Assignments** (create and delete) | Create Assignment, Read Assignment and Read Subject | **Enable Remote Assignments** under **Admin Panel** > **Instance** > **Settings**, gateway support, and a group selected | +| **Admin Panel** | Manage (All) on All, which only admins hold | | +| **Start Session** | Create Session | | +| **Administer Instrument** | Create Instrument Record | An active session | +| **Remote Assignment** | Create Assignment | Gateway support and an active session | +| **View Current Subject** | Read Subject and Read Instrument Record | An active session | + +### Data Hub + +The Data Hub navigation item only checks the permissions listed above, but each page loads its own data, and a page the user lacks a permission for shows an error. To give someone working access to the Data Hub, make sure they have everything in this table. + +| Page or action | Permissions | +| -------------------------------------------- | ------------------------------------------------------------------------------- | +| Subjects list, subject lookup and **Export** | Read Subject and Read Instrument Record | +| A subject's **Table** and **Graph** tabs | Read Subject, Read Instrument Record and Read Instrument | +| A single record | Read Subject, Read Instrument Record and Read Instrument | +| The files attached to a file record | Group Manager or Admin base level (cannot be granted) | +| A subject's **Assignments** tab | Read Assignment and Read Instrument (the tab appears only with gateway support) | +| Cancelling or emailing an assignment | Update Assignment | +| Instruments list | Read Instrument and Read Instrument Record | +| An instrument's **Table** and **Graph** tabs | Read Instrument and Read Instrument Record | + +Every page shows only data from the group selected in the group switcher, and only for groups the user's permissions cover. + +### Example: Data Hub Access for a Standard User + +A Standard user can already read subjects and instruments in their groups, but not instrument records, so they do not see the Data Hub. To give them read-only access to their group's data: + +1. Add **Read** on **Instrument Record**, scoped to their group. This shows **Data Hub** and the **Dashboard**, and makes the subject and instrument pages work. +2. If gateway support is enabled, also add **Read** on **Assignment**, scoped to their group, so the **Assignments** tab works. + +They still cannot see files attached to file records, which requires the Group Manager or Admin base level. + +## Default Permissions + +Except on Instrument, the Read, Manage (All) and Delete permissions below apply only within the user's groups. Instruments are shared, so Read Instrument covers every instrument. + +| Resource | Group Manager | Standard | +| ----------------------- | ----------------------------------------------- | ---------------------- | +| Assignment | Manage (All) | None | +| Group | Manage (All) | Read | +| Instrument | Read, Create, Delete series made in their group | Read | +| Instrument Record | Read, Create | Create | +| Instrument record files | Read, Create | Create | +| Instrument Repository | Read | None | +| Session | Read, Create | Read, Create | +| Subject | Read, Create | Read, Create | +| User | Read | Read their own account | + +Instrument record files are not a resource you can choose in a permission; only the base level grants them. + +Admins hold Manage (All) on All. A user with no base permission level starts with nothing and has only what their permission set or custom permissions give them. diff --git a/docs/en/5-reference/5.1-security.md b/docs/en/5-reference/5.1-security.md index 14677cba6..f98985ad4 100644 --- a/docs/en/5-reference/5.1-security.md +++ b/docs/en/5-reference/5.1-security.md @@ -33,7 +33,7 @@ When creating a user, a default set of permissions _may_ be assigned based on th 2. Group Manager 3. Standard User -If no role is specified, then the user is created with no permissions. In this case, an admin can apply additional, custom permissions to this user, or link them to a [permission set](#permission-sets). +If no role is specified, then the user is created with no permissions. In this case, an admin can apply additional, custom permissions to this user, or link them to a [permission set](#permission-sets). For step-by-step instructions and the permissions each page needs, see [How to Configure Permissions](/en/docs/guides/how-to-configure-permissions/). After validating the access token, the server checks whether the user has authorization to perform the selected action (`create`, `read`, `update`, or `delete`) on the subject (e.g., `Group`). These are specified on a per-route basis. If a route does not have any required permission set specified, the user must have permission to manage all resources to have access (i.e., the platform admin). If the user does not have adequate permissions, HTTP status 403 is returned. From 71abd686ae035ed53c041f8b34b2b304ffef4d29 Mon Sep 17 00:00:00 2001 From: joshunrau Date: Tue, 10 Nov 2026 15:48:50 -0500 Subject: [PATCH 2/2] chore: scope finishing-changes checks to what a diff can break A diff confined to files no check reads, to the outreach site, or to unit tests now runs only the checks that can reach it instead of the full `pnpm check`. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/finishing-changes/SKILL.md | 10 ++++++++++ AGENTS.md | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.agents/skills/finishing-changes/SKILL.md b/.agents/skills/finishing-changes/SKILL.md index 922d023cf..dd3cffecd 100644 --- a/.agents/skills/finishing-changes/SKILL.md +++ b/.agents/skills/finishing-changes/SKILL.md @@ -8,6 +8,16 @@ pull request. A PR with a failing check is never acceptable. A check you cannot line in your reply naming it and why. A failure unrelated to your change is not yours to patch over: file it with `.agents/skills/opening-issues/SKILL.md` and name the issue in your reply. +**A diff confined to these rows runs the row's checks in place of step 1**, then continues from step 7 (step 3 +for unit tests). A diff spanning rows runs each row's checks; any other file means the full list. + +| Files | Checks | +| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| `AGENTS.md`, `.agents/`, `.claude/`, `.vscode/`, `.editorconfig`, READMEs | None: nothing reads them | +| `.github/workflows/` | None locally: the pull request's CI run is the check | +| `/docs`, `/blog`, `apps/outreach` | `pnpm --filter @opendatacapture/outreach lint`, then `build`; no e2e reaches it | +| Unit tests (`__tests__/`, a package's `test/`) | `pnpm lint` and `pnpm test:coverage`; the apps never load them | + 1. **Run `pnpm check` from the repo root** and fix every failure, a coverage shortfall included. It runs `pnpm lint`, `pnpm test:coverage` and `pnpm test:e2e` in sequence, so a lint failure hides the rest until it is fixed. `pnpm test:e2e` needs its browsers installed once per machine diff --git a/AGENTS.md b/AGENTS.md index f7ed0973f..dc06b835c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -39,7 +39,7 @@ not every tool loads nested files. - **Ask before writing code if the task is ambiguous** or its stated scope cannot accomplish the goal. - **A change is not done until `.agents/skills/finishing-changes/SKILL.md` has run green.** It runs - `pnpm check` and the checks a green run does not prove. + `pnpm check` and the checks a green run does not prove, unless otherwise specified in that file. - **Adding a dependency follows `.agents/skills/adding-dependencies/SKILL.md`**, which starts with asking in-conversation. - **Unit test coverage stays at 100%.** `pnpm test:coverage` fails below 100% statements, branches,