Aller au contenu

Configurer LDAP / Active Directory

Repod prend en charge l'authentification des utilisateurs auprès d'un annuaire LDAP ou de Microsoft Active Directory. Une fois configurée, les utilisateurs peuvent se connecter avec leurs identifiants d'entreprise existants. Repod utilise la bibliothèque Python ldap3 pour toutes les communications LDAP.


1. Prérequis

Avant d'ouvrir l'écran des paramètres Repod, récupérez les informations suivantes auprès de votre administrateur d'annuaire :

Information nécessaire Exemple
Nom d'hôte ou IP du serveur LDAP ldap.example.com
Port 389 (LDAP), 636 (LDAPS), 3268 (AD Global Catalog)
Sécurité du transport Plain, STARTTLS ou SSL/TLS
Bind DN cn=repod-svc,ou=service-accounts,dc=example,dc=com
Mot de passe bind Le mot de passe du compte de bind
Base DN ou=users,dc=example,dc=com
Filtre de recherche utilisateur (objectClass=person) ou (objectClass=user)
Attribut du nom d'utilisateur uid (OpenLDAP) ou sAMAccountName (AD)
Attribut email mail
Base DN des groupes (si mappage groupe-rôle utilisé) ou=groups,dc=example,dc=com

Tip

Utilisez un compte de service dédié en lecture seule comme Bind DN. Ce compte n'a besoin que de la permission read sur les sous-arbres utilisateurs et groupes. N'utilisez jamais un compte administrateur de domaine comme compte de bind.


2. Étape 1 — Ouvrir les paramètres LDAP

  1. Connectez-vous à l'interface web Repod à l'adresse http://repod.example.com:3003 en tant qu'administrateur.
  2. Allez dans Paramètres → LDAP.
  3. Le panneau de configuration LDAP apparaît. LDAP est désactivé par défaut tant que vous n'avez pas enregistré une configuration valide et activé le bascule.

3. Étape 2 — Configurer la connexion

Renseignez les champs de connexion à l'aide des informations récupérées dans la section prérequis.

Champ Description
Host Nom d'hôte ou adresse IP de votre serveur LDAP. N'incluez pas de schéma (ldap://) — celui-ci est contrôlé par les bascules SSL/STARTTLS ci-dessous.
Port Port TCP. Vaut par défaut 389 pour non chiffré/STARTTLS et 636 pour LDAPS.
SSL / LDAPS Activer pour envelopper l'intégralité de la connexion dans TLS (connexion sur le port 636). Mutuellement exclusif avec STARTTLS.
STARTTLS Activer pour faire évoluer une connexion en clair vers TLS après la négociation initiale (port 389). Préférable au non chiffré lorsque LDAPS n'est pas disponible.
Vérifier le certificat TLS Activé par défaut (verify_cert=true). Repod valide le certificat du serveur par rapport au magasin de CA du système. Ne désactiver qu'en environnement de test — jamais en production.
Chemin du bundle CA Optionnel. Chemin vers un fichier de certificat CA personnalisé (format PEM) à l'intérieur du conteneur backend, pour les CA internes absentes du magasin système.
Bind DN Le nom distinctif complet du compte de service utilisé pour interroger l'annuaire.
Mot de passe bind Mot de passe du compte de bind. Stocké chiffré au repos.
Base DN La racine du sous-arbre de l'annuaire dans lequel rechercher les utilisateurs.
Filtre utilisateur Filtre de recherche LDAP appliqué lors de la recherche d'un utilisateur. Combiné avec l'attribut de nom d'utilisateur au moment de la connexion. Exemple : (objectClass=person)
Attribut du nom d'utilisateur L'attribut LDAP qui contient le nom de connexion. uid pour OpenLDAP, sAMAccountName pour Active Directory.
Attribut email L'attribut LDAP qui contient l'adresse email de l'utilisateur. Généralement mail.

Ne jamais désactiver la vérification du certificat en production

Mettre Vérifier le certificat TLS sur off désactive toute validation de certificat. Un attaquant en position d'intercepteur (man-in-the-middle) sur votre réseau pourrait intercepter les identifiants. Ce paramètre n'existe que pour des environnements de test isolés avec des certificats auto-signés. En production, installez plutôt votre certificat CA dans le chemin du bundle CA.


4. Étape 3 — Mapper les groupes vers des rôles

Repod peut attribuer automatiquement des rôles aux utilisateurs en fonction de leur appartenance à des groupes LDAP. Configurez le mappage dans Paramètres → LDAP en renseignant les champs group_<role>.

Champ Rôle Repod accordé
group_admin admin
group_maintainer maintainer
group_uploader uploader
group_auditor auditor
group_reader reader

Exemple de mappage :

DN (ou CN) du groupe LDAP Rôle Repod
cn=repod-admins,ou=groups,dc=example,dc=com admin
cn=repod-maintainers,ou=groups,dc=example,dc=com maintainer
cn=repod-publishers,ou=groups,dc=example,dc=com uploader
cn=repod-auditors,ou=groups,dc=example,dc=com auditor
cn=repod-readers,ou=groups,dc=example,dc=com reader

Rôles Repod disponibles :

Rôle Permissions
admin Accès complet : gestion des utilisateurs, paramètres, GPG, décisions CVE.
maintainer Cycle de vie des paquets : upload, suppression, mise en quarantaine, décisions CVE, journaux d'audit.
uploader Upload et import de paquets. Ne peut pas supprimer, gérer les utilisateurs, ni accéder aux journaux d'audit.
auditor Lecture seule : journaux d'audit, file de revue CVE, tous les paquets. Ne peut ni uploader ni écrire quoi que ce soit.
reader Accès en lecture seule aux listes de paquets et au tableau de bord.

Repod évalue les groupes par ordre de priorité (admin > maintainer > uploader > auditor > reader) et attribue le rôle correspondant le plus élevé. Si un utilisateur n'appartient à aucun groupe mappé, le default_role est appliqué (par défaut reader).

Note

L'appartenance aux groupes est évaluée au moment de la connexion. Si vous ajoutez un utilisateur à un groupe dans LDAP, il reçoit le rôle Repod correspondant dès sa prochaine connexion — aucune attribution manuelle de rôle n'est nécessaire.


5. Étape 4 — Activer le provisionnement automatique

Lorsque Provisionner automatiquement les comptes est activé, Repod crée un enregistrement utilisateur local la première fois qu'une personne s'authentifie avec succès via LDAP. L'enregistrement local stocke :

  • Le nom d'utilisateur (à partir de l'attribut du nom d'utilisateur)
  • L'email (à partir de l'attribut email)
  • Le rôle (à partir du mappage de groupes, ou le rôle par défaut si aucun mappage ne correspond)
  • Un indicateur marquant le compte comme géré par LDAP

