
OpenBao est un coffre-fort de secrets open source, fork de HashiCorp Vault (v1.14.0), maintenu par la Linux Foundation via l'OpenSSF. Il offre une alternative 100% open source après le passage de Vault sous licence BSL.
Ce guide vous montre comment installer, configurer et utiliser OpenBao pour gérer vos secrets en production.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »Le parcours suit l'ordre dans lequel une installation se construit réellement : d'abord le binaire et un serveur de test jetable, puis les secrets engines qui stockent et chiffrent, ensuite les méthodes d'authentification qui distribuent les tokens, et enfin les policies qui limitent ce que ces tokens peuvent faire. La dernière étape bascule cette configuration vers un serveur persistant avec TLS et stockage Raft.
- Installer OpenBao v2.5 sur Linux
- Configurer les secrets engines : KV v2, Transit
- Mettre en place l'authentification : userpass, AppRole
- Écrire des policies HCL pour le contrôle d'accès granulaire
- Préparer une configuration production-ready
Prérequis
Section intitulée « Prérequis »La partie découverte de ce guide tourne en mode dev, sans privilèges
particuliers ni port réservé. Le passage en production change la donne : il faut
sudo pour créer /var/lib/openbao, un certificat TLS valide, et de quoi
conserver hors ligne les unseal keys produites à l'initialisation. jq est
utilisé pour extraire les valeurs des réponses JSON dans les scripts.
OpenBao vs Vault : ce qui change
Section intitulée « OpenBao vs Vault : ce qui change »OpenBao est fonctionnellement équivalent à Vault Community Edition 1.14. Voici les différences principales :
| Aspect | Vault CE | OpenBao |
|---|---|---|
| Licence | BSL 1.1 (restrictions commerciales) | MPL 2.0 (100% open source) |
| Mainteneur | HashiCorp | Linux Foundation / OpenSSF |
| CLI | vault | bao |
| Version actuelle | 1.18+ | 2.5.5 |
| Namespaces | Enterprise only | Inclus (depuis v2.3) |
| Compatibilité API | - | Compatible Vault 1.14 |
1. Installation
Section intitulée « 1. Installation »OpenBao se distribue comme un binaire statique unique, bao, qui joue à la
fois le rôle de serveur et de client. Le même exécutable démarre le service et
émet les commandes, la distinction tenant uniquement au sous-commande utilisé.
Trois canaux sont disponibles, et le choix a des conséquences sur la mise à
jour : le binaire téléchargé se remplace à la main, le paquet dnf suit le
dépôt, l'image conteneur s'épingle par tag ou digest.
Téléchargement direct
Section intitulée « Téléchargement direct »Les artefacts publiés sur GitHub sont accompagnés de sommes de contrôle et de signatures qu'il est recommandé de vérifier avant l'installation, puisque ce binaire aura accès à l'ensemble de vos secrets.
-
Télécharger le binaire (v2.5.5, dernière version stable)
Fenêtre de terminal VERSION="2.5.5"ARCH="x86_64" # ou arm64curl -LO "https://github.com/openbao/openbao/releases/download/v${VERSION}/bao_${VERSION}_Linux_${ARCH}.tar.gz" -
Extraire et installer
Fenêtre de terminal tar xzf bao_${VERSION}_Linux_${ARCH}.tar.gzsudo mv bao /usr/local/bin/sudo chmod +x /usr/local/bin/bao -
Vérifier l'installation
Fenêtre de terminal bao version# OpenBao v2.5.5 (028992583c693c4de6350b8aa52ff85e30375a99)
Via package manager (Fedora/RHEL)
Section intitulée « Via package manager (Fedora/RHEL) »Le paquet EPEL installe en plus l'unité systemd et l'utilisateur système
openbao, ce que le binaire seul ne fait pas. En contrepartie, la version
disponible dans le dépôt suit rarement la dernière release amont.
# Activer EPEL si nécessairesudo dnf install -y epel-release
# Installer OpenBaosudo dnf install -y openbaoVia container
Section intitulée « Via container »L'image est publiée à l'identique sur trois registres, ce qui évite de dépendre
du seul Docker Hub et de ses quotas de téléchargement. Épinglez toujours une
version explicite plutôt que latest : une mise à jour d'image non maîtrisée
sur un service qui détient vos secrets est un changement à part entière.
# Docker Hubdocker pull openbao/openbao:2.5.5
# GitHub Container Registrydocker pull ghcr.io/openbao/openbao:2.5.5
# Quay.iodocker pull quay.io/openbao/openbao:2.5.52. Premier démarrage (mode dev)
Section intitulée « 2. Premier démarrage (mode dev) »Le mode dev est parfait pour apprendre. Il démarre un serveur en mémoire, non sécurisé, avec un token root prédéfini.
# Démarrer en mode développementbao server -dev -dev-root-token-id="root"Dans un autre terminal :
# Configurer l'environnementexport BAO_ADDR='http://127.0.0.1:8200'export BAO_TOKEN='root'
# Vérifier le statutbao statusSortie attendue :
Key Value--- -----Seal Type shamirInitialized trueSealed falseTotal Shares 1Threshold 1Version 2.5.5Storage Type inmemHA Enabled false3. Secrets Engine : KV v2
Section intitulée « 3. Secrets Engine : KV v2 »Le secrets engine KV v2 stocke des secrets avec versioning automatique.
Écrire un secret
Section intitulée « Écrire un secret »Chaque put remplace l'intégralité du secret et crée une nouvelle version :
un champ omis disparaît, il n'est pas conservé. La sortie ne renvoie que les
métadonnées, jamais les valeurs écrites.
# Stocker des credentialsbao kv put secret/demo \ username="admin" \ password="SuperSecret123"Sortie :
== Secret Path ==secret/data/demo
======= Metadata =======Key Value--- -----created_time 2026-03-16T13:16:20.324983703Zcustom_metadata <nil>deletion_time n/adestroyed falseversion 1Lire un secret
Section intitulée « Lire un secret »Le double .data.data du filtre jq n'est pas une faute de frappe : KV v2
imbrique les valeurs du secret dans une enveloppe qui porte aussi les
métadonnées. Notez que la valeur s'affiche alors en clair dans le terminal,
donc dans l'historique du shell si elle est réutilisée dans une commande.
# Lire la dernière versionbao kv get secret/demo
# Sortie JSON (pour scripts)bao kv get -format=json secret/demo | jq -r '.data.data.password'Versioning
Section intitulée « Versioning »Le versioning de KV v2 conserve par défaut les 10 dernières versions du
secret. Un mot de passe remplacé reste donc lisible par quiconque a la
capability read et connaît son numéro de version : la rotation d'un secret
compromis exige un destroy des anciennes versions, pas seulement une
réécriture.
# Mettre à jour le secret (crée version 2)bao kv put secret/demo \ username="admin" \ password="NewPassword456"
# Lire une version spécifiquebao kv get -version=1 secret/demoSupprimer un secret
Section intitulée « Supprimer un secret »Trois niveaux de suppression, aux effets très différents : delete marque la
version comme supprimée mais conserve la donnée, destroy efface réellement
le contenu, et metadata delete supprime le secret et tout son historique. Seul
destroy fait disparaître la valeur du stockage.
# Soft delete (récupérable)bao kv delete secret/demo
# Hard delete (définitif)bao kv destroy -versions=1,2 secret/demo
# Supprimer toutes les métadonnéesbao kv metadata delete secret/demo4. Secrets Engine : Transit (chiffrement as a service)
Section intitulée « 4. Secrets Engine : Transit (chiffrement as a service) »Transit permet de chiffrer/déchiffrer des données sans exposer les clés.
Activer Transit
Section intitulée « Activer Transit »Transit se monte par défaut sur le path transit/, qui sert ensuite de préfixe
à tous les endpoints et donc à toutes les règles de policy le concernant.
bao secrets enable transitCréer une clé de chiffrement
Section intitulée « Créer une clé de chiffrement »Le drapeau -f force l'écriture sans donnée : la clé est générée par OpenBao et
n'est jamais exportable par défaut. C'est tout l'intérêt de Transit, une
application qui chiffre n'a à aucun moment la clé en mémoire.
bao write -f transit/keys/my-app-keyChiffrer des données
Section intitulée « Chiffrer des données »L'encodage base64 du plaintext est obligatoire, y compris pour du texte
simple : l'API refuse les octets bruts. Le préfixe vault:v1: du chiffré
retourné indique la version de clé utilisée, ce qui permet le déchiffrement
après rotation.
# Les données doivent être en base64bao write transit/encrypt/my-app-key \ plaintext=$(echo "données sensibles" | base64)Sortie :
Key Value--- -----ciphertext vault:v1:5/94SlpHWje32JEfqYZjXEe32FL0...key_version 1Déchiffrer
Section intitulée « Déchiffrer »OpenBao lit la version de clé dans le préfixe du chiffré et sélectionne
automatiquement la bonne : aucun paramètre supplémentaire n'est nécessaire. Le
résultat revient encodé en base64, à repasser dans base64 -d.
bao write transit/decrypt/my-app-key \ ciphertext="vault:v1:5/94SlpHWje32JEfqYZjXEe32FL0..."
# Le plaintext retourné est en base645. Authentification : userpass
Section intitulée « 5. Authentification : userpass »La méthode userpass permet une authentification par identifiant/mot de passe, utile pour les développeurs et les tests.
Activer userpass
Section intitulée « Activer userpass »Les méthodes d'authentification se montent sous auth/, à distinguer des
secrets engines : userpass produit des tokens, il ne stocke aucun secret
applicatif.
bao auth enable userpassCréer un utilisateur
Section intitulée « Créer un utilisateur »Le mot de passe passé en argument atterrit dans l'historique du shell : en usage
réel, préférez une lecture sur l'entrée standard. Le champ policies est
remplacé en totalité à chaque écriture de l'utilisateur.
bao write auth/userpass/users/devuser \ password="devpassword" \ policies="default"Se connecter
Section intitulée « Se connecter »Le unset BAO_TOKEN est indispensable : tant que la variable contient le token
root, elle a la priorité et vous testeriez les permissions de root sans le
savoir. Le token retourné est écrit dans ~/.bao-token et réutilisé
automatiquement.
# Unset le token root d'abordunset BAO_TOKEN
# Loginbao login -method=userpass \ username=devuser \ password=devpasswordSortie :
Success! You are now authenticated.
Key Value--- -----token s.15Wjnl3DVKulHTuNAyrSuyvitoken_accessor u9dKTGCSPnWIPJeHVK6JHiyftoken_duration 768htoken_renewable truetoken_policies ["default"]6. Authentification : AppRole (pour CI/CD)
Section intitulée « 6. Authentification : AppRole (pour CI/CD) »AppRole est la méthode recommandée pour les applications et pipelines
CI/CD. Elle utilise un couple role_id + secret_id.
Activer AppRole
Section intitulée « Activer AppRole »Le retour en root est nécessaire ici, car devuser ne porte que la policy
default, qui n'autorise pas le montage d'une méthode d'authentification.
export BAO_TOKEN='root' # Revenir en rootbao auth enable approleCréer un rôle
Section intitulée « Créer un rôle »Chacune de ces durées borne une fenêtre d'attaque distincte : secret_id_ttl
limite la validité du credential éphémère, token_ttl et token_max_ttl la
durée d'exploitation du token obtenu, et token_num_uses le nombre d'appels API
qu'il autorise avant de devenir inutilisable.
bao write auth/approle/role/my-app \ secret_id_ttl=10m \ token_num_uses=10 \ token_ttl=20m \ token_max_ttl=30m \ secret_id_num_uses=1 \ policies="dev-policy"Obtenir les credentials
Section intitulée « Obtenir les credentials »La séparation des deux valeurs est le coeur du modèle AppRole : le role_id,
stable, peut vivre dans la configuration du pipeline, tandis que le secret_id,
généré à la demande et à usage unique, doit être injecté juste avant l'exécution
par un composant de confiance. Réunis dans le même dépôt, ils redeviennent un
simple mot de passe en dur.
# Le role_id est stable (stocké dans la config)bao read auth/approle/role/my-app/role-id# role_id fce7ab03-5449-e1c5-e102-5c2b90b3e7b0
# Le secret_id est éphémère (généré à la demande)bao write -f auth/approle/role/my-app/secret-id# secret_id 4bb62b7c-8deb-0781-4b7b-854e479483f2Login avec AppRole
Section intitulée « Login avec AppRole »L'échange retourne un token portant les policies du rôle. Avec
secret_id_num_uses=1, ce secret_id est consommé et un second appel identique
échouera, ce qui rend un rejeu détectable.
bao write auth/approle/login \ role_id="fce7ab03-5449-e1c5-e102-5c2b90b3e7b0" \ secret_id="4bb62b7c-8deb-0781-4b7b-854e479483f2"7. Policies HCL
Section intitulée « 7. Policies HCL »Les policies définissent qui peut accéder à quoi. Elles utilisent le format HCL.
Syntaxe de base
Section intitulée « Syntaxe de base »Une policy est une suite de blocs path, et le path correspond à l'URL de
l'API privée de son préfixe /v1/. Le modèle est deny by default : la
règle deny sur prod de cet exemple est redondante puisque rien ne l'autorise
par ailleurs, mais elle documente l'intention et résiste à l'ajout ultérieur
d'une policy plus large sur le même token. Retenez le segment data/ propre à
KV v2, absent du chemin que vous tapez dans la CLI.
# Lecture/écriture sur secret/data/dev/*path "secret/data/dev/*" { capabilities = ["create", "read", "update", "delete", "list"]}
# Lecture seule sur les métadonnéespath "secret/metadata/dev/*" { capabilities = ["list", "read"]}
# Interdire l'accès à secret/data/prod/*path "secret/data/prod/*" { capabilities = ["deny"]}Capabilities disponibles
Section intitulée « Capabilities disponibles »Sur KV v2, écrire exige à la fois create et update : la première version
d'un secret passe par create, les suivantes par update. La capability
deny l'emporte sur toutes les autres, et sudo est nécessaire pour les
endpoints d'administration que même une règle permissive ne couvre pas.
| Capability | HTTP Verb | Description |
|---|---|---|
create | POST | Créer si n'existe pas |
read | GET | Lire |
update | POST/PUT | Modifier |
delete | DELETE | Supprimer |
list | LIST | Lister les clés |
sudo | - | Opérations privilégiées |
deny | - | Refuser explicitement |
Appliquer une policy
Section intitulée « Appliquer une policy »bao policy write écrase intégralement la policy portant ce nom, sans
fusion avec la version précédente. Le fichier HCL fourni fait donc foi, ce qui
en fait un bon candidat au versionnement dans Git.
# Créer la policybao policy write dev-policy dev-policy.hcl
# Lister les policiesbao policy list
# Lire une policybao policy read dev-policyAssigner à un utilisateur
Section intitulée « Assigner à un utilisateur »Les policies sont inscrites dans le token au moment du login. Modifier l'utilisateur ne change donc rien pour les tokens déjà émis, qui gardent leurs permissions jusqu'à expiration.
bao write auth/userpass/users/devops \ password="devopspass" \ policies="dev-policy"8. Configuration production
Section intitulée « 8. Configuration production »Pour la production, créez un fichier config.hcl :
ui = true
# Storage avec Raft (intégré, recommandé)storage "raft" { path = "/var/lib/openbao/data" node_id = "node1"}
# Listener HTTPS (TLS obligatoire en prod !)listener "tcp" { address = "0.0.0.0:8200" tls_cert_file = "/etc/openbao/tls/server.crt" tls_key_file = "/etc/openbao/tls/server.key"}
# Addressesapi_addr = "https://openbao.example.com:8200"cluster_addr = "https://openbao.example.com:8201"
# Sécuritédisable_mlock = false # false si possible (performance)log_level = "info"Démarrer en production
Section intitulée « Démarrer en production »Le répertoire de données doit appartenir à l'utilisateur qui exécute le processus, sans quoi Raft échoue à créer son journal au démarrage. Lancez le service via systemd plutôt qu'en avant-plan, afin qu'il redémarre après un redémarrage machine.
# Créer les répertoiressudo mkdir -p /var/lib/openbao/datasudo mkdir -p /etc/openbao/tlssudo chown -R openbao:openbao /var/lib/openbao
# Démarrerbao server -config=/etc/openbao/config.hclInitialisation
Section intitulée « Initialisation »Cette commande génère la clé maîtresse qui chiffre le stockage, puis la découpe en 5 parts dont 3 suffisent à la reconstituer (partage de secret de Shamir). Distribuez ces parts à des personnes différentes : réunies au même endroit, elles annulent tout l'intérêt du mécanisme.
# Initialiser (une seule fois)bao operator init -key-shares=5 -key-threshold=3Au démarrage, OpenBao est scellé : il répond sur le réseau mais refuse toute opération tant que la clé maîtresse n'est pas reconstituée en mémoire. L'opération est à répéter après chaque redémarrage du service, ce qui justifie de mettre en place un mécanisme d'auto-unseal en production.
# Répéter avec 3 clés différentes (threshold=3)bao operator unseal <key1>bao operator unseal <key2>bao operator unseal <key3>9. Fonctionnalités OpenBao 2.5
Section intitulée « 9. Fonctionnalités OpenBao 2.5 »La version 2.5 apporte plusieurs améliorations notables :
- Horizontal Read Scalability : les nœuds standby peuvent servir les lectures, améliorant les performances
- Distribution de plugins OCI : téléchargement automatique de plugins depuis des registres de conteneurs
- OIDC Provider Client Credentials : nouveau flow pour l'OIDC
- Audit HTTP : webhook pour les événements d'audit
- Namespaces (depuis 2.3) : isolation multi-tenant sans licence Enterprise
À retenir
Section intitulée « À retenir »Deux points méritent d'être gardés en tête au-delà des commandes. D'abord, OpenBao ne protège que ce qu'il scelle : un serveur déscellé en permanence avec un token root disponible ne vaut pas mieux qu'un fichier de configuration. Ensuite, la compatibilité API avec Vault 1.14 s'arrête à cette version : les fonctionnalités apparues plus tard chez HashiCorp n'ont pas d'équivalent ici.
- OpenBao = Vault open source (MPL 2.0), maintenu par Linux Foundation
- Compatibilité API avec Vault 1.14, migration transparente
- KV v2 pour les secrets avec versioning
- Transit pour le chiffrement as a service
- AppRole pour l'authentification CI/CD
- Policies HCL pour le contrôle d'accès granulaire
- Namespaces inclus (vs Enterprise chez HashiCorp)
Prochaines étapes
Section intitulée « Prochaines étapes »Installer OpenBao ne règle que le stockage. Reste la question qui provoque les incidents : combien de temps un secret vit-il, qui le fait tourner, et comment prouver après coup qui y a accédé. Le guide sur le cycle de vie d'un secret traite ces quatre étapes, génération, rotation, révocation et audit, indépendamment de l'outil retenu.