Aller au contenu

PD-8 — Plan d'implémentation


📚 Navigation User Story | Document | | | ---------- | -- | | 📋 [Spécification](PD-8-specification.md) | | | 🛠️ **Plan d'implémentation** | *(ce document)* | | ✅ [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)

Objectif

Configurer HashiCorp Vault pour la gestion centralisée des secrets (credentials, tokens, certificates).

Choix techniques retenus

  • Deployment : Vault OSS sur VM OVH
  • Storage : PostgreSQL (backend persistant)
  • Unseal : Auto-unseal via AWS KMS
  • Auth : AppRole pour services
  • UI : Lecture seule (DEV/RECETTE), désactivée (PROD)

Stratégie par environnement

Règle d'or : Toute configuration Vault est réalisée exclusivement via Infrastructure as Code (Terraform/Ansible). L'UI est strictement limitée à des usages de lecture et diagnostic.

Environnement UI Terraform Accès humain
DEV Read-only Obligatoire Limité (VPN)
RECETTE Read-only Obligatoire Limité strict
PROD Désactivée Obligatoire Aucun

Architecture ciblée

┌─────────────────────────────────────────────────────────────────────┐
│                        VPS OVH (51.68.126.160)                      │
│                                                                     │
│  ┌─────────────────┐     ┌─────────────────┐     ┌───────────────┐ │
│  │  Vault Server   │────▶│   PostgreSQL    │     │  NestJS API   │ │
│  │  (port 8200)    │     │   vault_storage │     │  (AppRole)    │ │
│  └─────────────────┘     └─────────────────┘     └───────────────┘ │
│           │                                              │          │
│           │ TLS 1.3                                      │          │
│           ▼                                              ▼          │
│  ┌─────────────────┐                            ┌───────────────┐  │
│  │  Audit Logs     │                            │   Workers     │  │
│  │  /var/log/vault │                            │  (AppRole)    │  │
│  └─────────────────┘                            └───────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

Secret Engines

kv/
├── app/                    # Secrets API Backend
│   ├── jwt-secret
│   ├── encryption-key
│   └── smtp-credentials
├── worker/                 # Secrets Workers BullMQ
│   └── queue-config
├── ci/                     # Secrets GitLab CI
│   ├── deploy-token
│   └── registry-credentials
├── hsm/                    # Secrets CloudHSM
│   ├── cu-password
│   └── aws-credentials
├── vpn/                    # VPN PSK
│   └── psk
└── ovh/                    # API OVH
    └── api-credentials

Découpage technique

Phase 1 : Installation Vault

  1. Provisionner VM OVH :
  2. Ubuntu 22.04 LTS
  3. 2 vCPU, 4GB RAM
  4. SSD 50GB

  5. Installer Vault via Ansible role vault

Phase 2 : Configuration

Configuration /etc/vault.d/vault.hcl :

storage "postgresql" {
  connection_url = "postgresql://vault_backend:***@localhost:5432/vault_storage"
  table          = "vault_kv_store"
  max_parallel   = 128
}

listener "tcp" {
  address         = "127.0.0.1:8200"
  tls_cert_file   = "/opt/vault/tls/vault.crt"
  tls_key_file    = "/opt/vault/tls/vault.key"
  tls_min_version = "tls13"
}

api_addr = "https://127.0.0.1:8200"

ui = true  # DEV/RECETTE uniquement

Phase 3 : Initialisation

vault operator init -key-shares=5 -key-threshold=3

Distribution des clés Shamir :

Clé Stockage Responsable
Clé 1 1Password Admin principal
Clé 2 Bitwarden Admin backup
Clé 3 Coffre-fort physique Direction technique
Clé 4 USB chiffré Stockage hors-site
Clé 5 Enveloppe scellée Réserve

Phase 4 : Secret Engines

vault secrets enable -path=kv -version=2 kv
vault secrets enable database

Phase 5 : Auth AppRole

vault auth enable approle

vault write auth/approle/role/api-backend \
    token_policies="api-backend" \
    token_ttl=30m \
    token_max_ttl=2h \
    secret_id_ttl=5m \
    secret_id_num_uses=1

Phase 6 : TLS & DNS

Environnement Domaine
DEV vault.dev.probatiovault.com
TEST vault.test.probatiovault.com
PROD vault.probatiovault.com

Phase 7 : Backup

Script de backup PostgreSQL :

#!/bin/bash
BACKUP_DIR="/var/backups/vault"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
pg_dump -h localhost -U vault_backend -d vault_storage | gzip > "${BACKUP_DIR}/vault_storage_${TIMESTAMP}.sql.gz"

Cron : 0 2 * * * /opt/vault/scripts/vault-backup.sh

Note : Upload S3 et tests de restauration automatisés à implémenter.

Phase 8 : Policies

Policy api-backend :

path "kv/data/app/*" {
  capabilities = ["read", "list"]
}
path "database/creds/api-readwrite" {
  capabilities = ["read"]
}

Policy vault-observer (UI read-only) :

path "kv/data/*" {
  capabilities = ["read", "list"]
}
path "sys/health" {
  capabilities = ["read"]
}
path "auth/token/create*" {
  capabilities = ["deny"]
}

Phase 9 : Audit & Monitoring

vault audit enable file file_path=/var/log/vault/audit.log

Alertes Prometheus : - VaultSealed : Vault en état sealed - VaultDown : Vault indisponible - VaultRootTokenUsed : Root token utilisé (critique sécurité)

Points de vigilance

  • Root token : Révoquer après setup initial, stocker offline
  • Unseal keys : Distribuer à personnes différentes
  • TLS : Obligatoire, même en interne
  • Audit : Activer audit device
  • UI : Jamais source de vérité, lecture seule uniquement

Hors périmètre

  • PKI/CA interne (→ future US)
  • Dynamic secrets PostgreSQL (→ future US)
  • Transit encryption (→ future US)
  • Haute disponibilité multi-nœuds (→ PROD)