Aller au contenu

La licence machine

Kauze est concédé pour le seul serveur livré. Un fichier de licence signé par l'éditeur porte l'identité de l'établissement, l'empreinte de la machine et l'échéance de la maintenance. Le serveur le lit au démarrage.

Où il vit

Un seul fichier, en ~/.cause/licence.lic sur l'hôte. Il est déposé par l'éditeur à l'installation, et se relit dans un éditeur de texte : vous devez pouvoir constater ce qui a été convenu.

# Licence CAUSE — toute modification invalide ce fichier
etablissement: Hôpital de District de Bafia
lieu: Bafia, Cameroun
licence: KAUZE-2026-0001
recette: 2026-10-01
echeance: 2027-10-01
gpu: 3a91f0c4d5e6f708
carte-mere: 7c22be19a0b1c2d3
systeme: e4d158aa11223344
utilisateurs-simultanes: 8
signature: jm4iVumLJayQZwWB...

La dernière ligne est une signature cryptographique qui couvre tout ce qui la précède. Modifier un seul caractère du fichier, une date, un nombre, le rend invalide : seul l'éditeur peut en produire une nouvelle, avec une clé qui n'est pas sur ce serveur. Il n'y a donc rien à gagner à éditer ce fichier, et rien à craindre à le lire.

Un refus pour signature, le statut TAMPERED, n'accuse pourtant pas toujours le fichier. Il dit seulement que la signature ne correspond pas à la clé publique compilée dans le serveur. Un serveur mis à jour dont le conteneur n'a pas été recréé tourne encore sur l'ancienne image, donc sur l'ancienne clé, et refuse alors une licence parfaitement valable. Avant de suspecter le fichier, voir Dépannage.

Rien ne s'arrête le premier jour

Un refus de licence n'arrête jamais le logiciel sur le champ. Il ouvre une fenêtre de soixante-douze heures pendant laquelle tout continue de fonctionner normalement, avec un bandeau rouge en haut de l'écran qui annonce la cause et le décompte. C'est seulement au terme de ces trois jours que l'application se ferme.

Un seul cas échappe à ce délai, lié au fichier décrit juste en dessous : un compteur effacé, ou retouché à la main. Le seul geste utile pendant la fenêtre est d'appeler l'éditeur, et n'attendez pas la dernière heure : elle ne se renouvelle pas.

Le fichier qui compte les heures

Le serveur tient le compte dans ~/.cause/licence-grace.txt. Ouvrez-le, il tient en huit lignes et ses deux dernières sont celles qui parlent :

constat: valide
depuis: 2026-10-12T09:14:32Z
Ce que vous lisez Ce que ça veut dire
constat: valide La licence allait bien au dernier démarrage, à la date indiquée. Rien à faire.
constat: bloquant La licence est refusée depuis la date indiquée. La fermeture tombe soixante-douze heures après cette date.

Ne modifiez jamais ce fichier, et ne le supprimez pas. Il porte un sceau : une valeur retouchée ou un fichier réécrit à la main provoquent un arrêt immédiat, sans les trois jours. De même, le fichier effacé sur un serveur qui porte déjà des patients provoque un arrêt immédiat.

Il entre dans les sauvegardes, de sorte qu'un serveur reconstruit arrive avec son compteur et obtienne sa fenêtre de soixante-douze heures le temps d'obtenir la licence de la machine neuve. Vous n'avez rien à en faire par vous-même : il se réécrit seul à chaque démarrage où la licence est acceptée.

Une installation neuve a droit à la même fenêtre

Un serveur qu'on installe avant d'avoir reçu son fichier de licence démarre et fonctionne soixante-douze heures. C'est ce qui permet de créer les comptes, de charger le référentiel des actes et de faire essayer un médecin le jour de la livraison, sans attendre. Cette tolérance ne vaut que sur une installation vide : dès qu'un patient est enregistré, les règles ordinaires s'appliquent.

Quatre situations, quatre conséquences

L'échéance est dépassée. Un bandeau permanent s'affiche en haut de l'application, et c'est tout : le logiciel continue de fonctionner sans restriction, les rapports se génèrent, les données restent accessibles et exportables. L'échéance concerne la maintenance, pas le droit d'utiliser le logiciel.

