Files
edubox/docs/ONBOARDING_CLIENT.md
EduBox Dev a414f03a59 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.
2026-06-25 22:59:09 +00:00

16 KiB
Raw Permalink Blame History

Deployeur studioE5 — Onboarding dun nouvel établissement

Objectif

Ce document décrit le fonctionnement du deployeur studioE5, cest-à-dire lapplication / loutil qui provisionne et configure un nouvel environnement client (un établissement) prêt à accueillir lapplication studioE5.

Lapplication studioE5 elle-même (agent, VPN on-demand, resolver, Caddy, Headscale, etc.) est documentée dans SUIVI_VPN_ONDEMAND.md. Le deployeur est loutil qui déploie cette application sur un VPS dédié au client.


Public cible

  • Équipe produit / développement du deployeur
  • Équipe ops / déploiement
  • Référents techniques du client A

Glossaire

Terme Définition
Deployeur Application qui provisionne un VPS, déploie la stack studioE5 et configure le DNS/certificats pour un nouvel établissement.
Hub central Dashboard superadmin studioE5 qui orchestre les déploiements et la gestion multi-clients.
Établissement Entité client (école, lycée, université, entreprise).
Tag établissement Slug unique et court identifiant l’établissement dans les URLs et le DNS.
Domaine géré Sous-domaine fourni par studioE5 : *.tag.edudeploy.com.
Domaine propre Domaine détenu par l’établissement : *.tag.monetablissement.fr.
Application studioE5 Stack complète déployée sur le VPS : server, resolver, resolver-vpn, caddy, headscale, postgres, etc.
Agent générique Binaire agent unique, capable de se connecter à nimporte quel serveur studioE5 via résolution dURL à lactivation.

Architecture : deployeur vs application studioE5

┌─────────────────────────────────────────────────────────────┐
│                      Hub central studioE5                    │
│  (superadmin, gestion des établissements, monitoring)        │
└───────────────────────┬─────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────────┐
│                      Deployeur studioE5                      │
│  (provisionning VPS, DNS, certificats, déploiement stack)   │
└───────────────────────┬─────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────────┐
│              Application studioE5 (un par client)            │
│  Caddy — Resolver — Resolver-VPN — Headscale — Server — DB  │
│                         ▲                                   │
│                         │ WebSocket / VPN on-demand         │
│                         ▼                                   │
│                    Agent élève (Windows/Linux)               │
└─────────────────────────────────────────────────────────────┘

Flux donboarding par le deployeur (vue densemble)

Création de l’établissement dans le hub
    ↓
Choix du domaine (géré ou propre)
    ↓
Génération du tag établissement
    ↓
Provisionning du VPS
    ↓
Configuration DNS wildcard
    ↓
Génération du certificat wildcard
    ↓
Déploiement de la stack studioE5 (Docker Compose)
    ↓
Initialisation de Headscale et création des clés
    ↓
Création du compte administrateur de l’établissement
    ↓
Génération des codes dactivation
    ↓
Build et mise à disposition de lagent dédié
    ↓
Activation de lagent par un élève
    ↓
Création dune première instance (validation du déploiement)

1. Création de l’établissement dans le hub

Le superadmin crée un nouvel établissement dans le hub central.

Données minimales :

  • Nom officiel
  • Type d’établissement (école, lycée, université, entreprise)
  • Pays / fuseau horaire
  • Contact administrateur
  • Choix du mode de domaine (managed ou custom)

2. Choix du domaine

Option A — Domaine géré par studioE5 (MVP)

Le deployeur crée automatiquement un sous-domaine du domaine maître :

*.tag.edudeploy.com

Le hub gère le DNS chez le registrar studioE5 (actuellement Infomaniak).

Option B — Domaine propre de l’établissement (évolution)

L’établissement fournit son propre domaine :

*.tag.monetablissement.fr

Prérequis :

  • Le client pointe son DNS wildcard vers lIP du VPS provisionné.
  • Le deployeur dispose dun token API du registrar du client pour le challenge DNS-01.

