Cree uid=sysadmin et cn=sysadmin dans LDAP. Prouve sur idm-01 : le compte
s'authentifie, et le second passage ne touche a rien (changed=0, 7 taches
sautees) — idempotence par EXISTENCE, pas par conformite (D-67).
Il suit l'annuaire au lieu de se declarer au plan : il ecrit par `ldapi:///` et
doit tourner sur cet hote. Le declarer comme groupe obligerait chaque instance a
le poser sur le bon hote, et elles ne le nomment pas pareil (idm-01 ici,
id-ldap-01 chez Technolibre) — je l'ai d'abord pose sur infra-pki-01 par erreur.
Trois defauts trouves en le construisant :
1. `pwdReset` n'existe pas dans ce schema (overlay ppolicy non charge) :
l'entree entiere etait rejetee et `no_log` masquait la cause. J'avais suppose
un mecanisme sans verifier. Le role le DETECTE maintenant, et la doctrine ne
promet plus un changement force qui n'a pas lieu.
2. Le mot de passe aurait ete stocke EN CLAIR : `ldap_entry` ecrit userPassword
litteralement. Hache par `slappasswd -h {SSHA}` desormais.
3. `voute.py` ne scannait que roles/<groupe> : un role applique par un playbook
sans etre un groupe echappait au recensement, ce que D-20 interdit. Il suit
maintenant les listes `roles:` des playbooks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
165 lines
7.6 KiB
Markdown
165 lines
7.6 KiB
Markdown
# Accès et habilitations : Set-OPS amorce, le sysadmin gouverne
|
|
|
|
> **Directive d'architecture du 2026-08-07.** L'authentification dit *qui tu es*
|
|
> (`authentification.md`). Ce document dit *ce que tu peux faire* — et surtout **qui en
|
|
> décide**. La réponse n'est pas « le dépôt ».
|
|
|
|
## 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.
|
|
|
|
Toute personne qui s'authentifie obtient donc le défaut du service — tout, ou rien. Et
|
|
aucun humain n'a de compte : `ou=people` est vide aussi. L'écosystème est déployé et
|
|
personne ne peut y entrer autrement que par les comptes de secours en voûte.
|
|
|
|
## 2. Deux régimes, et la frontière entre eux
|
|
|
|
C'est la décision principale, et elle **contredit délibérément la doctrine du dépôt**.
|
|
|
|
Partout ailleurs, un écart entre le déclaré et le réel est un défaut à corriger : les devis
|
|
réconcilient, les applicateurs retirent ce qui n'est plus demandé. **Ici, l'écart est
|
|
légitime** — c'est le sysadmin qui fait son travail.
|
|
|
|
| | Qui décide | Régime |
|
|
|---|---|---|
|
|
| **Infrastructure** — quel groupe accorde quoi dans un service | Set-OPS | réconcilié à chaque déploiement, comme le reste |
|
|
| **Habilitations** — qui appartient à quel groupe | **une personne** | **amorcé une fois, jamais réconcilié** |
|
|
|
|
Le mapping « le groupe `sysadmin` vaut `Admin` dans Grafana » est de la configuration
|
|
d'infrastructure : il se déclare, se dérive et se corrige. Savoir **qui** est dans
|
|
`sysadmin` ne l'est pas — c'est une décision d'exploitation, prise par un humain, souvent
|
|
en urgence, et le dépôt n'a pas à la défaire au prochain `make deployer`.
|
|
|
|
Un dépôt qui réconcilierait les appartenances effacerait le compte créé la veille pour un
|
|
nouvel employé. C'est exactement le genre de « correction » qu'il ne faut pas faire.
|
|
|
|
## 3. L'amorçage est un one-shot
|
|
|
|
Set-OPS crée **un** accès : celui du sysadmin, pour qu'il puisse prendre la main. Rien de
|
|
plus.
|
|
|
|
**Idempotence par non-intervention.** La condition n'est pas la conformité, c'est
|
|
l'**existence** : si le compte est là, on n'y touche pas — ni son mot de passe, ni ses
|
|
groupes, ni ses attributs. Il a pu être renommé, promu, déplacé ; c'est le droit de celui
|
|
qui exploite.
|
|
|
|
```
|
|
compte sysadmin absent → créé, mot de passe généré en voûte, changement forcé
|
|
compte sysadmin présent → aucune action, quel que soit son état
|
|
```
|
|
|
|
C'est la différence entre `state: present` et une réconciliation. Le second serait un
|
|
défaut ici.
|
|
|
|
**Le premier mot de passe n'est pas *le* mot de passe de quelqu'un.** Généré, déposé en
|
|
voûte, **changement forcé à la première ouverture** : c'est un jeton d'amorçage à usage
|
|
unique. Sans ce changement, l'auteur du déploiement connaîtrait le mot de passe du
|
|
sysadmin — ce qui contredit « une identité, une personne ».
|
|
|
|
## 4. Où vivent les habilitations : LDAP, pas Keycloak
|
|
|
|
**Les groupes LDAP sont la source unique.** Keycloak les *projette* en rôles pour le web ;
|
|
les services non-OIDC les lisent directement.
|
|
|
|
L'argument est mécanique, pas doctrinal : **Dovecot et Postfix ne savent pas lire un rôle
|
|
Keycloak.** L'y loger rendrait la moitié courriel du système aveugle, et imposerait au
|
|
sysadmin de tenir deux modèles de permissions — donc de les voir diverger.
|
|
|
|
Conséquence pratique pour l'exploitant : **un seul endroit à administrer**. Ajouter
|
|
quelqu'un au groupe `sysadmin` dans LDAP lui ouvre Grafana, Forgejo, Icinga et le courriel,
|
|
sans toucher à un seul service.
|
|
|
|
## 5. Un service nomme un groupe, jamais une personne
|
|
|
|
C'est la règle qui rend la reprise possible. Chaque rôle déclare le **groupe** qu'il
|
|
reconnaît, dans son `meta/acces.yml` :
|
|
|
|
```yaml
|
|
acces:
|
|
- groupe: sysadmin # groupe LDAP
|
|
accorde: Admin # ce que ça vaut DANS ce service
|
|
raison: >-
|
|
Administration : sources de données, tableaux de bord, utilisateurs.
|
|
```
|
|
|
|
Le champ `accorde` est **le vocabulaire du service**, pas un niveau abstrait : `Admin` chez
|
|
Grafana, `owner` chez Forgejo. Inventer une échelle commune obligerait à la traduire
|
|
partout, et la traduction est exactement l'endroit où une habilitation se perd.
|
|
|
|
Un service qui nommerait une personne créerait une dette qu'on découvre le jour du
|
|
départ, service par service — et il faudrait un déploiement pour révoquer quelqu'un.
|
|
|
|
## 6. Prendre la main — le runbook
|
|
|
|
Ce qui suit est destiné au sysadmin le jour de la livraison. **C'est la partie utile de ce
|
|
document.**
|
|
|
|
### 6.1 Récupérer le mot de passe d'amorçage
|
|
|
|
```
|
|
ansible-vault view instance/inventories/principal/group_vars/all/vault.yml \
|
|
| grep vault_sysadmin_amorcage
|
|
```
|
|
|
|
**Change-le immédiatement.** Tant que l'overlay `ppolicy` n'est pas chargé, rien ne
|
|
l'impose techniquement (§3) — c'est à toi de le faire, et c'est le premier geste de la
|
|
reprise.
|
|
|
|
> Le mot de passe de la voûte est lu depuis `ANSIBLE_VAULT_PASSWORD_FILE`
|
|
> (`~/.config/setops-vault-pass` par défaut). **Sans ce fichier, rien de ce qui suit n'est
|
|
> possible** — c'est la clé de voûte au sens propre, et la première chose à sauvegarder
|
|
> hors de la machine.
|
|
|
|
### 6.2 Où administrer quoi
|
|
|
|
| Ce que tu veux faire | Où | Comment |
|
|
|---|---|---|
|
|
| créer/désactiver une personne | **LDAP** (`ou=people`) | via Keycloak, ou `ldapmodify` |
|
|
| donner ou retirer un accès | **LDAP** (`ou=groups`) | ajouter/retirer du groupe |
|
|
| changer ce qu'un groupe *vaut* dans un service | **le plan** (`meta/acces.yml`) | c'est de l'infrastructure : éditer, redéployer |
|
|
|
|
La troisième ligne est la seule qui passe par Set-OPS. Les deux premières t'appartiennent
|
|
et **le dépôt ne les touchera plus jamais**.
|
|
|
|
### 6.3 Si tu te fermes dehors
|
|
|
|
Les comptes locaux de chaque service existent, sont en voûte, et leur formulaire n'est pas
|
|
annoncé (`authentification.md` §3). L'accès de secours passe par `sudo` sur l'hôte :
|
|
|
|
```
|
|
grafana-cli admin reset-admin-password
|
|
forgejo admin user change-password
|
|
occ user:resetpassword
|
|
```
|
|
|
|
Et si LDAP lui-même est en panne, ces trois commandes fonctionnent quand même : elles ne
|
|
dépendent ni de Keycloak, ni de l'annuaire. C'est le sens de D-40.
|
|
|
|
### 6.4 Ce que tu dois changer en priorité
|
|
|
|
1. **Le mot de passe d'amorçage** — dès la première connexion. Rien ne l'impose encore :
|
|
voir §3.
|
|
2. **Les comptes de secours** générés au déploiement : ils sont en voûte, et l'auteur du
|
|
déploiement y a eu accès. Les régénérer transfère réellement le contrôle.
|
|
3. **Le mot de passe de la voûte** elle-même, si le dépôt change de mains.
|
|
|
|
## 7. Ce que ce document ne couvre pas
|
|
|
|
**La gestion courante des comptes.** Créer, suspendre, réaffecter : c'est le travail du
|
|
sysadmin, pas du dépôt. Set-OPS ne fournit ni registre de personnes, ni synchronisation —
|
|
volontairement. Un registre versionné mettrait des données personnelles dans l'historique
|
|
git, de façon permanente et difficile à retirer.
|
|
|
|
**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 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 de chaque
|
|
application.
|
|
|
|
**Rien n'est construit.** Ce document fixe la direction ; le rôle d'amorçage, les
|
|
`meta/acces.yml` et la preuve restent à écrire.
|