LightcodeSysadmin Open Source

S'authentifier à Vault avec Gitlab en OIDC

Gitlab peut être utilisé pour vous authentifier sur des sites externes à Gitlab en utilisant le protocole OIDC. Hashicorp Vault permet d’utiliser Gitlab comme source d’authentification pour vos utilisateurs.

Introduction

Gitlab, avec ses nombreuses fonctionnalités, peut devenir le cœur de votre écosystème. Il peut tout à fait être utilisé comme Identity Provider (IdP) notament grâce à sa gestion du protocole OIDC. Vous pourrez donc utiliser Gitlab pour vous authentifier auprès de sites externes supportant le protocole OIDC comme c’est le cas de Vault ou de Grafana. Dans mon article précédent, j’avais parlé de l’authentification entre Gitlab et Vault au sein des pipelines. Cette fois-ci, nous allons permettre aux utilisateurs de votre instance de Gitlab de se connecter à Vault afin de récupérer des secrets ou d’en ajouter.

Lors du processus d’authentification, plusieurs échanges seront réalisés entre Gitlab et Vault. Cette partie est complètement transparente pour l’utilisateur, mais il est nécessaire d’en avoir conscience lorsque l’on réalise la configuration des logiciels. Nous allons procéder en deux temps : configurer Gitlab et ensuite réaliser la configuration de Vault à l’aide de Terraform. Il n’est pas nécessaire d’utiliser ce logiciel de configuration, mais je trouve qu’il est très pratique et permet de facilement reproduire les différences étapes que je vais vous montrer. Vous pouvez toutefois faire la même chose avec la commande curl par exemple.

Configurer Gitlab

Avant de commencer avant de travailler avec Vault, il faut créer une nouvelle application dans Gitlab afin de récupérer un “Application ID” et un “Secret”.

Depuis le panneau d’administration, aller dans la section “Applications”, puis créer une nouvelle application. Vous vous retrouverez face à ce formulaire :

Le champ “Redirect URI” doit contenir l’URL de votre serveur Vault ainsi que le callback sur l’adresse “localhost” afin de pouvoir faire fonctionner l’authentification en CLI. Voici un exemple :

http://localhost:8250/oidc/callback
https://vault.example.com/ui/vault/auth/oidc/oidc/callback

Vous devez également sélectionner oicd dans la liste des scopes. Une fois terminé, vous pouvez valider le formulaire. Vous serez redirigé vers une page contenant un application id et un secret. Nous allons avoir besoin de ces valeurs dans la deuxième partie de l’article.

Configurer l’OIDC de Vault

Création d’un backend OIDC

Vault supporte une multitude de backends d’authentification. Pour pouvoir utiliser l’OIDC, nous devons activer et configurer ce backend :

resource "vault_jwt_auth_backend" "gitlab_oidc" {
  path               = "oidc"
  type               = "oidc"
  oidc_discovery_url = var.gitlab_url
  oidc_client_id     = var.oidc_client_id
  oidc_client_secret = var.oidc_client_secret
  bound_issuer       = "localhost"
  default_role       = "demo"
}

Les backends d’authentification sont montés sur un chemin (path). Dans notre cas, nous allons laisser la valeur par défaut qui est oidc.

