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):

  1. The permission is not usable yet. read_enterprise_ai_analytics (what UserMetricsResolver enforces) is still in config/authz/permissions/definitions_todo.txt with no assignable group, so Authz::PermissionGroups::Assignable.available_permissions rejects it as invalid_permission. It must be promoted first: a definition + an assignable entry (available_for: granular_access_token) + boundaries.

  2. The boundary needs design. Copying boundary: :group does not work: the *UserMetrics object is a per-user ClickHouse aggregation row (a hash keyed by user_id) with no .group/.project, so GranularScopeAuthorization#extract_resource resolves it to [] — passes the static validator, broken at runtime. The real boundary lives one level up, on the Group.aiUserMetrics / Project.aiUserMetrics fields where the resolver derives namespace from its parent.

Proposed fix

  • Promote read_enterprise_ai_analytics (definition + assignable group + boundaries).
  • Add authorize_granular_token to the FeatureUserMetricType factory / AiUserMetrics container — one place covering every AiTracking feature, clearing all the *UserMetrics todo entries at once.
  • Remove the type:*UserMetrics entries from authorization_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

Edited by 🤖 GitLab Bot 🤖