From 6f2acafdb64dceb5cf2dd32409dfc5ed6d3389d9 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Fri, 7 Aug 2026 13:59:33 -0400 Subject: [PATCH] acces : les cinq meta/acces.yml, et le mecanisme qui manque a chacun MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chaque role web declare le GROUPE qu'il reconnait et ce qu'il lui accorde. Un troisieme champ s'est impose en ecrivant : `porte_par` — le mecanisme qui transporte reellement l'habilitation. Sans lui, les declarations auraient decrit une chaine inexistante. Etat mesure : grafana `role-realm` (reel) ; forgejo, nextcloud et keycloak `aucun` ; icingaweb2 `liste-uid` — il NOMME DES PERSONNES, ce que D-66 interdit. Le maillon manquant est chez Keycloak : `role_assignments` assigne un role a un UTILISATEUR, et son propre commentaire l'admettait (« en prod, preferer l'assignation via groupe d'annuaire »). Sans group-ldap-mapper, les groupes LDAP n'atteignent jamais les services. Sa meta a donc une autre forme, `acces_projection` : Keycloak projette au lieu de consommer (D-65). Defaut corrige : `serveur_icingaweb2_admins` valait "testmail", un compte de test code en dur dans le moteur qu'aucune instance ne surchargeait — le seul administrateur declare de la supervision etait un utilisateur inexistant. Il suit desormais l'uid d'amorcage. Verifie sur mon-01 : users = "sysadmin". Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 38 ++++++++++++++++++++++ roles/serveur_forgejo/meta/acces.yml | 19 +++++++++++ roles/serveur_grafana/meta/acces.yml | 19 +++++++++++ roles/serveur_icingaweb2/defaults/main.yml | 11 ++++++- roles/serveur_icingaweb2/meta/acces.yml | 13 ++++++++ roles/serveur_keycloak/meta/acces.yml | 30 +++++++++++++++++ roles/serveur_nextcloud/meta/acces.yml | 18 ++++++++++ 7 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 roles/serveur_forgejo/meta/acces.yml create mode 100644 roles/serveur_grafana/meta/acces.yml create mode 100644 roles/serveur_icingaweb2/meta/acces.yml create mode 100644 roles/serveur_keycloak/meta/acces.yml create mode 100644 roles/serveur_nextcloud/meta/acces.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 72c3b11..0c976e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,44 @@ ## 2026-08-06 — le chemin nord-sud devient dérivable +### Les cinq `meta/acces.yml` — et ce qu'ils rendent visible + +Chaque rôle web déclare désormais le **groupe** qu'il reconnaît et ce qu'il lui accorde. Un +troisième champ s'est imposé en écrivant : **`porte_par`** — le mécanisme qui transporte +réellement l'habilitation. Sans lui, les déclarations auraient décrit une chaîne inexistante, +ce qui est exactement le défaut levé sept fois hier. + +L'état réel, mesuré rôle par rôle : + +| Rôle | `porte_par` | Ce que ça veut dire | +|---|---|---| +| `serveur_grafana` | `role-realm` | mécanisme réel : claim `roles` → `oidc_role_path` | +| `serveur_forgejo` | **`aucun`** | rien n'est câblé ; tout authentifié a le niveau par défaut | +| `serveur_nextcloud` | **`aucun`** | idem — l'administration passe par le compte local | +| `serveur_icingaweb2` | **`liste-uid`** | **nomme des personnes** (D-66) | +| `serveur_keycloak` | **`aucun`** | la **projection** LDAP → rôle de realm n'existe pas | + +Trois services sur cinq n'ont aucun mécanisme, et deux nomment des personnes — ce que D-66 +interdit, écrit une heure plus tôt. + +**Le maillon manquant est chez Keycloak.** `serveur_keycloak_role_assignments` assigne un rôle +à un **utilisateur**, nommément ; son propre commentaire l'admettait déjà (*« en prod, préférer +l'assignation via groupe d'annuaire ; ici, explicite pour la preuve »*). Sans mapper +`group-ldap-mapper`, les groupes LDAP n'atteignent jamais les services : la chaîne s'arrête +avant le premier. Sa méta a donc une autre forme — `acces_projection`, car Keycloak *projette* +au lieu de consommer (D-65). + +**Un défaut concret corrigé.** `serveur_icingaweb2_admins` valait `"testmail"` — un compte de +test **codé en dur dans le moteur**, qu'aucune instance ne surchargeait. Le seul administrateur +déclaré de la supervision était donc un utilisateur inexistant. Il suit désormais l'`uid` +d'amorçage ; vérifié sur `mon-01` : `users = "sysadmin"`. + +**Ce que la doctrine visait est maintenant lisible.** Le §1 d'`autorisation.md` disait +qu'aucun service ne lisait `ou=groups`. Les métas le disent maintenant service par service, +avec le mécanisme qui manque à chacun — c'est la condition pour qu'une preuve puisse un jour +le vérifier. + + ### `ppolicy` chargé — le jeton d'amorçage devient vraiment à usage unique `serveur_openldap` charge désormais l'overlay `ppolicy` et pose une politique par défaut. diff --git a/roles/serveur_forgejo/meta/acces.yml b/roles/serveur_forgejo/meta/acces.yml new file mode 100644 index 0000000..8704f18 --- /dev/null +++ b/roles/serveur_forgejo/meta/acces.yml @@ -0,0 +1,19 @@ +--- +# Habilitations reconnues par ce service. Voir docs/autorisation.md. +acces: + - groupe: sysadmin + accorde: admin + # /!\ AUCUN mecanisme ne porte cette habilitation aujourd'hui : le role ne + # configure ni claim de groupe, ni mapping d'equipe. Toute personne qui + # s'authentifie obtient le niveau par defaut, et le compte administrateur + # reste le compte local de secours (voute). + # Forgejo sait lire un claim OIDC de groupes (`GROUP_CLAIM_NAME` + + # `ADMIN_GROUP`) : c'est le cablage manquant. Constate le 2026-08-07. + porte_par: aucun + raison: >- + Administration de la forge : utilisateurs, organisations, reglages. + - groupe: dev + accorde: utilisateur + porte_par: defaut # tout utilisateur authentifie + raison: >- + Creation de depots et contribution. C'est le niveau par defaut. diff --git a/roles/serveur_grafana/meta/acces.yml b/roles/serveur_grafana/meta/acces.yml new file mode 100644 index 0000000..79312dd --- /dev/null +++ b/roles/serveur_grafana/meta/acces.yml @@ -0,0 +1,19 @@ +--- +# Habilitations reconnues par ce service. Voir docs/autorisation.md. +# +# `groupe` : le groupe LDAP — jamais une personne (D-66). +# `accorde` : le vocabulaire DU SERVICE, pas une echelle abstraite. +# `porte_par` : le mecanisme qui transporte reellement l'habilitation. Le nommer +# rend visible, dans la declaration meme, ce qui n'est pas cable. +acces: + - groupe: sysadmin + accorde: Admin + porte_par: role-realm # claim `roles` -> serveur_grafana_oidc_role_path + raison: >- + Administration : sources de donnees, tableaux de bord, organisations. + - groupe: personnel + accorde: Viewer + porte_par: defaut # tout utilisateur authentifie, sans role + raison: >- + Lecture des tableaux de bord. C'est le niveau par defaut : aucun role de + realm n'est requis pour l'obtenir. diff --git a/roles/serveur_icingaweb2/defaults/main.yml b/roles/serveur_icingaweb2/defaults/main.yml index f0f0fc7..bc64cce 100644 --- a/roles/serveur_icingaweb2/defaults/main.yml +++ b/roles/serveur_icingaweb2/defaults/main.yml @@ -40,7 +40,16 @@ serveur_icingaweb2_ldap_user_class: "inetOrgPerson" serveur_icingaweb2_ldap_user_attr: "uid" # Qui reçoit le rôle Administrateur (liste d'uid séparés par des virgules). -serveur_icingaweb2_admins: "testmail" +# +# /!\ NOMMER DES PERSONNES contredit D-66 : révoquer quelqu'un demande alors un +# déploiement, et la liste vieillit sans que rien ne le signale. Icinga Web 2 sait +# lire un groupe d'annuaire (backend LDAP de type `group`) — c'est là qu'il faut +# aller. Voir roles/serveur_icingaweb2/meta/acces.yml. +# +# En attendant, le défaut suit l'`uid` d'amorçage plutôt qu'un compte de test : +# `testmail` était codé en dur et n'existe dans aucune instance — le seul +# administrateur déclaré était donc un utilisateur inexistant (2026-08-07). +serveur_icingaweb2_admins: "{{ amorcage_acces_uid | default('sysadmin') }}" # Backend d'authentification : "ldap" (direct) ou "external" (utilisateur fourni par une # passerelle SSO devant, ex. oauth2-proxy → Keycloak). En "external", nginx doit poser REMOTE_USER. diff --git a/roles/serveur_icingaweb2/meta/acces.yml b/roles/serveur_icingaweb2/meta/acces.yml new file mode 100644 index 0000000..eaa589d --- /dev/null +++ b/roles/serveur_icingaweb2/meta/acces.yml @@ -0,0 +1,13 @@ +--- +# Habilitations reconnues par ce service. Voir docs/autorisation.md. +acces: + - groupe: sysadmin + accorde: Administrateur + # /!\ `liste-uid` NOMME DES PERSONNES (`serveur_icingaweb2_admins`), ce que + # D-66 interdit : revoquer quelqu'un demande alors un deploiement, et le + # service porte une liste qui vieillit sans que rien ne le signale. + # Icinga Web 2 sait lire un groupe d'annuaire (backend LDAP de type `group`) : + # c'est vers cela qu'il faut aller. Constate le 2026-08-07. + porte_par: liste-uid + raison: >- + Acces complet a la supervision : hotes, services, commandes. diff --git a/roles/serveur_keycloak/meta/acces.yml b/roles/serveur_keycloak/meta/acces.yml new file mode 100644 index 0000000..1e4a503 --- /dev/null +++ b/roles/serveur_keycloak/meta/acces.yml @@ -0,0 +1,30 @@ +--- +# Keycloak n'est pas un CONSOMMATEUR d'habilitations : il les PROJETTE (D-65). +# LDAP porte les groupes, Keycloak les traduit en roles de realm que les services +# lisent dans le jeton. Sa declaration a donc une autre forme. +# +# `projette` decrit la traduction attendue ; `porte_par` dit ce qui la realise. +acces_projection: + # /!\ LA PROJECTION N'EXISTE PAS. `serveur_keycloak_role_assignments` assigne + # un role a un UTILISATEUR, nommement — ce que D-66 interdit. Le commentaire du + # role l'admettait deja : « En prod, preferer l'assignation via groupe + # d'annuaire ; ici, explicite pour la preuve. » + # + # Sans mapper `group-ldap-mapper` + politique role<-groupe, la chaine s'arrete + # ici : les groupes LDAP n'atteignent jamais les services. Constate le + # 2026-08-07, au moment d'ecrire les meta/acces.yml des cinq roles web. + - groupe: sysadmin + projette: [grafana-admin] + porte_par: aucun + raison: >- + Le groupe d'administration doit devenir le role de realm que Grafana lit + dans le claim `roles`. + +# Ce que Keycloak accorde SUR LUI-MEME (sa propre console d'administration). +acces: + - groupe: sysadmin + accorde: realm-admin + porte_par: aucun + raison: >- + Administration du realm : clients, mappers, politiques. Aujourd'hui seul le + compte local `admin` (voute) l'obtient. diff --git a/roles/serveur_nextcloud/meta/acces.yml b/roles/serveur_nextcloud/meta/acces.yml new file mode 100644 index 0000000..70d3eda --- /dev/null +++ b/roles/serveur_nextcloud/meta/acces.yml @@ -0,0 +1,18 @@ +--- +# Habilitations reconnues par ce service. Voir docs/autorisation.md. +acces: + - groupe: sysadmin + accorde: admin + # /!\ AUCUN mecanisme ne porte cette habilitation aujourd'hui : le role ne + # configure pas de mapping de groupes OIDC. L'administration passe donc par + # le compte local de secours (voute, `occ`), ce qui contredit « une identite, + # un mot de passe ». Constate le 2026-08-07. + # `user_oidc` sait mapper un claim de groupes : c'est le cablage manquant. + porte_par: aucun + raison: >- + Administration : utilisateurs, quotas, applications, partages. + - groupe: personnel + accorde: utilisateur + porte_par: defaut # tout utilisateur authentifie + raison: >- + Son espace de fichiers et ses partages. C'est le niveau par defaut.