Aller au contenu

PD-8 — Rétrospective

1. Contexte

Champ Valeur
Story ID PD-8
Titre Configuration HashiCorp Vault OVH
Domaine infrastructure-souveraine
Projet infra
Date complétion 2025-01-XX
Verdict ACCEPTÉ AVEC RÉSERVES

2. Métriques

Métrique Valeur
Écarts majeurs 2
Écarts mineurs 3
Points fluides 18
Points difficiles 6

3. Learnings clés

  • PostgreSQL backend vs Raft : Le choix PostgreSQL plutôt que Raft (embedded) simplifie les backups (pg_dump standard) et s'intègre à la stack existante, au prix d'une dépendance externe.

  • TLS end-to-end nécessite attention : La combinaison Nginx Let's Encrypt (externe) + Vault autosigné (interne) avec proxy_ssl_verify off crée une zone de confiance implicite.

  • Bootstrap AppRole cross-role est un pattern accepté : Permettre au worker de générer des SecretIDs pour api-backend (pattern Prefect) évite les credentials statiques au démarrage.

  • Audit syslog = centralisation obligatoire pour conformité : L'audit fichier seul ne suffit pas pour une architecture avec SIEM.

  • Les backups Vault nécessitent tests de restauration : Un pg_dump quotidien sans test de restore automatisé est insuffisant pour garantir le RTO.

4. Patterns applicables

Nouveau pattern : AppRoles TTL courts avec bootstrap cross-role

# AppRole api-backend (consommé par le backend)
resource "vault_approle_auth_backend_role" "api_backend" {
  role_name      = "api-backend"
  token_ttl      = 1800   # 30 min
  token_max_ttl  = 7200   # 2h
  secret_id_num_uses = 1  # Single-use (AC4)
}

# Policy worker autorise bootstrap SecretID pour api-backend
resource "vault_policy" "worker" {
  name = "worker"
  policy = <<EOT
path "auth/approle/role/api-backend/secret-id" {
  capabilities = ["create", "update"]
}
EOT
}

Pattern confirmé : Secrets engines Database avec TTL courts

resource "vault_database_secret_backend_connection" "pv_postgres" {
  backend       = vault_mount.database.path
  name          = "pv-postgres"
  plugin_name   = "postgresql-database-plugin"

  postgresql {
    connection_url = "postgres://{{username}}:{{password}}@postgres:5432/probatiovault?sslmode=require"
  }

  allowed_roles = ["backend-read", "backend-readwrite"]
}

resource "vault_database_secret_backend_role" "backend_readwrite" {
  backend     = vault_mount.database.path
  name        = "backend-readwrite"
  db_name     = vault_database_secret_backend_connection.pv_postgres.name
  default_ttl = 3600   # 1h
  max_ttl     = 86400  # 24h

  creation_statements = [
    "CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';"
  ]
}

5. Signal CLAUDE.md

Priorité moyenne : Bootstrap AppRole pattern avec TTL courts.

### HashiCorp Vault — Bootstrap AppRole cross-role (2026-02-XX)

**Pattern Prefect** : Le worker génère des SecretIDs pour api-backend au démarrage.

**Bénéfice** : Évite credentials statiques dans la config backend.

**Configuration** :
1. Worker a `create` sur `auth/approle/role/api-backend/secret-id`
2. Worker démarre, génère SecretID single-use
3. Backend récupère SecretID, s'authentifie
4. SecretID consommé (1 usage)

**Risque accepté** : Worker peut créer des SecretIDs → contrôlé par network isolation + audit logs.

6. Conclusion

PD-8 a livré HashiCorp Vault avec backend PostgreSQL TLS, secrets engines KV v2 + Database, AppRoles TTL courts, policies least-privilege, et audit logging. Les 2 écarts majeurs (certificat autosigné, audit syslog désactivé) illustrent l'importance de la validation TLS end-to-end et de la centralisation des logs pour conformité.


Rétrospective générée 2026-02-19 (Étape 10 batch infra-souveraine)