[infra] Checkov est rouge sur develop : huit constats sur le compte de stockage, dont deux vrais manques #249

Closed
opened 2026-09-09 13:37:18 +00:00 by olivier · 0 comments
Member

Exigence couverte

ENF-11 · Chaîne d'approvisionnement (scan bloquant). Touche aussi ENF-05 (continuité, fenêtre de récupération) et ENF-13 (coût).

Épreuve servie

EC04 · Cloud et sécurisation

Charge estimée

une demi-journée

Ce qu'on veut obtenir

Depuis la fusion du #72 (PR #242), la tâche « Checkov — audit de la configuration » est rouge sur develop, et toute demande de fusion en hérite. Ce n'est pas un défaut de la chaîne : le scan fait son travail, sur un compte de stockage que le #69 (PR fusionnée avant lui) avait déclaré entre-temps.

Rejoué en local avec le checkov épinglé du dépôt (3.3.16, infra/terraform/requirements-ci.txt) et la configuration versionnée :

checkov --directory infra/terraform --config-file infra/terraform/.checkov.yml --output cli --compact
→ Passed checks: 9, Failed checks: 8, Skipped checks: 0

Les huit portent tous sur azurerm_storage_account.archive (infra/terraform/stockage.tf:83-183). Ils se répartissent en deux familles très inégales, et c'est tout l'enjeu de ce ticket.

Six règles inapplicables ici, et le dépôt écrit déjà pourquoi. Chacune a son argument dans stockage.tf ou dans l'exception voisine CKV2_AZURE_21 de .checkov.yml — ils sont vérifiables, ce qui est la condition posée par le #72 pour qu'une exception soit légitime :

Règle Ce qu'elle veut Ce que le dépôt écrit déjà
CKV_AZURE_59 public_network_access_enabled = false Décidé à true, l. 118-131 : un point de terminaison privé n'est pas permis par l'abonnement école, et false couperait le terraform init qui lit l'état dans ce compte
CKV2_AZURE_33 un point de terminaison privé Même cause, même ligne
CKV2_AZURE_40 shared_access_key_enabled = false Décidé à true, l. 133-145 : nécessaire au jeton SAS du #70
CKV2_AZURE_1 chiffrement par clé client (Key Vault) Hors des droits du rôle Devops-cours-projet-eadl (ADR 0007), comme le dit déjà l'exception CKV2_AZURE_21
CKV_AZURE_33 journalisation du service Queue Même famille que CKV2_AZURE_21 : demande un paramètre de diagnostic et un espace Log Analytics, hors droits — et aucune queue n'est utilisée
CKV_AZURE_206 réplication GRS/ZRS au lieu de LRS LRS est ce que bootstrap.sh a créé (l. 88-99) ; monter en GRS double le stockage facturé, ce qui relève de l'ENF-13

Deux vrais manques, et ils ne doivent PAS être exemptés. Les éteindre serait exactement ce que l'en-tête de .checkov.yml refuse en capitales — « CE QUI N'EST PAS UNE EXCEPTION ACCEPTABLE : ça fait rougir la chaîne » :

  • CKV2_AZURE_38suppression réversible désactivée. stockage.tf l. 147-158 le dit lui-même : « L'activer serait un vrai gain pour l'archive comme pour l'état — c'est une décision à prendre, pas un effet de bord à subir ». Et docs/runbooks/stockage-secours.md § « Activer la suppression réversible » ajoute : « à ouvrir en ticket plutôt qu'à glisser dans une demande de fusion qui parle d'autre chose ». D'où ce ticket.
  • CKV2_AZURE_41aucune politique d'expiration des SAS. Non discuté nulle part. Directement utile au #70, qui va émettre un jeton.

Critères d'acceptation

  • checkov --directory infra/terraform --config-file infra/terraform/.checkov.yml sort en code 0, et la tâche « Checkov » est verte sur develop.
  • CKV2_AZURE_38 est satisfaite par un delete_retention_policy réellement posé dans le bloc blob_properties, pas par une exception. La durée retenue est écrite avec son coût.
  • CKV2_AZURE_41 est satisfaite par un bloc sas_policy réellement posé, pas par une exception. Si expiration_action vaut Log plutôt que Block, le motif est écrit — un Block mal dimensionné casserait le #70.
  • Les six autres règles sont exemptées dans infra/terraform/.checkov.yml, une par ligne, chacune avec un motif qu'un relecteur peut vérifier dans le dépôt — la forme que le #72 impose. Aucune exemption ne dit « ça fait rougir la chaîne ».
  • terraform plan montre 0 to destroy sur azurerm_storage_account.archive : le compte porte l'état de Terraform et son prevent_destroy doit rester non sollicité.
  • docs/runbooks/stockage-secours.md ne présente plus la suppression réversible comme « non posée aujourd'hui », et son § 7 dit comment revenir en arrière.

Comment on le vérifie