Les comptes gérés par LDAP ne peuvent pas voir leur mot de passe changé dans Repod — l'authentification renvoie toujours vers l'annuaire LDAP.

Si le provisionnement automatique est désactivé, un administrateur Repod doit créer manuellement le compte utilisateur avant que la personne puisse se connecter via LDAP.


6. Étape 5 — Tester la connexion

Avant d'enregistrer et d'activer LDAP, utilisez le bouton Tester la connexion en bas du panneau de paramètres.

Ce que fait le test :

  1. Ouvre une connexion TCP vers le serveur LDAP sur l'hôte et le port configurés.
  2. Négocie TLS si SSL ou STARTTLS est activé.
  3. Effectue un bind en tant que compte de service à l'aide du Bind DN et du mot de passe.
  4. Effectue une recherche d'un utilisateur correspondant à la Base DN et au filtre utilisateur configurés.
  5. Renvoie un succès ou une erreur structurée.

Interpréter le résultat :

Résultat Signification
« Connection successful » Tous les champs sont corrects. Cliquez sur Enregistrer et activez LDAP.
CERTIFICATE_VERIFY_FAILED Le certificat TLS du serveur n'est pas approuvé. Voir la résolution de problèmes ci-dessous.
INVALID_CREDENTIALS Le Bind DN ou le mot de passe bind est incorrect.
NO_SUCH_OBJECT La Base DN n'existe pas dans l'annuaire.
CONNECTION_REFUSED Hôte ou port incorrect, ou un pare-feu bloque la connexion.
SERVER_DOWN Le serveur LDAP est inaccessible depuis le conteneur backend Repod.

Tip

Si le test échoue avec une erreur réseau, vérifiez la connectivité depuis l'intérieur du conteneur backend : docker compose exec backend nc -zv ldap.example.com 389


7. Étape 6 — Première connexion LDAP

Une fois LDAP activé et la configuration enregistrée :

  1. Ouvrez la page de connexion Repod.
  2. Saisissez votre nom d'utilisateur LDAP (la valeur de sAMAccountName ou uid, pas le DN complet).
  3. Saisissez votre mot de passe LDAP.
  4. Cliquez sur Se connecter.

Repod se bind à l'annuaire en tant que compte de service, recherche l'utilisateur, vérifie les identifiants, évalue l'appartenance aux groupes, puis crée ou met à jour l'enregistrement utilisateur local.

Le JWT émis après une connexion LDAP réussie est identique à celui émis après une connexion locale — tous les appels API utilisent le même en-tête Authorization: Bearer <token> quelle que soit la méthode d'authentification.


8. Exemple de configuration OpenLDAP

Un déploiement OpenLDAP typique utilisant uid comme attribut de nom d'utilisateur :

Champ Valeur
Host openldap.example.com
Port 636
SSL Activé
STARTTLS Désactivé
Vérifier le certificat TLS Activé
Bind DN cn=repod-svc,ou=service-accounts,dc=example,dc=com
Mot de passe bind s3cr3tpassword
Base DN ou=users,dc=example,dc=com
Filtre utilisateur (objectClass=inetOrgPerson)
Attribut du nom d'utilisateur uid
Attribut email mail