La licence ne correspond pas à cette machine. Après la fenêtre de soixante-douze heures, l'application refuse de s'ouvrir et affiche un écran expliquant la cause, avec l'empreinte constatée. Les données présentes sur le serveur ne sont ni effacées ni modifiées.

La licence est refusée, mais la fenêtre court encore. Tout fonctionne, un bandeau rouge annonce la cause et l'heure de fermeture. Voir Rien ne s'arrête le premier jour.

L'identité de la machine n'a pas pu être lue. C'est un cas distinct, et l'écran le dit autrement : « Kauze ne sait pas sur quelle machine il tourne ». Il survient quand les fichiers qui portent l'identité sont absents, vides ou inaccessibles, typiquement un montage manquant dans docker-compose.yml. Ce n'est pas un problème de licence mais d'installation. L'écran nomme alors chaque source, son chemin exact et ce qu'elle a donné (lu, absent, vide, permission refusée, montage cassé), pour que la réparation prenne quelques minutes.

L'application refuse quand même de s'ouvrir, sans quoi il suffirait de faire pointer les montages vers un chemin vide pour rendre le contrôle sans effet. En contrepartie, le message n'accuse personne et la fenêtre de soixante-douze heures couvre l'attente.

L'empreinte de la machine

Elle est calculée à partir de trois éléments du serveur, lus dans des fichiers du système montés en lecture seule dans le conteneur :

Élément Fichier de l'hôte
Carte graphique /proc/driver/nvidia/gpus/<adresse PCI>/information
Carte mère /sys/class/dmi/id/product_uuid
Système installé /etc/machine-id

Chacun est haché ; le fichier de licence ne contient donc aucun numéro de série en clair.

La machine est reconnue dès que deux des trois concordent. Remplacer une carte graphique en panne, ou réinstaller le système, ne bloque pas l'application. Deux changements simultanés, si.

Le dossier du pilote NVIDIA est monté tel quel et le serveur y trouve lui-même le sous-dossier nommé d'après l'adresse PCI de la carte. Sur une machine à plusieurs cartes, c'est celle de plus petite adresse de bus qui décide, et elle seule, pour qu'une panne de l'une ne change pas l'empreinte. C'est aussi ce que donne la commande de la section suivante, dont le motif * est trié par le shell. Si aucune carte n'est détectée, l'empreinte repose sur les deux autres éléments et un seul changement suffit alors à bloquer.

Ces trois chemins sont écrits dans le code, pas dans un fichier de configuration : aucune variable d'environnement ne choisit ce qui est lu.

Lire l'empreinte avant d'en avoir besoin

Si vous préparez un changement de carte graphique ou de carte mère, relevez l'empreinte pendant que tout fonctionne et transmettez-la à l'éditeur : la nouvelle licence peut être prête avant l'intervention. Connecté en ADMIN :

curl -s http://localhost:8090/api/licence/machine -H "Authorization: Bearer <votre jeton>"

Cette route donne l'empreinte et l'état de chaque source quel que soit l'état de la licence. Elle est réservée aux comptes ADMIN : la route publique /api/licence, elle, ne montre l'empreinte qu'en cas de refus, pour ne pas publier l'identité du serveur à qui sait joindre le port.

Sans compte et sans l'application

L'empreinte ne vient pas de l'application : elle est le début du condensé SHA-256 de trois fichiers de l'hôte. Elle se calcule donc depuis un simple terminal, même si rien ne démarre et sans qu'aucun compte ne soit nécessaire :

printf '%s' "$(grep -h 'GPU UUID' /proc/driver/nvidia/gpus/*/information | head -1 \
  | sed 's/.*GPU UUID:[[:space:]]*//')" | sha256sum | cut -c1-16   # Carte graphique
printf '%s' "$(sudo cat /sys/class/dmi/id/product_uuid)" | sha256sum | cut -c1-16  # Carte mère
printf '%s' "$(cat /etc/machine-id)" | sha256sum | cut -c1-16      # Système installé

La carte mère est la seule des trois dont la lecture est réservée à root, d'où le sudo. Si une ligne rend e3b0c44298fc1c14, c'est le condensé de la chaîne vide : le fichier lu était absent, vide ou interdit, et l'application, elle, aurait annoncé la source comme illisible plutôt que de produire cette valeur. Recommencez avec les droits voulus plutôt que de dicter ce condensé.

Obtenir une nouvelle licence

