Vault certificats

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche

Vault & gestion des certificats

1. Deux usages distincts à ne pas confondre

PKI Secrets Engine Cert Auth Method
Rôle Vault agit comme CA : il émet/signe des certificats Vault utilise un certificat client TLS pour authentifier une entité
Sens du flux Vault → client (émission) Client → Vault (authentification)
Mount type pki/ cert/
Cas d'usage TLS pour apps, mTLS interne, cert-manager Machine-to-machine sans token (auth via mTLS)

2. PKI Secrets Engine — activation & structure

vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki      # durée de vie max du mount

# Root CA (souvent gardée offline/externe en prod)
vault write pki/root/generate/internal \
  common_name="nexiat-root-ca" ttl=87600h

# Intermediate CA (celle utilisée en usage courant)
vault secrets enable -path=pki_int pki
vault write pki_int/intermediate/generate/internal \
  common_name="nexiat-intermediate-ca"
# → CSR signé par root, puis :
vault write pki_int/intermediate/set-signed certificate=@signed.pem

Bonne pratique : root CA générée une fois, exportée/scellée hors Vault (ou dans un mount séparé désactivé après usage), seule l'intermédiaire reste active pour l'émission quotidienne.

3. Rôles — les policies d'émission

Un rôle définit ce qu'un demandeur a le droit d'obtenir (CN autorisés, SAN, TTL max, key type, usages).

vault write pki_int/roles/app-server \
  allowed_domains="clipsy.tech,internal.nexiat.fr" \
  allow_subdomains=true \
  max_ttl=720h \
  key_type=rsa key_bits=2048 \
  server_flag=true client_flag=false

4. Fonctions d'accès aux certificats

Émission / signature

Endpoint CLI Usage
POST /pki/issue/:role vault write pki_int/issue/app-server common_name=... Vault génère clé + certificat
POST /pki/sign/:role vault write pki_int/sign/app-server csr=@app.csr Le client fournit son propre CSR (clé privée jamais transmise à Vault)
POST /pki/sign-verbatim — Signe sans contrainte de rôle (usage restreint, à éviter en prod)
Pour ne jamais faire transiter la clé privée par Vault (préférable côté sécurité), toujours privilégier sign avec un CSR généré localement.

Lecture / consultation

Endpoint CLI Usage
GET /pki/cert/:serial vault read pki_int/cert/<serial> Récupère un certificat émis par son n° de série
GET /pki/cert/ca vault read pki_int/cert/ca Certificat CA en PEM
GET /pki/ca_chain vault read pki_int/ca_chain Chaîne complète (intermédiaire + root)
LIST /pki/certs vault list pki_int/certs Liste tous les n° de série stockés
LIST /pki/issuers vault list pki_int/issuers Liste les issuers (multi-CA depuis Vault 1.11+)

Révocation & CRL

Endpoint CLI Usage
POST /pki/revoke vault write pki_int/revoke serial_number=... Révoque un certificat
GET /pki/crl vault read pki_int/crl CRL courante (DER)
POST /pki/crl/rotate vault write -f pki_int/crl/rotate Force la régénération de la CRL
POST /pki/tidy vault write pki_int/tidy tidy_cert_store=true Nettoyage des certs expirés/révoqués (le storage Vault grossit sinon indéfiniment)

5. Sécurité & accès — ACL Policies

L'accès à chaque fonction ci-dessus se contrôle finement par chemin via les policies Vault (RBAC natif) :

# policy: app-can-issue.hcl
path "pki_int/issue/app-server" {
  capabilities = ["create", "update"]
}

path "pki_int/cert/*" {
  capabilities = ["read"]
}

# Interdire explicitement sign-verbatim et root/*
path "pki_int/root/*" {
  capabilities = ["deny"]
}

Principes clés :

  • Least privilege : un rôle applicatif ne doit avoir accès qu'à issue/<son-role>, jamais à root/* ni config/*.
  • Namespace/mount isolation : séparer pki/ (root, quasi jamais utilisé) et pki_int/ (usage courant).
  • Auth backend en amont : l'accès aux chemins PKI se fait via un token/rôle obtenu par un auth method (Kubernetes auth, AppRole, LDAP…), jamais par token racine en usage courant.

6. Cert Auth Method (authentification PAR certificat)

vault auth enable cert

vault write auth/cert/certs/nexiat-clients \
  display_name="nexiat-mtls" \
  policies="app-policy" \
  certificate=@ca-client.pem \
  ttl=3600
Un client présente son certificat TLS client ; Vault le valide contre la CA configurée et attribue un token avec les policies associées. Utile pour du machine-to-machine sans gestion de secret/token distribué.

7. Intégration Kubernetes

Deux approches complémentaires, pas exclusives :

Vault Agent Injector (vault-k8s)
Annotations sur les pods, injecte le certificat directement dans le filesystem du conteneur au démarrage/renouvellement.
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-tls: "pki_int/issue/app-server"
vault.hashicorp.com/role: "app"
cert-manager + Vault Issuer
cert-manager pilote le cycle de vie (Certificate CR, renouvellement auto avant expiration), Vault reste l'autorité de signature en backend.
apiVersion: cert-manager.io/v1
kind: Issuer
spec:
  vault:
    path: pki_int/sign/app-server
    server: https://vault.nexiat.fr:8200
    auth:
      kubernetes:
        role: cert-manager
        mountPath: /v1/auth/kubernetes

8. Bonnes pratiques sécurité — synthèse

  • Root CA offline ou mount séparé, verrouillé après génération de l'intermédiaire.
  • TTL courts pour les certs applicatifs (rotation fréquente = surface d'exposition réduite, moins besoin de révoquer).
  • Privilégier sign (CSR local) plutôt que issue quand la clé privée ne doit jamais quitter l'app.
  • tidy planifié régulièrement pour éviter la croissance illimitée du storage backend.
  • Policies ACL strictes par chemin, jamais de wildcard pki/* en usage applicatif.
  • Auditer les accès PKI via le audit device Vault (vault audit enable file / syslog) — traçabilité de chaque émission/révocation.
  • Pour multi-CA (Vault 1.11+), documenter clairement quel issuer est le default du mount.