Add granular token authorization for AiTracking *UserMetrics GraphQL types
Summary
The auto-generated <feature>UserMetrics GraphQL types — built by Types::Analytics::AiMetrics::FeatureUserMetricType.[](feature) and exposed via Group.aiUserMetrics / Project.aiUserMetrics — lack granular personal access token (gPAT) authorization. They are listed in config/authz/graphql/authorization_todo.txt (type:chatUserMetrics, type:codeReviewUserMetrics, type:troubleshootJobUserMetrics, …, plus new ones added during the #567159 AiTracking audit), but that file's header says new entries should not be added — the types should carry authorize_granular_token instead.
Sibling pattern: #602145 (granular token authorization for AI Tool Rule GraphQL endpoints).
Why it is not a one-line copy
Per @alexbuijs's review on !241206 (merged), two prerequisites block copying the existing authorize_granular_token pattern (e.g. AllowListType):
-
The permission is not usable yet.
read_enterprise_ai_analytics(whatUserMetricsResolverenforces) is still inconfig/authz/permissions/definitions_todo.txtwith no assignable group, soAuthz::PermissionGroups::Assignable.available_permissionsrejects it asinvalid_permission. It must be promoted first: a definition + an assignable entry (available_for: granular_access_token) + boundaries. -
The boundary needs design. Copying
boundary: :groupdoes not work: the*UserMetricsobject is a per-user ClickHouse aggregation row (a hash keyed byuser_id) with no.group/.project, soGranularScopeAuthorization#extract_resourceresolves it to[]— passes the static validator, broken at runtime. The real boundary lives one level up, on theGroup.aiUserMetrics/Project.aiUserMetricsfields where the resolver derivesnamespacefrom its parent.
Proposed fix
- Promote
read_enterprise_ai_analytics(definition + assignable group + boundaries). - Add
authorize_granular_tokento theFeatureUserMetricTypefactory /AiUserMetricscontainer — one place covering every AiTracking feature, clearing all the*UserMetricstodo entries at once. - Remove the
type:*UserMetricsentries fromauthorization_todo.txt.
Guide: https://docs.gitlab.com/development/permissions/granular_access/graphql_implementation_guide/
Context
Surfaced during the #567159 AiTracking audit. The in-flight audit MRs keep their interim todo entries (approved by @alexbuijs) until this lands. Placement confirmed: the factory is the only home, since these types are auto-generated and resolver-authorized.
cc @alexbuijs