Add granular token authorization to Compliance & governance mutations

What does this MR do?

Adds granular (fine-grained) Personal Access Token authorization to the GraphQL mutations in Group 3 — Compliance & governance of the authorization todo list, following the GraphQL implementation guide.

For each mutation it adds an authorize_granular_token directive, the required raw/assignable permission definitions, and a shared-example authorization test per declared boundary. The corresponding mutation: lines are removed from config/authz/graphql/authorization_todo.txt.

27 of the 28 group mutations are covered. BulkUpdateSecurityAttributes is intentionally left in the todo list (see Skipped below).

Mutation → permission → boundary

Mutation Permission Boundary
CreateComplianceFramework create_compliance_framework group (namespace_path)
CreateComplianceFrameworkFromTemplate create_compliance_framework group (namespace_path)
UpdateComplianceFramework update_compliance_framework group (idnamespace)
DestroyComplianceFramework delete_compliance_framework group (idnamespace)
CreateComplianceRequirement create_compliance_requirement group (compliance_framework_idnamespace)
UpdateComplianceRequirement update_compliance_requirement group (idnamespace)
DestroyComplianceRequirement delete_compliance_requirement group (idnamespace)
CreateComplianceRequirementsControl create_compliance_requirements_control group (compliance_requirement_idnamespace)
UpdateComplianceRequirementsControl update_compliance_requirements_control group (idnamespace)
DestroyComplianceRequirementsControl delete_compliance_requirements_control group (idnamespace)
LinkProjectComplianceViolationIssue update_compliance_violations_report project (violation_idproject)
UnlinkProjectComplianceViolationIssue update_compliance_violations_report project (violation_idproject)
UpdateProjectComplianceViolation update_compliance_violations_report project (idproject)
ProjectSetComplianceFramework update_compliance_framework project (project_id)
ProjectUpdateComplianceFrameworks update_compliance_framework project (project_id)
RefreshStandardsAdherenceChecks read_compliance_dashboard group (group_path)
SecurityAttributeCreate create_security_attribute group (namespace_id)
SecurityAttributeUpdate update_security_attribute group (idnamespace)
SecurityAttributeDestroy delete_security_attribute group (idnamespace)
SecurityAttributeProjectUpdate update_security_attribute project (project_id)
SecurityCategoryCreate create_security_category group (namespace_id)
SecurityCategoryUpdate update_security_category group (namespace_id)
SecurityCategoryDestroy delete_security_category group (idnamespace)
MemberRoleDelete delete_member_role group (idnamespace) + instance
MemberRoleUpdate update_member_role group (idnamespace) + instance
MemberRoleToUserAssign assign_member_role instance
GroupMembersExport read_member group (group_id)

Permissions: created vs reused

Reused (no new assignable created where possible):

  • read_member — reused existing raw + assignable (system_access/member/read) for GroupMembersExport.
  • delete_member_role — reused existing raw + assignable (groups/member_role/delete).
  • update_compliance_violations_report — raw permission already existed; bundled into a new assignable so it is grantable to granular tokens.

New raw permissions (17): create/update/delete_compliance_framework, create/update/delete_compliance_requirement, create/update/delete_compliance_requirements_control, read_compliance_dashboard, create/update/delete_security_attribute, create/update/delete_security_category, update_member_role, assign_member_role.

New assignable permissions (10): nested resources are bundled into their parent resource's per-verb assignable rather than standalone assignables, following the multi-raw pattern used by update_merge_request/create_work_item. The create/update/delete_compliance_requirement and ..._compliance_requirements_control raws join the matching create/update/delete_compliance_framework bundle, and create/update/delete_security_category join create/update/delete_security_attribute. Raw permission names and mutation directives are unchanged — only assignable membership moved. The resulting new assignables are create/update/delete_compliance_framework, read_compliance_dashboard, update_compliance_violations_report, create/update/delete_security_attribute, update_member_role, and assign_member_role. update_compliance_framework and update_security_attribute span group + project boundaries; update_member_role spans group + instance; assign_member_role is instance-only.

Judgment calls

  • ProjectSet/UpdateComplianceFramework reuse update_compliance_framework at the project boundary (assigning frameworks to a project is a framework update scoped to the project) rather than introducing a boundary-encoded permission.
  • RefreshStandardsAdherenceChecks reuses read_compliance_dashboard, matching the mutation's existing authorize :read_compliance_dashboard ability (it recomputes data gated by dashboard read access).
  • GroupMembersExport uses read_member (a bulk read of member data).
  • Member role update/delete follow the merged MemberRoleCreate pattern (group + instance boundaries; instance-level roles resolve namespace to nil and fall through to the standalone instance boundary).

Skipped

  • BulkUpdateSecurityAttributes — left in the todo list. Its items argument is a mixed array of Group and Project global IDs. The granular-token BoundaryExtractor resolves a single GlobalID/path per boundary_argument and returns nil for array arguments, so no single boundary can be derived. Documenting rather than forcing an incorrect boundary.

How validated

  • bundle exec rake gitlab:permissions:validate — passes.
  • bundle exec rake gitlab:permissions:graphql:compile_docs and ...:routes:compile_docs — regenerated doc/auth/tokens/fine_grained_access_tokens_graphql.md and the member role description line in the REST doc; both committed.
  • Authorization specs run in CI (not run locally).

See the implementation guide.

Edited by Alex Buijs

Merge request reports

Loading
Loading