Authorize Analytics and its deployments engine for fine-grained tokens
What does this MR do and why?
Project.analytics, Group.analytics and Organization.analytics return the Analytics type, which has no authorize_granular_token directive: a fine-grained personal access token gets analytics: null. So the read_cycle_analytics directive of the mergeRequests engine is never reached, and its spec passes only because the shared example checks the top-level value.
This MR:
- Gives
Analyticsskip_reason: :child_authorizes: it resolves to the project, group or organization itself, whichread_project,read_groupandread_organizationauthorize, and no single permission fits the three, so each engine field checks the token with its own scope. An engine whose mount declares no scope stays denied. - Opts the
deploymentsengine in withread_dora_metric(project and group), which the DORA REST endpoints check before the sameread_dora4_analyticsability. - Removes the five types from
authorization_todo.txt, adds a.metadata.ymlfordora_metric, and regenerates the token docs. - Makes both engine specs assert the nodes, and that
read_grouporread_projectalone returnsanalyticswithout the engine.
Four follow-up MRs opting in the other six engines depend on this one: their specs pass only once analytics resolves.
A question for Authorization: under Organization.analytics the engines stay denied, since neither boundary matches an organization. Should they also take the instance boundary?
References
- Related to #593878.
I found this while working on gitlab-mcp-server.
Screenshots or screen recordings
Not applicable: the only UI change is DORA Metric in capitals.
How to set up and validate locally
-
With ClickHouse and Siphon replication enabled, create a fine-grained personal access token for a group where you are a Reporter, with Group: Read and DORA Metric: Read.
-
Run:
curl --request POST --header "Authorization: Bearer <your_token>" --header "Content-Type: application/json" \ --data '{"query": "{ group(fullPath: \"<group>\") { analytics { deployments { aggregated { nodes { totalCount } } } } } }"}' \ --url "http://gdk.test:3000/api/graphql" -
On master
analyticsisnull. On this branch the nodes come back, and with only Group: Readdeploymentsisnull.
I ran steps 2 and 3 as two new group examples in ee/spec/requests/api/graphql/analytics/deployments_spec.rb, which post this query as a Reporter, one with the token of step 1 and one with Group: Read alone: on master's code the first gets no nodes and the second no analytics, and on this branch the first gets the nodes and the second analytics without deployments.
Checks I ran (Ruby 3.3.11, ClickHouse 26.2)
- Master's type, todo list and doc with the changed specs: 132 examples, 11 failures, all new, each getting
analytics: null. - This branch, with the other engine request specs and the aggregation type and mounter specs: 500 examples, 0 failures.
gitlab:permissions:validatepasses andcompile_docschanges nothing. RuboCop and the commit linter: no findings.
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.