Jump to content

RefractTrack Permissions and Roles: Difference between revisions

From Pixel Refraction Studio
Created page with "== Permissions and Roles == RefractTrack uses a full role-based access control (RBAC) system. There is no longer a fixed "Member vs. Reporter" split baked into the code — that distinction now exists only as a seeded, ordinary, fully-editable '''Reporter''' role preset, like any other role. === Permission keys === <code><nowiki>includes/permissions.php</nowiki></code>'s <code><nowiki>PERMISSION_DEFS</nowiki></code> is the single source of truth for every permission k..."
 
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Permissions and Roles ==
== Permissions and Roles ==


RefractTrack uses a full role-based access control (RBAC) system. There is no longer a fixed "Member vs. Reporter" split baked into the code — that distinction now exists only as a seeded, ordinary, fully-editable '''Reporter''' role preset, like any other role.
Not everyone on a team needs (or should have) the same level of access. RefractTrack lets an admin control, in fine detail, exactly what each teammate can see and do — from full admins down to a playtester who can only submit bug reports.


=== Permission keys ===
[[File:RefractTrack_Roles.png|border|center|700px|Roles are reusable permission presets you can apply to a teammate in one click.]]


<code><nowiki>includes/permissions.php</nowiki></code>'s <code><nowiki>PERMISSION_DEFS</nowiki></code> is the single source of truth for every permission key that can exist. Adding a new permission is a code change, never a database migration.
=== What can be controlled ===


{| class="wikitable"
Access can be granted separately for each area of the app, including:
! Category !! Key !! Meaning
|-
| tasks || <code><nowiki>tasks:view</nowiki></code> || View tasks on the board or list
|-
| tasks || <code><nowiki>tasks:report</nowiki></code> || Report tickets through the simplified reporter form
|-
| tasks || <code><nowiki>tasks:create</nowiki></code> || Create new tasks with full features
|-
| tasks || <code><nowiki>tasks:bulkcreate</nowiki></code> || Use the bulk task creation tool
|-
| tasks || <code><nowiki>tasks:edit:content</nowiki></code> || Edit a task's content (title, description, type, priority, groups)
|-
| tasks || <code><nowiki>tasks:edit:stage</nowiki></code> || Move tasks between stages (also allows setting the assignee and due date)
|-
| tasks || <code><nowiki>tasks:review</nowiki></code> || Approve, reject, or reset a task's review status
|-
| tasks || <code><nowiki>tasks:delete</nowiki></code> || Permanently delete tasks
|-
| tasks || <code><nowiki>tasks:archive</nowiki></code> || Archive or unarchive tasks
|-
| tasks || <code><nowiki>tasks:clone</nowiki></code> || Clone existing tasks
|-
| comments || <code><nowiki>comments:view</nowiki></code> || View comments on tasks
|-
| comments || <code><nowiki>comments:create</nowiki></code> || Post comments on tasks
|-
| comments || <code><nowiki>comments:edit</nowiki></code> || Edit your own comments after posting (admins can edit anyone's)
|-
| attachments || <code><nowiki>attachments:view</nowiki></code> || View attachments on tasks
|-
| attachments || <code><nowiki>attachments:create</nowiki></code> || Upload new attachments to tasks
|-
| attachments || <code><nowiki>attachments:delete</nowiki></code> || Remove attachments from tasks
|-
| projects || <code><nowiki>projects:view</nowiki></code> || View existing projects
|-
| projects || <code><nowiki>projects:create</nowiki></code> || Create new projects
|-
| projects || <code><nowiki>projects:edit</nowiki></code> || Edit existing projects
|-
| projects || <code><nowiki>projects:activate</nowiki></code> || Activate or deactivate projects
|-
| stages || <code><nowiki>stages:view</nowiki></code> || View existing stages
|-
| stages || <code><nowiki>stages:create</nowiki></code> || Create new stages
|-
| stages || <code><nowiki>stages:edit</nowiki></code> || Edit existing stages
|-
| stages || <code><nowiki>stages:reorder</nowiki></code> || Reorder stages
|-
| stages || <code><nowiki>stages:delete</nowiki></code> || Delete stages
|-
| groups || <code><nowiki>groups:view</nowiki></code> || View existing groups
|-
| groups || <code><nowiki>groups:create</nowiki></code> || Create new groups
|-
| groups || <code><nowiki>groups:edit</nowiki></code> || Edit existing groups
|-
| groups || <code><nowiki>groups:delete</nowiki></code> || Delete existing groups
|-
| lists || <code><nowiki>lists:view</nowiki></code> || View bulk-create saved lists
|-
| lists || <code><nowiki>lists:create</nowiki></code> || Create bulk-create saved lists
|-
| lists || <code><nowiki>lists:edit</nowiki></code> || Edit bulk-create saved lists
|-
| backups || <code><nowiki>backups:export</nowiki></code> || Export a project as JSON or CSV
|-
| backups || <code><nowiki>backups:import</nowiki></code> || Import a project from JSON or CSV
|-
| themes || <code><nowiki>themes:change</nowiki></code> || Change the application's color theme
|-
| themes || <code><nowiki>themes:brand</nowiki></code> || Change the application's name/branding
|-
| users || <code><nowiki>users:view</nowiki></code> || View existing users
|-
| users || <code><nowiki>users:create</nowiki></code> || Create new users (including their permissions and projects)
|-
| users || <code><nowiki>users:edit:contents</nowiki></code> || Edit a user's display name and password (usernames can't be changed after creation)
|-
| users || <code><nowiki>users:edit:permissions</nowiki></code> || Edit the permissions granted to a user
|-
| users || <code><nowiki>users:edit:projects</nowiki></code> || Edit which projects a user has access to
|-
| users || <code><nowiki>users:activate</nowiki></code> || Activate or deactivate users
|-
| roles || <code><nowiki>roles:view</nowiki></code> || View existing role presets
|-
| roles || <code><nowiki>roles:create</nowiki></code> || Create new role presets
|-
| roles || <code><nowiki>roles:edit</nowiki></code> || Edit existing role presets
|-
| roles || <code><nowiki>roles:delete</nowiki></code> || Delete role presets
|}


