feat(ci): allow CI_JOB_TOKEN to push to allowlisted repositories

Note: Frontend changes have been split out to !232351 to avoid GitLab.com deployment skew (see discussion on !229671 (merged)#note_3269395247). This MR is now backend-only. The FE MR will merge only after this backend reaches .com.

What does this MR do and why?

Adds the ability for CI/CD job tokens to push to repositories in other projects, when the source project is on the target project's inbound job token allowlist with the admin_repositories policy.

Today, CI_JOB_TOKEN can only push to the same repository that the pipeline runs in. This MR extends that to support cross-project pushes, gated behind four independent security checks:

  1. Feature flag allow_push_to_allowlisted_projects (gitlab_com_derisk, default off)
  2. Target project setting cross_project_push_for_job_token_allowed (new boolean, default false)
  3. Target project inbound scope must be enabled
  4. Allowlist entry from target → source with the admin_repositories fine-grained policy

All four gates must be satisfied simultaneously. The existing push_repository_for_job_token_allowed setting must also be enabled, as it remains the top-level toggle for any job-token push.

Related to #479907

References

Screenshots or screen recordings

Screenshots will be added in the FE follow-up !232351. The UI adds a second checkbox ("Allow cross-project Git push requests from allowlisted projects") under Settings > CI/CD > Token access > Additional permissions.

How to set up and validate locally

You will need both this MR and !232351 checked out locally to exercise the UI path, or you can validate backend-only via the GraphQL mutation:

  1. Enable the feature flag:
    Feature.enable(:allow_push_to_allowlisted_projects)
  2. Create two projects: source-project and target-project
  3. On target-project, enable the setting via GraphQL (or via the UI if !232351 is checked out):
    mutation {
      projectCiCdSettingsUpdate(input: {
        fullPath: "path/to/target-project",
        pushRepositoryForJobTokenAllowed: true,
        crossProjectPushForJobTokenAllowed: true
      }) { errors }
    }
  4. On target-project, go to Settings > CI/CD > Token access and add source-project to the inbound allowlist with admin_repositories policy
  5. Create a pipeline in source-project with a job that pushes to target-project using CI_JOB_TOKEN
  6. Verify the push succeeds
  7. Disable any one of the four gates and verify the push is rejected with 403

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.

Edited by Mark Mishaev

Merge request reports

Loading