Chapitre 4. Architecture générale de Vault
Objectifs pédagogiques¶
Décrire Vault comme serveur d'API. Dérouler le cycle de vie d'une requête et situer chaque type de refus. Expliquer la table des montages et l'isolement par chemin. Définir la barrière. Situer le seal. Décrire magasin de tokens, gestionnaire d'expiration, audit devices et plugins.
Prérequis¶
Partie I, en particulier la section 3.4 dont ce chapitre est le développement.
Cours¶
4.1 Un serveur, une API, des clients¶
Vault est un binaire qui, en mode serveur, fait trois choses : il écoute, par défaut sur le port 8200 en TLS ; il traite des requêtes HTTP dont les chemins commencent par /v1/ ; il persiste son état, exclusivement chiffré, vers un stockage.
Tout le reste est client de cette API. vault kv get secret/billing/prod/db n'est qu'un GET /v1/secret/data/billing/prod/db habillé. L'interface web appelle la même API depuis le navigateur. Une bibliothèque cliente, un curl, l'agent du chapitre 40 parlent la même langue.
Deux ordres de conséquences. Pédagogique : quand une commande semble magique, demandez quel appel d'API elle recouvre. De sécurité : la surface d'attaque est l'API, toute l'API, rien qu'elle. Il n'existe pas de porte d'administration séparée, ni de raccourci local ; l'administrateur connecté en SSH sur la machine doit présenter un token comme tout le monde.
Un second port apparaît dès le chapitre 7 : le port de cluster, 8201 par défaut. Il ne sert pas aux clients mais aux nœuds entre eux, réplication et transfert de requêtes, sous un TLS interne que Vault gère lui-même. Règle d'hygiène : 8200 pour les clients, 8201 pour les nœuds, rien d'autre ne doit le joindre.
4.2 Le cycle de vie d'une requête¶
L'ordre des contrôles fixe l'endroit exact où chaque échec se produit. Savoir où une requête échoue est la moitié du diagnostic.
client
|
| 1. TLS : le listener termine la connexion chiffree
v
[ listener 8200 ]
|
| 2. la requete HTTP est analysee (methode, chemin, corps)
v
[ routeur ] -- chemin non authentifie ? (sys/health, login, unseal...)
| |
| non | oui : traitement direct, sans token
v v
[ verification du token ] (reponse)
| valide, non expire, non revoque ? echec --> 403, journalise
v
[ evaluation des policies ]
| refus par defaut ; deny prioritaire echec --> 403, journalise
v
[ table des montages ] --> routage vers le prefixe le plus long
v
[ moteur ou methode ] -- tout acces persistant traverse
| [ la barriere ] : chiffrement systematique
v
[ reponse ] -- si un bail s'applique : enregistrement aupres du
| gestionnaire d'expiration
v
[ audit ] -- requete et reponse journalisees, valeurs en HMAC
Entrée. Le listener termine TLS : c'est Vault qui présente son certificat et déchiffre. La requête est analysée : méthode, chemin, corps JSON. La correspondance est régulière : lire par GET, écrire par POST ou PUT, supprimer par DELETE, lister par LIST, extension propre à Vault qui s'exprime aussi en GET ...?list=true.
Chemins non authentifiés. Une liste close est servie sans token, parce que leur fonction l'exige : sys/health et sys/seal-status, qu'un répartiteur doit pouvoir interroger ; l'opération de descellement, puisqu'on ne peut exiger un token d'un serveur incapable de déchiffrer ; et auth/*/login, dont la raison d'être est de transformer une preuve en token. L'absence d'en-tête X-Vault-Token n'est légitime que sur ces chemins.
Vérification du token. Existe-t-il, est-il échu, a-t-il été révoqué directement ou par cascade ? La question est « qui êtes-vous », pas encore « avez-vous le droit ». Point de diagnostic : Vault répond 403 pour un token invalide comme pour un droit manquant, choix délibéré qui évite de confirmer à un attaquant que son token est valide.
Évaluation des policies. Le token porte ses policies et celles héritées de son identité (chapitre 13). Tout ce qui n'est pas explicitement accordé est refusé, et une règle deny l'emporte sur toute autorisation concurrente. L'ordre compte : authentification d'abord, autorisation ensuite, la séparation de la section 2.2 inscrite dans la mécanique.
Routage. Le composant monté sur le préfixe correspondant le plus long reçoit la requête, avec le chemin relatif à son montage : le moteur monté sur secret/ voit data/billing/prod/db, pas le chemin complet. Chaque composant ignore où il est monté, ce qui rend les montages déplaçables.
Traitement et barrière. Dès qu'un composant lit ou écrit du persistant, l'accès passe par la barrière. Rien ne part en clair, rien n'en revient sans déchiffrement, et le composant n'a pas le choix : la barrière est la seule voie d'accès au stockage.
Réponse et bail. Si la réponse contient un secret à durée de vie, un bail lui est attaché : identifiant, durée, caractère renouvelable. Il est enregistré auprès du gestionnaire d'expiration.
Audit. Requête et réponse sont journalisées : identité, chemin, opération, origine, résultat, avec les valeurs sensibles remplacées par un HMAC.
4.3 La table des montages¶
Monter un composant, c'est l'installer sur un préfixe : vault secrets enable -path=secret kv-v2 place un moteur KV sous secret/, vault auth enable approle place la méthode sous auth/approle/. La table des montages est le registre de ces installations : chemin, type, identifiant, configuration dont les durées de bail par défaut. Elle est elle-même persistée derrière la barrière.
Quatre montages existent d'office. sys/, l'interface d'administration du serveur : santé, scellement, montages, policies, audit. auth/token/, la méthode native par token, socle de toutes les autres. identity/, la couche qui unifie les acteurs. Et cubbyhole/, un moteur dont chaque token possède une instance privée que personne d'autre ne peut lire, pas même root, et dont le chapitre 12 fera un usage remarquable. Précision utile : le montage secret/ n'est automatique qu'en mode développement ; en production, c'est vous qui l'activez.
L'isolement dépasse le routage : chaque montage reçoit une vue de stockage propre, un préfixe dédié hors duquel il ne peut ni lire ni écrire. Le moteur secret/ ne peut pas feuilleter les données du moteur database/. Trois conséquences : démonter un moteur supprime les données de sa vue, c'est une destruction et non un débranchement ; déplacer un montage déplace la vue avec lui ; et la sauvegarde d'un Vault est nécessairement globale, les données d'un montage n'ayant de sens qu'avec la table qui les décrit.
4.4 La barrière et le stockage¶
C'est la décision d'architecture la plus structurante : le stockage n'est pas digne de confiance, et le cœur est conçu pour que cela n'ait pas d'importance, du moins pour la confidentialité.
La barrière sépare le cœur de son stockage. Toute écriture la traverse et en sort chiffrée en AES-256-GCM ; toute lecture y est déchiffrée et authentifiée. Le mode de chiffrement détecte l'altération : une donnée modifiée dans le stockage est rejetée comme corrompue, pas silencieusement acceptée. Tant que la barrière n'a pas ses clés, le cœur lui-même est incapable de lire ses propres données ; une fois descellée, elle chiffre et déchiffre à la volée, et les clés ne vivent qu'en mémoire.
Le stockage est un entrepôt de paires chemin-valeur opaques. Il ne voit jamais de clair et ignore la structure comme le sens de ce qu'il range. Le stockage intégré, fondé sur le protocole de consensus Raft, est le choix par défaut recommandé, celui de ce cours et du fil rouge.
Répartition des rôles, à réciter : la barrière garantit la confidentialité et l'intégrité ; le stockage garantit la durabilité et la disponibilité. Un voleur de disque, de snapshot ou de sauvegarde n'emporte que du chiffré. Un stockage qui perd des données ou ne répond plus arrête Vault, et contre cela la barrière ne peut rien.
Deux conséquences anticipées. Un snapshot est déjà du chiffré : la question se déplace vers « qui détient de quoi le déchiffrer », c'est-à-dire vers le seal. Et l'équipe qui administre disques et sauvegardes travaille sans jamais pouvoir lire un secret : le moindre privilège réalisé par construction cryptographique plutôt que par règlement.
4.5 Le seal : la position du verrou¶
Le seal ne chiffre pas les données, c'est le travail de la barrière. Le seal protège la clé qui permet à la barrière de fonctionner.
Au démarrage, le processus trouve dans son stockage toutes ses données chiffrées, et le matériel de clés nécessaire pour les lire, chiffré lui aussi. Il est scellé : structurellement incapable de se déchiffrer. Le descellement reconstitue en mémoire la clé racine qui déverrouille ce matériel, par un quorum de fragments humains, par un service de clés externe, ou par un autre Vault. S'il redémarre, tout est à refaire : la clé n'existait qu'en mémoire.
Scellé, le serveur n'est pas éteint : il répond sur les chemins non authentifiés qui permettent de constater son état et d'y remédier. Tout le reste est impossible, authentification comprise.
Formule de position : la barrière est le verrou des données, le seal est le verrou de la clé du verrou. Le point terminal de cette chaîne est la racine de confiance du chapitre 2.
4.6 Méthodes d'authentification, moteurs, magasin de tokens¶
Deux familles sont montées d'office, symétriques. Les méthodes d'authentification, sous auth/, consomment des preuves et produisent des tokens : userpass vérifie un mot de passe, AppRole un couple d'identifiants, la méthode Kubernetes une assertion de compte de service, OIDC une identité fédérée. Les moteurs de secrets produisent des secrets : valeurs stockées pour KV, credentials créés à la demande pour Database, certificats pour PKI, opérations cryptographiques pour Transit.
Entre les deux, un composant pivot : le magasin de tokens, face persistante de auth/token/. Tout token de service y est enregistré avec ses policies, ses durées et sa filiation ; les tokens forment des arbres, et la révocation d'un parent emporte ses enfants (chapitre 12). Détail de conception : le magasin ne stocke pas les tokens mais leur empreinte salée, de sorte que la lecture du stockage déchiffré ne livrerait pas de tokens utilisables.
4.7 Le gestionnaire d'expiration¶
Chaque bail est confié au gestionnaire d'expiration. Il tient le registre des baux en cours, honore les renouvellements dans les limites fixées, et exécute les révocations à l'échéance, ce qui pour un credential dynamique signifie retourner voir le système cible et y détruire le compte créé. Un secret expiré n'est pas un secret qu'on a cessé d'utiliser, c'est un secret qui a cessé d'exister.
Il fait du temps une dépendance de sécurité : des horloges fausses faussent les échéances. Et il fait du volume de baux une dimension d'exploitation : une application qui se reconnecte en boucle peut en créer des millions et mettre le serveur à genoux, ce dont le chapitre 31 fera un scénario d'attaque et le chapitre 36 une métrique.
4.8 Les audit devices¶
Chaque requête et chaque réponse partent vers une ou plusieurs destinations, fichier local, syslog ou socket, sous forme d'entrées JSON : identité et accessor du token, chemin, opération, adresse d'origine, résultat, horodatage. Les valeurs sensibles n'apparaissent jamais en clair : chacune est remplacée par son empreinte HMAC, calculée avec un sel propre au device.
Le paradoxe de la section 2.5, journaliser l'accès sans journaliser le secret, est ainsi résolu. Mieux : l'empreinte étant déterministe pour un device donné, on peut rechercher, en calculant l'empreinte d'une valeur connue.
Règle de configuration, déduite du comportement bloquant : puisque Vault cesse de répondre quand plus aucun device n'écrit, on n'exploite jamais un device unique. Deux dispositifs indépendants, dont un hors de la machine.
4.9 Le système de plugins¶
Méthodes d'authentification et moteurs de secrets sont des plugins, les uns intégrés au binaire, les autres externes et enregistrés. Cette architecture explique l'uniformité du modèle : un plugin reçoit des requêtes relatives à son montage, ne voit que sa vue de stockage, et ne peut rien faire que l'API n'expose. Elle explique aussi l'extensibilité du produit, et la vigilance qui l'accompagne : un plugin externe s'exécute dans le périmètre du serveur, et son enregistrement est un acte d'administration privilégié.
Exemple : une lecture de secret, étape par étape¶
L'application billing, depuis app-billing-01, s'est authentifiée par AppRole et détient un token porteur de la policy billing-kv. Elle émet GET /v1/secret/data/billing/prod/db vers https://vault.astrea.lab:8200.
Le listener termine TLS ; l'application a vérifié le certificat, personne sur le réseau n'a pu lire ni altérer l'échange. Le routeur constate un chemin ordinaire : token exigé. Le magasin de tokens confirme que le token existe et n'est ni échu ni révoqué. L'évaluation des policies confronte billing-kv au couple chemin-lecture : accordé. La table des montages route vers le moteur KV monté sur secret/, qui reçoit data/billing/prod/db. Le moteur lit derrière la barrière, qui déchiffre. Aucun bail n'est créé, KV n'en produit pas. L'audit enregistre l'entité, le chemin, l'opération et le résultat, valeurs en HMAC.
Trois variantes utiles. Sans token : refus à l'étape 3. Avec un token valide mais hors périmètre, par exemple sur secret/data/hr/paie : refus à l'étape 4, et l'audit garde la trace de la tentative. Avec un serveur scellé : la requête n'atteint même pas le routage, seul sys/seal-status répond.
Architecture : l'assemblage complet¶
clients
CLI UI (navigateur) applications
\ | /
v v v
+--------------------------------------+
| listener 8200 (TLS) | 8201 : port de
+--------------------------------------+ cluster (partie VIII)
|
v
+--------------------------------------+
| ROUTEUR |
| chemins non authentifies a part |
+--------------------------------------+
| |
v v
+-----------+ +--------------------+
| auth/ | | moteurs de secrets |
| methodes | | secret/ database/ |
+-----------+ | transit/ pki/ |
| +--------------------+
v |
+-----------+ |
| tokens + | |
| identity/ | |
+-----------+ |
| |
+------------+-------------+
v
+----------------+
| BARRIERE | AES-256-GCM
+----------------+
v
+----------------+ +--------------+
| STOCKAGE | | audit devices|
+----------------+ +--------------+
^
+----------------+
| SEAL | protege la cle racine
+----------------+
Sécurité : ce que l'architecture décide¶
L'API unique concentre la surface en un point énumérable, filtrable et journalisé : il n'y a pas de porte de service à oublier.
L'ordre authentification puis autorisation, avec refus par défaut et deny prioritaire, inscrit le moindre privilège dans la mécanique plutôt que dans la discipline.
L'isolement des montages par vue de stockage borne le rayon d'un moteur compromis ou défaillant.
La barrière rend le stockage, ses sauvegardes, ses disques et ses administrateurs incapables de trahir la confidentialité.
Le seal fait de l'état sûr l'état initial : un serveur qui démarre ne sait rien lire.
L'audit avec pouvoir d'arrêt fait de la trace une condition de fonctionnement.
En creux, l'architecture désigne son point sensible : tout se joue dans la mémoire du processus, et c'est l'objet du chapitre 5.
Erreurs fréquentes¶
Chercher une opération hors API. Les fichiers du stockage sont chiffrés ; la seule voie est l'API, avec un token et des droits. C'est la garantie, pas la limitation.
Confondre la barrière et TLS. TLS protège en transit, la barrière au repos. Désactiver TLS parce que le stockage est chiffré expose tokens et secrets en clair sur le réseau.
Croire le seal chargé du chiffrement des données. La barrière s'en charge, seal ou pas ; le seal protège la clé de la barrière.
Traiter le démontage comme un débranchement. vault secrets disable détruit la vue de stockage du montage.
Exploiter un seul dispositif d'audit. Son disque plein arrête le serveur. Deux dispositifs indépendants, dont un distant.
Exposer le port de cluster. Le 8201 n'appartient qu'aux nœuds ; ouvert plus largement, c'est une porte de service sur la salle des coffres.
Oublier que le magasin de tokens ne stocke que des empreintes. Chercher un token en clair dans le stockage déchiffré n'aboutit pas, et c'est voulu.
Mise en pratique : dérouler trois requêtes¶
Sans machine. Munissez-vous du schéma, redessiné de mémoire puis vérifié, et déroulez les trois requêtes en notant pour chacune : les étapes traversées, l'étape d'arrêt le cas échéant, ce qui est écrit dans l'audit, et si un bail est créé. Réponses commentées en fin de partie.
- Un script sans token appelle
GET /v1/sys/health. - L'application billing, avec un token valide porteur de la seule policy
billing-kv, appelleGET /v1/secret/data/hr/paie. - Un opérateur présente un token expiré depuis une heure et appelle
GET /v1/secret/data/billing/prod/db.
Complément : sur le schéma, marquez l'endroit où vivent des données en clair. Il n'y en a qu'un, et c'est la porte d'entrée du chapitre 5.
Questions de compréhension¶
- Justifiez « la CLI n'est qu'un client » avec deux arguments techniques, et donnez sa conséquence pour l'automatisation.
- Restituez les huit étapes du cycle d'une requête, et le type d'échec propre à chacune.
- Pourquoi certains chemins sont-ils servis sans token ? Citez-en trois et justifiez.
- Qu'est-ce que la vue de stockage d'un montage, et quelles conséquences pratiques en découlent ?
- Répartissez les responsabilités entre barrière et stockage, et déduisez ce qu'emporte un voleur de sauvegarde.
- Énoncez la formule de position du seal et expliquez « l'état sûr est l'état initial ».
- Quel est le rôle du gestionnaire d'expiration, et ses deux implications ?
- Comment l'audit résout-il le paradoxe de la trace, et quel usage d'investigation cela ouvre-t-il ?
- Que se passe-t-il si plus aucun dispositif d'audit ne peut écrire, et quelle règle de configuration en découle ?
Synthèse¶
Vault est un serveur d'API dont tout le reste est client. Une requête suit un ordre invariable : TLS, analyse, authentification, autorisation à refus par défaut, routage, traitement avec passage obligé par la barrière, bail éventuel, audit. Chaque échec a son étage. Les composants sont des plugins montés sur des chemins, isolés jusque dans leurs vues de stockage. Le magasin de tokens et le gestionnaire d'expiration font vivre identités et baux ; les audit devices voient tout et peuvent tout arrêter. La barrière chiffre ce qui part au stockage, le seal ne protège que la clé de ce verrou.