cd ..

DevSecOps : intégrer la sécurité dans une chaîne automatisée

AU
Aubin Puyoou · 15 août 2026

Introduction

Le DevOps a réconcilié deux métiers qui se regardaient en chiens de faïence. Il a aussi, au passage, industrialisé la livraison logicielle à un rythme que les processus de sécurité traditionnels n'ont pas suivi. Quand une équipe déploie quinze fois par jour, l'audit de sécurité trimestriel n'a plus de sens : il arrive systématiquement après la mise en production de ce qu'il était censé valider.

Le DevSecOps n'est pas une couche supplémentaire posée sur le DevOps, c'est la correction d'un modèle incomplet. Cet article revient sur cette évolution, détaille les recommandations structurantes, puis présente deux applications concrètes : la protection des secrets avec HashiCorp Vault et le contrôle d'intégrité du code déployé au travers du modèle de Biba.


Partie 1 — Du DevOps au DevSecOps

Genèse : deux équipes, deux objectifs contradictoires

Le DevOps englobe le développement (Development) et l'exploitation (Operations), en généralisant les méthodes agiles à l'ensemble du système d'information. Cette fusion est née d'un antagonisme structurel entre deux métiers dont les objectifs sont, sur le papier, incompatibles :

Développement Exploitation
Objectif Livrer des changements fonctionnels Garantir la stabilité du système
Mesure du succès Vélocité, features livrées Uptime, nombre d'incidents
Rapport au changement Le changement est le produit Le changement est le risque

Les développeurs ajoutent des fonctionnalités, corrigent des bugs, et sous pression du business peuvent négliger la qualité de code ou les problématiques de performance. En face, l'équipe d'exploitation est tenue de limiter les perturbations au minimum. Mécaniquement, les modifications introduites par les développeurs sont perçues comme des menaces à la fiabilité du système, ce qui pousse à ralentir les délais de mise à jour.

L'automatisation au cœur de la collaboration

En encourageant la collaboration, le DevOps brise cette barrière. La responsabilité devient partagée : chacun est sensibilisé aux contraintes de l'autre sur l'ensemble du cycle de développement.

Cette collaboration n'est possible qu'à une condition : l'automatisation. Sans pipeline CI/CD (Continuous Integration / Continuous Deployment) capable de valider et de déployer les modifications, la majorité des principes DevOps restent lettre morte. C'est l'outillage qui rend le partage de responsabilité tenable, pas la bonne volonté des équipes.

Figure 1 — Fusion des enjeux « Dev » et « Ops » : deux cycles aux objectifs opposés réconciliés par l'automatisation

L'angle mort : la sécurité sacrifiée en premier

Cette automatisation s'accompagne d'une dérive prévisible. Lorsqu'elle ne sert qu'une mentalité de délivrer à tout prix un produit minimum viable (MVP), les courts délais forcent à arbitrer. Et dans cet arbitrage, la sécurité est toujours la première variable d'ajustement : elle ne se voit pas dans la démo, elle n'apparaît dans aucun graphique d'avancement du projet, et son absence ne casse aucun test.

C'est précisément ce constat qui fait apparaître le « Sec » dans l'acronyme.

Le facteur culturel, pas le facteur technique

Le point souvent négligé : la culture organisationnelle est le facteur clé de réussite d'une adoption DevSecOps. Une organisation très hiérarchisée, orientée contrôle, aura du mal à laisser place aux changements nécessaires, quelle que soit la qualité des outils déployés.

Le DevSecOps suppose une résolution de problèmes collective, indépendante de la hiérarchie. L'inspiration vient de la culture startup ; innovation, flexibilité, importance moindre des titres ; mais l'objectif est ailleurs : la transparence et l' efficacité collective, parce que les connaissances techniques nécessaires sont trop éparses et trop nombreuses pour tenir dans une seule équipe.

Les quatre piliers du processus