3. Génération du tag établissement

Le tag est un slug court, unique au niveau du hub, utilisé dans les URLs et le DNS.

Règles

  • Uniquement [a-z0-9-]
  • Pas de tiret au début ni à la fin
  • Longueur conseillée : 2 à 20 caractères
  • Vérification dunicité en base

Exemples

Nom d’établissement Tag
Lycée Jules Ferry ljf
Institut Supérieur du Digital isd
École Notre-Dame end

Gestion des collisions

  • ljfljf-2, ljf-3, etc.

4. Provisionning du VPS

Le deployeur provisionne un VPS dédié pour l’établissement.

Prérequis sur le VPS vierge

  • OS Linux (Ubuntu LTS recommandé)
  • Docker + Docker Compose installés
  • Accès SSH avec clé
  • Ports ouverts : 22, 80, 443

Actions automatisées par le deployeur

  1. Installation de Docker et Docker Compose si absent.
  2. Création de la structure de dossiers (/opt/studioe5-<tag>/).
  3. Génération des secrets (.env) :
    • INTERNAL_API_KEY
    • HEADSCALE_API_KEY
    • HEADSCALE_AUTH_KEY (réutilisable, taguée tag:student-agent)
    • HEADSCALE_RESOLVER_AUTH_KEY
    • INFOMANIAK_API_TOKEN (si domaine géré)
    • NEXTAUTH_SECRET, DATABASE_URL, etc.
  4. Récupération des images Docker depuis le registry privé (ou build sur place en attendant).
  5. Génération des fichiers de configuration (Caddyfile, docker-compose.yml, headscale/config.yaml, headscale/acl_policy.hujson).

5. Configuration DNS wildcard

Domaine géré

Le deployeur appelle lAPI du registrar pour créer :

*.tag.edudeploy.com  A  <IP_DU_VPS>

Domaine propre

Le deployeur vérifie que lenregistrement existe :

*.tag.monetablissement.fr  A  <IP_DU_VPS>

6. Certificat wildcard

Principe

Un seul certificat wildcard couvre toutes les instances futures de l’établissement.

Mise en œuvre avec Caddy

Le deployeur génère le Caddyfile :

*.tag.edudeploy.com {
    tls {
        dns infomaniak {env.INFOMANIAK_API_TOKEN}
    }

    reverse_proxy resolver:2020 {
        header_up Host {host}
    }
}

Pour un domaine propre, le provider DNS est celui du client.

Renouvellement

Géré automatiquement par Caddy.


7. Déploiement de la stack studioE5

Le deployeur lance la stack Docker Compose complète :

cd /opt/studioe5-<tag>
docker compose up -d

Services déployés :

  • server : API + WebSocket + UI Next.js
  • resolver : reverse proxy interne vers les instances
  • resolver-vpn : sidecar Tailscale dans le netns du resolver
  • caddy : reverse proxy public + TLS
  • headscale : contrôleur Tailscale
  • postgres : base de données

8. Initialisation de Headscale

Le deployeur initialise Headscale et crée les clés nécessaires :

# Création de lutilisateur dédié au resolver
docker compose exec headscale headscale users create resolver

# Création de la clé pré-auth réutilisable pour les agents
docker compose exec headscale headscale preauthkeys create \
  --user studioe5 \
  --reusable \
  --tags tag:student-agent \
  -e 87600h

# Création de la clé pré-auth pour le resolver
docker compose exec headscale headscale preauthkeys create \
  --user resolver \
  --tags tag:resolver \
  -e 87600h

# Création dune clé API Headscale valable 10 ans
docker compose exec headscale headscale apikeys create -e 87600h

Ces secrets sont stockés dans le .env du serveur.


9. Création du compte administrateur de l’établissement

Une fois la stack déployée, le deployeur (ou le hub) crée le premier compte administrateur de l’établissement via lAPI du serveur nouvellement déployé.

