HashiCorp Vault — PKI, SSH CA & Secrets

Qu'est-ce que Vault ?

HashiCorp Vault est un gestionnaire centralise de secrets et d'identites cryptographiques. Il resout trois problemes majeurs dans une infrastructure :

Probleme Sans Vault Avec Vault
Secrets Mots de passe en clair dans des fichiers, variables d'environnement, ou code source Stockage chiffre, acces controle par politique, versionne, auditable
Certificats TLS Certificats auto-signes ou gestion manuelle (openssl, copie de fichiers) PKI automatisee : emission, renouvellement, revocation via API
Acces SSH Cles authorized_keys copiees manuellement sur chaque serveur, jamais revoquees Certificats SSH ephemeres signes par une CA, avec TTL et principals

En une phrase

Vault est un coffre-fort programmable : il chiffre les donnees au repos, controle qui peut acceder a quoi, genere des secrets dynamiques, et trace chaque operation dans un log d'audit.


Architecture interne de Vault

Composants principaux

graph TB
    subgraph Clients["Clients"]
        CLI["vault CLI"]
        API["API HTTP/REST"]
        UI["Interface Web"]
        ANSIBLE["Ansible<br/>hashi_vault"]
    end

    subgraph Vault["Vault Server"]
        direction TB
        AUTH["Auth Methods<br/>(token, approle, ldap...)"]
        POLICY["Policies (ACL)<br/>Qui peut faire quoi"]
        BARRIER["Encryption Barrier<br/>(AES-256-GCM)"]
        ENGINES["Secrets Engines"]

        subgraph ENGINES_DETAIL["Secrets Engines"]
            direction LR
            PKI["PKI<br/>Certificats X.509"]
            SSH["SSH<br/>Certificats SSH"]
            KV2["KV v2<br/>Cles/Valeurs"]
        end
    end

    subgraph Storage["Stockage (Raft)"]
        RAFT["Donnees chiffrees<br/>sur disque"]
    end

    CLI --> AUTH
    API --> AUTH
    UI --> AUTH
    ANSIBLE --> AUTH
    AUTH --> POLICY
    POLICY --> BARRIER
    BARRIER --> ENGINES_DETAIL
    BARRIER --> RAFT