Le processus DevSecOps repose sur un outillage qui sert quatre propriétés :

Pilier Objectif Réalisation et outils concrets
Répétabilité Rejouer un processus à l'identique Outils de développement orientés "Infra as Code", "Config as Code"
Visibilité Connaître l'état de l'infrastructure à chaque étape Inventaire des configurations, provisionnement traçable des machines
Fiabilité & scalabilité Permettre la redondonce d'environnements identiques interagissant avec le reste de l'architecture Redondance simplifiée, diagnostic des échecs d'installation
Microservices Isoler de petites unités fonctionnelles API cohérentes (souvent HTTP), redéploiement unitaire

Les quatre propriétés du processus DevSecOps et leur outillage : répétabilité, visibilité, fiabilité/scalabilité et microservices

Ces quatre propriétés ne sont pas de la sécurité à proprement parler, mais elles en sont le prérequis. On ne sécurise pas ce qu'on ne sait pas décrire, et on ne corrige pas en urgence une infrastructure qu'on ne sait pas reconstruire.

La sécurité sur tout le cycle

Le cycle de vie DevSecOps se représente classiquement par un ruban de Möbius : Plan → Code → Build → Test → Release → Deploy → Operate → Monitor, puis retour au Plan. La spécificité du DevSecOps est que la sécurité englobe la boucle entière plutôt que de s'intercaler entre deux étapes. Il n'y a pas de « phase sécurité » : il y a une exigence de sécurité à chaque phase.

Figure 2 — Le cycle DevSecOps en ruban de Möbius : la sécurité (Security) englobe l'ensemble des phases, du Plan au Monitor


Partie 2 — Principales recommandations

Sécuriser la chaîne CI/CD

Le CI/CD regroupe l'intégration continue (automatisation de l'intégration régulière des modifications) et la distribution / déploiement continu. Ce double volet concentre intégration, tests et distribution, ce qui en fait mécaniquement une cible de choix : compromettre le pipeline, c'est compromettre tout ce qu'il produit.

Trois familles d'analyse s'y intègrent, à des moments et pour des coûts différents :

  1. SAST (Static Application Security Testing) : analyse du code source sans exécution. Ne nécessite aucune infrastructure, s'exécute en début de chaîne, et vite. C'est la première couche : elle détecte les anomalies au niveau du code lui-même.

  2. DAST (Dynamic Application Security Testing) : analyse de l'application en cours d'exécution. Nécessite une infrastructure dédiée pour tester l'application « en réel ». Plus lourd, plus lent, mais rattrape ce que l'analyse statique ne peut pas voir : erreurs de configuration serveur, comportements d'authentification, failles qui n'existent qu'à l'exécution.

  3. SCA (Software Composition Analysis) : analyse des composants tiers embarqués. L'objectif est de savoir exactement ce qu'on livre, dépendances transitives comprises, pour pouvoir réagir quand une CVE tombe sur un composant enfoui sur les niveaux plus bas. Le SBOM (Software Bill of Materials) est le document qu'elle produit et qui sera confronté aux bases de vulnérabilités. Docker sait le générer directement depuis une image :

docker sbom mon-image:tag

Figure 3 — Répartition des tests de sécurité le long de la chaîne : SCA et SAST au plus tôt (Dev/CI), DAST et RASP à l'exécution (CD)

L'idée directrice reste la même dans les trois cas : identifier les vulnérabilités le plus tôt possible, là où le coût de correction est le plus faible.

Policy as Code

La Policy as Code (PAC) prolonge la démarche « as Code » au domaine réglementaire : les stratégies et règles de l'entreprise deviennent du code versionné, testable et évaluable automatiquement. Sa mise en œuvre repose sur trois éléments :

  • La politique : l'ensemble des règles et autorisations, exprimées dans un langage dédié ;

  • Les données : l'état réel à confronter à la politique ;

  • La requête : l'évaluation des données au regard des politiques définies.