Rôles :

  • admin : gestion des élèves, instances, agents.
  • teacher : gestion limitée à certaines classes/groupes.
  • superadmin (studioE5) : accès transverse.

Ladministrateur reçoit un lien dactivation sécurisé.


10. Génération des codes dactivation

Le deployeur configure le serveur pour permettre la génération de codes dactivation.

Règles de sécurité (implémentées côté application studioE5)

  • Génération avec crypto.randomBytes
  • Alphabet sans ambiguïté : ABCDEFGHJKLMNPQRSTUVWXYZ23456789
  • 6 caractères
  • Expiration après 60 minutes
  • Invalidation après usage
  • Rate-limiting : 5 tentatives par code / 5 tentatives par nodeId sur 15 minutes

Flux

  1. Ladministrateur génère un code pour un élève.
  2. L’élève saisit le code dans lagent.
  3. Le serveur valide et renvoie :
    • lidentité de l’élève
    • lURL Headscale
    • une clé pré-auth Headscale éphémère
  4. Lagent démarre automatiquement le VPN.

11. Build et mise à disposition de lagent

Principe

Lagent est un binaire générique, mais il doit être capable de se connecter au bon serveur. Le deployeur génère un agent pré-configuré ou un installeur qui embarque lURL du serveur de l’établissement.

Build

cd /opt/studioe5-<tag>/agent
./download-tailscale-bins.sh 1.98.4
./build.sh

Artifacts générés :

  • studioE5-agent-vX.Y.Z-windows.zip
  • studioE5-agent-vX.Y.Z.exe
  • studioE5-agent-vX.Y.Z (Linux)

Mise à disposition

Les fichiers sont servis par Caddy depuis server/public/agent/ :

https://tag.edudeploy.com/studioE5-agent-vX.Y.Z-windows.zip

12. Activation de lagent

Activation zéro-config

  1. L’élève télécharge lagent depuis lURL de l’établissement.
  2. Il extrait larchive et lance studioE5-agent.exe.
  3. Il ouvre http://localhost:7070.
  4. Il saisit le code dactivation à 6 caractères.
  5. Lagent contacte le serveur, récupère la configuration et démarre le VPN.

Les détails techniques du VPN on-demand (named pipes Windows, logs, ACL, tokens, clés éphémères) sont documentés dans SUIVI_VPN_ONDEMAND.md.


13. Création dune instance et construction de lURL (validation)

Le deployeur ou ladministrateur crée une première instance pour valider le déploiement.

Format dURL

<appli>-<initiales><id-court>.<tag>.<domaine>

Exemple :

wp-jd47.ljf.edudeploy.com

Avec :

  • wp : type dapplication
  • jd : initiales de l’élève
  • 47 : identifiant court unique
  • ljf : tag de l’établissement
  • edudeploy.com : domaine de base

Mapping type dapplication → préfixe

Application Préfixe
WordPress wp
PrestaShop ps
Moodle mdl
Nextcloud nc

Protection de lidentité

  • LURL ne contient pas le nom complet de l’élève.
  • Seules les initiales + un identifiant court opaque sont exposées.

14. Modèles de données du deployeur

Table / modèle Organization (établissement dans le hub)

{
  "id": "uuid",
  "name": "Lycée Jules Ferry",
  "tag": "ljf",
  "domainMode": "managed",
  "baseDomain": "edudeploy.com",
  "adminEmail": "admin@ljf.fr",
  "status": "active",
  "createdAt": "2026-06-25T17:28:07Z"
}

Table / modèle Deployment (déploiement sur un VPS)

{
  "id": "uuid",
  "organizationId": "uuid",
  "serverIp": "203.0.113.10",
  "serverHostname": "ljf.studioe5.edudeploy.com",
  "wildcardDnsConfigured": true,
  "wildcardCertificateReady": true,
  "dnsProvider": "infomaniak",
  "dnsProviderTokenRef": "env:INFOMANIAK_TOKEN_LJF",
  "headscaleApiKeyRef": "env:HEADSCALE_API_KEY_LJF",
  "status": "ready",
  "deployedAt": "2026-06-25T17:28:07Z"
}

