[Yandex Cloud documentation](../../index.md) > [Yandex Managed Service for GitLab](../index.md) > [Tutorials](index.md) > Secure storage of GitLab CI passwords as Yandex Lockbox secrets

# Secure storage of GitLab CI passwords as Yandex Lockbox secrets

# Secure storage of GitLab CI passwords as Yandex Lockbox secrets

You can securely store passwords as [Yandex Lockbox secrets](../../lockbox/concepts/secret.md) 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:

1. [Set up your infrastructure](#infra).
1. [Configure the CI pipeline](#ci).
1. [Check the result](#check-result).
1. [Fix potential vulnerabilities](#eliminate-vulnerabilities).

If you no longer need the resources you created, [delete them](#clear-out).

## Required paid resources {#paid-resources}

The infrastructure support cost includes:

* Fee for [disks](../../compute/concepts/disk.md) and continuously running VMs (see [Yandex Compute Cloud pricing](../../compute/pricing.md)).
* Fee for storing the secret and requests to the secret (see [Yandex Lockbox pricing](../../lockbox/pricing.md)).
* Fee for a [public IP address](../../vpc/concepts/address.md#public-addresses) (see [Yandex Virtual Private Cloud pricing](../../vpc/pricing.md)).

## Set up your infrastructure {#infra}

1. [Create and activate](../operations/instance/instance-create.md) a Managed Service for GitLab instance.
1. [Create a GitLab project](https://docs.gitlab.com/ee/user/project/).
1. [Create](../../lockbox/operations/secret-create.md) a Yandex Lockbox secret named `MY_SECRET`.
1. [Create a service account](../../iam/operations/sa/create.md) with the `lockbox.payloadViewer` role.

   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.

1. [Create](https://docs.gitlab.com/ee/ci/variables/#for-a-project) 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 `Maintainer` or `Owner` roles 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.

1. [Install GitLab Runner](install-gitlab-runner.md) 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](https://docs.gitlab.com/ee/user/project/protected_branches.html) 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.

   {% cut "Configuring GitLab Runner" %}

   1. Open the GitLab project in your browser.
   1. In the left-hand menu, go to **Settings** → **CI/CD**.
   1. Under **Runners**, click **Expand**.
   1. Next to the GitLab Runner you need, click ![icon](../../_assets/console-icons/pencil.svg) 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.

   1. Click **Save changes**.

   Read more about GitLab Runner settings in [this GitLab guide](https://docs.gitlab.com/ee/ci/runners/configure_runners.html).

   {% endcut %}

## Configure the CI pipeline {#ci}

1. Create a branch for the CI pipeline. [Enable its protection](https://docs.gitlab.com/ee/user/project/protected_branches.html#for-one-project) at the project level.
1. Switch locally to the branch you created.
1. In the repository root, create a file named `.gitlab-ci.yml` with the following CI script to output the Yandex Lockbox secret value:

   ```yaml
   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
   ```

1. Create a commit and push it to the remote repository named `origin`:

   ```bash
   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 {#check-result}

1. In GitLab left-hand menu, navigate to **Build** → **Pipelines**.
1. Make sure the build status is **Passed**. This means that the build was successful.

## Fix potential vulnerabilities {#eliminate-vulnerabilities}

1. [Enable and configure](../operations/approval-rules.md) approval rules for the CI pipeline branch.

   This will prevent attackers from getting the variable value using such commands as `env`, `printenv`, or `echo`. The information security team will be able to track changes in the branch.

1. [Set up a security group](../../vpc/operations/security-group-add-rule.md) 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 {#clear-out}

Some resources are not free of charge. Delete the resources you no longer need to avoid paying for them:

* [GitLab instance](../operations/instance/instance-delete.md)
* [Yandex Lockbox secret](../../lockbox/operations/secret-delete.md)
* [VM with GitLab Runner](../../compute/operations/vm-control/vm-delete.md)
* [Service account](../../iam/operations/sa/delete.md)