GitLab logo

Secret handling in GitLab CI

In GitLab CI, secrets are usually stored as environment variables and injected into the pipeline. This approach to secret handling has a number of disadvantages.

For starters, to run tests locally with this setup, secrets need to be manually synchronized between different developers and environments, which makes rotating secrets needlessly complicated.

Moreover, any environment variables defined in the pipeline also need to be configured on the local workstation.

Secret management with SecretHub

SecretHub simplifies secret management by storing secrets securely in a central database and providing them automatically to all authenticated parties.

When using SecretHub, the secret to environment variable mapping will be moved to a secrethub.env file which can also be used for running the code in production or locally, from your IDE or the command line.

What’s more, SecretHub supports versioning, which simplifies the process of regularly rotating secrets.

Before you begin

To follow along, you will need to:

Step 1: Write your secrets

First, write your secrets to SecretHub to have them provided to the CI pipeline or any development environment.

SecretHub organizes secrets in repositories. To create a repository for your secrets use the repo init command:

secrethub repo init your-username/repo-name

Now you can write the secrets that you want to have access to later with the write command:

secrethub write your-username/repo-name/password

Step 2: Add the secrethub.env file

To provide a mapping between environment variables and secrets, create a file named secrethub.env in your project’s root directory, similar to this one:

DB_HOST = localhost
DB_USER = test-user
DB_PASS = {{ your-username/repo-name/password }}

The path {{ your-username/repo-name/password }} references the secret defined in the previous step.

Step 3: Set up your GitLab CI configuration

To configure your Gitlab CI pipeline add a file named .gitlab-ci.yml to your repository, similar to this one:

image: node:alpine

stages:
    - test

test:
    stage: test
    before_script:
        - apk add --repository https://alpine.secrethub.io/alpine/edge/main --allow-untrusted secrethub-cli
    script:
        - secrethub run -- node test.js

The command in the before_script section installs the SecretHub CLI onto the pipeline environment.

Alternatively the installation can be included in a docker image. With this approach the SecretHub CLI will not be installed every time the pipeline is executed.

On the last line of the file, the command you usually run test with (in this case node test.js) is wrapped with the secrethub run command. This command fetches the secrets required by the application and injects them as environment variables according to the mapping specified in the secrethub.env file.

Note that in this example we will be using a Node.js app, however the same steps apply for other test commands as well.

Step 4: Create a SecretHub service account

SecretHub uses service accounts to grant non-human parties (such as CIs) access to secrets. To create a service account, run the secrethub service init command:

secrethub service init --permission read your-username/repo-name

This command will output the generated account credential. Make sure to copy it as it will be needed in the next step.

The --permission read flag will grant the service read access to the specified repo.

Note that you can use the --clip flag to write the output of the command to your clipboard:

secrethub service init --clip --permission read your-username/repo-name

Step 5: Provide the credential to GitLab CI

  1. Open your GitLab project in the browser and go to the Settings, CI / CD page.
    Go to the settings, CI / CD page in the GitLab web app
  2. Scroll to the Variables section and click on expand.
    Scroll to the variables section and click on expand
  3. Set the variable type to Variable, the key to SECRETHUB_CREDENTIAL and the value to the credential generated in the previous step. Make sure to tick Protected and choose the appropriate scope of this variable.
    Set type, key and value to variable, SECRETHUB_CREDENTIAL and the previously generated key respectively

    Note that GitLab does not support masking the SECRETHUB_CREDENTIAL since it contains a . character.

  4. Click on Save variables.

You have successfully configured your GitLab CI/CD pipeline to automatically fetch secrets from the SecretHub API, while also simplifying secret provisioning in development and production environments. Moreover, you can now rotate your secrets and the pipeline will automatically use their latest version.

See also

Happy coding!