# Runbook — portail licence/téléchargement pour bêta contrôlée

Portail `app_aivanov` (FastAPI). Objectif : permettre à un **client bêta** de
récupérer la GUI et d'activer sa licence.

> ⚠️ Pré-requis de déploiement (voir §5) : servir derrière un reverse proxy
> **HTTPS** et définir des **secrets forts** (`APP_SECRET_KEY`, `ADMIN_PASSWORD`).
> C'est le niveau adéquat : le portail ne contient **aucune donnée patient**
> (licences + compteurs agrégés uniquement). Pas besoin de VPN/IP allowlist.

## 0. État réel du déploiement (2026-06-18, en place)
- Domaine public : **`app.aivanov.eu`** (DNS → `82.64.97.95`).
- App servie en tmux `app_aivanov_web` : `uvicorn app.main:app --host 0.0.0.0 --port 8088`,
  `APP_ENV=production`, secrets forts dans `/home/dom/ai/app_aivanov/.env` (perms `600`).
  SQLite `data/app_aivanov.db`, artefacts `data/artifacts`, clés licences `data/keys`.
- Reverse proxy **NPM** : proxy host `11` → `http://172.18.0.1:8088`, certificat
  Let's Encrypt (exp. 2026-09-16), **Force SSL + HTTP/2 + Block Common Exploits** ON.
- Vérifié live : `http://…/login` → 301 HTTPS ; `https://…/login` → 200 ;
  login admin → 303 `/admin`, **cookie `Secure` + `HttpOnly` + `SameSite=Lax`**
  (le cookie Secure confirme que le fix `884661a` tourne — APP_ENV=production).

## 1. Publier l'installateur GUI comme artefact actif
**Pré-requis : l'EXE Windows doit d'abord être copié sur le serveur Linux** (il est
aujourd'hui sur la machine de build Windows, non diffusé). Une fois sur le serveur,
depuis `/home/dom/ai/app_aivanov` avec l'environnement prod chargé :
```bash
cd /home/dom/ai/app_aivanov
set -a; source .env; set +a            # APP_ENV=prod + secrets → même DB que le serveur
python3 scripts/publish_artifact.py --version 2026.06.18.1203 \
  --file /chemin/vers/Anonymisation-Setup.exe --active
```
(ou via le back-office admin → « Publier une version » : version, fichier, « rendre active »).
Le script copie le fichier dans `data/artifacts/`, recalcule le SHA-256 côté serveur,
crée/active la version (canal `beta`) et **désactive** l'éventuelle version active précédente.
**Vérification après publication** (étape 4) : `GET /api/v1/version` doit renvoyer
`2026.06.18.1203` + SHA-256 **`8B437346…DED2F`**. Sinon, ne pas diffuser.

## 2. Créer / valider le compte client bêta
- Option A — auto-inscription : le client va sur `/register` (organisation, e-mail, mot de passe ≥ 8) → compte **en attente**.
- Puis **admin** : `/admin` → section « Inscriptions en attente » → **Approuver** (crée automatiquement une **licence active** via `approve_user_with_default_licence`).
- Option B — création admin directe : back-office « Nouveau client ».
- (Reset admin si besoin : `python3 scripts/create_admin.py <email> <mdp> --force`.)

## 3. Licence + jeton d'activation
- Vérifier la **licence active** du client (back-office « Licences » : statut `active`, postes, expiration).
- Le client (espace `/licences`) génère un **jeton d'activation** (« Générer un jeton », valable 48 h) à saisir dans la GUI (bouton « Activer »).
- L'activation poste appelle `POST /api/v1/activate` (token + machine_id) → licence signée RSA renvoyée.

## 4. Vérifier la disponibilité du téléchargement
- `GET /api/v1/version` → doit renvoyer la version active (`2026.06.18.1203` + SHA + `download_url`). 404 = aucun artefact actif (revoir §1).
- **Téléchargement authentifié** : `GET /api/v1/download/{version}` exige une **session web connectée** + licence active (ou admin). Vérifier qu'un client connecté avec licence peut télécharger, et qu'un anonyme reçoit 401.
- UX : un navigateur anonyme sur une route protégée est redirigé vers `/login` ; le logo renvoie à `/` ; favicon OK (correctifs F1/F2/F3).

## 5. Sécurité — niveau proportionné (pas la NASA)
Modèle de menace réel : le portail ne stocke **aucune donnée patient** (tout le
traitement est local au poste client) — uniquement licences, jetons d'activation
et **compteurs d'usage agrégés**. Le seul actif sensible = l'installateur publié
et les actions admin. Le niveau adéquat est donc **HTTPS + login/mot de passe fort**,
pas un durcissement de banque.

**Indispensable — état actuel (tout ✅ en place, cf. §0) :**
- **HTTPS** : ✅ NPM + Let's Encrypt, Force SSL ON. Cookie de session `Secure`
  automatiquement (`APP_ENV` ≠ `dev`/`test`, fix `884661a` qui tourne en prod).
- **Secrets forts** : ✅ `APP_SECRET_KEY` + `ADMIN_PASSWORD` dans `.env` (`600`),
  défauts dev (`dev-change-me-INSECURE` / `change-me`) écartés. C'est le vrai point :
  un admin compromis pourrait publier un faux installateur.

**Déjà couvert / non bloquant :**
- **CSRF** : le cookie est en `SameSite=Lax`, ce qui bloque déjà l'envoi du cookie
  sur un POST cross-site (l'attaque CSRF classique). Pas de middleware dédié requis
  pour une bêta sous login.
- **Rate-limiting `/login`** : *nice-to-have*, se gère au reverse proxy (fail2ban/limit_req)
  si besoin ; avec un mot de passe fort + l'approbation manuelle des comptes, le risque
  brute-force est marginal. Non bloquant.

**Hygiène (non urgent) :** sortir l'e-mail admin par défaut (`dom@aivanov.fr`) du
code source vers `.env`.

## 5bis. Dépôt modèles EDS/GLiNER (préparé, NON actif)
Arborescence de réception créée côté serveur (vide pour l'instant) :
- `data/depot/models/eds-pseudo-public/incoming/`
- `data/depot/models/gliner_multi_pii-v1/incoming/`

⚠️ **EDS-Pseudo et GLiNER restent NON ACTIFS** dans la bêta : ne les annoncer comme
disponibles qu'une fois le pack **complet ET testé** (chargement réel vérifié), pas
sur la simple présence d'un dossier. La GUI bêta tourne avec **CamemBERT-bio + règles/gazetteers**
uniquement (moteurs honnêtes). L'auto-download GUI des modèles = chantier séparé.

## 6. Données / RGPD
- Le portail ne reçoit **jamais** de contenu patient : uniquement licences, activations de postes, et **compteurs d'usage agrégés** (nb traitements/documents/pages).
- Le dashboard admin « Utilisation par client » affiche ces compteurs (clients sans usage inclus, à 0).
