Skip to content

Conversation

@ameliahsu
Copy link
Member

system-created monitors should not be deleted by anyone, regardless of permissions

backend fix to go with #103838

closes https://linear.app/getsentry/issue/NEW-646/prevent-api-from-deleting-error-monitor-detectors-via-bulk-edit

@ameliahsu ameliahsu requested a review from a team as a code owner November 21, 2025 19:08
@linear
Copy link

linear bot commented Nov 21, 2025

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Nov 21, 2025
# Filter out system-created detectors from deletion
deletable_detectors = [
detector for detector in queryset if not is_system_created_detector(detector)
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Permission check occurs before filtering system-created detectors

The permission check via can_edit_detectors happens on the full queryset before filtering out system-created detectors. This means if a user's query matches both user-created and system-created detectors, they need org:write permission even though system-created detectors won't actually be deleted. Users with only alerts:write permission are incorrectly denied from deleting their own user-created detectors when system-created detectors are in the queryset. The permission check needs to happen after filtering to deletable_detectors.

Fix in Cursor Fix in Web

)

# Check if the user has edit permissions for all detectors
if not can_edit_detectors(queryset, request):
Copy link
Member

@malwilley malwilley Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should have a can_delete_detectors function for this? We should also lock down the DELETE /detectors/<id>/ endpoint.

I think for this API it would be better if we rejected if any system-created detectors are included in the queryset. That way the results are more consistent (since we already reject if you don't have edit permissions for some of the detectors)

@ameliahsu ameliahsu requested a review from malwilley November 22, 2025 00:18
Comment on lines +86 to +94
def can_delete_detector(detector: Detector, request: Request) -> bool:
"""
Determine if the requesting user has access to delete the given detector.
Only user-created detectors can be deleted, and require "alerts:write" permission.
"""
if is_system_created_detector(detector):
return False

return can_edit_user_created_detectors(request, detector.project)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having 2 functions that do the same thing, you could pass a single detector to can_delete_detectors as a list.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the single detector function is nice because it saves us a lookup from the Project table

@ameliahsu ameliahsu merged commit e1e8ef4 into master Nov 24, 2025
67 checks passed
@ameliahsu ameliahsu deleted the mia/aci/be-prevent-deleting-system-created-monitors branch November 24, 2025 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants