ajoute la visio de classe : Jitsi auto-hébergé, jetons du portail, prof seul modérateur

Jitsi (docker-jitsi-meet, version figée) derrière Nginx sur meet.syllabuslab.fr,
accès par jeton JWT signé par le portail, modération du micro, mains levées
synchronisées avec l'application. Pare-feu : UDP 10000 et pont interne
br-visio (accords d'Adam). Jicofo n'authentifie plus lui-même : il donnait
le rôle de propriétaire aux élèves. Capacité ramenée à 20 VM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-12 12:35:35 +02:00
parent dd4f9c3c55
commit ec4eae3744
36 changed files with 1406 additions and 18 deletions

View file

@ -0,0 +1,54 @@
# ADR 0005 — Visio de classe : Jitsi auto-hébergé, jetons du portail, prof seul modérateur
- **Date** : 2026-10-12
- **Statut** : accepté
## Contexte
Étape 15 : une visio pour la classe, sur le même serveur, où seuls les élèves
de la classe entrent (nom non modifiable), où tout le monde arrive en
sourdine et où seul le prof donne la parole.
## Décisions
1. **Jitsi Meet en Docker** (docker-jitsi-meet, version figée `stable-11248`),
rôle Ansible `visio`, derrière le Nginx de l'hôte sur `meet.syllabuslab.fr`.
2. **JVB sur le réseau de l'hôte** : Docker tourne sans pont par défaut ni règles
iptables (étape 5), donc la publication de l'UDP 10000 par NAT Docker est
impossible. JVB écoute directement l'UDP 10000 (ouvert dans nftables, accord
d'Adam) et joint Prosody par `127.0.0.1:5222`.
3. **Pont interne `br-visio` autorisé** dans la chaîne `forward` (accord d'Adam) :
avec `br_netfilter`, le trafic entre conteneurs d'un même réseau Docker passe
par `forward`, dont la politique `drop` bloquait Jicofo et le conteneur web.
Seul le trafic qui entre ET ressort par `br-visio` est accepté.
4. **Accès par jeton JWT (HS256) signé par le portail**, un par personne, pour
une salle au nom imprévisible ; pas d'invités (`ENABLE_GUESTS=0`). Le secret
est généré sur le serveur et copié dans le `.env` du portail par Ansible.
5. **Rôle de modérateur lu dans le jeton** (`context.user.moderator`, module
natif `token_affiliation`) ; `ENABLE_AUTO_OWNER=0` et **`JICOFO_ENABLE_AUTH=0`** :
sinon Jicofo authentifie chaque participant et donne le rôle de propriétaire à
tous (constaté : un élève pouvait ouvrir son micro sans la parole).
6. **Modération du micro** activée par la page du prof à son arrivée
(`toggleModeration`), « Donner la parole » = `askToUnmute` (qui autorise le
micro quand la modération est active, d'après la documentation de l'IFrame API).
7. **État de la classe tenu par le portail** (cache Redis, verrou) : mains levées
par ordre d'arrivée, correspondance élève ↔ participant Jitsi, salle d'attente.
La main levée suit toujours l'événement Jitsi (`raiseHandUpdated`) : une seule source.
## Alternatives écartées
- **Publier l'UDP 10000 par Docker** : demande de rendre à Docker la main sur
iptables, ce qu'on a refusé dès l'étape 5.
- **Mettre tous les conteneurs sur le réseau de l'hôte** : conflits de ports avec
Kolla (ex. 10.10.0.1:8000) et services internes exposés sur toutes les interfaces.
- **Relais TURN sur 443** pour les réseaux qui bloquent l'UDP : impose de
restructurer l'entrée HTTPS (aiguillage par nom) ; reporté (choix d'Adam).
## Conséquences
- Réseaux scolaires qui bloquent l'UDP : pas de son ni d'image tant que le relais
TURN sur 443 n'existe pas (`docs/dette.md`).
- Capacité ramenée de 22 à 20 VM (`docs/capacite.md`).
- `Permissions-Policy` du portail délègue caméra, micro et partage d'écran au seul
`meet.syllabuslab.fr` ; le site `meet` n'est intégrable que dans le portail
(`frame-ancestors`).