Authenticate Gitlab to access secrets from HashiCorp Vault


Bicycle

Secrets Distribution

The problem domain of secrets distribution is a common one. You have a secret, you want to distribute to a service, and you want to implement this action in a secure way. The secret could be a password, an API key, a TLS certificate, or anything else that you want to keep secret.

Also, a common problem within secrets distribution is the need to rotate secrets. This is a security best practice, and it's often required by compliance standards. Rotating secrets can be a complex process, especially when you must do it across multiple services.

And finally, you might also be aware of the problem that distributed secrets can be hard to manage. You might have secrets stored in multiple places, and it can be hard to keep track of where they are and who is allowed to access them.

Authenticate Gitlab to access secrets from HashiCorp Vault

HashiCorp Vault is a secrets management tool that can help you solve these problems. Vault can store secrets, distribute them to services, and rotate them. It can also help you manage access to secrets, so you can manage access permissions effectively.

You can configure Gitlab to authenticate against HashiCorp Vault to retrieve necessary secrets without duplication of data. This way you can store your secrets in a central place and fetch them from your services in a secure way. For this setup already exists a documentation within Gitlab documentation, but we want to show you how to set up the authentication with HashiCorp Terraform.

Json Web Token Authentication (JWT)

1resource "vault_jwt_auth_backend" "jwt_gitlab" {
2  description        = "Gitlab.com auth backend"
3  path               = "jwt_gitlab"
4  oidc_discovery_url = "https://gitlab.com"
5  bound_issuer       = "https://gitlab.com"
6  default_role       = "gitlab_readonly"
7}

As first step, we need to define the JWT authentication backend for out Gitlab instance - in our sample we are going to stay on gitlab.com. In this first configuration block is already a reference to the default role that will be used on the authentication workflow if the client does not request a dedicated role.

 1resource "vault_jwt_auth_backend_role" "jwt_gitlab_readonly" {
 2
 3  backend                = vault_jwt_auth_backend.jwt_gitlab.path
 4  role_name              = "gitlab_readonly"
 5  role_type              = "jwt"
 6  user_claim             = "user_email"
 7  token_explicit_max_ttl = 60 * 10
 8  token_policies         = [vault_policy.packer_ansible_update.name, vault_policy.tfc_access.name, "default"]
 9  bound_claims_type      = "glob"
10  bound_claims = {
11    namespace_path = "infralovers"
12    project_path   = "**/*"
13  }
14}

The default role in this sample we define the bound_claims to match the namespace of the infralovers organisation within gitlab.com. On the documentation of Gitlab you will find a more detailed description of parameters that can be useful to be aware of, when tailoring the bound_claims definition for you roles according to the actual requirements for certain clients.

JWT Authentification within Gitlab CI/CD Pipeline

Afterwards, we are able to modify our Gitlab CI/CD pipeline to consume the previous configuration and access secrets from our Vault installation.

 1variables:
 2  VAULT_ADDR: "https://vault.example.com"
 3  VAULT_ROLE: "gitlab_readonly"
 4  VAULT_PATH: "jwt_gitlab"
 5  VAULT_AUTH_PATH: "auth"
 6
 7job_with_secrets:
 8  id_tokens:
 9    VAULT_ID_TOKEN:
10      aud: $VAULT_ADDR
11  secrets:
12    STAGING_DB_PASSWORD:
13      vault: secret/myproject/staging/db/password@secrets # authenticates using $VAULT_ID_TOKEN
14  script:
15    - access-staging-db.sh --token $STAGING_DB_PASSWORD

The variables block defined environment variables to define the parameters we specified on the previous terraform configuration. The actual id_tokens block and secrets block will inject tasks into the pipeline that Gitlab will interact with our HashiCorp Vault instance to fetch the defined secrets and pass this information as environment variable into the actual pipeline job.

Have fun trying it yourself!

Go Back explore our courses

We are here for you

You are interested in our courses or you simply have a question that needs answering? You can contact us at anytime! We will do our best to answer all your questions.

Contact us