L'intérêt pratique : une règle du type « aucun conteneur ne tourne en root » ou « aucun bucket n'est public » cesse d'être une ligne dans une spécification Word, pour devenir un test qui casse le pipeline.

"Infrastructure as Code" et conteneurisation

L' IaC est un mode de configuration qui automatise l'approvisionnement et l'administration d'une infrastructure. Elle accélère et fiabilise le déploiement, et fournit au développeur un environnement à isopérimètre de la production. C'est condition nécessaire pour que l'intégration continue signifie quelque chose. L'outil Terraform en est l'exemple canonique.

Docker, de son côté, permet de créer et déployer des environnements applicatifs en passant de l'un à l'autre sans friction. Son fonctionnement repose sur le déploiement d'images, avec un contrôle basé sur l'historisation de leurs versions, ce qui donne, gratuitement, une capacité de retour arrière et une référence pour la vérification d'intégrité.

Une précision qui a des conséquences directes en sécurité : un conteneur n'est pas une machine virtuelle. Une VM embarque son propre noyau et l'hyperviseur assure l'isolation ; un conteneur est un ensemble de processus isolés par namespaces et cgroups, mais qui partagent le noyau de l'hôte. La frontière d'isolation est donc bien plus fine : une vulnérabilité noyau ou une capability laissée en trop peut suffire à s'en échapper. C'est ce qui justifie les règles de durcissement habituelles : pas d'exécution en root, système de fichiers en lecture seule, capabilities réduites au strict nécessaire, et surtout pas de conteneur privilégié (pouvant utiliser des fonctions plus larges du système hôte).

Surveillance continue

Dans un projet DevSecOps, la surveillance temps réel conditionne la rapidité de réaction. Elle embarque une pluralité de technologies : scans de vulnérabilité, contrôles de conformité, gestion de configuration. Un SIEM (Security Information and Event Management) apporte la vision d'ensemble de l'environnement et, surtout, son historisation, sans laquelle aucune investigation post-incident n'est possible.


Partie 3 — Lecture par la triade CID

Le modèle CID (Confidentialité, Intégrité, Disponibilité) reste la grille de lecture la plus utile pour structurer une politique de sécurité. Appliqué à une chaîne DevSecOps :

Confidentialité

Deux leviers, à ne pas confondre avec ceux de l'intégrité.

Le contrôle d'accès, d'abord : filtrage rigoureux des droits utilisateurs, pour empêcher un acteur malveillant d'atteindre les systèmes et les données. Dans un contexte automatisé, cela concerne autant les humains que les comptes de service du pipeline, souvent les plus privilégiés et les moins audités.