Le flux d'une requete :

  1. Le client s'authentifie (token, approle, ldap...)
  2. Vault verifie l'identite et attribue un token avec des politiques
  3. La politique definit les chemins autorises (pki_int/issue/*, secret/data/*, etc.)
  4. La requete traverse le barrier de chiffrement (AES-256-GCM)
  5. Le secrets engine traite la requete (genere un cert, lit un secret...)
  6. Tout est logue dans l'audit log

Le Barrier de chiffrement

Le barrier est le concept central de Vault. Rien ne sort de Vault en clair sans passer par le barrier.

graph LR
    subgraph Exterieur["Monde exterieur (clair)"]
        REQ["Requete API"]
        RESP["Reponse"]
    end
    subgraph Barrier["Barrier AES-256-GCM"]
        LOGIC["Logique metier"]
    end
    subgraph Backend["Stockage (chiffre)"]
        DISK["Donnees sur disque"]
    end

    REQ --> LOGIC
    LOGIC --> RESP
    LOGIC <-->|"chiffre/dechiffre"| DISK
  • Le stockage backend (Raft) ne contient que des donnees chiffrees — meme avec un acces physique au disque, les secrets restent illisibles
  • La cle de chiffrement du barrier est elle-meme chiffree par la master key
  • La master key est protegee par le mecanisme de scellement (seal)

Seal / Unseal — Le partage de secret de Shamir

Au demarrage, Vault est scelle (sealed) : il possede les donnees chiffrees sur disque mais ne peut pas les dechiffrer. Pour le desceller, il faut reconstituer la master key.

graph TB
    MK["Master Key<br/>(jamais stockee en entier)"]
    MK -->|"Shamir's Secret Sharing"| K1["Cle 1 — Admin A"]
    MK -->|"Shamir's Secret Sharing"| K2["Cle 2 — Admin B"]
    MK -->|"Shamir's Secret Sharing"| K3["Cle 3 — Admin C"]
    MK -->|"Shamir's Secret Sharing"| K4["Cle 4 — Admin D"]
    MK -->|"Shamir's Secret Sharing"| K5["Cle 5 — Admin E"]

    K1 -->|"3 cles suffisent"| UNSEAL["Vault UNSEALED<br/>Pret a servir"]
    K2 --> UNSEAL
    K3 --> UNSEAL

    style MK fill:#e74c3c,color:#fff
    style UNSEAL fill:#27ae60,color:#fff

Algorithme de Shamir

L'algorithme de Shamir's Secret Sharing (1979) permet de decouper un secret en n parts dont k suffisent pour le reconstituer (schema k-of-n).

Principe mathematique : on construit un polynome de degre k-1 dont le terme constant est le secret. Chaque part est un point sur la courbe. Avec k points, on peut reconstruire le polynome par interpolation de Lagrange et retrouver le secret (le terme constant). Avec moins de k points, le secret est statistiquement impossible a deviner.

Dans notre cas : 3-of-5 — 5 cles distribuees, 3 necessaires. Aucun administrateur seul ne peut desceller Vault.

Stockage Raft

Vault utilise le protocole de consensus Raft comme backend de stockage integre.

Propriete Valeur
Type Log replique avec consensus
Avantage Pas de dependance externe (pas de Consul, etcd, ou base de donnees)
Donnees Toujours chiffrees par le barrier avant ecriture
HA Supporte le multi-noeud avec election de leader (pour un futur cluster Vault)

Concepts : Secrets Engines

Un secrets engine est un composant enfichable (plugin) qui gere un type de secret. Chaque engine est monte sur un chemin dans l'arborescence de Vault.

vault/
├── pki/           → PKI engine (Root CA)
├── pki_int/       → PKI engine (Intermediate CA)
├── ssh-user/      → SSH engine (certificats utilisateurs)
├── ssh-host/      → SSH engine (certificats hosts)
├── secret/        → KV v2 engine (cles/valeurs)
├── cubbyhole/     → Stockage ephemere par token
├── identity/      → Identites et groupes
└── sys/           → Operations systeme

Les engines se comportent comme un systeme de fichiers virtuel : chaque operation est un read, write, list ou delete sur un chemin.

Operation Chemin Effet
write pki_int/issue/server-tls Emet un nouveau certificat TLS
read secret/data/freeipa Lit le secret FreeIPA
write pki_int/revoke Revoque un certificat
list pki_int/certs Liste les certificats emis

Secrets dynamiques

Contrairement a un coffre-fort classique qui stocke des secrets statiques, Vault peut generer des secrets a la volee (certificats, credentials base de donnees, tokens cloud...). Ces secrets ont un TTL (duree de vie) et sont automatiquement revoques a expiration.


Concepts : PKI et certificats X.509

Comment fonctionne TLS ?

Quand un client (ex: navigateur, curl, git) se connecte a un serveur HTTPS :

sequenceDiagram
    participant Client
    participant Serveur
    participant CA as "Trust Store<br/>(CA connues)"

    Client->>Serveur: 1. ClientHello (TLS handshake)
    Serveur-->>Client: 2. Certificat serveur + chaine CA
    Client->>CA: 3. Le certificat est-il signe par une CA de confiance ?
    CA-->>Client: 4. Oui (chaine validee jusqu'a la Root CA)
    Client->>Serveur: 5. Echange de cles (ECDHE/RSA)
    Note over Client,Serveur: 6. Canal chiffre etabli (AES-256-GCM)

Un certificat X.509 contient :

Champ Description Exemple
Subject (CN) Identite du serveur CN=gitlab.infra.indio
Issuer CA qui a signe le certificat CN=Infra Indio Intermediate CA
SAN (Subject Alternative Name) Noms/IPs alternatifs DNS:gitlab.infra.indio, IP:10.15.100.71
Validity Dates de debut/fin 2026-03-30 → 2027-03-30
Public Key Cle publique RSA/ECDSA RSA 4096 bits
Key Usage Usages autorises de la cle DigitalSignature, KeyEncipherment
Extended Key Usage Usages applicatifs ServerAuth (HTTPS), ClientAuth (mTLS)
CRL Distribution Points URL de la liste de revocation https://vault:8200/v1/pki_int/crl
OCSP Responder URL de verification en ligne https://vault:8200/v1/pki_int/ocsp
Serial Number Identifiant unique du cert 6d:8c:18:b8:af:a3:cb:0b:...

Chaine de confiance (Chain of Trust)

La securite de TLS repose sur une chaine de confiance hierarchique :

graph TB
    ROOT["Root CA<br/>(auto-signee, dans le trust store)<br/>Infra Indio Root CA<br/>Validite: 10 ans"]
    INT["Intermediate CA<br/>(signee par Root)<br/>Infra Indio Intermediate CA<br/>Validite: 5 ans"]
    LEAF["Certificat serveur<br/>(signe par Intermediate)<br/>gitlab.infra.indio<br/>Validite: 1 an"]

    ROOT -->|"signe"| INT
    INT -->|"signe"| LEAF

    TRUST["Trust Store systeme<br/>(/etc/pki/tls/certs/ca-bundle.crt)"]
    ROOT -.->|"installe dans"| TRUST

    style ROOT fill:#e74c3c,color:#fff
    style INT fill:#f39c12,color:#fff
    style LEAF fill:#27ae60,color:#fff

Verification par le client :

  1. Le client recoit le certificat de gitlab.infra.indio (signe par Intermediate CA)
  2. Il remonte la chaine : Intermediate CA est-elle signee par une CA connue ?
  3. Intermediate CA est signee par Root CA → Root CA est dans le trust store systeme
  4. Chaine validee → la connexion TLS est etablie

Pourquoi Root CA → Intermediate CA → Leaf ?

  • La Root CA est le point d'ancrage de confiance. Sa cle privee doit etre tres protegee car la compromettre invalide toute la PKI
  • L'Intermediate CA fait le travail quotidien d'emission. Si elle est compromise, on la revoque et on en genere une nouvelle sans toucher au trust store des clients
  • Les certificats leaf (serveurs) ont une duree de vie courte (1 an max) et sont renouvelables automatiquement

Key Usage et Extended Key Usage

Les champs Key Usage et Extended Key Usage restreignent ce qu'un certificat peut faire :

Flag Signification Quand l'utiliser
ServerAuth Le cert peut prouver l'identite d'un serveur HTTPS, tout service TLS
ClientAuth Le cert peut prouver l'identite d'un client mTLS (authentification mutuelle)
DigitalSignature La cle peut signer des donnees Tous les cas (handshake TLS)
KeyEncipherment La cle peut chiffrer des cles de session RSA key exchange
KeyAgreement La cle peut participer a un echange de cles ECDHE, DH

Exemple : le role elasticsearch a ServerAuth + ClientAuth car les noeuds ES s'authentifient mutuellement (mTLS) sur le transport inter-noeuds.


Concepts : Revocation (CRL & OCSP)

Un certificat peut etre revoque avant expiration (compromission de la cle, changement de service, etc.). Deux mecanismes permettent aux clients de verifier si un certificat est encore valide :

CRL (Certificate Revocation List)

sequenceDiagram
    participant Admin
    participant Vault
    participant Client
    participant CRL as "CRL Endpoint"

    Admin->>Vault: Revoquer cert serial 5b:92:...
    Vault->>Vault: Ajouter a la CRL, reconstruire
    Note over Vault: Auto-rebuild toutes les 15 min (delta)

    Client->>CRL: Telecharger la CRL
    CRL-->>Client: Liste des serials revoques
    Client->>Client: Le serial du cert est-il dans la liste ?
    Note over Client: Non → cert valide | Oui → cert revoque
  • Avantage : fonctionne hors-ligne apres le telechargement
  • Inconvenient : la CRL peut etre perimee entre deux telechargements (expiry: 72h)
  • Delta CRL : ne contient que les changements depuis la derniere CRL complete, reduit le trafic

OCSP (Online Certificate Status Protocol)

sequenceDiagram
    participant Client
    participant OCSP as "OCSP Responder<br/>(Vault)"

    Client->>OCSP: Ce cert (serial 5b:92:...) est-il valide ?
    OCSP-->>Client: Reponse signee : GOOD / REVOKED / UNKNOWN
    Note over Client: Reponse en cache pendant 12h (ocsp_expiry)
  • Avantage : verification en temps reel, pas besoin de telecharger toute la liste
  • Inconvenient : necessite une connexion reseau vers le responder OCSP

Complementarite CRL + OCSP

On configure les deux car certains clients ne supportent que CRL (openssl, certains outils systeme) et d'autres preferent OCSP (navigateurs modernes). Les deux URLs sont embarquees dans chaque certificat emis via les extensions Authority Information Access et CRL Distribution Points.


Concepts : SSH par certificats

SSH traditionnel vs SSH par certificats

SSH traditionnel (authorized_keys)

graph LR
    ADMIN["Admin"] -->|"copie id_rsa.pub"| S1["Serveur 1<br/>~/.ssh/authorized_keys"]
    ADMIN -->|"copie id_rsa.pub"| S2["Serveur 2<br/>~/.ssh/authorized_keys"]
    ADMIN -->|"copie id_rsa.pub"| S3["Serveur 3<br/>~/.ssh/authorized_keys"]
    ADMIN -->|"copie id_rsa.pub"| SN["... Serveur N"]

Problemes :

  • Il faut copier la cle publique sur chaque serveur (ou utiliser Ansible)
  • Revoquer un acces = supprimer la cle sur tous les serveurs
  • Pas d'expiration : la cle reste valide indefiniment
  • Pas de traçabilite : on ne sait pas qui s'est connecte avec quelle cle
  • Un nouveau serveur ne reconnait aucune cle existante

SSH par certificats (Vault CA)

graph TB
    CA["Vault SSH CA<br/>(cle publique deployee<br/>une seule fois)"]
    ADMIN["Admin"]

    ADMIN -->|"1. signe sa cle<br/>publique"| CA
    CA -->|"2. certificat SSH<br/>(TTL 12h)"| ADMIN
    ADMIN -->|"3. ssh avec cert"| S1["Serveur 1"]
    ADMIN -->|"3. ssh avec cert"| S2["Serveur 2"]
    ADMIN -->|"3. ssh avec cert"| SN["... Serveur N"]

    S1 -.->|"verifie avec<br/>TrustedUserCAKeys"| CA
    S2 -.->|"verifie avec<br/>TrustedUserCAKeys"| CA
    SN -.->|"verifie avec<br/>TrustedUserCAKeys"| CA

Avantages :

  • Deployer la CA une seule fois sur tous les serveurs (via Ansible)
  • Revoquer un acces = ne plus signer de certificats pour cet utilisateur
  • Expiration automatique : le certificat a un TTL (12h pour les admins)
  • Principals : controle fin de qui peut se connecter en tant que quel utilisateur
  • Un nouveau serveur reconnait immediatement tous les certificats signes par la CA

Contenu d'un certificat SSH

Un certificat SSH signe par Vault contient :

Champ Description Exemple
Type User ou Host user
Key ID Identifiant unique vault-token-abc123-admin-ssh
Serial Numero de serie 9182736455
Valid Principals Utilisateurs autorises indio-adm, root, ansible
Valid Periode de validite 2026-03-30T10:00:00 → 2026-03-30T22:00:00 (12h)
Extensions Fonctionnalites autorisees permit-pty, permit-agent-forwarding
Signing CA Cle publique de la CA ssh-rsa AAAA... (ssh-user CA)
# Inspecter un certificat SSH
ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub

Notre deploiement

Parametres generaux

Parametre Valeur
IP 10.15.100.74 (VLAN 106 — Services)
Version 1.21.4
UI https://10.15.100.74:8200/ui
Stockage Raft (integre)
Unseal Shamir — 5 cles, seuil 3
TLS Certificat emis par sa propre PKI (CN=vault.infra.indio)
Audit /var/log/vault/audit.log (fichier JSON)
graph TB
    subgraph Vault["HashiCorp Vault (10.15.100.74)"]
        direction TB
        PKI_ROOT["pki/<br/>Root CA<br/>10 ans"]
        PKI_INT["pki_int/<br/>Intermediate CA<br/>5 ans"]
        SSH_USER["ssh-user/<br/>CA utilisateurs"]
        SSH_HOST["ssh-host/<br/>CA hosts"]
        KV["secret/<br/>KV v2"]
        PKI_ROOT --> PKI_INT
    end

    PKI_INT -->|"Certs TLS"| SERVICES["Services<br/>GitLab, Nexus, etc."]
    PKI_INT -->|"Certs TLS"| SOC["SOC<br/>ES, Wazuh, Kibana"]
    SSH_USER -->|"Certs SSH"| ADMINS["Admins & Operateurs"]
    SSH_HOST -->|"Certs host"| VMS["Toutes les VMs"]
    KV -->|"Secrets"| ANSIBLE["Ansible<br/>(hashi_vault lookup)"]

Secrets Engines montes

Path Type Description
pki/ PKI Root CA — Infra Indio Root CA (10 ans, expire 2036)
pki_int/ PKI Intermediate CA — Infra Indio Intermediate CA (5 ans, expire 2031)
ssh-user/ SSH CA pour certificats SSH utilisateurs
ssh-host/ SSH CA pour certificats SSH hosts
secret/ KV v2 Secrets cle/valeur versionnes
cubbyhole/ Cubbyhole Stockage ephemere par token
identity/ Identity Gestion des identites et groupes

PKI — Certificats TLS

Chaine de confiance deploye

graph TB
    ROOT["Infra Indio Root CA<br/>CN=Infra Indio Root CA<br/>RSA 4096 | SHA-256<br/>Validite: 2026-03-30 → 2036-03-27<br/>Serial: 44A0:0EE9:B701:7C34:..."]
    INT["Infra Indio Intermediate CA<br/>CN=Infra Indio Intermediate CA<br/>RSA 4096 | SHA-256<br/>Validite: 2026-03-30 → 2031-03-29<br/>Serial: 77CF:5561:D3AB:88C0:..."]
    LEAF1["gitlab.infra.indio"]
    LEAF2["vault.infra.indio"]
    LEAF3["nexus.infra.indio"]
    LEAF4["*.infra.indio"]
    ROOT -->|"signe"| INT
    INT -->|"signe"| LEAF1
    INT -->|"signe"| LEAF2
    INT -->|"signe"| LEAF3
    INT -->|"signe"| LEAF4

    style ROOT fill:#e74c3c,color:#fff
    style INT fill:#f39c12,color:#fff

Roles PKI (pki_int/)

Chaque role definit un profil d'emission avec des contraintes specifiques. Tous les roles sont restreints au domaine infra.indio (sous-domaines et wildcards autorises).

Role Usage Cle TTL max Key Usage Extended Key Usage
server-tls HTTPS services (GitLab, Nexus, Kibana...) RSA 4096 1 an DigitalSignature, KeyEncipherment ServerAuth
client-tls Authentification mTLS RSA 4096 1 an DigitalSignature ClientAuth
elasticsearch Transport inter-noeuds ES RSA 4096 1 an DigitalSignature, KeyEncipherment ServerAuth + ClientAuth
wazuh Manager + agents Wazuh RSA 4096 1 an DigitalSignature, KeyAgreement, KeyEncipherment ServerAuth + ClientAuth
docker-services Conteneurs Docker RSA 2048 6 mois DigitalSignature, KeyAgreement, KeyEncipherment ServerAuth
vault-server Vault lui-meme RSA 4096 1 an DigitalSignature, KeyAgreement, KeyEncipherment ServerAuth
infra-indio Generique *.infra.indio RSA 4096 1 an DigitalSignature, KeyAgreement, KeyEncipherment ServerAuth + ClientAuth

Emettre un certificat TLS

CLI Vault

vault write pki_int/issue/server-tls \
  common_name="gitlab.infra.indio" \
  alt_names="gitlab.infra.indio" \
  ip_sans="10.15.100.71" \
  ttl="8760h"

API (curl)

curl -sk \
  --header "X-Vault-Token: $VAULT_TOKEN" \
  --request POST \
  --data '{
    "common_name": "gitlab.infra.indio",
    "alt_names": "gitlab.infra.indio",
    "ip_sans": "10.15.100.71",
    "ttl": "8760h"
  }' \
  https://10.15.100.74:8200/v1/pki_int/issue/server-tls

Ansible (hashi_vault)

- name: Emettre un certificat TLS via Vault
  community.hashi_vault.vault_write:
    path: pki_int/issue/server-tls
    data:
      common_name: "gitlab.infra.indio"
      alt_names: "gitlab.infra.indio"
      ip_sans: "10.15.100.71"
      ttl: "8760h"
  register: vault_cert

La reponse contient : certificate, private_key, ca_chain, issuing_ca, serial_number.

Revoquer un certificat

vault write pki_int/revoke serial_number="5b:92:01:21:34:13:84:2e:..."

La CRL est automatiquement reconstruite apres revocation.


CRL & OCSP — Configuration

Parametre Valeur
CRL Distribution Point https://10.15.100.74:8200/v1/pki_int/crl
OCSP Responder https://10.15.100.74:8200/v1/pki_int/ocsp
CA Issuers (AIA) https://10.15.100.74:8200/v1/pki_int/ca
CRL auto-rebuild Oui (grace period 12h)
Delta CRL Oui (rebuild toutes les 15 min)
CRL expiry 72h
OCSP expiry 12h

Chaque certificat emis par pki_int/ contient automatiquement ces extensions :

Authority Information Access:
    OCSP - URI:https://10.15.100.74:8200/v1/pki_int/ocsp
    CA Issuers - URI:https://10.15.100.74:8200/v1/pki_int/ca

X509v3 CRL Distribution Points:
    Full Name:
      URI:https://10.15.100.74:8200/v1/pki_int/crl

Verifier manuellement

CRL

# Telecharger et lire la CRL
curl -sk https://10.15.100.74:8200/v1/pki_int/crl/pem -o crl.pem
openssl crl -in crl.pem -noout -text

OCSP

# Verifier un certificat via OCSP
openssl ocsp \
  -issuer intermediate-ca.pem \
  -cert gitlab.infra.indio.crt \
  -url https://10.15.100.74:8200/v1/pki_int/ocsp \
  -resp_text

SSH CA — Certificats SSH

Roles SSH

Utilisateurs (ssh-user/)

Role Utilisateurs autorises Defaut TTL Max TTL Extensions
admin-ssh root, ansible, indio-adm, iac iac 12h 24h pty, agent-forwarding, port-forwarding
operator-ssh ansible, operator operator 8h 12h pty uniquement

Separation des privileges

Les operateurs SOC (operator-ssh) n'ont pas le port-forwarding ni l'agent-forwarding. Seuls les admins (admin-ssh) ont acces a root et aux fonctionnalites SSH avancees.

Hosts (ssh-host/)

Role Domaine TTL Usage
host-ssh infra.indio (+ sous-domaines) 10 ans Certificats host pour toutes les VMs

Signer une cle SSH

Utilisateur (admin)

vault write -field=signed_key ssh-user/sign/admin-ssh \
  public_key=@$HOME/.ssh/id_rsa.pub \
  valid_principals="indio-adm,root" \
  > $HOME/.ssh/id_rsa-cert.pub

Host

vault write -field=signed_key ssh-host/sign/host-ssh \
  public_key=@/etc/ssh/ssh_host_rsa_key.pub \
  cert_type=host \
  > /etc/ssh/ssh_host_rsa_key-cert.pub

Configuration sshd (cote serveur)

Le role Ansible common distribue la cle publique de la CA et configure sshd :

# /etc/ssh/sshd_config (extrait)
TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub

Configuration client (known_hosts)

# ~/.ssh/known_hosts (extrait)
@cert-authority *.infra.indio ssh-rsa AAAA...

Cela supprime les prompts "Are you sure you want to continue connecting?" pour toutes les VMs.


KV v2 — Secrets cle/valeur

Le moteur KV v2 stocke des secrets versionnes. Chaque ecriture cree une nouvelle version, l'ancienne reste accessible (rollback possible).

Fonctionnement

graph LR
    V1["Version 1<br/>password=abc"]
    V2["Version 2<br/>password=xyz"]
    V3["Version 3<br/>password=s3cure!"]
    V1 --> V2 --> V3
    V3 -.->|"version courante"| READ["vault kv get"]
    V1 -.->|"vault kv get -version=1"| ROLLBACK["Rollback"]
  • Versionnement : chaque put cree une nouvelle version, les anciennes sont conservees
  • Soft delete : supprimer une version la marque comme detruite mais elle reste recuperable
  • Metadata : chaque secret a des metadonnees (date creation, nombre de versions, TTL)

Utilisation dans Ansible

# group_vars/all.yml — exemple
freeipa_admin_password: "{{ lookup('community.hashi_vault.hashi_vault',
  'secret/data/freeipa:admin_password',
  url='https://10.15.100.74:8200',
  token=vault_token) }}"

Operations courantes

Ecrire

vault kv put secret/mon-service \
  username="admin" \
  password="s3cure!"

Lire

vault kv get secret/mon-service

# Version specifique
vault kv get -version=1 secret/mon-service

Lister

vault kv list secret/

Historique

vault kv metadata get secret/mon-service

Distribution de la CA

Le role Ansible common installe les certificats de la CA sur toutes les VMs au premier deploiement.

Fichier Destination Usage
infra-root-ca.pem /etc/pki/ca-trust/source/anchors/ Root CA dans le trust store systeme
infra-ca-chain.pem /etc/pki/ca-trust/source/anchors/ Chaine complete (Root + Intermediate)
ssh-user-ca.pub /etc/ssh/trusted-user-ca-keys.pem Verification des certs SSH utilisateurs
ssh-host-ca.pub Client ~/.ssh/known_hosts Verification des certs SSH hosts

Apres installation, update-ca-trust met a jour le bundle systeme. Tous les outils (curl, git, pip, dnf...) font alors confiance a la CA.


Securite & Operations

Modele de securite

Vault applique un modele deny by default : tout est interdit sauf ce qui est explicitement autorise par une politique.

graph LR
    CLIENT["Client"]
    AUTH["Authentification<br/>(token, approle...)"]
    TOKEN["Token + Politiques"]
    POLICY["Politique ACL<br/>path pki_int/issue/* {<br/>  capabilities = [create, update]<br/>}"]
    ENGINE["Secrets Engine"]

    CLIENT -->|"1. identifie"| AUTH
    AUTH -->|"2. token"| TOKEN
    TOKEN -->|"3. verifie"| POLICY
    POLICY -->|"4. autorise"| ENGINE

Les politiques sont des documents HCL qui definissent les permissions par chemin :

# Exemple : politique pour un pipeline CI/CD
path "pki_int/issue/docker-services" {
  capabilities = ["create", "update"]
}

path "secret/data/ci/*" {
  capabilities = ["read"]
}

Politiques actuelles

Politique Description
root Acces total (administration initiale)
default Acces minimal (lookup de son propre token)

Amelioration prevue

Ajouter des politiques granulaires : ci-pipeline (emission de certs Docker), soc-operator (lecture des secrets SOC), ansible-deploy (emission de certs + lecture KV).

Authentification

Methode Statut Description
token Active Methode par defaut — tokens Vault
approle A deployer Pour les pipelines CI/CD (GitLab)
ldap A deployer Pour les operateurs (via FreeIPA)

Audit

Toutes les operations sont loguees dans /var/log/vault/audit.log (JSON). Chaque entree contient : timestamp, operation, chemin, informations d'authentification, requete et reponse.

Audit obligatoire

Vault refuse de servir des requetes si aucun device d'audit n'est configure et fonctionnel. Si le fichier d'audit ne peut plus etre ecrit (disque plein), Vault se bloque. C'est un choix de securite : mieux vaut un service indisponible qu'un service sans traces.

# Consulter les dernieres operations
tail -f /var/log/vault/audit.log | python3 -m json.tool

Unseal apres redemarrage

vault operator unseal <cle_1>
vault operator unseal <cle_2>
vault operator unseal <cle_3>

Stockage des cles unseal

Les 5 cles et le root token initial sont dans /root/vault-init.json sur la VM. En production, ces cles doivent etre distribuees a des personnes differentes et le fichier supprime.


Endpoints de reference

Endpoint URL Description
UI https://10.15.100.74:8200/ui Interface web
Health https://10.15.100.74:8200/v1/sys/health Etat du cluster
Root CA (PEM) https://10.15.100.74:8200/v1/pki/ca/pem Certificat Root CA
Intermediate CA (PEM) https://10.15.100.74:8200/v1/pki_int/ca/pem Certificat Intermediate CA
CA Chain https://10.15.100.74:8200/v1/pki_int/ca_chain Chaine complete
CRL (PEM) https://10.15.100.74:8200/v1/pki_int/crl/pem Liste de revocation
CRL (DER) https://10.15.100.74:8200/v1/pki_int/crl CRL format DER
OCSP https://10.15.100.74:8200/v1/pki_int/ocsp Responder OCSP