=== Implied permissions ===
* '''Tasks''' — viewing, creating, editing content, moving between columns, reviewing, archiving, cloning, and deleting
* '''Comments''' — viewing, posting, and editing
* '''Attachments''' — viewing, uploading, and removing files
* '''Projects''' — viewing, creating, editing, and deactivating
* '''Stages and Groups''' — viewing and managing a project's columns and tags
* '''Saved lists''' — viewing and managing bulk-create lists
* '''Export and import''' — backing a project up or bringing data in
* '''Themes and branding''' — changing the app's look and name
* '''Users and roles''' — managing teammates and the roles they can be assigned


Holding a more capable permission implies holding the corresponding <code><nowiki>:view</nowiki></code> permission, so granting <code><nowiki>tasks:create</nowiki></code> also grants <code><nowiki>tasks:view</nowiki></code> without a separate step, and so on for essentially every noun/verb pair above. Two deliberate exceptions:
Broader access always includes the narrower access it depends on — for example, being able to create tasks automatically means being able to view them too, so nobody ends up able to create something they can't then see.


* <code><nowiki>tasks:report</nowiki></code> implies nothing — it's the stripped-down reporter flow, not real task visibility.
=== Roles make this easy ===
* <code><nowiki>tasks:bulkcreate</nowiki></code> additionally implies <code><nowiki>lists:view</nowiki></code> (it needs to ''read'' saved lists, not manage them), on top of the usual <code><nowiki>tasks:view</nowiki></code>.


