acces : les cinq meta/acces.yml, et le mecanisme qui manque a chacun

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 <noreply@anthropic.com>
This commit is contained in:
Daniel Allaire 2026-08-07 13:59:33 -04:00
parent 69536a2b1a
commit 6f2acafdb6
7 changed files with 147 additions and 1 deletions

View file

@ -2,6 +2,44 @@
## 2026-08-06 — le chemin nord-sud devient dérivable ## 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 ### `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. `serveur_openldap` charge désormais l'overlay `ppolicy` et pose une politique par défaut.

View file

@ -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.

View file

@ -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.

View file

@ -40,7 +40,16 @@ serveur_icingaweb2_ldap_user_class: "inetOrgPerson"
serveur_icingaweb2_ldap_user_attr: "uid" serveur_icingaweb2_ldap_user_attr: "uid"
# Qui reçoit le rôle Administrateur (liste d'uid séparés par des virgules). # 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 # 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. # passerelle SSO devant, ex. oauth2-proxy → Keycloak). En "external", nginx doit poser REMOTE_USER.

View file

@ -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.

View file

@ -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.

View file

@ -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.