Feature request: Global and per-user CI variables
Description
We have a lot (almost all) of projects in our Gitlab that build packages through Gitlab CI. packages covers docker images, debian package, Ruby gem, Python, and a lot of other artifacts. After build these package are upload in their respectives repositories, depending of the packaging technology.
I will now details only Debian packaging , but what follow applies in almost all other type of package.
Creating a debian package means, among others things:
- Sign the package a specific (per user) GPG key
- Upload the .deb to a repository, whose hostname is common for all the organisation, like
debian.my.org
- Before uploding, login to this repository using specific (per user) credentials.
The hostname of each repositories type is subject to change over time (no control on that), and we want to avoid having it explicitly used in .gitlab-ci.yml
, so that we don't have to edit all our projets when a hostname change.
For now, this is what we are using to do that in Gitlab CI:
- An environment variable is set directly in the runners configuration (config.toml file), containing the repository hostname (e.g.: DEBIAN_HOST=debian.my.org).
- We created a generic GPG key (per team), and a generic upload account, that each project of a team set as secret variables. With the solution we have 2 issues:
- We cannot track per user, it's only per team, at best. Security guys are (with reasons) not really happy.
- When the password of a generic account expires and need to be changed, each team must edit secret variables of all its projects.
Proposal
Here is a proposal that should cover the previous use cases (which is I think pretty common everywhere), and maybe some other ones that still not occurs.
It consists of adding 2 new level of variables:
- Global variables, that can be defined by admin directly in the Gitlab GUI. Much easier, than runner's
config.toml
, centralized (no needs to update every runners config), more secured (global variables will not be in clear text file, but stored enrcypted, like actual project variables). - Per users variables: each user in Gitlab, should have a new section in its profile settings, where it can add any variables he wants. Exactly like project variables. Encrypted as well.
Then, the precedence of the variables in a pipeline can be changed like that:
- Trigger variables
- Global secure variables
- Project secure variables
- Per user secure variables
- YAML-defined job-level variables
- YAML-defined global variables
- Predefined variables
This way, regarding the previous use case:
- Administrators can define a gobal
DEBIAN_HOST
and change it easly for all the organisation - Organisation define a list of variable name each user needs to set in its profile for personnal credential (like
DEBUILG_GPG
,DEB_REPO_USER
,DEB_REPO_PASS
). So each user can manage its credential secretly and change passwords at only one place on each pasword expiration for all its projects, full tracking is preserved...
Edit: per user variables can also cover security issue in deployment stage jobs: if the user pushing the job does not have the valid credential in their user variables, the jobs naturally fails. This can also cover the vault security pattern: a centralized vault service contains secrets (credential, ssh key, ssl certificates, ...) needed to build, configure or deploy things. Each user has a personnal account to access the vault, and the vault has ACL telling precisely what secret whom user can access. In Gitlab-CI, user variables can contain only the credential to login to the vault. Then in the job, if the user does not have access to the needed secret in the vault, the job fails. By the way, that part (security and vault pattern) can be covered by gitlab-foss#20367 (closed).
Links / references
Like credential for external services or repository, per users variables can also be used to store a Gitlab API tocken. This will allows scripts in Gitlab CI jobs to use the API to upload files in the Gitlab release representing a tags, add auto comment in a related issue/merge request, ...
In a first iteration, that API token name cas be defined by the user. And In a next iteration, some of the per user variables can be autolocally defined by gitlab, for example the user API token, automatically defined and temporarlly for each build, like the CI registry token.