Add "Archive group" as a customizable permission

Problem

A custom role can be granted "Delete subgroup" (remove_group), but there is no custom ability for archiving a group.

That leaves the permission model backwards. Deleting a subgroup is destructive and needs a retention window to recover from. Archiving is reversible: it makes the group and its contents read-only, and you can unarchive at any time. Today, if you want to delegate group lifecycle management to a non-Owner, the only ability you can give them is the destructive one.

The equivalent already exists for projects. archive_project has been a custom ability since 16.6, alongside remove_project.

Current behaviour

  • archive_group is defined in config/authz/permissions/group/archive.yml and enforced in Namespaces::Groups::ArchiveService, Namespaces::Groups::UnarchiveService, and POST /groups/:id/archive / POST /groups/:id/unarchive.
  • archive_group is granted only through the Owner role (config/authz/roles/owner.yml).
  • ee/config/custom_abilities/ has archive_project.yml but no group equivalent.
  • ee/config/custom_abilities/remove_group.yml grants delete_subgroup, which EE::GroupPolicy turns into remove_group. It does not grant archive_group.

The two abilities only overlap at view_edit_page in GroupPolicy, which renders the settings page but does not authorize the archive action.

Proposal

Add an archive_group custom ability so it can be assigned to a custom role independently of "Delete subgroup".

  • New ee/config/custom_abilities/archive_group.yml with group_ability: true, enabled_for_group_access_levels: [50], and group_permissions: [archive_group, unarchive_group].
  • No policy changes are needed. EE::GroupPolicy already iterates MemberRole.all_customizable_group_permissions and enables each ability's declared group_permissions.
  • No migration is needed. member_roles.permissions is a jsonb column.

Acceptance criteria

  • A custom role based on any role below Owner can be given the archive_group ability.
  • A member holding that role can archive and unarchive a group through the REST API and GraphQL.
  • The ability does not grant deletion.
  • Generated docs (doc/user/custom_roles/abilities.md, GraphQL reference) list the new ability.
  • #425957 (closed) — added archive_project as a custom ability in 16.6. The direct precedent for this proposal.
  • #470604 (closed) — earlier duplicate request for the project-level ability.
  • #597400 — open request to split unarchive_project out of archive_project, so archiving and unarchiving can be granted separately. The same question applies here: POST /groups/:id/archive and POST /groups/:id/unarchive both authorize archive_group, so one ability covers both directions. If that issue lands a split for projects, groups should follow the same shape.
Edited by Jimmy Spagnola