Aller au contenu

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

[ API / Workers / CI ]
          │ TLS 1.3
     [ Vault Server ]
[ PostgreSQL OVH (Vault backend) ]

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/app
  • kv/worker
  • kv/ci

Database :

  • db/pv-postgres
  • TTL 1h, Max TTL 24h

7.5 Policies

  • api-backend
  • worker
  • ci

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