Le chiffrement, ensuite. Il rend la donnée illisible sans la clé :

  • Au repos : protège contre la perte ou le vol de données stockées. On utilise typiquement de la cryptographie symétrique : la même clé chiffre et déchiffre, pour des raisons de performance sur de gros volumes.

  • Intégralité du disque : étend la même protection à l'ensemble du support, y compris en cas de perte physique de la machine.

  • En transit : TLS entre les composants de la chaîne (registre d'images, runners, coffre à secrets).

Le chiffrement n'assure pas l'intégrité. C'est la confusion la plus répandue sur la triade CID. Un chiffré modifié par un attaquant reste déchiffrable, mais en données corrompues, silencieusement. Sans mécanisme dédié, personne ne le détecte. C'est précisément pourquoi les modes de chiffrement modernes sont authentifiés (AES-GCM, ChaCha20-Poly1305) : ils ajoutent explicitement une balise d'intégrité au chiffrement, parce que celui-ci ne la fournit pas.

Intégrité

L'intégrité repose sur des mécanismes distincts du chiffrement, par ordre de garantie croissante.

Le hachage (SHA-256) détecte la modification accidentelle. Il ne protège de rien si l'attaquant peut modifier à la fois la donnée et l'empreinte publiée. L'empreinte doit donc provenir d'un canal de confiance distinct.

Le MAC (Message Authentication Code, type HMAC) ajoute une clé secrète au hachage : seul un détenteur de la clé peut produire une empreinte valide. La clé étant partagée entre émetteur et vérificateur, il n'y a pas de preuve d'origine opposable, les deux parties peuvent produire le même MAC.

La signature numérique lève cette limite par la cryptographie asymétrique. Le sens des clés est ici essentiel :

  • on signe avec la clé privée, que seul le signataire détient ;

  • on vérifie avec la clé publique, que tout le monde peut détenir.

L'inverse n'aurait aucun sens : si la signature s'effectuait avec la clé publique, n'importe qui pourrait signer.

Docker propose ce mécanisme pour ses images. Une image signée est une image dont on peut vérifier la provenance et l'intégrité avant de l'exécuter. C'est le maillon qui empêche un registre d'images compromis de substituer une image à une autre.

Disponibilité

La détection relève en temps réel les problématiques techniques d'une application ou d'un serveur, avec une logique de priorisation des métriques. L'objectif est le maintien en condition opérationnelle (MCO) et l'anticipation des anomalies. Des solutions comme Nagios récupèrent les données hardware et système et déclenchent des alertes personnalisées.

La redondance vient en complément : assurer une continuité de service minimale en cas de panne. La conteneurisation facilite cette évolution automatique de l'infrastructure : duplication de conteneurs, cluster actif/passif, répartition de charge par load balancing.


Partie 4 — Mise en pratique : protection des secrets avec Vault

Le problème du secret statique

Un mot de passe de base de données écrit dans un fichier de configuration pose trois problèmes cumulés : il est connu de tous ceux qui ont accès au dépôt, il est rarement changé (parce que le changer implique de redéployer), et sa compromission est indétectable. Ajoutez à cela une chaîne CI/CD qui doit y accéder pour déployer, et la surface d'exposition devient difficile à cartographier.

HashiCorp Vault

Vault stocke chiffrés les secrets critiques, clés d'API, mots de passe, certificats, dans un coffre partagé. Il apporte trois choses qui manquent au fichier de configuration :

  1. Des politiques d'accès strictes définissant qui peut lire quoi.

  2. Une journalisation permettant de détecter changements et activités suspectes.

  3. La génération dynamique de secrets à durée de vie limitée.

C'est le troisième point qui change réellement le modèle de menace. Plutôt que de distribuer un mot de passe permanent, Vault détient les accès administrateurs aux serveurs et génère à la demande des identifiants temporaires. Des rôles paramètrent les limites d'accès des clés distribuées aux applications, via les commandes renseignées à leur création.

Démonstration : identifiants PostgreSQL éphémères

Voici la mise en œuvre complète sur un serveur PostgreSQL. Première étape, l'activation du moteur de secrets database. Notez l'erreur volontairement conservée : un coffre scellé refuse toute opération, ce qui est le comportement attendu.

export VAULT_ADDR="https://127.0.0.1:8200"
export VAULT_SKIP_VERIFY=true
export VAULT_TOKEN="hvs.xxxxxxxxxxxxxxxxxxxxxxxx"

vault secrets enable database
# Error enabling: Error making API request.
# URL: POST https://127.0.0.1:8200/v1/sys/mounts/database
# Code: 503. Errors:
# * Vault is sealed

Il faut donc d'abord desceller le coffre :

vault operator unseal <clé_de_descellement>
# Seal Type       shamir
# Initialized     true
# Sealed          false
# Total Shares    1
# Threshold       1
# Version         1.18.2

vault secrets enable database
# Success! Enabled the database secrets engine at: database/

Le seuil de descellement (Threshold) est ici à 1 pour la démonstration. En production, l'algorithme de partage de secret de Shamir doit être configuré avec plusieurs porteurs de parts, précisément pour qu'aucune personne seule ne puisse ouvrir le coffre. Ce n'est autre que le nombre de clés partagées requises pour le desceller.

Deuxième étape, la configuration de la connexion administrateur. C'est le seul endroit où le compte postgres est manipulé :

vault write database/config/my-postgresql-db \
    plugin_name="postgresql-database-plugin" \
    allowed_roles="my-role" \
    connection_url="postgresql://{{username}}:{{password}}@192.168.1.206:5432/my-postgresql-db" \
    username="postgres" \
    password="example" \
    password_authentication="scram-sha-256"

Troisième étape, la définition du rôle. C'est ici que tout se joue : les creation_statements décrivent exactement les droits que Vault accordera au compte temporaire, et les TTL bornent sa durée de vie.

vault write database/roles/my-role \
    db_name="my-postgresql-db" \
    creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
        GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
    default_ttl="1h" \
    max_ttl="24h"

Le rôle n'accorde qu'un GRANT SELECT : lecture seule, rien d'autre. Il ne reste qu'à demander un accès :

vault read database/creds/my-role
# lease_id          database/creds/my-role/u24gB35buVk1UF7rwJqVgD0a
# lease_duration    1h
# lease_renewable   true
# password          j-bQ0qeYGwCFWuLPA0ag
# username          v-root-my-role-xPQd4jiuFRdldriYdsaf-1732567062

Vérification côté base

Le compte existe bien côté PostgreSQL, avec une date d'expiration :

postgres=# \du
                     Role name                      |               Attributes
----------------------------------------------------+----------------------------------------
 postgres                                           | Superuser, Create role, Create DB, …
 v-root-my-role-xPQd4jiuFRdldriYdsaf-1732567062     | Password valid until 2024-11-25 21:37:47+00

Et ses droits sont bien ceux du rôle, pas davantage :

my-postgresql-db=> CREATE TABLE my_table ( id int PRIMARY KEY );
ERROR:  permission denied for schema public
LINE 1: CREATE TABLE my_table (

Le compte lit, il n'écrit pas, et il disparaît au bout d'une heure. Trois propriétés obtenues sans qu'aucun mot de passe permanent n'ait circulé, et sans qu'aucun secret n'ait à figurer dans un fichier de configuration ou une variable de pipeline.


Partie 5 — Mise en pratique : intégrité du code déployé

Le modèle de Biba

Préserver l'intégrité des fichiers de code source et des artefacts déployés revient à bloquer les corruptions et modifications non autorisées. Le modèle de Biba formalise cet objectif par deux propriétés :

  • « No read down » : un intervenant d'un certain niveau d'intégrité ne peut lire un objet d'intégrité inférieure. Consommer une donnée moins fiable que soi, c'est se contaminer.

  • « No write up » : un intervenant d'un niveau inférieur ne peut modifier un objet d'intégrité supérieure.

C'est le double exact du modèle de Bell-LaPadula, qui protège la confidentialité (« no read up, no write down »). Biba protège l'intégrité, et c'est précisément ce qui nous intéresse dans une chaîne de déploiement.

Le modèle de Biba appliqué à un pipeline CI/CD : les flux autorisés passent (✓), le « read down » vers une ressource de plus haute intégrité et le « write up » depuis une source de plus basse intégrité sont bloqués (✗)

« No read down » : vérification des dépendances

L'application la plus directe se joue avant d'utiliser une dépendance : on vérifie son intégrité par un calcul de hachage (SHA-256, typiquement) comparé à celui fourni par la source fiable : le registre officiel, PyPI, Maven Central ou npm. Si les hachages ne correspondent pas, la dépendance est rejetée, évitant qu'une version altérée ou compromise entre dans la construction.

C'est ici que la réserve posée plus haut sur le hachage prend tout son sens : l'empreinte de référence ne doit pas transiter par le même canal que l'artefact, sans quoi un attaquant capable de substituer le paquet substitue aussi son empreinte. D'où le fait de la figer dans un fichier de verrouillage versionné dans le dépôt, un canal distinct du registre, et lui-même soumis à revue.

C'est exactement le rôle des fichiers de verrouillage (*.lock) :

# npm — vérifie les intégrités du lockfile, échoue si divergence
npm ci

# composer — refuse d'installer si composer.lock ne correspond plus
composer install

Dans les deux cas, le package-lock.json ou le composer.lock portent les empreintes attendues, et la commande d'installation en CI refuse tout écart. Le niveau d'intégrité du registre officiel est supérieur à celui d'un artefact téléchargé sans vérification : on ne « lit » que ce qu'on a pu authentifier.

« No write up » : contrôle des modifications du code source

La seconde propriété se matérialise dans le modèle de branches, dont c'est une lecture rarement explicitée :

Objet Niveau d'intégrité Règle
Branche de travail (feat/…, fix/…) Inférieur Modification directe autorisée
Branche principale (master, main) Supérieur Écriture directe interdite

Un développeur travaille sur une branche de niveau d'intégrité inférieur, séparée de la branche principale. Cette branche n'étant pas soumise à modification directe de la cible, son travail passe par une vérification avant fusion : c'est là que sont joués les tests garantissant l'intégrité des fonctionnalités existantes, et que le code doit être accepté par un intervenant de niveau équivalent à l'intégrité de la branche de destination.

Traduit en configuration, cela donne :

  • branche protégée, push direct refusé ;

  • pipeline vert obligatoire avant fusion ;

  • revue approuvée par un pair habilité.

Ces trois règles, qu'on présente habituellement comme des bonnes pratiques d'équipe, sont en réalité l'implémentation opérationnelle d'un modèle formel d'intégrité vieux de quarante ans.

Conclusion

Le DevSecOps n'ajoute pas une étape au DevOps : il corrige un déséquilibre. L'automatisation qui a rendu la livraison continue possible a aussi créé une surface d'attaque nouvelle, le pipeline lui-même, et supprimé les points de contrôle manuels sur lesquels reposait la sécurité traditionnelle.

Les deux mises en pratique présentées ici illustrent la même logique, appliquée à deux problèmes différents. Les secrets dynamiques de Vault remplacent un secret permanent et invérifiable par un identifiant éphémère, borné en droits et en durée. Le contrôle d'intégrité inspiré de Biba remplace la confiance implicite envers les dépendances et les contributions par une vérification systématique et automatisée.

Dans les deux cas, la sécurité ne ralentit pas la chaîne : elle est intégrée à l'outillage qui la fait fonctionner. C'est la seule façon tenable de sécuriser une chaîne qui déploie plusieurs fois par jour — et, accessoirement, le seul moyen pour que la sécurité cesse d'être la première variable d'ajustement.

Reste la condition la plus difficile à satisfaire, qui n'est pas technique : sans une culture organisationnelle acceptant la responsabilité partagée et la transparence, le meilleur outillage du monde ne produira qu'un pipeline très bien instrumenté qu'on contourne dès que la date de livraison approche.


Références

  • Suehring, S. Learning DevSecOps, 1re éd., O'Reilly, 2024, pp. 8–15.

  • ANSSI. Les Essentiels DevSecOps, v1.0. cyber.gouv.fr

  • OWASP. DevSecOps Guideline. owasp.org

  • OWASP. DevSecOps Verification Standard. owasp.org

  • HashiCorp. Why we need dynamic secrets. hashicorp.com

  • Kerrache, M. Dynamic Secrets: HashiCorp Vault, PostgreSQL and Python, Medium, 2023. medium.com

  • Google Cloud. Concevoir des pipelines de déploiement sécurisés. cloud.google.com

  • Red Hat. Qu'est-ce que le DevSecOps ?. redhat.com

  • Check Point. What is CI/CD Security?. checkpoint.com

  • Wikipedia. Biba Model. en.wikipedia.org