Set-OPS-Public/docs/autorisation.md
Daniel Allaire 84afa6a2af docs : l'autorisation devient une doctrine (D-65, D-66)
L'authentification etait resolue et gardee ; l'autorisation n'existait nulle
part. `ou=groups` est cree depuis le debut et AUCUN des 29 roles ne le lit —
toute personne authentifiee obtient le defaut du service.

D-65 : les groupes LDAP portent l'autorisation, Keycloak les projette.
L'argument est mecanique : Dovecot et Postfix ne savent pas lire un role
Keycloak. L'y loger rendrait la moitie courriel aveugle et imposerait deux
modeles de permissions.

D-66 : un service nomme un GROUPE, jamais une personne. Un depart devient une
ligne au plan, sans toucher un service.

Le vocabulaire d'habilitation reste celui du service : une echelle commune
devrait etre traduite partout, et la traduction est ou l'habilitation se perd.

Rien n'est construit : registre, role, meta/acces.yml et P31 restent a ecrire.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 13:05:48 -04:00

5.5 KiB

Autorisation : le groupe LDAP est l'unité d'habilitation

Directive d'architecture du 2026-08-07. L'authentification dit qui tu es (authentification.md). Ce document dit ce que tu peux faire. Les deux sont distincts, et le second n'existait pas.

1. Le constat, mesuré

ou=groups est créé par serveur_openldap depuis le début. Au 2026-08-07, c'est un conteneur vide qu'aucun service ne lit : pas un memberOf, pas un filtre de groupe dans les 29 rôles du catalogue.

Conséquence : toute personne qui s'authentifie obtient ce que le service accorde par défaut. Selon le service, c'est tout ou rien — jamais ce qu'on a décidé, puisqu'on n'avait rien décidé.

Ce n'est pas une négligence : l'authentification était le problème à résoudre d'abord. Mais une chaîne d'identité sans habilitations n'est qu'une porte d'entrée.

2. La décision : LDAP porte les habilitations, pas Keycloak

Les groupes LDAP sont la source unique de l'autorisation. Keycloak les projette en rôles pour le web ; les services non-OIDC les lisent directement.

L'argument n'est pas doctrinal, il est mécanique : Dovecot et Postfix ne savent pas lire un rôle Keycloak. Si l'habilitation vivait dans Keycloak, la moitié courriel du système y serait aveugle, et il faudrait tenir deux modèles de permissions — donc les voir diverger.

C'est le prolongement de ce qui était déjà décidé pour les comptes (D-39), étendu aux habilitations : une identité, un mot de passe, et un seul endroit qui dit ce qu'elle peut.

Ce que porte LDAP Ce qui le consomme
l'identité (ou=people) Keycloak (fédération), Dovecot, Postfix
l'habilitation (ou=groups) Keycloak → rôles OIDC ; Dovecot/Postfix directement

3. Un service nomme un groupe, jamais une personne

C'est la règle qui rend une arrivée ou un départ instantané : une ligne au plan, aucun service touché. Un service qui nomme quelqu'un crée une dette qu'on découvre le jour du départ, service par service.

Chaque rôle déclare donc son modèle dans meta/acces.yml — même patron que meta/flux.yml et meta/authentification.yml :

acces:
  - groupe: obs-admin      # groupe LDAP, déclaré au plan
    accorde: Admin         # ce que ça vaut DANS ce service
    raison: >-
      Édition des tableaux de bord et des sources de données.      

Le champ accorde est le vocabulaire du service, pas un niveau abstrait : Admin chez Grafana, owner chez Forgejo, admin chez Nextcloud. Inventer une échelle commune obligerait à la traduire partout, et la traduction est exactement l'endroit où une habilitation se perd.

4. Les groupes se déclarent au plan

Un registre instance/plan/acces.yml déclare les personnes et les groupes, et le rôle qui peuple LDAP le dérive — comme les VMID, les adresses et le supernet. Le plan reste la seule chose qu'un opérateur édite.

Trois ou quatre groupes, pas un modèle RBAC. Chezlepro a un sysadmin et quatorze VM ; une hiérarchie fine coûterait plus qu'elle ne protège. Affiner plus tard est facile, l'inverse ne l'est pas.

Groupe Qui Ce que ça ouvre
sysadmin l'exploitant administration des services, supervision
personnel toute personne de l'organisation courriel, nuage, espace de travail
dev qui écrit du code forge

Le groupe personnel mérite d'être nommé plutôt que sous-entendu : sans lui, « avoir un compte » et « avoir une boîte aux lettres » seraient la même chose, et on ne saurait pas désactiver l'un sans l'autre.

5. Le premier mot de passe

Une personne est un tiers : elle choisit son mot de passe, le dépôt ne l'invente pas. La règle du dépôt est constante — un secret se génère quand le dépôt en est la source, et se saisit quand un tiers l'est. Mais il faut bien un secret pour la première connexion.

Généré, déposé en voûte, changement forcé à la première ouverture. Le secret généré n'est donc jamais le mot de passe de quelqu'un : c'est un jeton d'amorçage à durée de vie d'un usage. La distinction compte — sans le changement forcé, l'exploitant connaîtrait le mot de passe de chacun, ce qui contredit « une identité, une personne ».

6. La garde

Une directive qu'aucune garde ne vérifie finit par ne plus être vraie — c'est ce que authentification.md §5 a déjà appris. P31 confronterait les deux sens :

  • tout groupe nommé dans un meta/acces.yml existe au plan ;
  • toute personne déclarée appartient à au moins un groupe ;
  • aucun rôle web-sso n'accorde d'accès sans déclarer son modèle ;
  • aucun meta/acces.yml ne nomme une personne.

Le dernier point est le plus important : c'est la règle du §3, et c'est celle qu'on enfreint sans le remarquer, un service à la fois.

7. Ce que ce document ne couvre pas

L'autorisation machine-à-machine. Les comptes de service (PostgreSQL, Redis, jetons d'API) ne sont pas des humains et ne passent pas par LDAP — ils vivent en voûte, liés à un service et non à une personne. Les mêler aux groupes humains rendrait les deux illisibles.

Les permissions internes à un service. Qui peut écrire dans quel dépôt Forgejo, qui voit quel dossier Nextcloud : ça se règle dans le service, à partir du groupe qu'il a reçu. Set-OPS accorde l'entrée et le niveau ; il ne réimplémente pas le modèle interne de chaque application.

Rien n'est construit. Ce document fixe la direction ; le registre, le rôle qui peuple LDAP, les meta/acces.yml et la preuve P31 restent à écrire.