Chiffrement et secrets
Plusieurs paramètres portent des valeurs sensibles — mots de passe de pool, jetons d'authentification de connecteurs API, secret client OIDC. Le framework propose une primitive simple pour les protéger : tout champ secret de l'interface Paramètres dispose d'un interrupteur 🔒 qui bascule la saisie entre texte clair et chiffré. Les valeurs chiffrées sont enregistrées sous forme de blocs opaques que seul le processus en cours d'exécution peut déchiffrer ; la clé maîtresse qui réalise le déchiffrement reste dans l'environnement de l'hôte, jamais sur disque.
Cette page couvre l'interrupteur dans l'interface, la clé maîtresse, la procédure de rotation des clés et la convention sur ce qui doit être chiffré par rapport à ce qui doit rester dans l'environnement.
Vue d'ensemble
Clé de signature JWT. Clé de licence. Clé d'API IA.
Jamais sur disque.
Versionnable dans git sans risque.
Mise en cache pour la durée de vie du processus.
La clé maîtresse n'arrive jamais sur disque ; le bloc chiffré n'arrive jamais dans l'environnement. Les deux ne se rencontrent qu'au moment du déchiffrement, à l'intérieur du processus en cours.
L'interrupteur 🔒 dans l'interface Paramètres
Tout champ marqué comme secret — Mot de passe d'un pool, Jeton d'authentification d'un connecteur, Client secret OIDC, URL webhook Slack, etc. — affiche une icône 🔒 à côté de la saisie. Cliquer dessus bascule le champ entre mode clair et chiffré.
| Mode | Effet à l'enregistrement |
|---|---|
| Clair | La valeur littérale est enregistrée. À n'utiliser que pour des valeurs par défaut non secrètes (par exemple un mot de passe vide sur un pool SQLite local). |
| 🔒 Chiffré | Le framework chiffre la valeur avec la clé maîtresse courante avant l'enregistrement. Le champ affiche chiffré + une rangée de points masqués. Modifier le champ écrase la valeur précédente (aucune révélation automatique). |
Un champ déjà en mode chiffré affiche un bouton Révéler (visible uniquement par les opérateurs qui ont settings:reveal-secrets). Cliquer dessus demande l'empreinte de la clé maîtresse en confirmation, puis affiche le texte clair déchiffré pendant 10 secondes. L'action Révéler est journalisée à l'audit.
Quelques champs — le Client secret OIDC, l'URL webhook Slack — ont l'interrupteur 🔒 verrouillé sur On. Le mode clair n'est pas proposé car la valeur est manifestement sensible.
La clé maîtresse
La clé maîtresse est une clé AES-256-GCM de 32 octets que le framework charge depuis l'environnement au démarrage. La section Framework → Chiffrement de l'interface Paramètres configure d'où vient la clé, non sa valeur :
| Champ | Effet |
|---|---|
| Clé maîtresse | Nom de la variable d'environnement qui porte la clé. Défaut ${LIBERTY_MASTER_KEY}. |
| Clés héritées | Liste de clés anciennes, utilisées uniquement pour le déchiffrement pendant une rotation. Les nouveaux chiffrements utilisent toujours Clé maîtresse. Cliquer sur + Ajouter clé héritée pour ajouter une entrée — chaque entrée est un nom de variable d'environnement. |
Générer une clé fraîche avec la CLI liberty-crypto :
.venv/bin/liberty-crypto genkey
# 7c4f1c2d8e3a6b9f0c1d4e5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c
L'exporter sous le nom de variable d'environnement configuré ci-dessus, redémarrer le framework, et chaque nouvel enregistrement passant par l'interrupteur 🔒 utilise la nouvelle clé.
Une empreinte de la clé maîtresse (SHA-256 de la clé) est affichée dans la section Paramètres → Framework → Chiffrement — utile pour confirmer que deux répliques partagent la même clé sans dévoiler la clé elle-même.
Rotation de la clé maîtresse
Quand la clé maîtresse doit changer — politique annuelle, suspicion de fuite, changement d'opérateur — la rotation se fait en ligne :
| Phase | Action |
|---|---|
| 1. Générer une nouvelle clé | liberty-crypto genkey. L'exporter sous un nouveau nom de variable d'environnement (par exemple LIBERTY_MASTER_KEY_NEW). |
| 2. Ajouter l'ancienne clé en héritée | Dans Paramètres → Framework → Chiffrement, mettre Clé maîtresse sur le nouveau nom de variable d'environnement et ajouter l'ancien nom dans Clés héritées. Enregistrer — le framework déchiffre désormais avec l'une ou l'autre clé (essaie d'abord la maîtresse, puis chaque héritée dans l'ordre). |
| 3. Redémarrer | Obligatoire car la clé maîtresse elle-même est lue au démarrage, pas à l'enregistrement-rechargement. |
| 4. Re-chiffrer chaque secret | Exécuter liberty-crypto rewrap — voir ci-dessous — pour re-chiffrer chaque bloc enregistré avec la nouvelle maîtresse. Relançable sans risque ; sûr à rejouer. |
| 5. Retirer l'entrée héritée | Une fois que Rewrap signale zéro bloc encore chiffré avec l'ancienne clé, retirer l'entrée héritée du formulaire Paramètres et désactiver l'ancienne variable d'environnement. Redémarrer. |
La commande rewrap :
.venv/bin/liberty-crypto rewrap
# 4 encrypted fields re-wrapped with the current master key
# 0 still using legacy keys
La commande parcourt chaque emplacement de stockage, déchiffre chaque bloc avec la clé qui fonctionne, et le re-chiffre avec la maîtresse courante. Relançable sans risque — un nouveau lancement produit un chiffré différent (nouveau nonce aléatoire) mais le texte clair reste inchangé.
Ce qui se chiffre par rapport à ce qui reste dans l'environnement
La séparation est délibérée et mérite d'être suivie :
| Secret | Où il vit | Pourquoi |
|---|---|---|
| Mot de passe de pool | 🔒 Chiffré dans la définition du pool. | Vit à côté du pool — un seul changement de stockage met à jour les deux. |
| Jeton d'auth de connecteur API | 🔒 Chiffré sur le connecteur. | Même raison. |
| Client secret OIDC | 🔒 Chiffré sur le sous-formulaire OIDC. | Toujours chiffré (interrupteur verrouillé). |
| Webhook Slack | 🔒 Chiffré sur le sous-formulaire Notifications. | Idem. |
| Clé d'API par app pour un connecteur HTTP | 🔒 Chiffré sur le connecteur. | Idem qu'OIDC. |
| Clé maîtresse | Environnement uniquement. | Tout le mécanisme dépend du fait qu'elle ne touche jamais le disque. |
| Clé de signature JWT | Environnement uniquement. | Renouvelée indépendamment de la clé maîtresse. |
| Clé de licence | Environnement uniquement. | JWT signé en RS256, vérifiable avec une clé publique ; non sensible à divulguer, mais gardée dans l'environnement pour être remplaçable sans enregistrement. |
| Clé d'API du fournisseur IA | Environnement uniquement. | Convention dans l'écosystème Anthropic. |
Une règle simple : tout ce qui a une portée liée à un seul connecteur / paramètre passe par l'interrupteur 🔒 ; tout ce qui est global au framework va dans l'environnement.
Permissions
| Code | Effet |
|---|---|
settings:framework | Voir la section Framework → Chiffrement. |
settings:reveal-secrets | Voir le bouton Révéler à côté des champs chiffrés. Journalisé à l'audit. |
L'affichage de l'empreinte de la clé maîtresse est visible par toute personne disposant de settings:read — elle n'est pas sensible par elle-même.
Modes d'échec
| Symptôme | Cause | Récupération |
|---|---|---|
connector loaded, but password rejected by database | Le bloc chiffré a été emballé avec une clé qui n'est plus dans Clés héritées. | Réintégrer l'ancienne clé en héritée, redémarrer, exécuter liberty-crypto rewrap, puis retirer l'ancienne clé. |
crypto: master key not set au démarrage | La variable d'environnement configurée dans Clé maîtresse n'est pas définie et au moins un bloc chiffré existe. | Exporter la clé sous le bon nom ; ou basculer temporairement le champ en clair pour sauver l'installation. |
crypto: authentication tag mismatch | Un bloc a été édité à la main, ou la mauvaise clé est chargée. | Re-chiffrer la valeur depuis la source en clair ; ne jamais éditer un chiffré à la main. |
| Bouton Révéler grisé | L'appelant n'a pas settings:reveal-secrets. | Accorder la permission (ou la refuser — les auditeurs ne devraient souvent pas révéler). |
Conseils et bonnes pratiques
- Générer la clé maîtresse avec
liberty-crypto genkey. Les clés artisanales sont un piège — 32 octets aléatoires depuis le PRNG du framework, c'est la voie la plus simple et correcte. - Utiliser le même nom de variable d'environnement sur les répliques. Paramètres → Framework → Chiffrement enregistre le nom, pas la valeur — le même formulaire fonctionne sur chaque réplique tant que la variable d'environnement résout vers la même clé.
- Exécuter
liberty-crypto rewrapaprès chaque rotation. Sinon les anciens blocs restent sur les clés héritées et la rotation n'est pas vraiment terminée. - Ne pas désactiver l'interrupteur 🔒 sur une valeur déjà chiffrée. Repasser en clair dévoile la valeur sur disque ; l'opérateur doit confirmer et l'action est journalisée à l'audit.
- Garder les clés héritées seulement aussi longtemps que nécessaire. Passé un cycle de rotation, chaque bloc encore pertinent a été ré-emballé — l'entrée héritée peut être retirée.
Sous le capot
Les valeurs chiffrées sont enregistrées comme blocs opaques préfixés ENC: à l'intérieur des fichiers TOML par section. Les opérateurs n'éditent pas ces blocs à la main ; l'interrupteur 🔒 est la seule voie sûre. L'empreinte de la clé maîtresse est également enregistrée sur disque pour que le framework détecte une clé incompatible sur le mauvais hôte sans dévoiler la clé elle-même.
La CLI liberty-crypto est la seule voie scriptée pour les opérations avancées (rewrap, inspection d'empreinte, chiffrement manuel pour une mise en place pilotée par script).
Pour aller plus loin
- Variables d'environnement — y compris la variable d'environnement de la clé maîtresse.
- Paramètres du framework — la sous-section Chiffrement.
- Référence CLI → liberty-crypto — chaque sous-commande.
- Authentification — où vit le client secret OIDC.