Table / modèle Student (dans lapplication studioE5 déployée)

{
  "id": "uuid",
  "organizationId": "uuid",
  "firstName": "Jean",
  "lastName": "Dupont",
  "initials": "jd",
  "activationCode": "AB3D9F",
  "activationCodeExpiresAt": "2026-06-25T18:28:07Z",
  "nodeId": "vps-8fc665eb",
  "nodeToken": "..."
}

Table / modèle Instance (dans lapplication studioE5 déployée)

{
  "id": "cmqqgrur20001lw67t2bdgzkg",
  "organizationId": "uuid",
  "studentId": "uuid",
  "nodeId": "vps-8fc665eb",
  "templateId": "wordpress-wordpress-latest",
  "applicationPrefix": "wp",
  "shortId": "47",
  "subdomain": "wp-jd47",
  "fqdn": "wp-jd47.ljf.edudeploy.com",
  "port": 8001,
  "status": "running"
}

15. Sécurité et RGPD

Protection de lidentité de l’élève

  • LURL publique ne contient pas le nom complet de l’élève.
  • Seules les initiales + un identifiant court opaque sont exposées.

Isolation réseau

  • Les agents élèves ne peuvent pas communiquer entre eux (ACL Headscale).
  • Le resolver est le seul service autorisé à joindre les agents sur leurs ports dinstance.

Authentification

  • Token unique par agent (node.token).
  • Clé API interne pour les endpoints serveur → agent.
  • Sessions NextAuth sur les routes API métier.

Clés pré-auth Headscale

  • Éphémères, à usage unique, 15 minutes dexpiration.
  • Non persistées côté agent.

16. Checklist de validation du deployeur

À lissue dun onboarding, les points suivants doivent être validés :

  • L’établissement est créé dans le hub avec un tag unique.
  • Le VPS est provisionné et accessible en SSH.
  • Docker et Docker Compose sont installés.
  • Le DNS wildcard est résolu (*.tag.edudeploy.com → IP du VPS).
  • Le certificat wildcard est obtenu et valide.
  • La stack studioE5 est démarrée (docker compose ps).
  • Headscale est initialisé avec les utilisateurs et clés nécessaires.
  • Le compte administrateur de l’établissement est créé.
  • Un code dactivation peut être généré pour un élève.
  • Lagent est buildé et téléchargeable depuis le serveur de l’établissement.
  • Lagent sactive avec le code zéro-config.
  • Une instance peut être créée et son URL est accessible en HTTPS.
  • Deux instances différentes reçoivent des URL uniques.
  • Le flux HTTPS complet retourne bien HTTP 200.

17. Roadmap du deployeur

Court terme (MVP)

  • Déploiement manuel ou semi-automatisé dun nouvel établissement sur un VPS.
  • Domaine géré par studioE5 uniquement.
  • Build des images sur le VPS cible.
  • Agent avec URL serveur hardcodée ou fournie à lactivation.

Moyen terme

  • Agent générique : déterminer lURL serveur cible à lactivation (code structuré, hub de résolution, ou champ URL).
  • Script de provisionning : installation Docker, déploiement stack, génération secrets, DNS wildcard.
  • Registry dimages privé : builder une fois, déployer partout.
  • Support de domaines propres à l’établissement.
  • Support multi-registrar DNS.

Long terme

  • Hub central multi-clients : dashboard superadmin, gestion des versions, logs distants.
  • Mises à jour à distance : pousser une nouvelle version du serveur et de lagent sur tous les déploiements.
  • Monitoring / support : alertes serveur down, certificat expiré, agent hors ligne.
  • Tests automatisés : validation du flux activation → VPN → instance → HTTPS public à chaque déploiement.
  • Console/log intégré et barre de progression dans lagent.
  • Génération automatique de codes dactivation par import CSV.