Aller au contenu

TokenVeil : guide d'installation chez un client

Ce document décrit le déploiement complet de TokenVeil (édition Enterprise) chez un client, via Docker. Il est pensé pour être suivi de bout en bout sans connaissance préalable du projet.

L’édition Enterprise est un produit sous licence : elle est livrée par TokenVeil (image + clé de licence) une fois le contrat activé. Ce guide part du moment où vous avez reçu ces éléments. Pour évaluer le produit sans licence, voir plutôt l’édition Community (dépôt public, docker compose up).


  • Un serveur Linux (physique, VM ou cloud) avec Docker et Docker Compose v2 installés
  • 4 Go de RAM minimum (les modèles NLP fr/en chargés en mémoire au démarrage en consomment une bonne partie), 4 vCPU recommandés
  • ~3 Go d’espace disque pour l’image (modèles spaCy inclus)
  • Un port HTTP disponible (8500 par défaut, configurable)
  • Si exposition publique : un nom de domaine et un reverse proxy devant le service (voir §7)
  • Si authentification LDAP/Active Directory : accès réseau au contrôleur de domaine depuis le serveur
  • Pour l’activation de licence : soit un accès sortant HTTPS vers le serveur de licence, soit un déploiement totalement air-gap assumé (voir §3, note licence)

Aucune dépendance à installer à la main sur le serveur : Python, Node.js et le CLI Claude Code sont tous embarqués dans l’image Docker.

2. Récupération de l’image Enterprise et de la licence

Section intitulée « 2. Récupération de l’image Enterprise et de la licence »

L’édition Enterprise est livrée sous forme d’image Docker pré-construite (code compilé en bytecode, pas de source Python dans l’image), accompagnée d’une clé de licence signée propre au client. Deux modes de livraison, selon l’accès réseau du client :

a. Registre privé authentifié (recommandé si le serveur a un accès sortant)

Fenêtre de terminal
docker login <registre-prive> # identifiants livrés avec la licence
docker pull <registre-prive>/tokenveil:enterprise

b. Archive hors-ligne (client air-gap ou sans accès au registre)

Fenêtre de terminal
# fichier tokenveil-enterprise-<version>.tar transmis par canal sécurisé
docker load -i tokenveil-enterprise-<version>.tar

Dans les deux cas, TokenVeil vous transmet également :

  • le docker-compose.yml et le .env.example de déploiement,
  • une clé de licence (LICENSE_KEY) : un token signé Ed25519, propre à ce client et à ce contrat.

Placer docker-compose.yml et .env.example dans un dossier de travail (par exemple tokenveil/), puis continuer la configuration ci-dessous.

Fenêtre de terminal
cp .env.example .env

Ouvrir .env et renseigner :

VariableRôleComment l’obtenir
LICENSE_KEYClé de licence Enterprise (token signé) qui déverrouille l’instanceLivrée par TokenVeil à l’activation du contrat
LICENSE_SERVER_URLURL du serveur de licence, pour la validation périodique (phone-home) et la révocationLivrée avec la licence ; laisser vide seulement pour une instance totalement air-gap
ANON_DB_KEYClé de chiffrement des données au repos (mapping anonymisation, tokens OAuth)python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
AUTH_BACKENDlocal ou ldapSelon l’infra du client
WEBAPP_USERSComptes locaux bootstrap, format user:motdepasse,user2:motdepasse2À définir si AUTH_BACKEND=local
LDAP_*Config annuaireVoir les exemples commentés dans .env.example si AUTH_BACKEND=ldap
ANON_LANGUAGELangue par défaut de détection (fr/en)Selon la langue des logs/données du client
ANON_PORTPort d’écoute exposé sur l’hôte8500 par défaut, à changer si déjà pris

Point d’attention sécurité : ANON_DB_KEY ne doit jamais être perdue ni régénérée sur une instance qui contient déjà des données. Sans elle, le mapping anonymisation devient illisible et les conversations existantes ne peuvent plus être désanonymisées à l’affichage. La sauvegarder dans un coffre-fort (password manager d’entreprise), pas seulement dans le .env sur le serveur.

Licence : sans LICENSE_KEY valide, l’instance démarre en période de grâce puis se désactive au bout de 15 jours sans licence. Une fois activée et en contact avec LICENSE_SERVER_URL, elle dispose d’une grâce réseau de 14 jours si le serveur de licence devient injoignable ; au-delà elle se suspend (une révocation ne peut donc pas être contournée en coupant le réseau après activation). Une instance totalement air-gap (jamais de contact, LICENSE_SERVER_URL vide) n’est pas concernée par la grâce réseau et fonctionne sur la seule validité du token. La clé peut aussi être fournie autrement que par le .env : montée dans le fichier data/license.lic, ou collée après coup dans Administration > Licence (elle est validée avant d’être écrite, un token invalide ne casse pas la licence en place).

L’image étant pré-construite, aucun build local n’est nécessaire :

Fenêtre de terminal
docker compose up -d

