feat(grafana): SSO OIDC via Authentik + admin par groupe lab-admins

- values.yaml monitoring : auth.generic_oauth (auth_url navigateur,
  token/api sur le Service interne), root_url, mapping lab-admins→Admin /
  sinon Viewer. Login local conservé (break-glass).
- vault : vault_grafana_oauth_client_secret (= secret k8s
  monitoring/grafana-oauth-secret, déjà créé)
- doc : runbook « ajouter une app » complété (exemple Grafana concret +
  groupe lab-admins) et procédure SQL pour promouvoir un compte SSO admin
  Guacamole (appliquée à Alkatrazz)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
alkatrazz 2026-07-07 12:09:05 +02:00
parent dc9fc884ac
commit fa2e7402a0
3 changed files with 208 additions and 131 deletions

View file

@ -14,6 +14,18 @@ sont dans **`admin/k8s/auth-portal.md`** ; le guide à envoyer aux utilisateurs
> `guacadmin` (compte local) est **inaccessible** tant que le SSO est prioritaire —
> c'est voulu. Dépannage : piège n°3 de `auth-portal.md`.
> **Rendre un compte SSO admin Guacamole** (fait pour `Alkatrazz`) : les droits système
> ne s'assignent pas via un compte non-admin, donc au bootstrap on passe par la base
> (`guacamole_entity` : `type='USER'`, `name` = username Authentik casse comprise) :
> ```sql
> -- sur storage-01, id de l'entité = son entity_id dans guacamole_entity
> INSERT INTO guacamole_system_permission (entity_id, permission)
> SELECT <id>, perm::guacamole_system_permission_type
> FROM (VALUES ('ADMINISTER'),('CREATE_CONNECTION'),('CREATE_CONNECTION_GROUP'),
> ('CREATE_SHARING_PROFILE'),('CREATE_USER'),('CREATE_USER_GROUP')) AS v(perm);
> ```
> Ensuite ce compte gère tout depuis l'UI (y compris promouvoir d'autres admins).
## Cycle de vie d'un utilisateur
### Créer (≈2 min)
@ -75,6 +87,37 @@ Pour chaque nouvelle app (Grafana, n8n…) :
La tuile apparaît automatiquement sur le hub des membres du groupe.
### Le groupe `lab-admins` (admin partout)
Groupe transverse : ses membres reçoivent le **rôle admin dans chaque app** intégrée
(mapping fait côté app, ex. Grafana `role_attribute_path`). `Alkatrazz` en fait partie.
Créer si absent : *Directory → Groups → Create* `lab-admins`, y ajouter les admins.
### Exemple concret : Grafana (SSO OIDC)
Côté k8s c'est déjà fait (values.yaml monitoring : `auth.generic_oauth`, secret k8s
`monitoring/grafana-oauth-secret` = `vault_grafana_oauth_client_secret`). **Reste la
config Authentik (UI)** :
1. *Applications → Providers → Create → OAuth2/OpenID Provider* :
- Name `grafana`, Authorization flow `default-provider-authorization-implicit-consent`
- **Client type : Confidential** (Grafana garde un secret, contrairement à Guacamole)
- **Client ID : `grafana`** · **Client Secret : coller `vault_grafana_oauth_client_secret`**
(`make vault-view`) — doit être **identique** des deux côtés
- **Redirect URI (Strict) : `http://grafana.lab.local/login/generic_oauth`**
- **Signing Key** : le certificat self-signed
2. *Applications → Create* : Name `Grafana`, **slug `grafana`**, provider `grafana`,
Launch URL `http://grafana.lab.local`, une icône si tu veux
3. *Bindings* → lier un groupe (ou laisser ouvert). Pour être admin : être dans
`lab-admins` (mappé → rôle Grafana **Admin** ; les autres → **Viewer**)
4. Tester : hub → tuile Grafana → connecté en Admin. **Break-glass** si le SSO casse :
`http://grafana.lab.local/login` en `admin` / `adminPassword` (values.yaml).
⚠️ Grafana n'est exposé que sur le **LAN** (`grafana.lab.local`) — la tuile ne
fonctionne donc que depuis le LAN tant qu'on n'ajoute pas de redirection Internet
dédiée (comme pour le portail). Pièges : redirect_uri au caractère près, et les pods ne
résolvant pas `lab.local`, `token_url`/`api_url` pointent sur le Service interne.
## Durcissement (quand l'usage s'installe)
- **MFA/TOTP** : chaque utilisateur peut enrôler une app d'authentification