Remove per-source permission checks from participants

What does this MR do and why?

Context

As part of incident 20931, we reverted previously introduced performance improvements that included removing per-source (!213623 (merged)) (for example, notes or comments) and per-participant (!214345 (merged)) permission checks from the participants API endpoints.

As stated in the post-incident review, both changes were not security vulnerabilities. However, due to a high number of customer support tickets and customers expressing security concerns, we decided to revert both MRs during the incident via !215092 (merged).

Also, as noted in the post-incident review, only one of the two reverted MRs was the cause of the customer support tickets and the incident. That change was the removal of per-participant permission checks, not the removal of per-source permission checks.

Given that, we discussed and decided to reintroduce the per-source permission check removal for performance improvements. This time, the change is being rolled out behind a short-lived de-risk feature flag to allow for a safe rollout and an easy rollback in case of any reports.

Problem

The current participant system performs multiple levels of permission checks:

  1. Per-source checks – validate user access to each individual source, such as notes or comments, before processing
  2. Reference extraction – process accessible content for mentions and references
  3. Confidential content handling – apply separate filtering for confidential notes
  4. Per-participant filtering – apply final access control based on project or group permissions

The per-source permission checks (step 1) create significant performance overhead, especially for issues and merge requests with many comments, as they require database queries for each source to verify user access.

Solution

This change introduces the remove_per_source_permission_from_participants de-risk feature flag, which bypasses the expensive per-source permission checks while keeping the existing per-participant filtering in place. When enabled, it:

  • Skips verify_access checks during participant collection from sources like notes and comments
  • Removes unnecessary database includes for project and system_note_metadata
  • Relies on the final per-participant filtering to ensure only users with appropriate project or group access appear in the participant list
  • Adds permission filtering for confidential work items using the users_that_can_read_confidential_issues method
  • Maintains the same security guarantees while improving performance

References

Screenshots or screen recordings

Before After
Non-member user Screenshot_2025-12-16_at_5.32.41_pm Screenshot_2025-12-16_at_5.31.37_pm
Member user Screenshot_2025-12-16_at_5.29.22_pm Screenshot_2025-12-16_at_5.29.22_pm
Confidential work item Screenshot_2026-01-07_at_8.25.09_pm Screenshot_2026-01-07_at_8.17.26_pm

How to set up and validate locally

  1. Enable the remove_per_source_permission_from_participants feature flag.
  2. Create one public project and one private project.
  3. As a non-member user, create an issue in the public project.
  4. As a member user, create an issue in the private project and add a comment that includes a link to the public issue.
  5. Visit the public issue as a non-member user; the participant list should show 2 participants, including the comment author from the private issue.
  6. Visit the public issue as a member user; the participant list should also show 2 participants.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Agnes Slota

Merge request reports

Loading