Après un changement de matériel qui provoque le refus :

  1. Relevez les trois lignes affichées par l'écran de refus, ou par le bandeau rouge si la fenêtre court encore. Ce sont seize caractères chacune, dictables au téléphone.
  2. Transmettez-les à l'éditeur en précisant l'intervention réalisée.
  3. Déposez le fichier reçu en ~/.cause/licence.lic et redémarrez : docker compose restart backend.

Cas du serveur remplacé : une installation restaurée sur une machine neuve fonctionne soixante-douze heures, son compteur ayant voyagé dans l'archive. Ce délai ne se renouvelle pas, donc relevez l'empreinte de la machine neuve et demandez la licence le jour de la bascule.

Il n'y a pas de code de déblocage à demander : la fenêtre de soixante-douze heures s'ouvre d'elle même, sans appel et sans réseau. Appelez pour obtenir la nouvelle licence, pas pour obtenir du délai.

Vérifier l'état sans ouvrir l'application

L'état de la licence se consulte sans être connecté, ce qui aide quand plus rien ne s'ouvre :

curl -s http://localhost:8090/api/licence

La réponse porte le statut (VALID, EXPIRED, MISSING, WRONG_MACHINE, TAMPERED, UNREADABLE, UNDETERMINED), l'empreinte constatée lorsque le métier est refusé, et le détail des sources lorsque l'identité n'a pas pu être lue. Deux champs disent où en est la fenêtre : graceOpen vaut true tant qu'elle court, et graceClosesAt porte l'heure de sa fermeture, à venir ou déjà passée. Les deux vides sur un refus signifient qu'aucune fenêtre n'a été accordée, donc que le compteur manque ou a été retouché.

Le journal du backend dit la même chose au démarrage, une ligne par source :

Identité de la machine illisible : 1 source(s) sur 3. Défaut de déploiement, pas de licence
  Carte graphique : /machine/gpu-info — absent
  Carte mère : /machine/product-uuid — permission refusée
  Système installé : /machine/machine-id — lu

scripts/setup.sh vérifie ces trois chemins dans le conteneur à chaque installation et avertit avant la mise en service.

Le logiciel s'est arrêté : la marche à suivre

Trois questions, dans cet ordre. Chacune se répond en moins d'une minute, et les données ne sont jamais en jeu : rien n'est effacé ni modifié par un refus de licence.

1. Que dit l'écran ? Il nomme la cause en français et, juste au-dessus du dernier paragraphe, dit si la fenêtre de soixante-douze heures s'est écoulée ou si elle n'a jamais été accordée. Les deux ne se réparent pas pareil.

  • « la fenêtre s'est fermée le ... » : le serveur refusait déjà depuis trois jours. Le remède est la cause nommée au-dessus, ou une nouvelle licence.
  • « aucune fenêtre n'a été accordée » : le compteur licence-grace.txt manque ou a été modifié. Cherchez qui a touché à ~/.cause, par exemple une restauration de sauvegarde ou un nettoyage.

2. L'image est-elle à jour ? C'est la cause la plus fréquente d'un TAMPERED sur une licence parfaitement valable, et la plus facile à écarter :

docker compose ps

Si la colonne IMAGE du backend affiche un identifiant sha256:... au lieu d'un nom, le conteneur tourne sur une image périmée. docker compose up -d backend le recrée. Attention, docker compose restart ne suffit pas, il ne recrée pas le conteneur.

3. Les montages d'identité sont-ils là ?

curl -s http://localhost:8090/api/licence

Un statut UNDETERMINED est un défaut d'installation, pas un problème de licence : l'écran nomme chaque source et son chemin. Rétablissez les montages du docker-compose.yml, puis docker compose up -d.

Si aucune de ces trois questions ne donne la réponse, appelez l'éditeur avec sous les yeux la sortie de curl -s http://localhost:8090/api/licence et les deux dernières lignes de ~/.cause/licence-grace.txt. C'est tout ce qu'il lui faut.

Le contrôle ne se configure pas

Il n'existe aucune clé, aucune variable d'environnement et aucune option de ligne de commande pour désactiver la vérification de licence, pour désigner d'autres fichiers d'identité, ou pour allonger la fenêtre de soixante-douze heures. Tout est compilé dans le programme, une variable d'environnement l'emportant dans Spring Boot sur les fichiers de configuration, y compris ceux du profil de production.