Let fine-grained tokens read CI configs and CI variables

What does this MR do and why?

A fine-grained personal access token gets no data from the CiLint config, the deprecated ciConfig query and the CI variable types, which declare no authorize_granular_token directive. These 16 types now declare one with an existing permission and leave authorization_todo.txt:

  • CiConfigV2, CiConfigStageV2, CiConfigGroupV2, CiConfigJobV2, CiConfigInclude, CiConfigJobRestriction and CiConfigNeed declare parent_authorizes: :validate_ci_config, which CiLint checks. The deprecated CiConfig, CiConfigStage, CiConfigGroup and CiConfigJob inherit it as subclasses, so Query.ciConfig now checks validate_ci_config on its projectPath, as POST /projects/:id/ci/lint does.
  • CiProjectVariable (and its subclass CiGroupVariable), CiGroupEnvironmentScope and InheritedCiVariable declare parent_authorizes: :read_variable. Project.ciVariables, Project.inheritedCiVariables, Group.ciVariables and Group.environmentScopes check it on their project or group, as GET /projects/:id/variables and GET /groups/:id/variables do. Inherited variables are checked on the project, as the admin_cicd_variables user check is.
  • CiInstanceVariable checks read_variable on the instance, as GET /admin/ci/variables does.

The issue's other type, CiCatalogResourceComponentUsage, is in !267264 (merged).

References

Closes #638946

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

Screenshots or screen recordings

No UI change.

How to set up and validate locally

  1. As a Maintainer of a private project with a CI/CD variable, create a fine-grained token for the project with Project: Read, CI Config: Validate and Variable: Read, and run:

    query { project(fullPath: "<project>") { ciVariables { nodes { key } } } }
    mutation { ciLint(input: { projectPath: "<project>", content: "test:\n  script: echo" }) { config { status stages { name } } } }
  2. On master the query returns no variables and config is null; on this branch they return the variable and the linted config.

  3. Remove Variable: Read from the token: ciVariables is null, and the lint result stays.

Checks I ran (Ruby 3.3.11)

I ran the steps above as examples of the changed request specs: each new example compares a fine-grained token's answer with what the session of the same user gets, or uses the granular token shared examples.

  • With master's types, resolvers and todo list, the changed specs give 110 examples, 17 failures, all of them new examples. On this branch: 110 examples, 0 failures.
  • gitlab:permissions:validate, both compile_docs tasks (no change after the committed rows), RuboCop, the commit linter and Danger's linters pass. Left to the pipeline: Ruby 3.4 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