Granular permissions for Personal Access Tokens

Note: This issue has been re-scoped as of June 2024 to be for personal access tokens only. Other token types are covered with issues in this epic.

Proposal

Access token of every kind, like Personal Access Tokens, OAuth Access Tokens, Deploy Token and alike are a constant security concern due to their broad access levels. A simple read_api access token of a Gitlab team member might for instance read any internal issue under gitlab.com/gitlab-com even if it's just intended to read issues from a specific public project.

In order to have a really fine grained and auditable access control of tokens I'd like to propose to attach a allow list to every token issues.

For a first iteration targeting the REST API the allow list should have the form of:

OPERATION PATH

Where OPERATION is one or many of the used HTTP methods GET, POST, PUT, DELETE or a * for all methods. PATH would be the path to the intended API endpoint (with wildcards) like /projects/278964/issues to allow access to the gitlab.com/gitlab-org/gitlab project's issues.

So an allow list entry of:

GET,POST  /projects/278964/issues

would limit the access token to only read existing and create new issues in gitlab.com/gitlab-org/gitlab but not edit or delete existing issues as PUT and DELETE are missing.

Another example would be

GET /projects/278964/*

which would allow read access to all project resources exposed for gitlab.com/gitlab-org/gitlab.

Having those allow lists would enable us to create very specific task-bound tokens with least privileged access to the resources needed. Also the allow list could be audited for overly permissive rules like

* *

which would be the current api scope granting full access on behalf of the user.

Edited by Joe Randazzo