Mappage de groupes :

DN du groupe LDAP Rôle Repod
cn=repod-admins,ou=groups,dc=example,dc=com admin
cn=repod-maintainers,ou=groups,dc=example,dc=com maintainer
cn=developers,ou=groups,dc=example,dc=com uploader

9. Exemple de configuration Active Directory

Active Directory utilise sAMAccountName pour les noms d'utilisateur courts, ou userPrincipalName pour les connexions au format UPN (user@domain).

Champ Valeur
Host dc01.corp.example.com
Port 636
SSL Activé
STARTTLS Désactivé
Vérifier le certificat TLS Activé
Bind DN CN=repod-svc,OU=Service Accounts,DC=corp,DC=example,DC=com
Mot de passe bind s3cr3tpassword
Base DN OU=Employees,DC=corp,DC=example,DC=com
Filtre utilisateur (objectClass=user)
Attribut du nom d'utilisateur sAMAccountName
Attribut email mail

sAMAccountName vs userPrincipalName

Utilisez sAMAccountName si vos utilisateurs se connectent avec leur nom d'utilisateur court (jsmith). Utilisez userPrincipalName s'ils se connectent avec leur UPN (jsmith@corp.example.com). Le nom de l'attribut doit correspondre exactement à ce que vos utilisateurs saisissent dans le champ de connexion Repod — il n'y a pas de normalisation automatique.

Mappage de groupes pour les groupes de sécurité AD :

DN du groupe LDAP Rôle Repod
CN=Repod-Admins,OU=Groups,DC=corp,DC=example,DC=com admin
CN=Repod-Publishers,OU=Groups,DC=corp,DC=example,DC=com uploader
CN=All-Staff,OU=Groups,DC=corp,DC=example,DC=com reader

Pour les requêtes Active Directory Global Catalog (recherche sur plusieurs domaines), utilisez le port 3268 (plain) ou 3269 (SSL) au lieu des ports LDAP standards.


10. Résolution de problèmes

CERTIFICATE_VERIFY_FAILED

Le certificat TLS du serveur LDAP n'est pas signé par une CA présente dans le magasin système du conteneur backend.

Options : 1. Recommandé : Montez votre certificat CA interne dans le conteneur backend et définissez le champ Chemin du bundle CA vers son emplacement.

# Dans docker-compose.yaml, sous le service backend :
volumes:
  - /etc/ssl/certs/internal-ca.pem:/etc/ssl/certs/internal-ca.pem:ro
Puis définissez Chemin du bundle CA sur /etc/ssl/certs/internal-ca.pem.

  1. Environnements de test uniquement : Désactivez Vérifier le certificat TLS dans les paramètres LDAP. Ne jamais faire ceci en production.

INVALID_CREDENTIALS

Le Bind DN ou le mot de passe bind est incorrect.

  • Vérifiez le format du Bind DN. Active Directory exige la forme complète CN=...,DC=..., pas seulement le nom d'utilisateur.
  • Vérifiez que le mot de passe du compte de service n'a pas expiré. Les comptes de service AD devraient avoir l'expiration du mot de passe désactivée.
  • Confirmez que le compte de service n'a pas été verrouillé suite à des tentatives de connexion échouées lors d'un test de connexion mal configuré précédent.

NO_SUCH_OBJECT

La Base DN n'existe pas dans l'annuaire, ou le compte de bind n'a pas la permission de la lire.

  • Vérifiez la Base DN en vous connectant avec ldapsearch depuis le conteneur backend Repod :
    docker compose exec backend \
      ldapsearch -H ldaps://ldap.example.com \
        -D "cn=repod-svc,ou=service-accounts,dc=example,dc=com" \
        -w "s3cr3tpassword" \
        -b "ou=users,dc=example,dc=com" \
        "(uid=testuser)"
    
  • Si la commande renvoie des résultats, la Base DN est correcte et le problème vient de la configuration de Repod. Si elle renvoie No such object, c'est la Base DN elle-même qui est incorrecte.

Le mappage de groupes ne s'applique pas

Les utilisateurs se connectent avec succès mais reçoivent le mauvais rôle.

  • Vérifiez que le DN du groupe dans la table de mappage est exactement correct, y compris la casse de chaque composant.
  • Vérifiez que l'utilisateur est bien membre du groupe dans LDAP :
    docker compose exec backend \
      ldapsearch -H ldaps://ldap.example.com \
        -D "cn=repod-svc,ou=service-accounts,dc=example,dc=com" \
        -w "s3cr3tpassword" \
        -b "cn=repod-admins,ou=groups,dc=example,dc=com" \
        "(member=uid=testuser,ou=users,dc=example,dc=com)"
    
  • Dans Active Directory, memberOf se trouve sur l'objet utilisateur ; dans OpenLDAP, member se trouve sur l'objet groupe. Repod interroge l'objet groupe — assurez-vous que l'attribut member du groupe contient le DN complet de l'utilisateur.