docs: Correct epic permissions across group hierarchies

What does this MR do?

Two documentation pages state different prerequisites for the same action, and one of them is wrong.

doc/user/work_items/child_items.md says, for both "Add an existing issue to an epic" and "Remove an issue from an epic":

You must have the Guest, Planner, Reporter, Developer, Maintainer, or Owner role for the issue's project and the epic's group.

doc/user/permissions.md says, for the "Add issues to an epic" row of the Group planning table (footnote 2):

You must have permission to view the epic and edit the issue.

The second one matches the code. In ee/app/services/ee/work_items/parent_links/create_service.rb, can_add_to_parent? returns can?(current_user, :read_work_item, parent_work_item) when the parent is a group-level epic, under a comment that states the intent:

For legacy epics, we allow to add child items to the epic, when the user only has read access to the group. This could be the case when the group is public, or also when the group is private, but the user has access to a project within the group.

ee/app/services/ee/issues/base_service.rb guards the same relation with can?(current_user, :read_epic, epic) && can?(current_user, :admin_issue_relation, issue).

This MR restates the epic side of both prerequisite blocks as permission to view the epic, which is what the code enforces, and links to the section that defines it.

Two smaller corrections on doc/user/group/epics/manage_epics.md:

  1. "Who can view an epic" and "View epics list" say a viewer can be a member of "a project in one of the group's subgroups". Read plainly, that is one level down. Read access reaches descendant groups at any depth. child_items.md already uses the accurate wording elsewhere, "the epic's group or one of its descendant subgroups", so this aligns the two pages.
  2. "Who can view an epic" does not say what a viewer can then see. The Child items list is filtered to items the viewer can access, and the counts are not. child_items.md already documents this ("The numbers reflect all child work items associated with the epic, including those you might not have permission to view"), but a reader who wants to know who can see an epic is on the other page. This adds a cross-reference, not a new claim.

Why it matters

A reader mapping several organizations onto one group hierarchy needs to know what crosses the boundary: a top-level group, a middle group per organization, lower groups beneath, projects at the bottom. They read "role for the epic's group" as that boundary and design a release-of-information posture around it. The role is not a boundary: a person with a role in one project can attach their issues to an epic several levels above them, and can read that epic's title and description.

The behavior is intended. #208425 (closed) changed the permissions on purpose in 14.5 (!66865 (merged)), and #358612 (closed) asked for the opposite behavior and was closed as won't do. #443534 reported this documentation mismatch on the removal side and was closed as won't do, with the ruling "This is indeed expected behaviour but there is an error in the documentation". #456241 was opened to fix that documentation and has not moved. This MR changes documentation only and asks for no change in the product.

Reproduction

The rule corrected here is read from the master source quoted above, so it does not turn on a release. I also confirmed it by measurement, on a GitLab Self-Managed 19.x Enterprise Edition instance: Linux package (Omnibus), single node, Ultimate license. Epics need Premium or Ultimate, and multi-level child epics need Ultimate.

Minimal setup:

  1. Create a private top-level group top, a private subgroup top/mid, and a private subgroup top/mid/low.
  2. Create a project top/mid/low/app and a second project under a sibling subgroup, top/mid/other/app2.
  3. Create an epic in top/mid and add three children: one issue from top/mid/low/app, one issue from top/mid/other/app2, and one child epic.
  4. Create an epic in top and add the top/mid epic plus children of your choice below it.
  5. Add a user as Developer on top/mid/low/app only. Give them no role in top, top/mid, top/mid/low, or any other project.

Observed with that user's own token:

Request Response
GET /api/v4/groups/top%2Fmid/epics/1 200, with title and description
GET /api/v4/groups/top/epics/1 200, with title and description
Epic in an unrelated top-level group 404
POST /api/v4/groups/top%2Fmid/epics/1/issues/<issue_id> for an issue in top/mid/low/app 201, the issue becomes a child of the top/mid epic

In the epic view for the same user, the Child items section of the top/mid epic listed only the item from top/mid/low/app while the section header count read 3, and the top epic listed 1 item while the header count read 7. Both are consistent with what child_items.md already documents about counts.

The 201 above was observed on the Epic Issues REST endpoint, deprecated since 17.0. The proposed wording states the requirement as permission to view the epic and names no single interface, because that is the condition the code checks on the work-items path as well.

One question for the reviewer

Three more prerequisite blocks on child_items.md carry the same "role for the issue's project and the epic's group" wording: "Create an issue from an epic", "Reorder issues assigned to an epic", and "Move issues between epics". I did not measure those three, so I left them alone. If the same correction applies, say so and I will fold them into this MR.

  • Related to #456241 (Update epic permissions documentation). That issue asks for an audit of every place the epic permissions documentation disagrees with the permissions model. This MR fixes two of them and supplies the measured rule its thread was missing.
  • Context, no change requested: #443534, #208425 (closed), !66865 (merged), #358612 (closed), #505855.

Author's checklist

If you are a GitLab team member and only adding documentation, do not add any of the following labels:

  • ~"frontend"
  • ~"backend"
  • ~"type::bug"
  • ~"database"

These labels cause the MR to be added to code verification QA issues.

Reviewer's checklist

Documentation-related MRs should be reviewed by a Technical Writer for a non-blocking review, based on Documentation Guidelines and the Style Guide.

If you aren't sure which tech writer to ask, use roulette or ask in the #docs Slack channel.

  • If the content requires it, ensure the information is reviewed by a subject matter expert.
  • Technical writer review items:
    • Ensure docs metadata is present and up-to-date.
    • Ensure the appropriate labels are added to this MR.
    • Ensure a release milestone is set.
    • If relevant to this MR, ensure content topic type principles are in use, including:
      • The headings should be something you'd do a Google search for. Instead of Default behavior, say something like Default behavior when you close an issue.
      • The headings (other than the page title) should be active. Instead of Configuring GDK, say something like Configure GDK.
      • Any task steps should be written as a numbered list.
      • If the content still needs to be edited for topic types, you can create a follow-up issue with the docs-technical-debt label.
  • Review by assigned maintainer, who can always request/require the reviews above. Maintainer's review can occur before or after a technical writer review.

AI-Generated Content Disclosure: This MR was prepared with assistance from Claude Code. Every factual claim was verified against master source or a fetched upstream issue, the behavior was confirmed on a GitLab Self-Managed instance, and the wording was checked against the documentation style guide.

Merge request reports

Loading