Skip to content

[BE] A user can define permissions for projects in the Job token permissions settings

Why are we doing this work?

We are implementing this solution to give project owners and maintainers more control over the permissions available in a CI_JOB_TOKEN. This will allow them to limit the scope of access and minimize security risks by specifying the maximum set of permissions needed for their CI/CD jobs. These permissions will be restricted to those required for the APIs listed below, ensuring that the token only has access to what is necessary for the specific project.

By reducing unnecessary permissions, we can improve security, minimize potential misuse of the token, and align with best practices for least privilege access control.

Permissions

The following permissions were compiled based on findings from this investigation.

Containers

Action Permission(s)
Delete a registry repository tag :admin_container_image OR :destroy_container_image
Delete a registry repository tags in bulk :admin_container_image OR :destroy_container_image
Delete registry repository :admin_container_image OR :destroy_container_image
Get details of a registry repository tag :admin_container_image OR :read_container_image
List registry repositories :admin_container_image OR :read_container_image
List registry repository tags :admin_container_image OR :read_container_image

Deployments

Action Permission(s)
List project deployments :read_deployment
Get a specific deployment :read_deployment
Create a deployment :read_deployment AND :create_deployment
Update a deployment :read_deployment AND :update_deployment
Delete a specific deployment :destroy_deployment

Environments

Action Permission(s)
List environments :read_environment
Get a specific environment :read_environment
Create a new environment :create_environment
Update an existing environment :update_environment
Delete an environment :read_environment AND :destroy_environment
Delete multiple stopped review apps :read_environment AND :destroy_environment
Stop an environment :read_environment AND :stop_environment
Stop stale environments :read_environment AND :stop_environment

Jobs

Action Permission(s)
Get job token's job :read_build
Get GitLab agent by CI_JOB_TOKEN :read_build
Update pipeline metadata :update_pipeline
Get job artifacts :read_build AND :read_job_artifacts
Download the artifacts archive :read_build AND :read_job_artifacts
Download a single artifact file by job ID :read_build AND :read_job_artifacts
Download a single artifact file from a specific tag or branch :read_build AND :read_job_artifacts

Packages

Route Permission(s)
List packages :read_package
Get a project package :read_package
List package files :read_package
List package pipelines :read_package AND :read_pipeline
Delete a project package :destroy_package
Delete a package file :destroy_package
PUT /projects/:id/packages/generic/:package_name/*package_version/(*path/):file_name/authorize :read_project AND :create_package
GET /projects/:id/packages/generic/:package_name/*package_version/(*path/):file_name :read_project AND :read_package
PUT /projects/:id/packages/generic/:package_name/*package_version/(*path/):file_name :read_project

Maven

Permission(s) Route
Download a package file at the instance level :read_package
Download a package file at the group level :read_group AND :read_package
Download a package file at the project level :read_project AND :read_package
Upload a package file :read_project AND :create_package
PUT /projects/:id/packages/maven/*path/:file_name/authorize :read_project AND :create_package

PyPI

Permission(s) Route
Download a package file from a group :read_group AND :read_package
Group-level simple API index :read_group AND :read_package
Group level simple API entry point :read_group AND :read_package
Download a package file from a project :read_project AND :read_package
Project-level simple API index :read_project AND :read_package
Project-level simple API entry point :read_project AND :read_package
Upload a package :read_project AND :create_package
POST /projects/:id/-/packages/pypi/authorize :read_project AND :create_package

Composer

Permission(s) Route
Base repository request :read_group
V1 packages list :read_group
V2 Package Metadata :read_group
Create a package :create_package

NPM

Permission(s) Route
Project-level: Download a package :read_package
Project-level: Upload a package :create_package
Group-level: Package Metadata :read_package
Project-level: Package Metadata :read_package
Group-level: List tags :read_package
Project-level: List tags :read_package
Group-level: Create or update a tag :create_package
Project-level: Create or update a tag :create_package
Group-level: Delete a tag :destroy_package
Group-level: Delete a tag :destroy_package
POST /groups/:id/-/packages/npm/-/npm/v1/security/advisories/bulk :read_package
POST /groups/:id/-/packages/npm/-/npm/v1/security/audits/quick :read_package
POST /projects/:id/-/packages/npm/-/npm/v1/security/advisories/bulk :read_package
POST /projects/:id/-/packages/npm/-/npm/v1/security/audits/quick :read_package

Go Proxy

Permission(s) Route
List packages :read_package
Version metadata :read_package
Download module file :read_package
Download module source :read_package

Releases

Action Permission(s)
List links of a release :read_release
Get a release link :read_release
Create a release link :create_release
Update a release link :update_release
Delete a release link :destroy_release

Secure Files

Action Permission(s)
List project secure files :read_secure_files OR :admin_secure_files
Show secure file details :read_secure_files OR :admin_secure_files
Create secure file :admin_secure_files
Download secure file :read_secure_files OR :admin_secure_files
Remove a secure file :admin_secure_files

Terraform

Action Permission(s)
Retrieve individual Terraform state version :read_terraform_state OR :admin_terraform_state
Remove individual Terraform state version :admin_terraform_state
Remove a state file :admin_terraform_state
Retrieve a state file :read_terraform_state OR :admin_terraform_state
Create a state file :admin_terraform_state
Create a lock file :admin_terraform_state
Delete a lock file :admin_terraform_state

Internal

Action Permission(s)
POST /internal/dast/site_validations/:id/transition :create_on_demand_dast_scan

mockup

Relevant links

Implementation Plan

  • database Add a permissions JSONB column to the ci_job_token_project_scope_links table.
  • backend Provide an API to save enabled permissions to the ci_job_token_project_scope_links.permissions column.
  • UX Create mockups for the frontend
  • frontend TBD

Verification steps

  • Enabling a permission on an Allow list entry is persisted to the database.
  • Disabling a permission on an Allow list entry is persisted to the database.
Edited by mo khan