diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-09-21 16:28:48 +0200 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-09-22 14:40:08 +0200 |
commit | 88d83e2e6f0089082f5db8841561f09a38d294a1 (patch) | |
tree | 5a5454d8b0c70517c0cee5b1296e5303e76ba2ee | |
parent | 2450625bbc1a9838b4ab76b652dfa1899c777927 (diff) | |
download | gitlab-ce-88d83e2e6f0089082f5db8841561f09a38d294a1.tar.gz |
Describe how the recent changes of CI permissions affect builds
-rw-r--r-- | doc/ci/README.md | 2 | ||||
-rw-r--r-- | doc/ci/dependent_projects/README.md | 117 | ||||
-rw-r--r-- | doc/user/permissions.md | 125 |
3 files changed, 244 insertions, 0 deletions
diff --git a/doc/ci/README.md b/doc/ci/README.md index 10ce4ac8940..a52277e582a 100644 --- a/doc/ci/README.md +++ b/doc/ci/README.md @@ -16,5 +16,7 @@ - [Trigger builds through the API](triggers/README.md) - [Build artifacts](../user/project/builds/artifacts.md) - [User permissions](../user/permissions.md#gitlab-ci) +- [Build permissions](../user/permissions.md#builds-permissions) +- [Access dependent projects](dependent_projects/README.md) - [API](../api/ci/README.md) - [CI services (linked docker containers)](services/README.md) diff --git a/doc/ci/dependent_projects/README.md b/doc/ci/dependent_projects/README.md new file mode 100644 index 00000000000..feb148e31b6 --- /dev/null +++ b/doc/ci/dependent_projects/README.md @@ -0,0 +1,117 @@ +## Dependent projects + +> Introduced in GitLab 8.12. + +GitLab 8.12 introduces a new [Build permissions model](../../user/permissions.md#builds-permissions). + +This opens an easy to use a way to access all dependent source codes: +1. Access project's `submodule`, +1. Access private Container Images, +1. Access project's and submodule LFS objects. + +### Submodules + +> It often happens that while working on one project, you need to use another project from within it. +> Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. +> A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. +> (from https://git-scm.com/book/en/v2/Git-Tools-Submodules) + +Your project usually have a file named `.gitmodules`. +This file usually looks like that: +``` +[submodule "tools"] + path = tools + url = git@gitlab.com/group/tools.git +``` + +Before 8.12 you had to do a multiple workarounds (ex. [SSH keys](../ssh_keys/README.md)) +in order to access the sources of `gitlab.com/group/tools`. + +GitLab 8.12 uses your permissions to evaluate what a CI build can access. +More information about how this system works can be found here: [Build permissions model](../../user/permissions.md#builds-permissions). + +To make use of a new changes you have to update your `.gitmodules` file to use a relative URL. + +Let's consider the following example: + +1. Your project is located at https://gitlab.com/secret-group/my-project, +1. To checkout your sources you usually use a SSH address: `git@gitlab.com:secret-group/my-project.git`, +1. Your project depend on https://gitlab.com/group/tools, +1. You have the `.gitmodules` file with above content. + +Since that you can use a relative URLs for your `.gitmodules` configuration +it easily allows you to use an HTTP cloning for all your CI builds, +and SSH clonning for all your local checkouts. + +If you change the `url` of your `tools` dependency: +``` +git@gitlab.com/group/tools.git => ../../group/tools.git +``` + +It will instruct GIT to automatically deduce a URL that should be used when cloning sources. +Whether you used a HTTP or SSH it will instruct GIT to use the same channel. +And this will allow to make all your CI builds to use HTTPS (because GitLab CI uses HTTPS for cloning your sources), +and all your local clones will continue using SSH. + +Given the above explanation, your `.gitmodules` file should look like this: +``` +[submodule "tools"] + path = tools + url = ../../group/tools.git +``` + +However, you have to instruct GitLab CI to clone your submodules as this is not done automatically. +You can achieve that by adding a `before_script` section to your `.gitlab-ci.yml` with `git submodule` command: + +``` +before_script: + - git submodule update --init --recursive + +test: + script: + - run-my-tests +``` + +This will make GitLab CI to initialize (fetch) and update (checkout) all your submodules recursively. + +It can happen that your environment or your Docker Image does not have a git installed. +You have to either ask your Administrator or install the missing dependency yourself: + +``` +# Debian / Ubuntu +before_script: + - apt-get update -y + - apt-get install -y git-core + - git submodule update --init --recursive + +# CentOS / RedHat +before_script: + - yum install git + - git submodule update --init --recursive + +# Alpine +before_script: + - apk add -U git + - git submodule update --init --recursive +``` + +### Container Registry + +With the update permission model we also extended support for accessing Container Registries for private projects. + +> Note: As of 1.6 the GitLab Runner doesn't yet incorporate the introduced changes for permissions. +> This makes a `image:` to not work with private projects automatically. +> The manual configuration by Administrator is required to use private images. +> We plan to remove that limitation in one of the upcoming releases. + +Your builds can access all container images that you would normally have access to. +The only implication is that you can push to Container Registry of project for which the build is triggered. + +This is how the example usage can look like: +``` +test: + script: + - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY + - docker pull $CI_REGISTRY/group/other-project:latest + - docker run $CI_REGISTRY/group/other-project:latest +``` diff --git a/doc/user/permissions.md b/doc/user/permissions.md index f1b75298180..7fc642f8c77 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -138,3 +138,128 @@ instance and project. In addition, all admins can use the admin interface under | Add shared runners | | | | ✓ | | See events in the system | | | | ✓ | | Admin interface | | | | ✓ | + +## Builds permissions + +> Changed in GitLab 8.12. + +GitLab 8.12 has completely redesigned build permission system. +You can find all discussion and all our concerns when choosing the current approach: +https://gitlab.com/gitlab-org/gitlab-ce/issues/18994 + +We decided that builds permission should be tightly integrated with a permission +of a user who is triggering a build. + +The reason to do it like that: + +- We already have permission system in place: group and project membership of users, +- We already fully know who is triggering a build (using git push, using web, executing triggers), +- We already know what user is allowed to do, +- We use the user permission for builds that are triggered by him, +- This opens us a lot of possibilities to further enforce user permissions, like: + allowing only specific users to access runners, secure variables and environments, +- It is simple and convenient, that your build can access to everything that you have access to, +- We choose to short living unique tokens, granting access for time of the build, + +Currently, any build that is triggered by the user, it's also signed with his permissions. +When user do `git push` or changes files through web (**the pusher**), +we will usually create a new Pipeline. +The Pipeline will be signed as created be the pusher. +Any build created in this pipeline will have the permissions of **the pusher**. + +This allows us to make it really easy to evaluate access for all dependent projects, +container images that the pusher would have access too. +The permission is granted only for time that build is running. +The access is revoked after the build is finished. + +It is important to note that we have a few types of Users: + +- Administrators: CI builds created by Administrators would not have access to all GitLab projects, + but only to projects and container images of projects that the user is a member of or that are either public, or internal, + +- External users: CI builds created by external users will have access only to projects to which user has at least reporter access, + this rules out accessing all internal projects by default, + +This allows us to make the CI and permission system more trustable. +Let's consider the following scenario: + +1. You are an employee of the company. Your company have number of internal tool repositories. + You have multiple CI builds that make use of this repositories. + +2. You invite a new user, a visitor, the external user. CI builds created by that user do not have access to internal repositories, + because 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. + +### Build privileges + +This table shows granted privileges for builds triggered by specific types of users: + +| Action | Guest, Reporter | Developer | Master | Admin | +|---------------------------------------------|-----------------|-------------|----------|--------| +| Run CI build | | ✓ | ✓ | ✓ | +| Clone source and LFS from current project | | ✓ | ✓ | ✓ | +| Clone source and LFS from other projects | | ✓ [^1] | ✓ [^1] | ✓ [^1] | +| Push source and LFS to current project | | | | | +| Push source and LFS to other projects | | | | | +| Pull container images from current project | | ✓ | ✓ | ✓ | +| Pull container images from other projects | | ✓ [^1] | ✓ [^1] | ✓ [^1] | +| Push container images to current project | | ✓ | ✓ | ✓ | +| Push container images to other projects | | | | | + +### Build token + +The above gives a question about trustability of build token. +Unique build token is generated for each project. +This build token allows to access all projects that would be normally accessible +to the user creating that build. + +We try to make sure that this token doesn't leak. +We do that by: +1. Securing all API endpoints to not expose the build token, +1. Masking the build token from build logs, +1. Allowing to use the build token only when build is running, + +However, this brings a question about runners security. +To make sure that this token doesn't leak you also make sure that you configure +your runners in most secure possible way, by avoiding using this configurations: +1. Any usage of `privileged` mode if the machines are re-used is risky, +1. Using `shell` executor, + +By using in-secure GitLab Runner configuration you allow the rogue developers +to steal the tokens of other builds. However, this problem existed before, +but + +### Before 8.12 + +In versions before 8.12 all CI builds would use runners token to checkout project sources. + +The project runners token was a token that you would find in +[CI/CD Pipelines](https://gitlab.com/my-group/my-project/pipelines/settings). + +The project runners token was used for registering new specific runners assigned to project +and to checkout project sources. + +The project runners token could also be used to use GitLab Container Registry for that project, +allowing to pull and push Docker images from within CI build. + +This token was limited to access only that project. + +GitLab would create an special checkout URL: +``` +https://gitlab-ci-token:<project-runners-token>/gitlab.com/gitlab-org/gitlab-ce.git +``` + +User could also use in his CI builds all docker related commands +to interact with GitLab Container Registry: +``` +docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com +``` + +Using single token had multiple security implications: + +- Token would be readable to anyone who has developer access to project who could run CI builds, + allowing to register any specific runner for a project, +- Token would allow to access only project sources, + forbidding to accessing any other projects, +- Token was not expiring, and multi-purpose: used for checking out sources, + for registering specific runners and for accessing project's container registry with read-write permissions |