Aucun téléchargement de modèle NLP : ils sont déjà dans l’image. Le premier démarrage prend ~30 à 60 s, le temps de charger les modèles fr/en en mémoire.

Vérifier que le service répond :

Fenêtre de terminal
curl http://localhost:8500/healthz
# {"status": "ok"}

Si ANON_PORT a été changé dans .env, adapter l’URL ci-dessus en conséquence. Vérifier aussi le statut de licence dans Administration > Licence après la première connexion (§5).

  • Ouvrir http://<serveur>:<port>/ (ou le domaine public si déjà en place, voir §7)
  • Se connecter avec un des comptes définis dans WEBAPP_USERS (le premier compte créé devient automatiquement admin)
  • Dans Préférences > Comptes IA, chaque utilisateur lie sa propre IA :
    • Claude : OAuth, abonnement Pro/Max personnel, aucune clé API facturée
    • Gemini : clé API personnelle générée sur aistudio.google.com, gratuite sur les modèles Flash
  • Pour ajouter d’autres comptes après coup : panneau Administration (visible uniquement pour les comptes admin) > onglet Utilisateurs

6. Mots-clés métier du client (optionnel mais recommandé)

Section intitulée « 6. Mots-clés métier du client (optionnel mais recommandé) »

Dans Préférences > Mots-clés à anonymiser, ajouter les codenames, noms de projets internes ou identifiants propres au client que la détection générique ne peut pas connaître à l’avance. Un admin peut déployer ces règles à toute l’équipe ou à un utilisateur précis depuis le panneau Administration.

TokenVeil utilise du streaming SSE (réponse de l’IA affichée au fur et à mesure). La plupart des reverse proxy bufferisent les réponses par défaut, ce qui casse cet effet (la réponse arrive d’un bloc à la fin au lieu d’être progressive). Ajouter ces directives sur le bloc qui pointe vers TokenVeil :

Nginx (bloc location dédié, ou config personnalisée Nginx Proxy Manager) :

proxy_buffering off;
proxy_cache off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_read_timeout 300s;

Sans ça, l’application reste fonctionnelle mais perd l’effet de streaming. Pas un bug du logiciel, un comportement par défaut du proxy à désactiver explicitement.

Forcer HTTPS (Force SSL) est fortement recommandé : les identifiants de connexion et le contenu des échanges (même anonymisés côté IA) transitent en clair sur le réseau sinon.

Sauvegarde : un seul dossier à sauvegarder, ./data (monté en volume Docker). Il contient la base SQLite (conversations, mapping chiffré), les comptes IA liés par utilisateur et l’état de licence. Sauvegarde simple :

Fenêtre de terminal
tar -czf tokenveil-backup-$(date +%F).tar.gz data/

Mise à jour (nouvelle version livrée) : récupérer la nouvelle image, puis relancer.

Fenêtre de terminal
docker pull <registre-prive>/tokenveil:enterprise # ou : docker load -i tokenveil-enterprise-<version>.tar
docker compose up -d

Le dossier ./data n’est jamais touché par le remplacement de l’image : les comptes liés, l’historique et la licence survivent à la mise à jour.

  • LICENSE_KEY renseignée et instance activée (statut vérifié dans Administration > Licence)
  • ANON_DB_KEY générée spécifiquement pour ce client, sauvegardée hors du serveur
  • HTTPS actif si exposition au-delà du réseau local
  • Mots de passe WEBAPP_USERS changés depuis les valeurs par défaut de .env.example
  • AUTH_BACKEND=ldap configuré si le client a déjà un annuaire d’entreprise (évite la gestion de mots de passe en doublon)
  • Accès réseau au port exposé restreint si pas d’exposition publique voulue (firewall/VPN)
  • Accès sortant vers LICENSE_SERVER_URL autorisé (ou air-gap assumé)
  • Sauvegarde de ./data planifiée (cron, ou intégrée à la politique de backup existante du client)
SymptômeCause probableSolution
docker compose up échoue, port déjà utiliséUn autre service occupe le portChanger ANON_PORT dans .env
Healthcheck reste unhealthyLe serveur met du temps à charger les modèles NLP au premier démarrageAttendre ~30-60s, revérifier avec docker ps
Bandeau licence expirée ou instance suspendueLICENSE_KEY absente/expirée, ou phone-home injoignable au-delà de la grâceVérifier LICENSE_KEY dans .env, la connectivité vers LICENSE_SERVER_URL, ou recoller le token dans Administration > Licence
Streaming pas fluide derrière un reverse proxyBuffering proxy activé par défautVoir §7
Page “Congratulations” Nginx au lieu de l’appDomaine pas associé au bon Proxy HostVérifier que le nom de domaine est bien dans les “Domain Names” du host visé
Liaison Claude échoueCLI claude indisponibleVérifier docker exec <conteneur> claude --version (doit répondre une version)
Un utilisateur ne voit pas le panneau AdministrationRôle non-adminPromouvoir depuis Administration > Utilisateurs (par un admin existant)

Pour le détail technique complet (architecture, choix de design, ce qui est encore en alpha), voir README.fr.md.