La configuration propre à l’OIDC se présente de la manière suivante :

  • oidc_discovery_url : l’URL de l’instance de votre Gitlab (par exemple : https://gitlab.example.com).
  • oidc_client_id : ce paramètre correspond au “Application ID” que nous avons généré créé dans l’étape précédente.
  • oidc_client_secret : ce paramètre correspond au “Secret” que nous avons généré dans l’étape précédente.

Les utilisateurs se connectant à Vault sans préciser de rôle recevront le rôle “demo” (default_role).

Création d’un rôle

Lorsque les utilisateurs vont se connecter à notre backend d’authentification, ils recevront un token lié à un rôle particulier. Un même backend d’authentification peut avoir plusieurs rôles, dans ce cas, l’utilisateur devra choisir le rôle à utiliser.

Les rôles vont également être lié à des RBAC appelées “policies” dans Vault. On va pouvoir spécifier un lot de contraintes lors de l’authentification afin de s’assurer que l’utilisateur a bien les droits d’utiliser notre rôle.

Dans notre exemple, nous allons créer un seul rôle que nous nommerons “demo” :

resource "vault_jwt_auth_backend_role" "gitlab_oidc_demo" {
  backend   = vault_jwt_auth_backend.gitlab_oidc.path
  role_type = vault_jwt_auth_backend.gitlab_oidc.type
  role_name = "demo"

  user_claim   = "nickname"
  groups_claim = "groups"
  oidc_scopes  = ["openid"]
  allowed_redirect_uris = [
    "http://localhost:8250/oidc/callback",
    "${var.vault_url}/ui/vault/auth/oidc/oidc/callback"
  ]

  token_policies = ["default"]
  token_ttl      = 3600
}

La première partie de la configuration permet de nommer notre rôle et de le lier à notre backend d’authentification.

La partie suivante configure l’OIDC. Lors de l’authentification, Gitlab va envoyer un token à Vault contentant des informations. La configuration du rôle va permettre de dire à Vault quels sont les champs à utiliser pour associer les utilisateurs et les groupes :

  • user_claim : nom du champ à utiliser pour identifier un utilisateur Gitlab. Ici nickname fait référence au nom de l’utilisateur dans Gitlab.
  • groups_claim : nom du champ à utiliser pour récupérer la liste des groupes de l’utilisateur. Gitlab nous fournit la liste des groupes de l’utilisateur dans la variable groups.

Le champ allowed_redirect_uris est utilisé pour valider les URL de redirection utilisées pendant la procédure d’authentification.

Comment s’authentifier ?

Depuis l’interface web

Pour vous connecter à Vault en utilisant l’interface web, vous devrez sélectionner la méthode “OIDC” puis cliquer sur “Sign in with Gitlab”. Le navigateur vous redirigera vers le formulaire de connexion de Gitlab. Une fois connecté, la fenêtre se fermera et vous serez connecté à Vault.

Depuis la CLI

Pour vous connecter en CLI, vous devrez commencer par exporter la variable d’environnement VAULT_ADDR contenant l’URL de votre Vault. Ensuite, vous pourrez utiliser la commande login de la commande Vault en précisant bien la méthode d’authentification.

export VAULT_ADDR=https://vault.example.com
vault login -method=oidc

Cette commande ouvrira dans votre navigateur le formulaire de connexion à Vault. Une fois connecté, la fenêtre se refermera et la commande vous rendra la main.

Création d’une policy pour un groupe

Pour cet article, j’ai décidé de créer un groupe dans Gitlab afin de le mapper avec une policy permettant d’éditer des secrets dans un certain chemin de Vault.

Créons d’abord le rôle de type external :

resource "vault_identity_group" "group" {
  name     = var.gitlab_group_name
  type     = "external"
  policies = ["default", "gitlab-${var.gitlab_group_name}"]
}

Deux policies sont associées à ce groupe, celle par défaut et une policy portant le nom du groupe Gitlab (vous pouvez mettre le nom que vous voulez).

Il faut ensuite associer ce groupe à notre backend d’authentification grâce à un alias de groupe :

resource "vault_identity_group_alias" "alias" {
  name           = vault_identity_group.group.name
  mount_accessor = vault_jwt_auth_backend.gitlab_oidc.accessor
  canonical_id   = vault_identity_group.group.id
}

Enfin, nous pouvons simplement créer la policy :

resource "vault_policy" "demo" {
  name = "gitlab-${var.gitlab_group_name}"

  policy = <<EOT
path "kv" {
  capabilities = ["list"]
}

path "kv/demo/*" {
  capabilities = ["list", "read", "create", "update", "delete"]
}
EOT
}

Après avoir fait ça, l’utilisateur devrait pouvoir tout dans dans le chemin kv/demo.

Conclusion

Dans cet article, nous avons vu comment mettre en œuvre l’authentification OIDC de Gitlab pour se connecter à des services externes. Nous avons vu comment l’utiliser avec Hashicorp Vault. Cette solution peut se révéler très pratique lorsque vous voulez avoir une politique de gestion des secrets unifiées entre vos pipelines et vos comptes utilisateurs dans Vault.

Vous pourrez retrouver sur mon compte Github l’intégralité du code utilisé dans cet article.

Voici quelques liens qui m’ont permis de rédiger cet article :