Prevent downgraded incident authors from managing metric images
What does this MR do and why?
The EE issuable policy in ee/app/policies/ee/issuable_policy.rb granted update_issuable_metric_image and delete_issuable_metric_image to the issuable's author regardless of their current role. Updating an incident itself requires at least the Reporter role. This left a gap: a user who created an incident while a Reporter, then got downgraded to Planner or Guest, kept the ability to update and delete that incident's metric images through the REST API. Uploading was not affected. Planners and Guests who did not author the incident were already denied.
This MR adds a new incident-scoped prevent rule to the EE issuable policy: rule { is_incident & ~can?(:update_issue) } blocks update_issuable_metric_image and delete_issuable_metric_image. Managing metric images on an incident now requires at least the Reporter role, matching the incident's own edit permission. Regular, non-incident issues are unchanged and keep the existing author-based rule, per the product decision on the related issue.
Tests: a new incident context in ee/spec/policies/issue_policy_spec.rb covering Guest, Planner, and Reporter, including the author case. In ee/spec/requests/api/issues_spec.rb, the PUT and DELETE permission tables are corrected, since the previous :guest | true rows asserted the old author behavior, and Planner rows are added for the POST, PUT, and DELETE metric image endpoints.
Docs: doc/user/permissions.md gains a "Manage incident metric images" row (Reporter and above). doc/operations/incident_management/incidents.md gains a Prerequisites note under Metrics requiring at least the Reporter role.
Two commits: one for the policy change and specs, one docs-only.
References
Related issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/536635
The issue is confidential, so readers outside GitLab may not be able to open it. It carries the security-fix-in-public label, which is why this MR is on the canonical project.
Screenshots or screen recordings
No UI changes.
How to set up and validate locally
-
Metric images (
incident_metric_upload) is a Premium and Ultimate licensed feature. Make sure your GDK has a Premium or Ultimate license. -
Create a private project.
-
Add a test user as Reporter on the project.
-
As that user, create an incident, either through Monitor > Incidents > New incident, or by creating an issue with type Incident.
-
Create a personal access token for that user with the
apiscope. -
Upload a metric image:
curl --request POST --header "PRIVATE-TOKEN: <token>" \ --form "file=@/path/to/chart.png" \ "https://gitlab.example.com/api/v4/projects/<project_id>/issues/<incident_iid>/metric_images" -
Note the returned image
idin the response. -
Downgrade the user to Planner in Manage > Members.
-
Repeat the update and delete requests and confirm both return 403 Forbidden:
curl --request PUT --header "PRIVATE-TOKEN: <token>" \ --form "url_text=Updated" \ "https://gitlab.example.com/api/v4/projects/<project_id>/issues/<incident_iid>/metric_images/<image_id>" curl --request DELETE --header "PRIVATE-TOKEN: <token>" \ "https://gitlab.example.com/api/v4/projects/<project_id>/issues/<incident_iid>/metric_images/<image_id>" -
Promote the user back to Reporter and confirm the same requests succeed.
-
Run the specs:
bin/rspec ee/spec/policies/issue_policy_spec.rb bin/rspec ee/spec/requests/api/issues_spec.rb