2020-06-23 00:09:42 +05:30
---
stage: Verify
group: Continuous Integration
2021-02-22 17:27:13 +05:30
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
2020-06-23 00:09:42 +05:30
type: reference
---
2017-08-17 22:00:37 +05:30
# New CI job permissions model
2016-09-29 09:46:39 +05:30
> Introduced in GitLab 8.12.
2020-04-22 19:07:51 +05:30
GitLab 8.12 has a completely redesigned [job permissions ](../permissions.md#job-permissions ) system. You can find
2016-09-29 09:46:39 +05:30
all discussion and all our concerns when choosing the current approach in issue
2020-06-23 00:09:42 +05:30
[#18994 ](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/18994 ).
2016-09-29 09:46:39 +05:30
2017-08-17 22:00:37 +05:30
Jobs permissions should be tightly integrated with the permissions of a user
who is triggering a job.
2016-09-29 09:46:39 +05:30
The reasons to do it like that are:
- We already have a permissions system in place: group and project membership
of users.
2017-08-17 22:00:37 +05:30
- We already fully know who is triggering a job (using `git push` , using the
2016-09-29 09:46:39 +05:30
web UI, executing triggers).
- We already know what user is allowed to do.
2017-08-17 22:00:37 +05:30
- We use the user permissions for jobs that are triggered by the user.
2016-09-29 09:46:39 +05:30
- It opens a lot of possibilities to further enforce user permissions, like
allowing only specific users to access runners or use secure variables and
environments.
2017-08-17 22:00:37 +05:30
- It is simple and convenient that your job can access everything that you
2016-09-29 09:46:39 +05:30
as a user have access to.
2017-08-17 22:00:37 +05:30
- Short living unique tokens are now used, granting access for time of the job
2016-09-29 09:46:39 +05:30
and maximizing security.
2017-08-17 22:00:37 +05:30
With the new behavior, any job that is triggered by the user, is also marked
2019-09-04 21:01:54 +05:30
with their read permissions. When a user does a `git push` or changes files through
2021-02-22 17:27:13 +05:30
the web UI, a new pipeline is usually created. This pipeline is marked
2019-12-04 20:38:33 +05:30
as created by the pusher (local push or via the UI) and any job created in this
2021-02-22 17:27:13 +05:30
pipeline has the read permissions of the pusher but not write permissions.
2016-09-29 09:46:39 +05:30
This allows us to make it really easy to evaluate the access for all projects
2020-04-22 19:07:51 +05:30
that have [Git submodules ](../../ci/git_submodules.md ) or are using container images that the pusher
2019-12-04 20:38:33 +05:30
would have access too. **The permission is granted only for the time that the job
is running. The access is revoked after the job is finished.**
2016-09-29 09:46:39 +05:30
## Types of users
It is important to note that we have a few types of users:
2021-02-22 17:27:13 +05:30
- **Administrators**: CI jobs created by Administrators don't have access
2016-09-29 09:46:39 +05:30
to all GitLab projects, but only to projects and container images of projects
2019-09-04 21:01:54 +05:30
that the administrator is a member of. That means that if a project is either
2016-09-29 09:46:39 +05:30
public or internal users have access anyway, but if a project is private, the
2021-02-22 17:27:13 +05:30
Administrator has to be a member of it in order to have access to it
2017-08-17 22:00:37 +05:30
via another project's job.
2016-09-29 09:46:39 +05:30
2021-02-22 17:27:13 +05:30
- **External users**: CI jobs created by [external users ](../permissions.md#external-users ) have
2020-03-13 15:44:24 +05:30
access only to projects to which the user has at least Reporter access. This
2019-09-04 21:01:54 +05:30
rules out accessing all internal projects by default.
2016-09-29 09:46:39 +05:30
This allows us to make the CI and permission system more trustworthy.
Let's consider the following scenario:
1. You are an employee of a company. Your company has a number of internal tools
2017-08-17 22:00:37 +05:30
hosted in private repositories and you have multiple CI jobs that make use
2016-09-29 09:46:39 +05:30
of these repositories.
2020-11-24 15:15:51 +05:30
1. You invite a new [external user ](../permissions.md#external-users ). CI jobs created by that user do not
2016-09-29 09:46:39 +05:30
have access to internal repositories, because the user also doesn't have the
access from within GitLab. You as an employee have to grant explicit access
for this user. This allows us to prevent from accidental data leakage.
2017-08-17 22:00:37 +05:30
## Job token
2016-09-29 09:46:39 +05:30
2021-03-08 18:12:59 +05:30
When a pipeline job is about to run, GitLab generates a unique token and injects it as the
[`CI_JOB_TOKEN` predefined variable ](../../ci/variables/predefined_variables.md ).
This token can authenticate [API requests ](../../api/README.md )
from the job script (Runner) that needs to access the project's resources (for example, when
fetching a job artifact).
Once the token is authenticated, GitLab identifies the user who triggered the job and uses this user
to authorize access to the resource. Therefore, this user must be assigned to
[a role that has the required privileges ](../permissions.md ).
The job token has these limitations:
- Not all APIs allow job tokens for authentication. See [this list ](../../api/README.md#gitlab-ci-job-token )
for available endpoints.
- The token is valid only while the pipeline job runs. Once the job finishes, the token can't be
used for authentication.
Although a job token is handy to quickly access a project's resources without any configuration, it
sometimes gives extra permissions that aren't necessary. There is [a proposal ](https://gitlab.com/groups/gitlab-org/-/epics/3559 )
to redesign the feature for more strategic control of the access permissions.
2021-02-22 17:27:13 +05:30
If you need your CI pipeline to push to the Package Registry, consider using [deploy tokens ](deploy_tokens/index.md ).
2016-09-29 09:46:39 +05:30
We try to make sure that this token doesn't leak by:
2017-08-17 22:00:37 +05:30
1. Securing all API endpoints to not expose the job token.
1. Masking the job token from job logs.
2019-12-04 20:38:33 +05:30
1. Granting permissions to the job token **only** when the job is running.
2016-09-29 09:46:39 +05:30
2020-11-24 15:15:51 +05:30
However, this brings up a question about the runner's security. To make sure that
2016-09-29 09:46:39 +05:30
this token doesn't leak, you should also make sure that you configure
2020-11-24 15:15:51 +05:30
your runners in the most possible secure way, by avoiding the following:
2016-09-29 09:46:39 +05:30
1. Any usage of Docker's `privileged` mode is risky if the machines are re-used.
2017-08-17 22:00:37 +05:30
1. Using the `shell` executor since jobs run on the same machine.
2016-09-29 09:46:39 +05:30
By using an insecure GitLab Runner configuration, you allow the rogue developers
2017-08-17 22:00:37 +05:30
to steal the tokens of other jobs.
2016-09-29 09:46:39 +05:30
## Before GitLab 8.12
2020-11-24 15:15:51 +05:30
In versions before GitLab 8.12, all CI jobs would use the runner's token
2016-09-29 09:46:39 +05:30
to checkout project sources.
2020-11-24 15:15:51 +05:30
The project's runner token was a token that you could find under the
2017-09-10 17:25:29 +05:30
project's **Settings > Pipelines** and was limited to access only that
2016-09-29 09:46:39 +05:30
project.
2020-11-24 15:15:51 +05:30
It could be used for registering new specific runners assigned to the project
2016-09-29 09:46:39 +05:30
and to checkout project sources.
It could also be used with the GitLab Container Registry for that project,
2017-08-17 22:00:37 +05:30
allowing pulling and pushing Docker images from within the CI job.
2016-09-29 09:46:39 +05:30
GitLab would create a special checkout URL like:
2020-04-08 14:13:33 +05:30
```plaintext
2019-12-04 20:38:33 +05:30
https://gitlab-ci-token:< project-runners-token > /gitlab.com/gitlab-org/gitlab-foss.git
2016-09-29 09:46:39 +05:30
```
2017-08-17 22:00:37 +05:30
And then the users could also use it in their CI jobs all Docker related
2016-09-29 09:46:39 +05:30
commands to interact with GitLab Container Registry. For example:
2020-04-08 14:13:33 +05:30
```shell
2017-08-17 22:00:37 +05:30
docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
2016-09-29 09:46:39 +05:30
```
Using single token had multiple security implications:
2020-03-13 15:44:24 +05:30
- The token would be readable to anyone who had Developer access to a project
2017-08-17 22:00:37 +05:30
that could run CI jobs, allowing the developer to register any specific
2020-11-24 15:15:51 +05:30
runner for that project.
2016-09-29 09:46:39 +05:30
- The token would allow to access only the project's sources, forbidding from
accessing any other projects.
- The token was not expiring and was multi-purpose: used for checking out sources,
for registering specific runners and for accessing a project's container
registry with read-write permissions.
2017-08-17 22:00:37 +05:30
All the above led to a new permission model for jobs that was introduced
2016-09-29 09:46:39 +05:30
with GitLab 8.12.
2017-08-17 22:00:37 +05:30
## Making use of the new CI job permissions model
2016-09-29 09:46:39 +05:30
2017-08-17 22:00:37 +05:30
With the new job permissions model, there is now an easy way to access all
2016-09-29 09:46:39 +05:30
dependent source code in a project. That way, we can:
2017-08-17 22:00:37 +05:30
1. Access a project's dependent repositories
2020-04-22 19:07:51 +05:30
1. Access a project's [Git submodules ](../../ci/git_submodules.md )
2016-09-29 09:46:39 +05:30
1. Access private container images
1. Access project's and submodule LFS objects
2016-11-03 12:29:30 +05:30
Below you can see the prerequisites needed to make use of the new permissions
model and how that works with Git submodules and private Docker images hosted on
2016-09-29 09:46:39 +05:30
the container registry.
2016-11-03 12:29:30 +05:30
### Prerequisites to use the new permissions model
2021-02-22 17:27:13 +05:30
With the new permissions model in place, there may be times that your job
fails. This is most likely because your project tries to access other project's
2017-08-17 22:00:37 +05:30
sources, and you don't have the appropriate permissions. In the job log look
2016-11-03 12:29:30 +05:30
for information about 403 or forbidden access messages.
In short here's what you need to do should you encounter any issues.
As an administrator:
2021-02-22 17:27:13 +05:30
- **500 errors**: You need to update [GitLab Workhorse ](https://gitlab.com/gitlab-org/gitlab-workhorse ) to at
2016-11-03 12:29:30 +05:30
least 0.8.2. This is done automatically for Omnibus installations, you need to
2020-04-22 19:07:51 +05:30
[check manually ](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/doc/update ) for installations from source.
2016-11-03 12:29:30 +05:30
- **500 errors**: Check if you have another web proxy sitting in front of NGINX (HAProxy,
Apache, etc.). It might be a good idea to let GitLab use the internal NGINX
2020-06-23 00:09:42 +05:30
web server and not disable it completely. See [this comment ](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/22484#note_16648302 ) for an
2016-11-03 12:29:30 +05:30
example.
- **403 errors**: You need to make sure that your installation has [HTTP(S)
2020-04-22 19:07:51 +05:30
cloning enabled](../admin_area/settings/visibility_and_access_controls.md#enabled-git-access-protocols). HTTP(S) support is now a **requirement** by GitLab CI
2016-11-03 12:29:30 +05:30
to clone all sources.
As a user:
- Make sure you are a member of the group or project you're trying to have
access to. As an Administrator, you can verify that by impersonating the user
2017-08-17 22:00:37 +05:30
and retry the failing job in order to verify that everything is correct.
2016-11-03 12:29:30 +05:30
2017-08-17 22:00:37 +05:30
### Dependent repositories
2016-09-29 09:46:39 +05:30
2021-03-11 19:13:27 +05:30
The [CI/CD variable ](../../ci/variables/README.md#predefined-cicd-variables ) `CI_JOB_TOKEN` can be used to
2017-08-17 22:00:37 +05:30
authenticate any clones of dependent repositories. For example:
2016-09-29 09:46:39 +05:30
2020-04-08 14:13:33 +05:30
```shell
2019-09-30 21:07:59 +05:30
git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/< user > /< mydependentrepo > .git
2016-09-29 09:46:39 +05:30
```
2017-08-17 22:00:37 +05:30
It can also be used for system-wide authentication
2021-02-22 17:27:13 +05:30
(only do this in a Docker container, it overwrites `~/.netrc` ):
2016-09-29 09:46:39 +05:30
2020-04-08 14:13:33 +05:30
```shell
2017-08-17 22:00:37 +05:30
echo -e "machine gitlab.com\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc
2016-09-29 09:46:39 +05:30
```
2017-08-17 22:00:37 +05:30
### Git submodules
2016-09-29 09:46:39 +05:30
2020-04-22 19:07:51 +05:30
To properly configure submodules with GitLab CI/CD, read the
[Git submodules documentation ](../../ci/git_submodules.md ).
2016-09-29 09:46:39 +05:30
### Container Registry
With the update permission model we also extended the support for accessing
Container Registries for private projects.
2021-02-22 17:27:13 +05:30
GitLab Runner versions prior to 1.8 don't incorporate the introduced changes
for permissions. This makes the `image:` directive not work with private
projects automatically and it needs to be configured manually on the GitLab Runner host
with a predefined account (for example administrator's personal account with
access token created explicitly for this purpose). This issue is resolved with
latest changes in GitLab Runner 1.8 which receives GitLab credentials with
build data.
Starting from GitLab 8.12, if you have [2FA ](../profile/account/two_factor_authentication.md ) enabled in your account, you need
to pass a [personal access token ](../profile/personal_access_tokens.md ) instead of your password in order to
login to the Container Registry.
2017-08-17 22:00:37 +05:30
Your jobs can access all container images that you would normally have access
2016-09-29 09:46:39 +05:30
to. The only implication is that you can push to the Container Registry of the
2017-08-17 22:00:37 +05:30
project for which the job is triggered.
2016-09-29 09:46:39 +05:30
This is how an example usage can look like:
2020-04-22 19:07:51 +05:30
```yaml
2016-09-29 09:46:39 +05:30
test:
script:
2021-01-03 14:25:43 +05:30
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
2016-09-29 09:46:39 +05:30
- docker pull $CI_REGISTRY/group/other-project:latest
- docker run $CI_REGISTRY/group/other-project:latest
```
2019-12-04 20:38:33 +05:30
### Pipeline triggers
2020-04-22 19:07:51 +05:30
Since 9.0 [pipeline triggers ](../../ci/triggers/README.md#ci-job-token ) do support the new permission model.
2019-12-04 20:38:33 +05:30
The new triggers do impersonate their associated user including their access
to projects and their project permissions.
### API
2021-01-03 14:25:43 +05:30
GitLab API can be used via `CI_JOB_TOKEN` , see [the relevant documentation ](../../api/README.md#gitlab-ci-job-token ).