Aller au contenu

PD-4 vs PD-5 : Audit de conformité

Date: 19/11/2025 23:45 Environnement: dev Objectif: Identifier les écarts entre PD-4 (existant) et PD-5 (requis)


📊 Synthèse globale

Composant PD-4 (Existant) PD-5 (Requis) Statut Écart
S3 Bucket documents-cold ✅ Déployé ✅ Requis Conforme Aucun
Object Lock COMPLIANCE ✅ 50 ans ✅ 50 ans Conforme Aucun
Versioning ✅ Enabled ✅ Enabled Conforme Aucun
Encryption AES-256 ✅ Enabled ✅ Enabled Conforme Aucun
Transition Glacier ⚠️ J+90 ⚠️ J+1 ⚠️ Non conforme 89 jours d'écart
Glacier Vault Lock ❌ Absent ✅ Requis Non conforme Manquant
IAM Role probatoire ❌ Absent ✅ Requis Non conforme Manquant
IAM User backend ✅ Déployé ✅ Requis ⚠️ Partiellement conforme Permissions trop larges
Audit logs ✅ Déployé ✅ Requis Conforme Aucun
S3 Access Logging ❌ Absent ✅ Requis Non conforme Manquant
Module Terraform ❌ Absent ✅ Requis Non conforme Pas modulaire
Tests automatisés ✅ Créés ✅ Requis ⚠️ Partiellement conforme Tests Vault Lock manquants
Documentation ⚠️ Partielle ✅ Requis ⚠️ Non conforme PROBATOIRE_WORM.md manquant

Score global : 6/13 conformes (46%) Score pondéré : 7.5/13 (58%) - en comptant partiels


1️⃣ Bucket S3 documents-cold-dev

✅ CONFORME

Fichier: storage-aws.tf:23-39

resource "aws_s3_bucket" "documents_cold" {
  bucket = "probatiovault-documents-cold-dev"
  object_lock_enabled = true

  lifecycle {
    prevent_destroy = true
  }

  tags = {
    Name         = "ProbatioVault Documents COLD Storage"
    Compliance   = "NF-Z42-013 ISO-14641"
    RetentionMax = "50years"
  }
}

Conformité PD-5 : - ✅ Nom bucket conforme - ✅ Object Lock activé à la création - ✅ prevent_destroy = true (protection) - ✅ Tags conformité présents - ✅ Région eu-west-3 (Paris)


2️⃣ Object Lock COMPLIANCE 50 ans

✅ CONFORME

Fichier: storage-aws.tf:82-91

resource "aws_s3_bucket_object_lock_configuration" "documents_cold_lock" {
  bucket = aws_s3_bucket.documents_cold.id

  rule {
    default_retention {
      mode  = "COMPLIANCE"  # ✅ Irréversible
      years = 50            # ✅ 50 ans
    }
  }
}

Conformité PD-5 : - ✅ Mode COMPLIANCE (hardware-backed WORM) - ✅ Rétention 50 ans - ✅ Irréversible (même root AWS)

Tests validés : 6/6 tests Object Lock passés (voir PD-4_FINAL_REPORT.md)


3️⃣ Versioning & Encryption

✅ CONFORME

Versioning : storage-aws.tf:73-79

resource "aws_s3_bucket_versioning" "documents_cold_versioning" {
  bucket = aws_s3_bucket.documents_cold.id

  versioning_configuration {
    status = "Enabled"  # ✅ Obligatoire pour Object Lock
  }
}

Encryption : storage-aws.tf:94-103

resource "aws_s3_bucket_server_side_encryption_configuration" "documents_cold_encryption" {
  bucket = aws_s3_bucket.documents_cold.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"  # ✅ Conforme PD-5
    }
    bucket_key_enabled = true
  }
}

Conformité PD-5 : - ✅ Versioning mandatory pour Object Lock - ✅ AES-256 encryption au repos - ✅ Bucket key optimization


4️⃣ Transition Glacier Deep Archive

⚠️ NON CONFORME (J+90 au lieu de J+1)

Fichier: storage-lifecycle-aws.tf:13-27

resource "aws_s3_bucket_lifecycle_configuration" "documents_cold_lifecycle" {
  bucket = aws_s3_bucket.documents_cold.id

  rule {
    id     = "transition-to-glacier-deep-archive"
    status = "Enabled"

    transition {
      days          = 90  # ⚠️ PD-5 demande J+1
      storage_class = "DEEP_ARCHIVE"
    }
  }
}

Écart : - ❌ Actuel : Transition après 90 jours - ✅ PD-5 : Transition après 1 jour - Impact : Coût S3 Standard plus élevé pendant 89 jours

Action requise :