pip install -r infra/terraform/requirements-ci.txt
checkov --directory infra/terraform --config-file infra/terraform/.checkov.yml \
        --output cli --compact          # attendu : Failed checks: 0
terraform -chdir=infra/terraform fmt -check
terraform -chdir=infra/terraform validate
tflint --chdir=infra/terraform

Et, sur l'abonnement, avant tout apply :

terraform -chdir=infra/terraform plan     # « 0 to destroy », et l'import déjà absorbé

Mesure préparatoire déjà faite. Les deux correctifs ont été essayés en local sur une copie : un sas_policy (expiration_period = "0.08:00:00", expiration_action = "Log") et un delete_retention_policy { days = 7 } font passer le compte de 8 constats à 6, et les 6 restants sont exactement les six inapplicables du tableau ci-dessus. Passed monte de 9 à 11. Ce n'est pas un plan, seulement le scan : la vérification sur l'abonnement reste à faire.

Manuel d'exploitation à mettre à jour

docs/runbooks/stockage-secours.md — le § « Activer la suppression réversible » devient un état posé, avec sa durée et son coût, et le § 7 « Retour arrière » gagne la ligne correspondante. docs/runbooks/ci.md § « Terraform et sécurité IaC » si la liste des exceptions y est reprise.

Risque et retour arrière

Le risque n'est pas le scan, c'est la ressource. Ce compte porte l'état de Terraform : il est adopté par un bloc import et protégé par prevent_destroy. sas_policy et delete_retention_policy sont modifiables en place et ne devraient rien remplacer — mais c'est le plan qui le dit, pas ce ticket, et un apply qui annoncerait un remplacement doit être interrompu.

expiration_action = "Log" journalise sans rejeter : un jeton SAS plus long que la politique reste valide. Passer à Block est un second geste, à ne pas confondre avec celui-ci — il casserait le #70 si la période est mal dimensionnée.

La suppression réversible a un coût : les blobs supprimés restent facturés pendant la fenêtre de rétention. Sur une archive quotidienne, c'est la taille d'une journée multipliée par la fenêtre. À chiffrer dans le ticket, ENF-13.

Retour arrière : retirer les deux blocs ramène l'état d'aujourd'hui ; la fenêtre de rétention déjà écoulée ne se rattrape pas, mais rien n'est perdu.

### Exigence couverte ENF-11 · Chaîne d'approvisionnement (scan bloquant). Touche aussi ENF-05 (continuité, fenêtre de récupération) et ENF-13 (coût). ### Épreuve servie EC04 · Cloud et sécurisation ### Charge estimée une demi-journée ### Ce qu'on veut obtenir Depuis la fusion du #72 (PR #242), la tâche **« Checkov — audit de la configuration » est rouge sur `develop`**, et toute demande de fusion en hérite. Ce n'est pas un défaut de la chaîne : le scan fait son travail, sur un compte de stockage que le #69 (PR fusionnée avant lui) avait déclaré entre-temps. Rejoué en local avec le checkov épinglé du dépôt (`3.3.16`, `infra/terraform/requirements-ci.txt`) et la configuration versionnée : ``` checkov --directory infra/terraform --config-file infra/terraform/.checkov.yml --output cli --compact → Passed checks: 9, Failed checks: 8, Skipped checks: 0 ``` Les huit portent tous sur `azurerm_storage_account.archive` (`infra/terraform/stockage.tf:83-183`). **Ils se répartissent en deux familles très inégales**, et c'est tout l'enjeu de ce ticket. **Six règles inapplicables ici, et le dépôt écrit déjà pourquoi.** Chacune a son argument dans `stockage.tf` ou dans l'exception voisine `CKV2_AZURE_21` de `.checkov.yml` — ils sont vérifiables, ce qui est la condition posée par le #72 pour qu'une exception soit légitime : | Règle | Ce qu'elle veut | Ce que le dépôt écrit déjà | |---|---|---| | `CKV_AZURE_59` | `public_network_access_enabled = false` | Décidé à `true`, l. 118-131 : un point de terminaison privé n'est pas permis par l'abonnement école, et `false` couperait le `terraform init` qui lit l'état **dans ce compte** | | `CKV2_AZURE_33` | un point de terminaison privé | Même cause, même ligne | | `CKV2_AZURE_40` | `shared_access_key_enabled = false` | Décidé à `true`, l. 133-145 : nécessaire au jeton SAS du #70 | | `CKV2_AZURE_1` | chiffrement par clé client (Key Vault) | Hors des droits du rôle `Devops-cours-projet-eadl` (ADR 0007), comme le dit déjà l'exception `CKV2_AZURE_21` | | `CKV_AZURE_33` | journalisation du service Queue | Même famille que `CKV2_AZURE_21` : demande un paramètre de diagnostic et un espace Log Analytics, hors droits — et aucune queue n'est utilisée | | `CKV_AZURE_206` | réplication GRS/ZRS au lieu de LRS | `LRS` est ce que `bootstrap.sh` a créé (l. 88-99) ; monter en GRS double le stockage facturé, ce qui relève de l'ENF-13 | **Deux vrais manques, et ils ne doivent PAS être exemptés.** Les éteindre serait exactement ce que l'en-tête de `.checkov.yml` refuse en capitales — « CE QUI N'EST PAS UNE EXCEPTION ACCEPTABLE : *ça fait rougir la chaîne* » : - `CKV2_AZURE_38` — **suppression réversible désactivée**. `stockage.tf` l. 147-158 le dit lui-même : « L'activer serait un vrai gain pour l'archive comme pour l'état — c'est une décision à prendre, pas un effet de bord à subir ». Et `docs/runbooks/stockage-secours.md` § « Activer la suppression réversible » ajoute : « **à ouvrir en ticket plutôt qu'à glisser dans une demande de fusion qui parle d'autre chose** ». D'où ce ticket. - `CKV2_AZURE_41` — **aucune politique d'expiration des SAS**. Non discuté nulle part. Directement utile au #70, qui va émettre un jeton. ### Critères d'acceptation - [ ] `checkov --directory infra/terraform --config-file infra/terraform/.checkov.yml` sort en **code 0**, et la tâche « Checkov » est verte sur `develop`. - [ ] `CKV2_AZURE_38` est satisfaite par un `delete_retention_policy` réellement posé dans le bloc `blob_properties`, **pas** par une exception. La durée retenue est écrite avec son coût. - [ ] `CKV2_AZURE_41` est satisfaite par un bloc `sas_policy` réellement posé, **pas** par une exception. Si `expiration_action` vaut `Log` plutôt que `Block`, le motif est écrit — un `Block` mal dimensionné casserait le #70. - [ ] Les six autres règles sont exemptées dans `infra/terraform/.checkov.yml`, une par ligne, **chacune avec un motif qu'un relecteur peut vérifier dans le dépôt** — la forme que le #72 impose. Aucune exemption ne dit « ça fait rougir la chaîne ». - [ ] `terraform plan` montre **`0 to destroy`** sur `azurerm_storage_account.archive` : le compte porte l'état de Terraform et son `prevent_destroy` doit rester non sollicité. - [ ] `docs/runbooks/stockage-secours.md` ne présente plus la suppression réversible comme « non posée aujourd'hui », et son § 7 dit comment revenir en arrière. ### Comment on le vérifie ``` pip install -r infra/terraform/requirements-ci.txt checkov --directory infra/terraform --config-file infra/terraform/.checkov.yml \ --output cli --compact # attendu : Failed checks: 0 terraform -chdir=infra/terraform fmt -check terraform -chdir=infra/terraform validate tflint --chdir=infra/terraform ``` Et, sur l'abonnement, avant tout `apply` : ``` terraform -chdir=infra/terraform plan # « 0 to destroy », et l'import déjà absorbé ``` **Mesure préparatoire déjà faite.** Les deux correctifs ont été essayés en local sur une copie : un `sas_policy` (`expiration_period = "0.08:00:00"`, `expiration_action = "Log"`) et un `delete_retention_policy { days = 7 }` font passer le compte de **8 constats à 6**, et les 6 restants sont exactement les six inapplicables du tableau ci-dessus. `Passed` monte de 9 à 11. Ce n'est pas un `plan`, seulement le scan : la vérification sur l'abonnement reste à faire. ### Manuel d'exploitation à mettre à jour `docs/runbooks/stockage-secours.md` — le § « Activer la suppression réversible » devient un état posé, avec sa durée et son coût, et le § 7 « Retour arrière » gagne la ligne correspondante. `docs/runbooks/ci.md` § « Terraform et sécurité IaC » si la liste des exceptions y est reprise. ### Risque et retour arrière **Le risque n'est pas le scan, c'est la ressource.** Ce compte porte l'**état de Terraform** : il est adopté par un bloc `import` et protégé par `prevent_destroy`. `sas_policy` et `delete_retention_policy` sont modifiables en place et ne devraient rien remplacer — mais c'est le `plan` qui le dit, pas ce ticket, et un `apply` qui annoncerait un remplacement doit être **interrompu**. `expiration_action = "Log"` journalise sans rejeter : un jeton SAS plus long que la politique reste valide. Passer à `Block` est un second geste, à ne pas confondre avec celui-ci — il casserait le #70 si la période est mal dimensionnée. La suppression réversible a un **coût** : les blobs supprimés restent facturés pendant la fenêtre de rétention. Sur une archive quotidienne, c'est la taille d'une journée multipliée par la fenêtre. À chiffrer dans le ticket, ENF-13. Retour arrière : retirer les deux blocs ramène l'état d'aujourd'hui ; la fenêtre de rétention déjà écoulée ne se rattrape pas, mais rien n'est perdu.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
g2/enervision#249
No description provided.