PD-8 — Configurer Vault OVH pour secrets management¶
📚 Navigation User Story
| Document | | | ---------- | -- | | 📋 **Spécification** | *(ce document)* | | 🛠️ [Plan d'implémentation](PD-8-plan.md) | | | ✅ [Critères d'acceptation](PD-8-acceptability.md) | | | 📝 [Retour d'expérience](PD-8-rex.md) | | [← Retour à infrastructure-souveraine](../PD-193-epic.md) · [↑ Index User Story](index.md)1. Métadonnées¶
- ID : PD-8
- Type : Infrastructure / Security
- Epic : PD-193 — INFRASTRUCTURE-SOUVERAINE
- Priorité : Critique
- Story Points : 5
- Statut : À faire
2. Contexte¶
Dans l'architecture ProbatioVault, tous les secrets serveur doivent être gérés de manière centralisée, chiffrée, auditée et souveraine.
Les secrets concernés incluent notamment :
- tokens API internes ;
- credentials techniques (PostgreSQL, Redis, OVH, AWS) ;
- secrets Terraform / CI ;
- clés de signature non probatoires (hors HSM).
HashiCorp Vault est retenu comme coffre-fort de référence pour :
- la gestion dynamique des secrets (rotation automatique, TTL courts) ;
- le stockage chiffré de secrets statiques ;
- l'authentification applicative via AppRole ;
- une traçabilité complète via audit logs.
Vault est déployé sur infrastructure OVH, avec un backend PostgreSQL managé garantissant la persistance et l'auditabilité du state.
3. Objectifs¶
Installer et configurer HashiCorp Vault afin de fournir un service de secrets management :
- souverain (hébergé OVH) ;
- sécurisé (TLS, policies minimales, AppRole) ;
- auditable (audit logs obligatoires) ;
- exploitable par l'API backend, les workers BullMQ et le CI/CD.
Vault doit permettre :
- l'accès contrôlé aux secrets applicatifs ;
- la génération dynamique de credentials PostgreSQL ;
- la rotation automatique des secrets ;
- l'absence totale de secrets statiques en clair dans GitLab CI.
4. Portée¶
Inclus¶
- Déploiement Vault (mono-instance) sur OVH
- Backend de stockage PostgreSQL OVH
- Initialisation, unseal et sécurisation
- Secrets engines (KV + Database)
- Authentification AppRole
- Policies fine-grained (least privilege)
- Audit logging
- Documentation et automatisation Terraform
Hors-périmètre¶
- Intégration HSM / PRE (PD-36)
- Gestion de K_master_user (hors Vault)
- Sécurisation réseau globale (mTLS backend/HSM)
5. Architecture cible¶
6. Exigences de sécurité¶
- Backend PostgreSQL en TLS 1.3
- Aucun secret stocké en clair dans Git
- Accès par AppRole uniquement
- Tokens courts (TTL strict)
- Policies minimales
- Audit logs obligatoires
7. Tâches techniques¶
7.1 Déploiement Vault¶
- Installation Vault (mono-instance)
- Service systemd actif
- HTTPS activé (certificat valide)
- Port 8200 restreint aux composants internes
7.2 Backend PostgreSQL¶
- Création utilisateur
vault_backend - Création base
vault_storage - Connexion TLS obligatoire
7.3 Initialisation & Unseal¶
- Initialisation Shamir (5 clés / seuil 3)
- Distribution des clés d'unseal
- Procédure documentée
7.4 Secrets Engines¶
KV v2 :
kv/appkv/workerkv/ci
Database :
db/pv-postgres- TTL 1h, Max TTL 24h
7.5 Policies¶
api-backendworkerci
Principe : read-only + périmètre minimal.
7.6 Auth AppRole¶
| AppRole | TTL | Max TTL | Usage |
|---|---|---|---|
| api-backend | 30m | 2h | API NestJS |
| worker | 20m | 1h | BullMQ |
| ci | 5m | 10m | GitLab CI |
7.7 Audit Logging¶
- Audit fichier
- Audit syslog
- Rotation logs
7.8 Terraform & Documentation¶
- Policies
- AppRoles
- Secrets engines
- Database engine
7bis. Diagrammes¶
7bis.1 Cycle de vie Vault (state diagram)¶
Vault traverse plusieurs etats depuis son installation jusqu'a son fonctionnement nominal. L'initialisation Shamir (§7.3) et le seuil ⅗ conditionnent la transition vers l'etat operationnel. L'audit log (§7.7, INV: audit logs obligatoires §6) est actif des l'etat Active.
stateDiagram-v2
[*] --> Uninitialized : Deploiement (§7.1)
Uninitialized --> Sealed : vault operator init\n(Shamir 5 cles / seuil 3, §7.3)
Sealed --> Active : vault operator unseal\n(3 cles minimum, §7.3)
Active --> Sealed : seal / redemarrage\n/ perte memoire
Active --> Active : renouvellement token\n(TTL §7.6)
Active --> Sealed : vault operator seal\n(maintenance)
note right of Sealed
Tous les secrets sont inaccessibles.
Aucune operation de lecture/ecriture.
INV §6 : aucun secret en clair dans Git.
end note
note right of Active
Secrets engines KV + Database actifs (§7.4).
AppRole auth active (§7.6).
Audit logs actifs (§7.7).
INV §6 : acces AppRole uniquement.
end note 7bis.2 Authentification AppRole (sequence diagram)¶
Sequence d'authentification d'un service (API backend, worker, CI) via AppRole (§7.6). Chaque AppRole a un TTL strict (INV §6 : tokens courts) et une policy minimale (§7.5).
sequenceDiagram
participant S as Service<br>(API / Worker / CI)
participant V as Vault Server
participant PG as PostgreSQL<br>(Vault backend)
participant AL as Audit Log
S->>V: POST /auth/approle/login<br>{role_id, secret_id}
V->>PG: Valide credentials AppRole
PG-->>V: OK
V->>AL: Audit: auth.login (§7.7)
V-->>S: 200 {client_token, TTL}
Note over S,V: INV §6 : TTL strict<br>api-backend=30m, worker=20m, ci=5m
S->>V: GET /kv/data/app/jwt-secret<br>X-Vault-Token: {client_token}
V->>V: Verifie policy (§7.5, least privilege)
V->>AL: Audit: secret.read (§7.7)
V-->>S: 200 {data}
Note over S,V: INV §6 : policies minimales<br>read-only + perimetre minimal 7bis.3 Generation de credentials DB dynamiques (sequence diagram)¶
Sequence de generation d'un credential PostgreSQL ephemere via le secrets engine Database (§7.4). Le TTL 1h / Max TTL 24h garantit la rotation automatique (INV §6 : rotation automatique des secrets).
sequenceDiagram
participant API as API Backend
participant V as Vault Server
participant DB as PostgreSQL OVH<br>(applicatif)
participant AL as Audit Log
API->>V: GET /database/creds/pv-postgres<br>X-Vault-Token: {client_token}
V->>V: Verifie policy api-backend (§7.5)
V->>DB: CREATE ROLE temp_user_xxx<br>WITH LOGIN PASSWORD 'xxx'<br>VALID UNTIL now()+1h
DB-->>V: OK
V->>AL: Audit: database.creds.read (§7.7)
V-->>API: 200 {username, password, TTL=1h}
Note over API,DB: INV §6 : credentials dynamiques<br>TTL 1h, Max TTL 24h (§7.4)
API->>DB: Connexion TLS 1.3<br>avec credentials ephemeres
DB-->>API: Connexion etablie
Note over V,DB: A expiration du TTL :<br>Vault revoque automatiquement le role
V->>DB: DROP ROLE temp_user_xxx
V->>AL: Audit: lease.revoke (§7.7) 8. Critères d'acceptation¶
- Vault initialisé et déverrouillé
- Backend PostgreSQL persistant
- Policies effectives
- AppRoles fonctionnels
- Audit logs actifs
- Credentials DB dynamiques valides
- Aucun secret exposé
9. Tests¶
- Lecture KV
- Credentials DB dynamiques
- Auth AppRole
- Vérification permissions
- Vérification audit logs
10. Dépendances¶
Bloquantes¶
- Infrastructure OVH disponible
- PostgreSQL managé opérationnel
Débloquées par cette PD¶
- Connexion DB sécurisée (PD-14)
- CI/CD sécurisé
- Workers BullMQ
- Services backend
11. Risques & mitigations¶
| Risque | Mitigation |
|---|---|
| Perte des clés d'unseal | Distribution multi-opérateurs |
| Mauvaise policy | Tests systématiques |
| Fuite secrets CI | AppRole + TTL courts |
12. Definition of Done¶
- Vault opérationnel et sécurisé
- Secrets engines actifs
- AppRoles fonctionnels
- Audit logs vérifiés
- Terraform appliqué
- Documentation publiée
13. Documentation¶
/docs/infra/vault/- Procédure unseal
- Guide AppRole
- Guide rotation secrets