transition {
  days          = 1  # ✅ Conforme PD-5
  storage_class = "DEEP_ARCHIVE"
}

Justification changement : - PD-5 spécifie : "Day 1: transition automatique vers Glacier Deep Archive" - Économie : $0.023/GB/mois (S3) → $0.00099/GB/mois (Glacier) dès J+1 - Économie mensuelle pour 10TB : ~$220 économisés


5️⃣ Glacier Vault Lock

❌ NON CONFORME (Absent)

Statut : Pas de ressource aws_glacier_vault ou aws_glacier_vault_lock dans le code

PD-5 exige :

resource "aws_glacier_vault" "probatoire_worm" {
  name = "probatiovault-probatoire-worm-dev"
}

resource "aws_glacier_vault_lock" "probatoire_lock" {
  vault_name    = aws_glacier_vault.probatoire_worm.name
  complete_lock = true  # IRREVERSIBLE !

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "DenyDeleteArchive"
        Effect = "Deny"
        Action = "glacier:DeleteArchive"
        Resource = aws_glacier_vault.probatoire_worm.arn
        Principal = "*"
      }
    ]
  })
}

Impact : - ❌ Pas de verrou administratif irréversible - ❌ Pas de preuve juridique Vault Lock - ❌ Non conforme NF Z42-013 (ancrage juridique manquant)

Action requise : Créer Glacier Vault + Vault Lock (Phase 3)


6️⃣ IAM Role probatoire dédié

❌ NON CONFORME (Absent)

Statut : Seul aws_iam_user.backend_user existe (pas de rôle dédié)

Fichier actuel: storage-aws.tf:479-495

resource "aws_iam_user" "backend_user" {
  name = "probatiovault-backend-dev"
  # ⚠️ User générique, pas de rôle probatoire spécifique
}

PD-5 exige : - Créer aws_iam_role.probatoire_worm - Policy ultra-restrictive : UNIQUEMENT PutObject avec Object Lock - Interdiction totale DeleteObject, BypassGovernanceRetention - Condition obligatoire : s3:x-amz-object-lock-mode = COMPLIANCE

Action requise : Créer IAM Role dédié (Phase 4)


7️⃣ IAM User backend - Permissions

⚠️ PARTIELLEMENT CONFORME (Permissions trop larges)

Fichier: storage-aws.tf:377-470

Permissions actuelles :

{
  Sid    = "DocumentsColdReadWrite"
  Action = [
    "s3:PutObject",
    "s3:PutObjectRetention",
    "s3:PutObjectLegalHold",  # ✅ OK
    "s3:GetObject",
    "s3:GetObjectVersion",
    "s3:ListBucket",
    "s3:ListBucketVersions"
  ]
}

Écart PD-5 : - ⚠️ Manque : Condition x-amz-object-lock-mode = COMPLIANCE - ⚠️ Manque : Explicit Deny sur DeleteObject - ⚠️ Manque : Explicit Deny sur BypassGovernanceRetention

Recommandation :

{
  Sid    = "AllowPutObjectWithLock"
  Action = ["s3:PutObject"]
  Condition = {
    StringEquals = {
      "s3:x-amz-object-lock-mode" = "COMPLIANCE"
    }
  }
},
{
  Sid    = "DenyDeleteEverything"
  Effect = "Deny"
  Action = [
    "s3:DeleteObject",
    "s3:DeleteObjectVersion",
    "s3:BypassGovernanceRetention"
  ]
  Resource = "*"
}


8️⃣ Audit Logs append-only

✅ CONFORME

Fichier: storage-aws.tf:119-256

resource "aws_s3_bucket" "audit_logs" {
  bucket = "probatiovault-audit-logs-dev"
  object_lock_enabled = true  # ✅

  tags = {
    Retention = "50years"  # ✅
  }
}

resource "aws_s3_bucket_object_lock_configuration" "audit_logs_lock" {
  rule {
    default_retention {
      mode  = "COMPLIANCE"  # ✅
      years = 50            # ✅
    }
  }
}

Bucket Policy : storage-aws.tf:136-216 - ✅ Append-only (PutObject autorisé, Delete denied) - ✅ HTTPS-only - ✅ Read admin avec condition PrincipalTag/Role = Admin

Conformité PD-5 : ✅ 100%


9️⃣ S3 Server Access Logging

❌ NON CONFORME (Absent)

Statut : Pas de configuration aws_s3_bucket_logging dans le code

PD-5 exige :

resource "aws_s3_bucket_logging" "documents_cold_logging" {
  bucket = aws_s3_bucket.documents_cold.id

  target_bucket = aws_s3_bucket.audit_logs.id
  target_prefix = "s3-access-logs/documents-cold/"
}

