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).
DeploymentApprovaltakes its own because a group's approval rules return it too, and reads its project through the deployment, since a database trigger sets theproject_idof a new approval. ClusterAgentTokenRevoketakesrevoke_cluster_agent_tokenon the token's project, as its REST endpoint does; the agents resolver preloads the tokens' project.- The resolvers of
Project.releases,Group.releases,Project.nestedEnvironmentsand three agent fields checkread_release,read_environmentorread_cluster_agent, as for the user; an object of another project needs it there too. - The 17 types returned only below
Release,ClusterAgent,Deploymentor those fields take their parent's permission withparent_authorizes:, asGET /projects/:id/releasesreturns 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
-
In a private Ultimate project with a release, a successful deployment to a protected
productionenvironment 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 } } } } } -
On master the release, token and event lists are empty, the deployment is
nullandprotectedEnvironmentshasnullnodes; on this branch all return data. -
Remove Release from the token:
releasesisnull, 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; bothcompile_docstasks 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.