feat(agent): v0.3.5 Windows inbound forwarding, UI actions, lifecycle

- Configure tailscale serve automatically for each instance on Windows userspace networking.
- Add local UI buttons: start/stop/reset/delete instances (stop/start preserve volumes).
- Clean shutdown: stop tailscaled and instances, notify server with instance_stopped.
- Restart tailscaled on agent boot using persisted state when pre-auth key is absent.
- Sync instance stopped/deleted status to dashboard (server/lib/websocket.ts).
- Security: include prior authz/scoping changes across API routes, ephemeral pre-auth keys, ACL policy, internal API key.
- Update SUIVI_VPN_ONDEMAND.md and docs/ONBOARDING_CLIENT.md.
- Bump agent version to 0.3.5.
This commit is contained in:
EduBox Dev
2026-06-25 22:59:09 +00:00
parent 331187e9b5
commit a414f03a59
33 changed files with 3075 additions and 340 deletions
+391 -33
View File
@@ -112,6 +112,59 @@ Validation manuelle sur Windows :
.\tailscale.exe --socket="\\.\pipe\studioe5-tailscaled" status # => Logged out (NeedsLogin)
```
## 🪟 Agent v0.3.5 forwarding entrant Windows + UI locale + cycle de vie
### Problème
Sur Windows, Tailscale en `userspace-networking` ne forwarde pas automatiquement les connexions entrantes du Tailnet vers `localhost`. Résultat : les URLs publiques retournaient une erreur 502/timeout, bien que lagent soit `online`.
Logs caractéristiques :
```text
client -> backend close connection: close tcp 100.64.0.12:8080->100.64.0.11:xxxxx: endpoint not connected
```
### Solution : `tailscale serve` automatique
Lagent configure automatiquement un proxy TCP pour chaque instance démarrée :
```powershell
tailscale serve --bg --tcp=<port> tcp://localhost:<port>
```
| Action agent | Commande Tailscale |
|--------------|--------------------|
| Démarrage dinstance | `serve --bg --tcp=<port> tcp://localhost:<port>` |
| Arrêt dinstance | `serve --bg --tcp=<port> off` |
| Suppression dinstance | `serve --bg --tcp=<port> off` |
| Redémarrage de lagent | reconfiguration pour les instances déjà `running` |
Fichiers modifiés : `agent/tailscale.go`, `agent/websocket.go`, `agent/main.go`, `agent/ui.go`.
### UI locale modernisée
- Tableau de bord avec indicateurs de service.
- Liste des applications avec badges de statut.
- Boutons daction par instance : **Démarrer**, **Arrêter**, **Redémarrer**, **Supprimer**.
- Panneau de logs et diagnostic intégré.
- Panneau de configuration (URL serveur, Headscale, node ID).
### Cycle de vie des instances
- **Arrêter** → `docker compose stop` (volumes conservés).
- **Démarrer** → `docker compose start` (ou `up -d` la première fois).
- **Redémarrer** → `docker compose down -v` + recréation (données remises à zéro).
- **Supprimer** → `docker compose down -v` + suppression des fichiers.
- À la fermeture de lagent, les instances en cours sont arrêtées proprement (`stop`) et le serveur est notifié (`instance_stopped`).
### Démarrage du VPN après activation
Lagent redémarre `tailscaled` automatiquement au lancement, même si la clé pré-auth a déjà été utilisée. Il se base sur l’état persistant `tailscaled.state` (`tailscale up` sans `--authkey`).
### Téléchargement
- **Windows (archive)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.5-windows.zip`
- **Windows (exe)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.5.exe`
- **Linux** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.5`
## 🛠️ Commandes utiles pour reprendre
### Voir lagent de test
@@ -190,11 +243,11 @@ Lagent est servi par Caddy depuis le dossier `agent/` monté dans le conteneu
### Binaires disponibles
- **Windows (archive complète)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.3-windows.zip`
- **Windows (archive complète)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.5-windows.zip`
- Contient `studioE5-agent.exe` + `tailscale-bin/windows/` (`tailscale.exe`, `tailscaled.exe`, `wintun.dll`) + `README-Windows.txt`.
- **Windows (exécutable seul)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.3.exe`
- **Windows (exécutable seul)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.5.exe`
- Nécessite davoir installé Tailscale Windows séparément ou davoir les binaires dans `tailscale-bin/windows/`.
- **Linux** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.3`
- **Linux** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.5`
### Builder / préparer les binaires
@@ -208,13 +261,13 @@ cd /opt/studioe5-client-a/agent
./build.sh
```
Le `build.sh` génère automatiquement `studioE5-agent-v0.3.0-windows.zip` et copie les binaires versionnés dans `server/public/`.
Le `build.sh` génère automatiquement `studioE5-agent-v0.3.5-windows.zip` et copie les binaires versionnés dans `server/public/`.
### Flow dactivation zéro-config (modèle commercialisable)
L’élève/employé na **aucune configuration technique** à saisir :
1. **Télécharger** lagent Windows (`studioE5-agent-v0.3.0-windows.zip`).
1. **Télécharger** lagent Windows (`studioE5-agent-v0.3.4-windows.zip`).
2. **Extraire** et **lancer** `studioE5-agent.exe`.
3. **Entrer le code dactivation** à 6 caractères fourni par l’établissement (affiché dans lUI locale `http://localhost:7070`).
4. Lagent contacte le serveur, le serveur vérifie le code et renvoie **automatiquement** :
@@ -245,47 +298,352 @@ Lancement :
.\studioE5-agent.exe -no-tray -data-dir C:\studioE5-agent\data
```
## 🔒 Durcissement du code dactivation
### Génération
- Les codes sont générés avec `crypto.randomBytes` (au lieu de `Math.random`).
- Longueur conservée à 6 caractères, alphabet sans ambiguïté (`ABCDEFGHJKLMNPQRSTUVWXYZ23456789`).
- Un champ `activationCodeExpiresAt` a été ajouté au modèle `Student` ; les codes expirent après **60 minutes**.
### Rate-limiting
- Maximum de **5 tentatives dactivation par code** sur une fenêtre de **15 minutes**.
- Maximum de **5 tentatives par `nodeId`** sur la même fenêtre.
- Au-delà, le serveur répond `activation_failed` avec `Too many attempts`.
### Cycle de vie
- Le code est **invalide après une activation réussie** (`activationCode` et `activationCodeExpiresAt` mis à `null`).
- Un code expiré renvoie `Code expired`.
- Un code déjà utilisé renvoie `Invalid code`.
### Tests validés
- Activation valide → `activated` + token node reçu.
- Code expiré → `Code expired`.
- Code déjà utilisé → `Invalid code`.
- 5+ tentatives invalides → `Too many attempts`.
## 🔒 ACL Headscale (isolation du tailnet)
### Objectif
Par défaut, tous les nœuds du tailnet peuvent communiquer entre eux. Les ACL restreignent la connectivité au strict nécessaire :
- les agents élèves ne peuvent pas se parler entre eux ;
- le resolver peut atteindre les agents sur leurs ports dinstance ;
- les agents peuvent joindre le resolver sur son port HTTP interne.
### Mise en œuvre
- Fichier de politique : `headscale/acl_policy.hujson`.
- `headscale/config.yaml` pointe vers ce fichier via `policy.path`.
- Le resolver a été déplacé dans un utilisateur Headscale dédié `resolver` (clé `HEADSCALE_RESOLVER_AUTH_KEY`).
- Les agents utilisent lutilisateur `studioe5` et sont tagués `tag:student-agent`.
- Les nouveaux agents recevront automatiquement le tag via la nouvelle clé pré-auth `HEADSCALE_AUTH_KEY` (créée avec `--tags tag:student-agent`).
### Contenu de la politique
```json
{
"groups": {
"group:agents": ["studioe5@studioe5.local"],
"group:resolvers": ["resolver@studioe5.local"]
},
"tagOwners": {
"tag:student-agent": ["studioe5@studioe5.local"],
"tag:resolver": ["resolver@studioe5.local"]
},
"acls": [
{ "action": "accept", "src": ["tag:resolver"], "dst": ["tag:student-agent:*"] },
{ "action": "accept", "src": ["tag:student-agent"], "dst": ["tag:resolver:2020"] }
]
}
```
### Tests validés
| Test | Résultat |
|------|----------|
| `resolver` ping agent | ✅ OK |
| Agent → agent (port instance) | ❌ bloqué (timeout) |
| Agent → resolver:2020 | ✅ OK |
| Flux HTTPS public | ✅ HTTP 200 |
## 🔒 Authentification du canal serveur → agent
### Token dauthentification par nœud
- Le modèle `Node` dispose dun champ `token` unique.
- Lagent envoie son token dans len-tête `Authorization: Bearer <token>` lors de la connexion WebSocket.
- Le serveur rejette toute connexion/register dont le token ne correspond pas au `nodeId` (fermeture `1008`).
- Lors de lactivation, le serveur génère un token aléatoire (32 octets hex) et le renvoie dans le message `activated` ; lagent le sauvegarde dans `<data-dir>/node.token` (permissions `0600`).
- Pour les nœuds existants sans token, le serveur en génère un à la première connexion et lenvoie via `set_token`.
### Endpoint `/api/internal/send-to-node`
- Protégé par la variable denvironnement `INTERNAL_API_KEY`.
- Requiert len-tête `Authorization: Bearer <INTERNAL_API_KEY>`.
- Appel sans clé → `401 Unauthorized`.
### Routes API métier
- Les routes de gestion des instances (`/api/instances`) requièrent une session NextAuth valide.
- Un administrateur ne peut agir que sur les ressources de son établissement ; le `superadmin` peut tout voir/tout faire.
### Endpoint `/api/resolve`
- Protégé par la même clé `INTERNAL_API_KEY`.
- Requiert len-tête `Authorization: Bearer <INTERNAL_API_KEY>`.
- Le resolver (`resolver:2020`) ne lutilise pas ; il interroge directement PostgreSQL. Cette route est donc réservée aux outils/scripts internes authentifiés.
### Exemples de commandes avec la clé interne
```bash
KEY=$(grep INTERNAL_API_KEY /opt/studioe5-client-a/.env | cut -d= -f2)
curl -sS -X POST https://studioe5.edudeploy.com/api/internal/send-to-node \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $KEY" \
-d '{"nodeId":"vps-8fc665eb","message":{"action":"start_vpn"}}'
curl -sS -H "Authorization: Bearer $KEY" \
"https://studioe5.edudeploy.com/api/resolve?subdomain=test-wp-001"
```
## 🔒 Clés pré-auth Headscale éphémères
### Principe
À lactivation zero-config, le serveur génère désormais une **clé pré-auth unique et à usage unique** pour chaque agent, au lieu denvoyer la clé réutilisable `HEADSCALE_AUTH_KEY`.
Avantages :
- une clé compromise ne permet pas denregistrer dautres nœuds ;
- traçabilité directe entre une activation et une clé Headscale ;
- expiration courte (15 min) ;
- la clé nest **pas persistée** dans `studioE5-config.json` côté agent.
### Implémentation
| Composant | Changement |
|-----------|------------|
| `server/lib/headscale.ts` | Nouveau helper : `getHeadscaleUserId()` + `createEphemeralPreAuthKey()` appelant `POST /api/v1/preauthkey`. |
| `server/lib/websocket.ts` | Sur `activate`, génère une clé éphémère taguée `tag:student-agent` pour lutilisateur `studioe5`. Fallback sur `HEADSCALE_AUTH_KEY` si `HEADSCALE_API_KEY` nest pas configurée. |
| `agent/websocket.go` | La clé reçue est utilisée immédiatement mais **nest plus écrite** dans `studioE5-config.json`. |
| `agent/tailscale.go` | `tailscale up` fonctionne sans `--authkey` quand le state Tailscale existe déjà (reconnexion). |
| `.env.example` / `docker-compose.yml` | Ajout de `HEADSCALE_API_KEY` pour le service `server`. |
### Configuration requise
Générer une clé API Headscale (depuis le conteneur ou la CLI) :
```bash
cd /opt/studioe5-client-a
# Clé valable 10 ans (87600h) pour éviter un renouvellement fréquent.
docker compose exec headscale headscale apikeys create -e 87600h
```
Puis lajouter dans `.env` :
```bash
HEADSCALE_API_KEY=hskey-api-...
```
> ⚠️ La clé API Headscale a une expiration par défaut de 90 jours. La clé de production a été créée avec une expiration de **10 ans** (`-e 87600h`). Les anciennes clés ont été révoquées.
### Rotation / renouvellement
Si la clé doit être changée :
1. Créer une nouvelle clé API :
```bash
docker compose exec headscale headscale apikeys create -e 87600h
```
2. Mettre à jour `.env` :
```bash
HEADSCALE_API_KEY=<nouvelle_clé>
```
3. Redémarrer le serveur :
```bash
docker compose up -d server
```
4. Révoquer lancienne clé :
```bash
docker compose exec headscale headscale apikeys expire --id <id_ancienne>
```
### Déploiement effectué
- Clé API créée et ajoutée au `.env` de production.
- Image serveur rebuildée et redémarrée.
- Agents Linux/Windows rebuildés en v0.3.4 et copiés dans `server/public/`.
## 🔒 Sécurité — points restants à traiter
> Le certificat wildcard `*.studioe5.edudeploy.com` est désormais du ressort du **deployeur** (voir `docs/ONBOARDING_CLIENT.md`). Les points ci-dessous concernent lapplication studioE5 proprement dite.
### Gestion et rotation des secrets
| Secret | Où ? | Action |
|--------|------|--------|
| `INTERNAL_API_KEY` | `.env` serveur | Prévoir une procédure de rotation régulière. |
| `HEADSCALE_API_KEY` | `.env` serveur | Rotation tous les 10 ans max, stockage sécurisé. |
| `NEXTAUTH_SECRET` | `.env` serveur | Génération robuste, rotation si suspicion de fuite. |
| `DATABASE_URL` | `.env` serveur | Utilisateur DB dédié, mot de passe fort. |
| `node.token` | `<data-dir>/node.token` | Vérifier permissions `0600` sur tous les OS. |
### Durcissement des conteneurs
- Limiter les `cap_add` au strict minimum.
- Faire tourner les services avec un utilisateur non-root quand possible.
- Mettre à jour régulièrement les images de base (Caddy, Node, Postgres, Headscale).
- Scanner les images Docker pour les CVE.
### Mises à jour de sécurité
- Mise à jour des binaires Tailscale (Windows et Linux).
- Mise à jour des images Docker (`server`, `resolver`, `caddy`, `postgres`, `headscale`).
- Mise à jour de lOS des VPS et des postes agents.
- Mécanisme de mise à jour automatique ou notification de lagent.
### Logs daudit
- Tracer la création / suppression dinstances.
- Tracer la génération et lusage des codes dactivation.
- Tracer les actions admin (connexion, création d’élève, démarrage/arrêt VPN).
- Conservation et consultation des logs daudit.
### Backups et reprise dactivité
- Backup régulier de la base PostgreSQL.
- Backup du state Headscale.
- Backup des states Tailscale côté agents.
- Procédure de restauration documentée et testée.
### Sécurité du build et distribution de lagent
- Vérifier lintégrité des binaires Tailscale téléchargés (checksum / signature).
- Signer lexécutable Windows `studioE5-agent.exe` pour éviter les alertes Defender.
- Fournir un hash SHA256 des archives dagent.
### RGPD et données personnelles
- Justifier la conservation des noms/prénoms des élèves.
- Gérer les droits daccès, la suppression de compte et lexport de données.
- Définir la durée de conservation des logs et historiques.
### Sécurité réseau complémentaire
- Restreindre laccès à `/api/internal/send-to-node` par IP source si possible.
- Vérifier lexposition publique du dashboard Headscale et la durcir si nécessaire.
- Évaluer si `headscale.studioe5.edudeploy.com` doit rester public.
### Rate limiting et quotas
- Rate-limiting global sur les routes publiques (`/api/auth/*`, activation, création dinstance).
- Limitation du nombre dinstances par élève et par établissement.
- Protection contre les abus sur la génération de codes dactivation.
### Tests de sécurité
- Tests dintrusion légers (agent → agent, accès aux endpoints internes sans clé, accès à une instance dun autre élève).
- Tests automatisés du flux complet avant chaque release.
---
## 📋 Prochaines étapes à faire
- [x] ~~Attendre la fin du rate limit Lets Encrypt~~ (levé le 2026-06-23).
- [x] ~~Relancer un test HTTPS sur `https://test-wp-001.studioe5.edudeploy.com/`~~ → **OK** (HTTP/2 200).
- [x] ~~Créer une branche dédiée et commiter les modifications VPN on-demand~~ → branche `feat/studioe5-vpn-ondemand`, commit `124543d`. Push vers Gitea à faire dès que le remote sera accessible (actuellement `localhost:3001` et `gitea.alfrednobel.edudeploy.com` injoignables).
- [x] ~~Tester le flux complet depuis linterface web~~ → **OK** via lAPI authentifiée (`POST /api/instances`), instance `cmqqgrur20001lw67t2bdgzkg` accessible en HTTPS public.
- [ ] **Obtenir un certificat wildcard** pour `*.studioe5.edudeploy.com` (voir étude ci-dessous).
- [ ] **Nettoyer les instances/agent de test** une fois le wildcard en place et le push effectué.
- [x] ~~Packager les binaires Tailscale pour Windows~~ → **OK**, `download-tailscale-bins.sh` + `studioE5-agent-v0.3.0-windows.zip` prêt.
- [ ] **Nettoyer les anciens nodes/volumes Headscale** créés pendant les tests.
- [ ] **Documenter la procédure de mise en production** pour le client A (config agent, clés Headscale, ports, etc.).
### ✅ Terminé
## 💡 Améliorations UI envisagées
- [x] Rate limit Lets Encrypt levé.
- [x] Flux HTTPS public validé (`test-wp-001.studioe5.edudeploy.com`).
- [x] Branche `feat/studioe5-vpn-ondemand` créée, commit `124543d`.
- [x] Flux complet UI → API → WebSocket → agent → Docker → VPN → Caddy validé.
- [x] Packager les binaires Tailscale pour Windows (`studioE5-agent-v0.3.5-windows.zip`).
- [x] **Sécurité authentification du canal serveur → agent** (token par nœud, clé API interne, sessions NextAuth sur les routes API).
- [x] **Sécurité durcissement du code dactivation** (`crypto.randomBytes`, expiration 60 min, rate-limiting, invalidation après usage).
- [x] **Sécurité ACL Headscale** (isolation agent ↔ agent, resolver → agent autorisé).
- [x] **Sécurité clés pré-auth Headscale éphémères** (génération côté serveur via `HEADSCALE_API_KEY`, non persistées côté agent).
- [x] **Agent v0.3.5 forwarding entrant Windows** (`tailscale serve` automatique au démarrage de chaque instance).
- [x] **Agent v0.3.5 UI locale moderne** (dashboard, logs, progression, actions dinstance).
- [x] **Agent v0.3.5 cycle de vie des instances** (`stop`/`start` préservent les volumes, `reset`/`delete` effacent).
- [x] **Agent v0.3.5 cleanup au shutdown** (arrêt propre de Tailscale et des instances, notification serveur).
- [x] **Synchronisation dashboard** (messages `instance_stopped` / `instance_deleted` traités côté serveur).
### Console / log intégré dans lagent
### ⏳ Reste à faire
Plutôt que de laisser Windows ouvrir une fenêtre noire à chaque commande `podman`/`docker`/`tailscale`, rediriger le `Stdout`/`Stderr` de chaque commande vers lUI locale de lagent (`http://localhost:7070`).
- [ ] **Certificat wildcard** : transféré au deployeur (`docs/ONBOARDING_CLIENT.md`). L’étude technique reste disponible ci-dessous pour référence.
- [ ] **Nettoyer les instances/agent de test** une fois le push effectué.
- [ ] **Nettoyer les anciens nodes/volumes Headscale** de test (nœuds `edubox`, `prof`, `invalid-*` hors ligne à supprimer).
- [ ] **Pousser la branche** vers Gitea dès que le remote sera accessible.
- [ ] **Documenter la procédure de mise en production** pour le client A (config agent, clés Headscale, ports, ACL, etc.).
- [ ] **Étude interface de déploiement multi-clients** : outil de provisionning dun nouveau serveur client + agent générique (option A : URL serveur déterminée à lactivation).
- [ ] **Sécurité gestion et rotation des secrets** (`INTERNAL_API_KEY`, `HEADSCALE_API_KEY`, `NEXTAUTH_SECRET`, `DATABASE_URL`).
- [ ] **Sécurité durcissement des conteneurs** (`cap_add`, utilisateurs non-root, scans CVE).
- [ ] **Sécurité mises à jour de sécurité** (Tailscale, images Docker, OS agents).
- [ ] **Sécurité logs daudit** (instances, codes dactivation, actions admin).
- [ ] **Sécurité backups et reprise dactivité** (DB, state Headscale, states agents).
- [ ] **Sécurité intégrité et signature de lagent** (checksum Tailscale, signature Windows, hash SHA256).
- [ ] **Sécurité conformité RGPD** (données élèves, suppression de compte, export).
- [ ] **Sécurité restriction réseau** (endpoint interne, dashboard Headscale).
- [ ] **Sécurité rate limiting et quotas** (routes publiques, instances par élève/établissement).
- [ ] **Sécurité tests de sécurité** (intrusion légère, tests automatisés avant release).
Bénéfices :
- Expérience utilisateur plus propre et commercialisable.
- Diagnostic facilité : lutilisateur voit exactement ce qui se passe (téléchargement dimage, démarrage, installation PrestaShop, etc.).
## 💡 Améliorations UI
Implémentation :
1. Remplacer `cmd.Stdout = os.Stdout` par un `io.Pipe()` ou `bytes.Buffer` dans `docker.go`, `tailscale.go`, etc.
2. Envoyer les lignes de log au frontend via le WebSocket existant (`agent/ui/websocket`).
3. Afficher les logs dans un panneau dédié du HTML.
### ✅ Console / log intégrée dans lagent (v0.3.5)
### Barre de progression
Les logs de lagent sont redirigés vers `<data-dir>/agent.log` et diffusés en temps réel dans lUI locale (`http://localhost:7070`) via le WebSocket existant.
Associer des étapes connues à une barre de progression dans lUI :
### ✅ Barre de progression (v0.3.5)
Lagent envoie des messages `progress` au frontend pendant le démarrage dune instance :
| Étape | Poids |
|-------|-------|
| Connexion au serveur | 10 % |
| Démarrage du VPN | 25 % |
| Téléchargement de limage Docker | 50 % |
| Création de la base de données | 70 % |
| Installation de PrestaShop/WordPress | 90 % |
| Instance prête | 100 % |
| Préparation de lapplication | 10 % |
| Configuration de lapplication | 30 % |
| Application en cours de démarrage | 60 % |
| Connexion sécurisée active | 80 % |
| Finalisation de linstallation | 90 % |
| Application prête | 100 % |
Lagent envoie des messages `progress` au frontend à chaque étape franchie.
### Boutons daction par instance (v0.3.5)
LUI locale affiche désormais des boutons **Démarrer**, **Arrêter**, **Redémarrer** et **Supprimer** pour chaque instance.
## 🚀 Scalabilité commerciale — déploiement multi-clients
### Objectif
Permettre de déployer facilement une stack studioE5 complète pour un nouvel établissement/client sur un VPS dédié, sans intervention technique lourde.
### Architecture cible
- **Un serveur = un client** : chaque établissement a sa propre stack Docker Compose, sa base PostgreSQL, son Headscale et son Caddy.
- **Agent générique (option A)** : un seul binaire agent pour tous les clients. LURL du serveur cible est déterminée au moment de lactivation, pas hardcodée dans lagent.
- Pistes : code dactivation résolu par un hub central, code structuré contenant lidentifiant du serveur, ou champ URL serveur saisi dans lUI locale.
- **Interface de déploiement** : dashboard superadmin (hub) permettant de créer un client, provisionner le VPS, générer les secrets et retourner les informations de connexion.
### Prérequis techniques à préparer
Avant de pouvoir déployer un nouveau client en quelques clics, il faut encore préparer les éléments suivants :
| # | Élément | État | Détail |
|---|---------|------|--------|
| 1 | **Agent générique** | ⏳ À faire | `defaultServerURL` est hardcodé (`wss://studioe5.edudeploy.com/api/websocket`). Lagent doit pouvoir déterminer lURL serveur cible à lactivation (option A : champ URL, hub de résolution, ou code structuré). |
| 2 | **Script de provisionning** | ⏳ À faire | Aucun outil automatisé pour provisionner un VPS vierge : installation Docker, déploiement de la stack, génération des secrets, création des clés Headscale, configuration DNS wildcard. |
| 3 | **Registry dimages** | ⏳ À faire | Les images `server` et `resolver` sont buildées sur le serveur cible. Il faut un registry privé pour builder une fois et déployer partout. |
| 4 | **Hub central** | ⏳ À faire | Dashboard superadmin listant les clients, état des serveurs, versions déployées, logs distants et mises à jour. |
| 5 | **Mises à jour à distance** | ⏳ À faire | Mécanisme pour pousser une nouvelle version du serveur et de lagent sur tous les déploiements clients. |
| 6 | **Monitoring / support** | ⏳ À faire | Collecte centralisée de logs, alertes (serveur down, certificat expiré, agent hors ligne). |
| 7 | **Branding / personnalisation** | ⏳ À faire | Logo, nom de l’établissement, couleurs configurables par client. |
| 8 | **Tests automatisés** | ⏳ À faire | Tests du flux activation → VPN → instance → HTTPS public pour valider chaque nouveau déploiement. |
| 9 | **Documentation procédure prod** | ⏳ À faire | Procédure complète de mise en production pour un nouveau client. |
### Statut
- ⏳ À étudier et planifier plus tard. Larchitecture actuelle (un serveur par client + agent zero-config) est déjà compatible avec cette vision, mais le code nest pas encore industrialisé pour un déploiement à grande échelle.
## 🔒 Étude certificat wildcard `*.studioe5.edudeploy.com`