Secure storage of GitLab CI passwords as Yandex Lockbox secrets
You can securely store passwords as Yandex Lockbox secrets and use them in your CI pipelines in Yandex Managed Service for GitLab. Thus you can protect and hide passwords in CI script from GitLab users, including administrators.
Below is how the integration with Yandex Lockbox works. First, you need to create a Yandex Lockbox secret and a GitLab environment variable that points to this secret. You also need to install GitLab Runner on a VM and assign a service account to it. Then, create the CI script provided below. It contains a special command that requests the service account's IAM token. The script uses the IAM token and the environment variable to retrieve the password from the secret. This way, the password is used in the CI script but kept in an external storage.
To enable a Managed Service for GitLab instance to access Yandex Lockbox secrets:
- Set up your infrastructure.
- Configure the CI pipeline.
- Check the result.
- Fix potential vulnerabilities.
If you no longer need the resources you created, delete them.
Required paid resources
The infrastructure support cost includes:
- Fee for disks and continuously running VMs (see Yandex Compute Cloud pricing).
- Fee for storing the secret and requests to the secret (see Yandex Lockbox pricing).
- Fee for a public IP address (see Yandex Virtual Private Cloud pricing).
Set up your infrastructure
-
Create and activate a Managed Service for GitLab instance.
-
Create a Yandex Lockbox secret named
MY_SECRET. -
Create a service account with the
lockbox.payloadViewerrole.This role has no permissions to get the list of secrets; therefore, without the secret ID, an attacker cannot retrieve the password from the secret.
-
Create
a GitLab environment variable for your project. Configure it as follows:-
Key:
MY_SECRET. -
Value: ID of the Yandex Lockbox secret you created.
-
Mask variable: Enabled.
To protect your passwords from attackers, mask the variable. This way, only users with the
MaintainerorOwnerroles in your GitLab project will be able to see the variable value, i.e., the Yandex Lockbox secret ID . If connected to a virtual machine with GitLab Runner, an attacker will not be able to retrieve the password from a secret without knowing the secret ID.
-
-
Install GitLab Runner on a separate Yandex Compute Cloud VM. When creating a VM, specify the service account you previously created.
In GitLab Runner settings, make it only available for protected branches
and specific projects (Protected and Lock to current projects). If you do not provide these settings, CI scripts with passwords can be run in projects that are not monitored by the information security team. Thus, your passwords could be compromised.Configuring GitLab Runner
-
Open the GitLab project in your browser.
-
In the left-hand menu, go to Settings → CI/CD.
-
Under Runners, click Expand.
-
Next to the GitLab Runner you need, click
and enable the following options:- Protected: GitLab Runner will only work with the protected branches.
- Lock to current projects: GitLab Runner will only work with the current projects.
-
Click Save changes.
You can learn more about GitLab Runner settings in this GitLab guide
. -
Configure the CI pipeline
-
Create a branch for the CI pipeline. Enable its protection
at the project level. -
Switch locally to the branch you created.
-
In the repository root, create a file named
.gitlab-ci.ymlwith the following CI script to output the Yandex Lockbox secret value:stages: - build build: stage: build script: - > export IAM_TOKEN_JSON=`curl --silent --header "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token` - export TOKEN=`echo $IAM_TOKEN_JSON | jq -rMc '.access_token'` - > curl --silent -header "Authorization: Bearer $TOKEN" https://payload.lockbox.api.cloud.yandex.net/lockbox/v1/secrets/$SECRET_ID/payload - > export SECRET_JSON=`curl --silent --header "Authorization: Bearer $TOKEN" https://payload.lockbox.api.cloud.yandex.net/lockbox/v1/secrets/$SECRET_ID/payload` - export VALUE_OF_MY_SECRET=`echo $SECRET_JSON | jq -rMc '.entries[] | select(.key | contains("MY_SECRET")) | .textValue'` - echo $VALUE_OF_MY_SECRET -
Create a commit and push it to the remote repository named
origin:git add . && git commit -m "Added .gitlab-ci.yml" && git push
This will run a build that will write the Yandex Lockbox secret value to the VALUE_OF_MY_SECRET environment variable.
Check the result
- In GitLab left-hand menu, navigate to Build → Pipelines.
- Make sure the build status is Passed. This means that the build was successful.
Fix potential vulnerabilities
-
Enable and configure approval rules for the CI pipeline branch.
This will prevent attackers from getting the variable value using such commands as
env,printenv, orecho. The information security team will be able to track changes in the branch. -
Set up a security group for your VM with GitLab Runner. In this security group, disable incoming traffic that allows external access to the VM.
If an attacker connects to a VM with GitLab Runner and knows the Yandex Lockbox secret ID, they can access the secret.
Delete the resources you created
Some resources are not free of charge. Delete the resources you no longer need to avoid paying for them: