Add audit event for group permanent deletion request
Summary
When a group is permanently deleted, there is no audit event written to record that the permanent deletion was requested. This creates a gap in the audit trail that is particularly significant for large groups where the deletion worker may run for an extended period.
Current Behaviour
The group deletion flow produces the following audit events:
group_deletion_marked- written when the soft delete is requested (group enters pending deletion state)group_destroyed- written only afterGroupDestroyWorkerhas fully completed and the group record no longer exists in the database
There is no audit event written at the point that permanent deletion is explicitly requested (i.e. when permanently_remove=true is passed to GroupsController#destroy).
The permanent deletion request is captured in production_json.log as an HTTP request entry, but this is a request log and is not surfaced in the audit UI or audit events API.
Impact
For large groups containing many projects, GroupDestroyWorker can run for an extended period - potentially many hours. During this time:
- The audit UI shows only
group_deletion_marked, giving no indication that permanent deletion has been requested or is in progress - Administrators have no audit trail evidence that permanent deletion was explicitly triggered, as distinct from the scheduled background job that runs after the retention period expires
- If the worker is interrupted before completion,
group_destroyedis never written, leaving the audit trail with only the soft delete event and no record of the permanent deletion request
This makes it difficult to:
- Distinguish between a user-initiated permanent deletion and the scheduled retention-period job
- Determine when permanent deletion was requested in cases where the worker runs for a long time or is interrupted
- Provide a complete audit trail for compliance purposes
Expected Behaviour
An audit event should be written at the point that permanent deletion is requested, before GroupDestroyWorker begins execution. This event should be written regardless of whether the worker completes successfully or is interrupted.
A suitable event name would be group_permanent_deletion_requested or similar, consistent with the existing naming convention.
Code Reference
The group_deletion_marked audit event is written in ee/app/services/ee/namespaces/mark_for_deletion_base_service.rb via log_event. An equivalent audit event for permanent deletion should be written in Groups::DestroyService or EE::Groups::DestroyService at the point execution begins, prior to any destructive operations.
The group_destroyed audit event is written in ee/app/services/ee/groups/destroy_service.rb in log_audit_event, which is only called after group&.persisted? returns false. This confirms that no audit event currently covers the initiation of permanent deletion.
Proposal
Add a new audit event, for example group_permanent_deletion_requested, written at the start of Groups::DestroyService#execute or unsafe_execute, before any projects or subgroups are destroyed. This would ensure the audit trail captures:
group_deletion_marked- soft delete requestedgroup_permanent_deletion_requested- permanent deletion initiated (new)group_destroyed- permanent deletion completed (written only on successful completion)
This would provide a complete and accurate audit trail for the full lifecycle of a group deletion, including long-running or interrupted deletions.