This is an explicit map, not something derived by pattern-matching the permission name, precisely to allow exceptions like these.
Rather than setting every permission by hand for every person, an admin can define named '''roles''' — like "Reporter" or "Team Lead" — as reusable presets, then apply one to a teammate in a single click. Applying a role copies its permissions onto that person at that moment; if the role is edited later, it won't retroactively change anyone it was already applied to, so nobody's access shifts under them unexpectedly. Individual permissions can still be fine-tuned per person afterward, on top of whatever role they started from.


=== Role presets ===
=== Admins see everything ===


* <code><nowiki>roles</nowiki></code> / <code><nowiki>role_permissions</nowiki></code> named presets (e.g. "Reporter"), managed from Manage → Roles.
A full admin account bypasses these checks entirely and always has complete access including to anything added in a future update, with nothing extra to configure.
* <code><nowiki>roles.is_system = 1</nowiki></code> is reserved for the built-in '''Admin''' role.
* Applying a role preset to a user (<code><nowiki>apply_role_to_user()</nowiki></code>) is a '''one-time copy''' into that user's own permission grants — not a live link. Editing a role afterward does not retroactively change users the preset was previously applied to.


=== Per-user permissions ===
=== Access can be limited per project ===


<code><nowiki>user_permissions</nowiki></code> is the actual, live source of truth for every non-admin user's grants — independent of whatever role preset (if any) was used to seed them.
For sensitive actions — working with tasks, comments, attachments, and backups — access can also be limited to specific projects. That means someone can be fully trusted to edit tasks in general, but still not see a project they haven't been given access to. Reporting a bug through the simplified ticket form works the other way around: by default a reporter can't submit anywhere until they're explicitly given access to at least one project, so a brand-new reporter account can't accidentally end up able to file into everything.


=== Admin bypass ===
Managing columns, tags, and saved lists, on the other hand, is a broader, team-wide grant rather than something scoped per project — someone either can manage these across the board, or they can't; it's just which project's columns or tags they happen to be looking at that changes from page to page.


<code><nowiki>users.is_admin</nowiki></code> is a bypass flag, not a materialized permission list. The core authorization check (<code><nowiki>user_can()</nowiki></code>) short-circuits to true for admins on every check, so a newly-added permission automatically applies to every admin user with no data migration needed.
=== You can't grant more than you have ===


=== Project-scoped permissions ===
Nobody can hand out a permission they don't hold themselves whether they're setting up a teammate's account or building a role preset and nobody can change their own permissions, even if they'd otherwise be allowed to manage everyone else's. Both are enforced automatically, not just hidden from view, so there's no way to accidentally (or deliberately) work around them from the account-editing screen.
 
Most permissions are additionally checked against <code><nowiki>user_project_access</nowiki></code> — a user can hold a permission globally but still be denied for a specific project they lack access to:
 
'''Checked per-project (default-allow granted globally unless a project access row restricts it):'''
<code><nowiki>tasks:view</nowiki></code>, <code><nowiki>tasks:create</nowiki></code>, <code><nowiki>tasks:bulkcreate</nowiki></code>, <code><nowiki>tasks:edit:content</nowiki></code>, <code><nowiki>tasks:edit:stage</nowiki></code>, <code><nowiki>tasks:review</nowiki></code>, <code><nowiki>tasks:delete</nowiki></code>, <code><nowiki>tasks:archive</nowiki></code>, <code><nowiki>tasks:clone</nowiki></code>, <code><nowiki>comments:view</nowiki></code>, <code><nowiki>comments:create</nowiki></code>, <code><nowiki>comments:edit</nowiki></code>, <code><nowiki>attachments:view</nowiki></code>, <code><nowiki>attachments:create</nowiki></code>, <code><nowiki>attachments:delete</nowiki></code>, <code><nowiki>backups:export</nowiki></code>, <code><nowiki>backups:import</nowiki></code>.
 
