Let fine-grained tokens read the Deploy GraphQL types

What does this MR do and why?

Without an authorize_granular_token directive, a fine-grained personal access token gets no data from 28 Deploy types and cannot run ClusterAgentTokenRevoke. Each now declares one and leaves authorization_todo.txt:

  • Eleven types take their REST endpoints' permission on their own project or group (table below). DeploymentApproval takes its own because a group's approval rules return it too, and reads its project through the deployment, since a database trigger sets the project_id of a new approval.
  • ClusterAgentTokenRevoke takes revoke_cluster_agent_token on the token's project, as its REST endpoint does; the agents resolver preloads the tokens' project.
  • The resolvers of Project.releases, Group.releases, Project.nestedEnvironments and three agent fields check read_release, read_environment or read_cluster_agent, as for the user; an object of another project needs it there too.
  • The 17 types returned only below Release, ClusterAgent, Deployment or those fields take their parent's permission with parent_authorizes:, as GET /projects/:id/releases returns a release's assets, links and evidences.
Each type, its parents and its directive

Without the permission, the release lists are null, and ApproveDeployment and ClusterAgentTokenCreate return no approval or token.

Types Returned by Directive
Release Project.releases, Project.release, Group.releases, Milestone.releases, the release mutations read_release, project
ReleaseAssets, ReleaseLinks, ReleaseEvidence, ReleaseSource, ReleaseAssetLink Release, directly or nested; ReleaseAssetLink also the three link mutations parent_authorizes: :read_release
Deployment Project.deployment, Environment.deployments, Environment.lastDeployment read_deployment, project
DeploymentTag, DeploymentApprovalSummary, DeploymentPermissions Deployment parent_authorizes: :read_deployment
DeploymentApproval Deployment.approvals, ProtectedEnvironmentApprovalRuleForSummary.approvals, ApproveDeployment read_deployment, project
ProtectedEnvironment Environment.protectedEnvironments read_protected_environment, project or group
ProtectedEnvironmentDeployAccessLevel, ProtectedEnvironmentApprovalRule, ProtectedEnvironmentApprovalRuleForSummary ProtectedEnvironment; the last DeploymentApprovalSummary.rules read_protected_environment, project or group
NestedEnvironment Project.nestedEnvironments (read_environment on its resolver) parent_authorizes: :read_environment
FeatureFlag WorkItemWidgetDevelopment.featureFlags read_feature_flag, project
GroupReleaseStats GroupStats.releaseStats read_release, group
AgentConfiguration, ClusterAgentAuthorizationCiAccess, ClusterAgentAuthorizationUserAccess Project.agentConfigurations, .ciAccessAuthorizedAgents, .userAccessAuthorizedAgents (read_cluster_agent on their resolvers); the last also ClusterAgent.userAccessAuthorizations parent_authorizes: :read_cluster_agent
ConnectedAgent, AgentMetadata, AgentWarning, AgentVersionWarning, ClusterAgentActivityEvent ClusterAgent, directly or nested parent_authorizes: :read_cluster_agent
ClusterAgentUrlConfiguration ClusterAgent.urlConfigurations, ClusterAgentUrlConfigurationCreate read_cluster_agent_url_configuration, project
ClusterAgentToken ClusterAgent.tokens, ClusterAgentActivityEvent.agentToken, ClusterAgentTokenCreate read_cluster_agent_token, project
ClusterAgentTokenRevoke (mutation) revoke_cluster_agent_token, the token's project

This is the Deploy domain in one MR, as @alexbuijs agreed in !267273 (comment 4195231927). It is over 1,000 lines because each type gets a spec for every parent; the code is 79 lines.

References

Closes #639319

Related to #593878.

I found this while working on gitlab-mcp-server.

Screenshots or screen recordings

No UI change.

How to set up and validate locally

  1. In a private Ultimate project with a release, a successful deployment to a protected production environment and an agent with a token and events, run as a Maintainer with a fine-grained token that reads Project, Release, Environment, Deployment, Protected Environment, Cluster Agent and Cluster Agent Token:

    query {
      project(fullPath: "<project>") {
        releases { nodes { tagName assets { count } } }
        environment(name: "production") {
          lastDeployment(status: SUCCESS) { iid tags { name } }
          protectedEnvironments { nodes { name } }
        }
        clusterAgent(name: "<agent>") { tokens { nodes { name } } activityEvents { nodes { kind } } }
      }
    }
  2. On master the release, token and event lists are empty, the deployment is null and protectedEnvironments has null nodes; on this branch all return data.

  3. Remove Release from the token: releases is null, and the rest stays.

Checks I ran (Ruby 3.3.11)

I ran the steps above as examples of the changed request specs, with a stubbed KAS client.

  • With master's types, resolvers, models and todo list, the changed specs give 701 examples, 84 failures: 55 new request examples, the 28 type and model checks, and one example quarantined on master (participants widget in the EE work_item_spec.rb).
  • On this branch, the changed specs and those of the touched resolvers, ClusterAgent, the release mutations, the agent token mutations and the URL configuration mutation: 1006 examples, 1 failure, the same quarantined example.
  • gitlab:permissions:validate, RuboCop, the commit linter and Danger's linters pass; both compile_docs tasks leave the committed docs unchanged. Left to the pipeline: Ruby 3.4.10 and the FOSS run.

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.

Merge request reports

Loading
Loading