Impact : - ❌ Pas de traçabilité des accès S3 - ❌ Non conforme ISO 27001 (logging obligatoire) - ❌ Pas d'audit trail en cas d'investigation

Action requise : Activer S3 Access Logging (Phase 2)


🔟 Module Terraform

❌ NON CONFORME (Pas modulaire)

Statut : Code monolithique dans storage-aws.tf (609 lignes)

PD-5 exige : - Module modules/worm_glacier/ - Variables : retention_years, transition_days, vault_lock_enable - Outputs : ARNs, statuts Object Lock

Avantages modularisation : - ✅ Réutilisabilité (documents, audit, autres buckets) - ✅ Testabilité isolée - ✅ Maintenance simplifiée - ✅ DRY (Don't Repeat Yourself)

Action requise : Refactoriser vers module (Phase 5)


1️⃣1️⃣ Tests automatisés

⚠️ PARTIELLEMENT CONFORME

Existant : /tmp/test-object-lock-pd4.sh - ✅ 6 tests Object Lock - ✅ Tests COMPLIANCE mode - ✅ Tests GOVERNANCE mode

Manquant pour PD-5 : - ❌ Tests Glacier Vault Lock - ❌ Tests immutabilité Vault Lock Policy - ❌ Tests IAM Role probatoire - ❌ Tests S3 Access Logging

Action requise : Compléter test suite (Phase 6)


1️⃣2️⃣ Documentation PROBATOIRE_WORM.md

❌ NON CONFORME (Manquant)

Statut : Documentation PD-4 existe, mais pas PROBATOIRE_WORM.md spécifique

Existant : - ✅ /tmp/PD-4_FINAL_REPORT.md - ✅ /tmp/PD-4_CREDENTIALS_SECURITY.md

PD-5 exige : - Document docs/storage/PROBATOIRE_WORM.md - Architecture technique détaillée - Conformité NF Z42-013, ISO 14641, eIDAS - Procédures opérationnelles - Rapport Vault Lock In Effect

Action requise : Créer documentation complète (Phase 7)


🎯 Plan d'action prioritaire

Phase 2 : Ajustements rapides (1h)

  1. ✅ Modifier lifecycle : J+90 → J+1
  2. ✅ Ajouter S3 Access Logging
  3. ✅ Corriger warning lifecycle backups ligne 357

Phase 3 : Glacier Vault Lock (2h)

  1. ✅ Créer Glacier Vault
  2. ⚠️ Configurer Vault Lock Policy (TEST MODE d'abord !)
  3. ⏳ Attendre 24-48h validation
  4. ✅ Activer complete_lock = true (IRREVERSIBLE)

Phase 4 : IAM Role probatoire (1h)

  1. ✅ Créer aws_iam_role.probatoire_worm
  2. ✅ Policy ultra-restrictive
  3. ✅ Deny explicite DeleteObject

Phase 5-9 : Modularisation + Tests + Doc + Deploy (6h)

  1. Refactoriser vers module
  2. Tests Vault Lock
  3. Documentation PROBATOIRE_WORM.md
  4. Déploiement validation
  5. Rapport final

📊 Métriques de conformité

Par catégorie

Catégorie Conformité Détails
Infrastructure S3 80% Buckets OK, lifecycle à ajuster
Object Lock WORM 100% COMPLIANCE parfait
Glacier Vault 0% Entièrement manquant
IAM Security 50% User OK, role manquant, permissions à durcir
Logging & Audit 50% Audit logs OK, S3 logging manquant
Code Quality 33% Tests partiels, pas modulaire, doc incomplète

Score global

Conformité technique : 58/100 Conformité juridique : 40/100 (Vault Lock manquant = critique) Production ready : ❌ NON (Vault Lock requis)


⚠️ Risques identifiés

Risque Impact Probabilité Mitigation
Pas de Vault Lock 🔴 Critique Élevé Implémenter Phase 3
Lifecycle J+90 🟡 Moyen Élevé Ajuster à J+1 (Phase 2)
S3 Logging absent 🟡 Moyen Moyen Activer logging (Phase 2)
IAM trop permissif 🟡 Moyen Faible Role dédié (Phase 4)
Code non modulaire 🟢 Faible Faible Refactoring (Phase 5)

✅ Validation finale PD-5

Pour clore PD-5, les 3 critères bloquants sont :

  1. Glacier Vault Lock actif (Phase 3)
  2. Lifecycle J+1 (Phase 2)
  3. IAM Role probatoire (Phase 4)

Sans ces 3 éléments, PD-5 ne peut pas être marquée comme terminée.


Généré le : 19/11/2025 23:45 Auteur : Claude Code (Anthropic) User Story : PD-5 - Audit conformité vs PD-4