GitLab CI Integration

Step by Step GitLab CI Integration with Vault

Intro

You can use Vault as secrets store for GitLab CI variables. JWT token is used to achieve this.

Using Vault as a secrets store gives you granular GitLab CI variables rights control.

Next pic shows how the secret retrieval to CI process works:

  1. The User starts GitLab CI.

  2. GitLab gathers User metadata. Login, email, running branch, etc.

  3. GitLab packs this metadata into base64 JWT token.

  4. GitLab signs JWT token with GitLab hidden private key. Now we have signed base64 text with User metadata (JWT token).

  5. You can use GitLab CI job command to request from Vault API a secret using this JWT token and Vault Role name (manually created in Vault). Or use a custom bash script in GitLab job to do the same.

  6. When Vault receives a request for secret it checks JWT signature from configured GitLab server address.

  7. Vault reads JWT metadata, and checks rights for this metadata and role (policy). Gives back a new Vault token with corresponding rights for secrets.

  8. Using this Vault token GitLab reads a secret from Vault store into CI shell.

Example of decoded JWT token for GitLab User gitlabuserloginone:

Setup

Activate JWT auth support in Vault node and add GitLab server (NOT GitLab Runner) connection:

Create a role for GitLab repository CI:

Create an access policy for the role above. This example is an access policy with a random name (gitlabuserloginone) with rights to read Vault secrets on the specified path (with project number for usage in scripting):

This role and policy allow for gitlabuserloginone from CI of project 6969 and main or master branch to access secrets in Vault path gitlabsecrets/6969 ("data" is not shown in UI of KV v2).

GitLab CI Scripts

First, define Vault server address in GitLab Variable VAULT_ADDR:

Next we can use this snippet in Gitlab CI to get (for free! no premium GitLab needed) secrets into running CI shell:

To use this script we must run our gitlab job inside container runner (or inside shell runner) with curl, jq available:

In this example k8s-utils:latest is the custom-build docker image with curl, jq, and other utils.

Last updated

Was this helpful?