ADR-0029 — Authentification LDAP et autorisation opérateur↔projet dans SIRRAT (moindre privilège au déploiement)¶
Date : 2026-08-09
Catégorie : B (sécurité / autorisation plateforme)
Décideur : Lead architecte DYNORS — validée CTO le 2026-08-12
Statut : Acceptée (2026-08-12) — implémentation par paliers, après l'exécuteur de déploiement
S'appuie sur : [[0015-sso-interne-echange-explicite-portail]], [[0019-modele-sirrat-dimension-couloir]] ; dynors-auth (LDAP central) ; OpenLDAP socle (dc=dynors,dc=com)
Sources : applications/sirrat/backend/.../config/SirratHumanSessionService.java (login local actuel), .../service/DeploymentAuthorizationService.java (règles d'autorisation), .../security/SirratScope.java, .../controller/HumanAuthController.java ; profil dynors-platform/auth/.../application-ldap-socle.yml ; seed 008-sirrat-dawalale-seed.yaml
Contexte¶
SIRRAT est le plan de contrôle du déploiement : il décide + trace, il n'exécute pas. État réel du code :
- Identité humaine = un compte local unique (
sirrat.security.human.local-username/-password, viaSirratHumanSessionService) donnant un rôleSIRRAT_OPSglobal. Aucune intégration LDAP. - Autorisation de déploiement (
DeploymentAuthorizationService) : vérifie la release-readiness — campagne unique par projet/env, embargo prod, karma minimum, Gate 2 (Tech Lead), Gate 3 (CTO) + PV recette, version non déjà déployée, manifeste effectifREADY. Elle ne vérifie PAS que l'opérateur a accès au projet déployé. - Les
SirratScope(MANIFEST_READ/RESOLVE,ENV_WRITE,TEMPLATE_ADMIN) sont des capacités d'API, pas un droit par projet.
Conséquence : en l'état, un opérateur authentifié peut déclencher une autorisation pour n'importe quel projet. Cela viole le moindre privilège : on ne doit pas pouvoir déployer une application à laquelle on n'a pas accès. Or l'identité DYNORS de référence est l'annuaire LDAP (déjà debout : socle dc=dynors,dc=com, ou=people/ou=groups) et l'auth centrale est dynors-auth.
Décision¶
-
Identité humaine SIRRAT = LDAP, déléguée à
dynors-auth. Le login local (SirratHumanSessionService) est un échafaudage de smoke (staging VPS). Cible : la personne s'authentifie via dynors-auth (login LDAP → JWT central portant identité + groupes) ; SIRRAT fait confiance à ce JWT pour la session console et ne réimplémente pas LDAP. Cohérent [[0015-sso-interne-echange-explicite-portail]]. -
Source de vérité de l'accès-projet = groupes LDAP, réconciliés avec l'appartenance GitLab. « Peut déployer l'app X » ⇔ « membre du/des groupe(s) LDAP mappé(s) sur X ». Là où GitLab est synchronisé sur LDAP (cible), les groupes LDAP sont les accès repo → une seule source de vérité (l'annuaire). L'appartenance GitLab (API) sert de réconciliation/vérification, jamais de source parallèle. Un mapping minimal
groupe LDAP → projet(s) SIRRATest tenu côté plateforme (Forge/SIRRAT), aligné surSirratProject.gitlab_url. En cas de divergence, LDAP fait foi. -
Enforcement dans SIRRAT — nouvelle règle d'autorisation, en plus des gates :
DeploymentAuthorizationServicerefuse/api/authorizesi l'opérateur n'a pas le droit sur le projet, même gates verts ;-
le dashboard est scopé : un opérateur ne voit et ne peut cibler que ses apps.
-
Séparation des rôles renforcée. L'opérateur (déclenche le déploiement, borné à son périmètre) reste distinct du Tech Lead (Gate 2) et du CTO (Gate 3 + PV). Le droit-projet borne l'opérateur ; les gates bornent la promotion.
-
Ne pas faire de SIRRAT un annuaire ni un miroir permanent de GitLab : identité = LDAP central ; accès = groupes LDAP (réconciliés) ; mapping groupe→projet = donnée plateforme minimale.
Conséquences¶
Positif : moindre privilège réel au déploiement ; traçabilité qui a déployé quoi attachée à une identité annuaire ; une seule identité (plus de comptes locaux à gérer) ; s'appuie sur le socle LDAP + dynors-auth déjà en place ; complète la séparation des rôles existante (Gates 2/3).
Coût / risques : le login console dépend désormais de la disponibilité de dynors-auth ; nécessite un référentiel de mapping groupe LDAP → projet (à modéliser + peupler) ; la réconciliation LDAP↔GitLab doit être cadrée (autoritaire = LDAP) ; migration du login local → JWT dynors-auth (échafaudage à retirer) ; règle d'autorisation + scoping dashboard à implémenter.
Composants impactés : SirratHumanSessionService / HumanAuthController (→ vérification du JWT dynors-auth), DeploymentAuthorizationService (règle opérateur↔projet), DashboardController (scoping), modèle SIRRAT (mapping groupe→projet), Forge (déclaration des groupes/accès), frontend (login SSO + vues scopées).
Placement roadmap : palier d'authentification, à réaliser après l'exécuteur de déploiement (DeploymentExecutor, palier 2). Le login local reste toléré uniquement hors-prod (smoke) jusqu'à la bascule.
Validation CTO — 2026-08-12¶
Les cinq décisions sont validées telles que rédigées.
Ce que cette validation ferme¶
La décision 1 — « SIRRAT fait confiance à ce JWT et ne réimplémente pas LDAP » — a une conséquence directe qui n'était pas écrite : SIRRAT ne se connecte jamais à l'annuaire.
La tâche « livrer l'UI d'admin LDAP dans SIRRAT » est donc caduque sous cette forme.
Elle était réputée bloquée sur l'exposition SLY ; elle l'était en réalité sur cette
décision. Arbitrage CTO du même jour : l'administration de l'annuaire va dans
dynors-auth, qui détient déjà la connexion LDAP et l'émission des JWT. Aucune autre
application DYNORS ne devient un point d'accès à l'annuaire.
Constat qui a mené là (vérifié sur le dépôt, pas déduit) : SIRRAT n'a aucune dépendance
LDAP, aucune configuration spring.ldap.*, aucun client — seulement un indicateur
de santé désactivé et un commentaire de SecurityConfig renvoyant à un futur adapter.
Construire l'écran aurait donc exigé d'ajouter cette connexion la veille de valider un ADR
qui l'interdit.
Ce qui reste ouvert, et doit être vérifié avant d'implémenter¶
La décision 2 s'appuie sur « là où GitLab est synchronisé sur LDAP (cible) ». Ce cible entre parenthèses n'a pas été vérifié. Si la synchronisation n'existe pas encore, la réconciliation LDAP↔GitLab n'est pas une vérification mais une seconde source de vérité — ce que la décision 5 interdit explicitement.
À établir avant le premier développement, dans cet ordre :
- La synchronisation GitLab↔LDAP est-elle en place ? Sinon, la décision 2 s'applique avec LDAP seul, et la réconciliation GitLab est différée — pas contournée.
- Le mapping
groupe LDAP → projet SIRRAT: où vit-il (Forge), qui l'écrit, comment il est audité. - Le défaut que cet ADR corrige est actif aujourd'hui : un opérateur authentifié peut demander une autorisation pour n'importe quel projet. Les gates bornent la promotion, rien ne borne le périmètre. À traiter comme un correctif de sécurité, pas seulement comme une évolution.