<code><nowiki>backups:export</nowiki></code>/<code><nowiki>backups:import</nowiki></code> are included here even though they're not "task" permissions by category, because both operate on a project's full task data wholesale — leaving them unscoped would let a restricted user route around the rest of the restriction by simply exporting (or importing into) a project they otherwise can't see.
 
'''Checked per-project (default-deny empty access means zero projects, not "everything"):'''
<code><nowiki>tasks:report</nowiki></code> — preserving the historical reporter-form behavior where a reporter with no explicit project grants can't submit anywhere.
 
'''Deliberately NOT project-scoped:''' <code><nowiki>stages:*</nowiki></code>, <code><nowiki>groups:*</nowiki></code>, and <code><nowiki>lists:*</nowiki></code>, even though the underlying ''data'' they manage (stages, groups, saved lists) is itself project-owned. The ability to manage stages/groups/lists at all remains a global grant; only which project's stages/groups/lists a user is looking at changes per page. This is intentional product precedent, not an oversight — see [[RefractTrack_Stages|Stages]] and [[RefractTrack_Groups|Groups]].


=== Related pages ===
=== Related pages ===
Line 144: Line 43:
* [[RefractTrack_Users|Users]]
* [[RefractTrack_Users|Users]]
* [[RefractTrack_Projects|Projects]]
* [[RefractTrack_Projects|Projects]]
* [[RefractTrack_Security|Security]]
 
[[Category:RefractTrack]]

Latest revision as of 23:00, 11 September 2026

Permissions and Roles

Not everyone on a team needs (or should have) the same level of access. RefractTrack lets an admin control, in fine detail, exactly what each teammate can see and do — from full admins down to a playtester who can only submit bug reports.

Roles are reusable permission presets you can apply to a teammate in one click.
Roles are reusable permission presets you can apply to a teammate in one click.

What can be controlled

Access can be granted separately for each area of the app, including:

  • Tasks — viewing, creating, editing content, moving between columns, reviewing, archiving, cloning, and deleting
  • Comments — viewing, posting, and editing
  • Attachments — viewing, uploading, and removing files
  • Projects — viewing, creating, editing, and deactivating
  • Stages and Groups — viewing and managing a project's columns and tags
  • Saved lists — viewing and managing bulk-create lists
  • Export and import — backing a project up or bringing data in
  • Themes and branding — changing the app's look and name
  • Users and roles — managing teammates and the roles they can be assigned

Broader access always includes the narrower access it depends on — for example, being able to create tasks automatically means being able to view them too, so nobody ends up able to create something they can't then see.

Roles make this easy

Rather than setting every permission by hand for every person, an admin can define named roles — like "Reporter" or "Team Lead" — as reusable presets, then apply one to a teammate in a single click. Applying a role copies its permissions onto that person at that moment; if the role is edited later, it won't retroactively change anyone it was already applied to, so nobody's access shifts under them unexpectedly. Individual permissions can still be fine-tuned per person afterward, on top of whatever role they started from.

Admins see everything

A full admin account bypasses these checks entirely and always has complete access — including to anything added in a future update, with nothing extra to configure.

Access can be limited per project

For sensitive actions — working with tasks, comments, attachments, and backups — access can also be limited to specific projects. That means someone can be fully trusted to edit tasks in general, but still not see a project they haven't been given access to. Reporting a bug through the simplified ticket form works the other way around: by default a reporter can't submit anywhere until they're explicitly given access to at least one project, so a brand-new reporter account can't accidentally end up able to file into everything.

Managing columns, tags, and saved lists, on the other hand, is a broader, team-wide grant rather than something scoped per project — someone either can manage these across the board, or they can't; it's just which project's columns or tags they happen to be looking at that changes from page to page.

You can't grant more than you have

Nobody can hand out a permission they don't hold themselves — whether they're setting up a teammate's account or building a role preset — and nobody can change their own permissions, even if they'd otherwise be allowed to manage everyone else's. Both are enforced automatically, not just hidden from view, so there's no way to accidentally (or deliberately) work around them from the account-editing screen.