{"id":489,"date":"2026-03-11T10:17:28","date_gmt":"2026-03-11T09:17:28","guid":{"rendered":"https:\/\/secure-pipelines.com\/?p=489"},"modified":"2026-03-24T12:55:19","modified_gmt":"2026-03-24T11:55:19","slug":"artifact-provenance-attestations-slsa-in-toto-2","status":"publish","type":"post","link":"https:\/\/secure-pipelines.com\/fr\/ci-cd-security\/artifact-provenance-attestations-slsa-in-toto-2\/","title":{"rendered":"Provenance des Artefacts et Attestations : De SLSA \u00e0 in-toto"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>La signature de code est depuis longtemps un pilier de la s\u00e9curit\u00e9 logicielle. Lorsque vous v\u00e9rifiez une signature, vous savez <em>qui<\/em> a sign\u00e9 un artefact. Mais savoir qui a sign\u00e9 quelque chose ne vous dit pas <em>comment<\/em> il a \u00e9t\u00e9 construit, <em>o\u00f9<\/em> il a \u00e9t\u00e9 construit, ni <em>quel code source<\/em> a \u00e9t\u00e9 utilis\u00e9. Un mainteneur pourrait signer un binaire compil\u00e9 sur un ordinateur portable compromis avec des d\u00e9pendances inject\u00e9es \u2014 et la signature serait tout de m\u00eame valide.<\/p>\n<p>C&rsquo;est la lacune que la <strong>provenance des artefacts<\/strong> comble. La provenance est un enregistrement v\u00e9rifiable de la mani\u00e8re dont un artefact logiciel a \u00e9t\u00e9 produit. Elle capture la plateforme de build, le d\u00e9p\u00f4t source, le point d&rsquo;entr\u00e9e, les param\u00e8tres de build et les d\u00e9pendances impliqu\u00e9es. Combin\u00e9e aux signatures, la provenance offre aux consommateurs une image compl\u00e8te : non seulement \u00ab qui se porte garant de cet artefact \u00bb, mais \u00ab quel processus l&rsquo;a r\u00e9ellement cr\u00e9\u00e9 \u00bb.<\/p>\n<p>Dans ce guide, nous explorerons les deux frameworks les plus importants dans ce domaine \u2014 <strong>SLSA<\/strong> (Supply-chain Levels for Software Artifacts) et <strong>in-toto<\/strong> \u2014 et nous parcourrons leur mise en \u0153uvre pratique dans les pipelines CI\/CD modernes. Que vous soyez un ing\u00e9nieur plateforme s\u00e9curisant votre infrastructure de build ou un d\u00e9veloppeur cherchant \u00e0 comprendre ce que le niveau 3 de SLSA exige r\u00e9ellement, cet article vous fournira la profondeur technique n\u00e9cessaire.<\/p>\n<h2>Qu&rsquo;est-ce que la provenance des artefacts ?<\/h2>\n<p>La provenance des artefacts est une m\u00e9tadonn\u00e9e qui d\u00e9crit l&rsquo;origine et le processus de build d&rsquo;un artefact logiciel. Consid\u00e9rez-la comme un re\u00e7u de build : un document structur\u00e9 et sign\u00e9 qui r\u00e9pond \u00e0 trois questions fondamentales :<\/p>\n<ul>\n<li><strong>O\u00f9<\/strong> l&rsquo;artefact a-t-il \u00e9t\u00e9 construit ? (Quelle plateforme de build, quel runner, quel environnement ?)<\/li>\n<li><strong>Comment<\/strong> a-t-il \u00e9t\u00e9 construit ? (Quelle commande de build, quelle configuration, quel point d&rsquo;entr\u00e9e ?)<\/li>\n<li><strong>\u00c0 partir de quoi<\/strong> a-t-il \u00e9t\u00e9 construit ? (Quel d\u00e9p\u00f4t source, quel commit, quelles d\u00e9pendances ?)<\/li>\n<\/ul>\n<h3>Provenance vs. Signatures<\/h3>\n<p>Les signatures et la provenance sont compl\u00e9mentaires mais servent des objectifs diff\u00e9rents :<\/p>\n<ul>\n<li><strong>Une signature<\/strong> lie une identit\u00e9 \u00e0 un artefact. Elle prouve qu&rsquo;un d\u00e9tenteur de cl\u00e9 sp\u00e9cifique a approuv\u00e9 ou produit l&rsquo;artefact. Elle ne dit rien sur le processus de build.<\/li>\n<li><strong>La provenance<\/strong> lie un processus de build \u00e0 un artefact. Elle prouve qu&rsquo;une r\u00e9vision source sp\u00e9cifique a \u00e9t\u00e9 transform\u00e9e en artefact par une plateforme de build sp\u00e9cifique utilisant des param\u00e8tres sp\u00e9cifiques.<\/li>\n<\/ul>\n<p>Vous avez besoin des deux. Une signature sans provenance est une d\u00e9claration de type \u00ab faites-moi confiance \u00bb. Une provenance sans signature est une affirmation non v\u00e9rifi\u00e9e. Ensemble, elles fournissent une preuve d&rsquo;int\u00e9grit\u00e9, une auditabilit\u00e9 et une base pour l&rsquo;application automatis\u00e9e de politiques.<\/p>\n<h3>Pourquoi la provenance est importante<\/h3>\n<p>La provenance r\u00e9pond \u00e0 plusieurs risques critiques de la cha\u00eene d&rsquo;approvisionnement :<\/p>\n<ul>\n<li><strong>Preuve d&rsquo;int\u00e9grit\u00e9 :<\/strong> Si un attaquant modifie un artefact apr\u00e8s sa construction, la provenance ne correspondra pas. S&rsquo;il modifie le processus de build, la provenance refl\u00e9tera un builder ou une configuration diff\u00e9rents de ceux attendus.<\/li>\n<li><strong>Auditabilit\u00e9 :<\/strong> Lorsqu&rsquo;une vuln\u00e9rabilit\u00e9 est d\u00e9couverte, la provenance vous permet de retracer exactement quel commit source et quelle configuration de build ont produit l&rsquo;artefact affect\u00e9.<\/li>\n<li><strong>Conformit\u00e9 :<\/strong> Des frameworks comme le NIST SSDF et les d\u00e9crets ex\u00e9cutifs sur la s\u00e9curit\u00e9 de la cha\u00eene d&rsquo;approvisionnement logicielle exigent de plus en plus la provenance comme contr\u00f4le de base.<\/li>\n<li><strong>Politique automatis\u00e9e :<\/strong> Les contr\u00f4leurs d&rsquo;admission et les portes de d\u00e9ploiement peuvent v\u00e9rifier la provenance de mani\u00e8re programmatique, en imposant que seuls les artefacts construits par des plateformes de confiance \u00e0 partir de d\u00e9p\u00f4ts approuv\u00e9s soient d\u00e9ploy\u00e9s.<\/li>\n<\/ul>\n<h2>Le framework SLSA<\/h2>\n<p><strong>SLSA<\/strong> (prononc\u00e9 \u00ab salsa \u00bb) est un framework de s\u00e9curit\u00e9 d\u00e9velopp\u00e9 \u00e0 l&rsquo;origine chez Google et maintenant maintenu par l&rsquo;OpenSSF. Il d\u00e9finit un mod\u00e8le de maturit\u00e9 pour la s\u00e9curit\u00e9 de la cha\u00eene d&rsquo;approvisionnement, avec la provenance en son c\u0153ur. SLSA ne prescrit pas d&rsquo;outils sp\u00e9cifiques \u2014 il d\u00e9finit des <em>exigences<\/em> que les outils et les plateformes doivent satisfaire.<\/p>\n<h3>Le mod\u00e8le de build SLSA<\/h3>\n<p>SLSA mod\u00e9lise la cha\u00eene d&rsquo;approvisionnement logicielle comme un pipeline simple :<\/p>\n<p><strong>Source \u2192 Plateforme de Build \u2192 Artefact<\/strong><\/p>\n<p>Chaque \u00e9tape pr\u00e9sente des menaces distinctes. La source peut \u00eatre alt\u00e9r\u00e9e (commits malveillants, VCS compromis). La plateforme de build peut \u00eatre compromise (scripts de build modifi\u00e9s, d\u00e9pendances inject\u00e9es). L&rsquo;artefact peut \u00eatre alt\u00e9r\u00e9 apr\u00e8s le build (empoisonnement du registre, attaque de l&rsquo;homme du milieu). SLSA r\u00e9pond \u00e0 chacune de ces menaces par des exigences de plus en plus strictes \u00e0 chaque niveau.<\/p>\n<h3>Les niveaux SLSA (v1.0)<\/h3>\n<p>SLSA v1.0 d\u00e9finit quatre niveaux de build, chacun s&rsquo;appuyant sur le pr\u00e9c\u00e9dent :<\/p>\n<h3>Niveau de Build 1 \u2014 La provenance existe<\/h3>\n<ul>\n<li>Le processus de build g\u00e9n\u00e8re une provenance d\u00e9crivant comment l&rsquo;artefact a \u00e9t\u00e9 produit.<\/li>\n<li>Le format de provenance suit la sp\u00e9cification SLSA.<\/li>\n<li>La provenance n&rsquo;a pas besoin d&rsquo;\u00eatre sign\u00e9e ni g\u00e9n\u00e9r\u00e9e par la plateforme de build elle-m\u00eame.<\/li>\n<li><strong>Menace trait\u00e9e :<\/strong> Fournit une base pour l&rsquo;auditabilit\u00e9. N&#8217;emp\u00eache pas la falsification.<\/li>\n<\/ul>\n<h3>Niveau de Build 2 \u2014 Build h\u00e9berg\u00e9, provenance sign\u00e9e<\/h3>\n<ul>\n<li>Le build s&rsquo;ex\u00e9cute sur une plateforme de build h\u00e9berg\u00e9e (pas un poste de travail de d\u00e9veloppeur).<\/li>\n<li>La provenance est sign\u00e9e par la plateforme de build, pas par le mainteneur du projet.<\/li>\n<li>La provenance est g\u00e9n\u00e9r\u00e9e par le service de build lui-m\u00eame et ne peut pas \u00eatre modifi\u00e9e par le locataire du build.<\/li>\n<li><strong>Menace trait\u00e9e :<\/strong> Emp\u00eache le locataire du build de falsifier la provenance. Les consommateurs peuvent v\u00e9rifier l&rsquo;identit\u00e9 du service de build.<\/li>\n<\/ul>\n<h3>Niveau de Build 3 \u2014 Plateforme de build renforc\u00e9e<\/h3>\n<ul>\n<li>La plateforme de build fournit une isolation forte entre les locataires de build (par exemple, environnements \u00e9ph\u00e9m\u00e8res et sandbox\u00e9s).<\/li>\n<li>La provenance est infalsifiable : m\u00eame un locataire de build compromis ne peut pas cr\u00e9er de fausse provenance pour un autre projet.<\/li>\n<li>Les builds s&rsquo;ex\u00e9cutent dans des environnements herm\u00e9tiques avec des d\u00e9pendances contr\u00f4l\u00e9es et d\u00e9clar\u00e9es.<\/li>\n<li><strong>Menace trait\u00e9e :<\/strong> Emp\u00eache un build compromis d&rsquo;affecter d&rsquo;autres projets. Emp\u00eache les builds d&rsquo;utiliser des d\u00e9pendances non d\u00e9clar\u00e9es.<\/li>\n<\/ul>\n<h3>Niveau de Build 4 \u2014 Revue \u00e0 deux parties et builds herm\u00e9tiques<\/h3>\n<ul>\n<li>Toutes les modifications de source n\u00e9cessitent une revue \u00e0 deux parties avant d&rsquo;\u00eatre accept\u00e9es dans le build.<\/li>\n<li>Les builds sont enti\u00e8rement herm\u00e9tiques : toutes les d\u00e9pendances sont d\u00e9clar\u00e9es et r\u00e9cup\u00e9r\u00e9es de mani\u00e8re reproductible.<\/li>\n<li>La plateforme de build est enti\u00e8rement isol\u00e9e et auditable.<\/li>\n<li><strong>Menace trait\u00e9e :<\/strong> Emp\u00eache un seul initi\u00e9 d&rsquo;injecter du code malveillant qui est construit et distribu\u00e9.<\/li>\n<\/ul>\n<h3>Sp\u00e9cification de la provenance SLSA<\/h3>\n<p>SLSA d\u00e9finit un format de provenance sp\u00e9cifique qui doit inclure :<\/p>\n<ul>\n<li><strong>Identit\u00e9 du builder :<\/strong> Quelle plateforme de build a produit l&rsquo;artefact (par exemple, GitHub Actions, Google Cloud Build).<\/li>\n<li><strong>Configuration du build :<\/strong> Le point d&rsquo;entr\u00e9e et les param\u00e8tres du build (par exemple, le fichier de workflow, la commande de build).<\/li>\n<li><strong>R\u00e9f\u00e9rence source :<\/strong> Le d\u00e9p\u00f4t source et le digest du commit qui a \u00e9t\u00e9 construit.<\/li>\n<li><strong>Mat\u00e9riaux :<\/strong> Une liste de toutes les entr\u00e9es du build, y compris les d\u00e9pendances et leurs digests.<\/li>\n<li><strong>M\u00e9tadonn\u00e9es :<\/strong> Horodatages, identifiants d&rsquo;invocation et autres m\u00e9tadonn\u00e9es de build.<\/li>\n<\/ul>\n<p>Cette provenance est exprim\u00e9e sous forme de document JSON structur\u00e9, plus pr\u00e9cis\u00e9ment comme une <strong>attestation in-toto<\/strong> \u2014 ce qui nous am\u00e8ne \u00e0 la section suivante.<\/p>\n<h2>Le framework d&rsquo;attestation in-toto<\/h2>\n<p><strong>in-toto<\/strong> est un framework pour s\u00e9curiser les cha\u00eenes d&rsquo;approvisionnement logicielles par le biais de m\u00e9tadonn\u00e9es sign\u00e9es cryptographiquement. Alors que SLSA d\u00e9finit <em>ce que<\/em> la provenance doit contenir et <em>quel niveau de s\u00e9curit\u00e9<\/em> elle fournit, in-toto d\u00e9finit le <em>format de donn\u00e9es et le m\u00e9canisme de signature<\/em> utilis\u00e9s pour repr\u00e9senter et v\u00e9rifier cette provenance.<\/p>\n<h3>Layout et m\u00e9tadonn\u00e9es de lien in-toto<\/h3>\n<p>Dans le mod\u00e8le original d&rsquo;in-toto, une cha\u00eene d&rsquo;approvisionnement est d\u00e9crite par deux types de m\u00e9tadonn\u00e9es :<\/p>\n<ul>\n<li><strong>Layout :<\/strong> Un document sign\u00e9 par le propri\u00e9taire du projet qui d\u00e9finit les \u00e9tapes attendues de la cha\u00eene d&rsquo;approvisionnement, qui est autoris\u00e9 \u00e0 effectuer chaque \u00e9tape, et quelles r\u00e8gles d&rsquo;inspection doivent \u00eatre appliqu\u00e9es lors de la v\u00e9rification.<\/li>\n<li><strong>M\u00e9tadonn\u00e9es de lien :<\/strong> Des preuves sign\u00e9es produites par chaque \u00e9tape de la cha\u00eene d&rsquo;approvisionnement, enregistrant les mat\u00e9riaux (entr\u00e9es) et les produits (sorties) de cette \u00e9tape.<\/li>\n<\/ul>\n<p>Ce mod\u00e8le est puissant pour les cha\u00eenes d&rsquo;approvisionnement multi-\u00e9tapes o\u00f9 vous devez v\u00e9rifier que l&rsquo;\u00e9tape A a produit la sortie X, qui a ensuite \u00e9t\u00e9 consomm\u00e9e par l&rsquo;\u00e9tape B pour produire la sortie Y, chaque \u00e9tape \u00e9tant effectu\u00e9e par un acteur autoris\u00e9.<\/p>\n<h3>Le format d&rsquo;attestation in-toto<\/h3>\n<p>Le format moderne d&rsquo;attestation in-toto (ITE-6) g\u00e9n\u00e9ralise le mod\u00e8le original en un framework flexible et extensible. Une attestation comporte trois couches :<\/p>\n<p><strong>1. Statement :<\/strong> L&rsquo;enveloppe ext\u00e9rieure qui lie un pr\u00e9dicat \u00e0 un ou plusieurs sujets.<\/p>\n<pre><code>{\n  \"_type\": \"https:\/\/in-toto.io\/Statement\/v1\",\n  \"subject\": [\n    {\n      \"name\": \"my-artifact\",\n      \"digest\": {\n        \"sha256\": \"a1b2c3d4e5f6...\"\n      }\n    }\n  ],\n  \"predicateType\": \"https:\/\/slsa.dev\/provenance\/v1\",\n  \"predicate\": { ... }\n}<\/code><\/pre>\n<p><strong>2. Predicate :<\/strong> Les m\u00e9tadonn\u00e9es r\u00e9elles concernant l&rsquo;artefact. Diff\u00e9rents types de pr\u00e9dicats servent diff\u00e9rents objectifs :<\/p>\n<ul>\n<li><code>https:\/\/slsa.dev\/provenance\/v1<\/code> \u2014 Provenance SLSA (informations de build)<\/li>\n<li><code>https:\/\/spdx.dev\/Document<\/code> \u2014 SBOM au format SPDX<\/li>\n<li><code>https:\/\/cyclonedx.org\/bom<\/code> \u2014 SBOM au format CycloneDX<\/li>\n<li><code>https:\/\/in-toto.io\/attestation\/vulns<\/code> \u2014 R\u00e9sultats d&rsquo;analyse de vuln\u00e9rabilit\u00e9s<\/li>\n<\/ul>\n<p><strong>3. Subject :<\/strong> Une ou plusieurs r\u00e9f\u00e9rences d&rsquo;artefacts, chacune identifi\u00e9e par un nom et un ensemble de digests cryptographiques. Cela lie le pr\u00e9dicat \u00e0 des artefacts sp\u00e9cifiques.<\/p>\n<h3>DSSE (Dead Simple Signing Envelope)<\/h3>\n<p>Les attestations in-toto sont encapsul\u00e9es dans un <strong>DSSE<\/strong> (Dead Simple Signing Envelope) pour la signature. DSSE r\u00e9sout plusieurs probl\u00e8mes des approches de signature pr\u00e9c\u00e9dentes :<\/p>\n<pre><code>{\n  \"payloadType\": \"application\/vnd.in-toto+json\",\n  \"payload\": \"&lt;base64-encoded statement&gt;\",\n  \"signatures\": [\n    {\n      \"keyid\": \"...\",\n      \"sig\": \"&lt;base64-encoded signature&gt;\"\n    }\n  ]\n}<\/code><\/pre>\n<p>DSSE signe \u00e0 la fois le type de payload et le payload ensemble (en utilisant un PAE \u2014 Pre-Authentication Encoding), emp\u00eachant les attaques de confusion o\u00f9 une signature pour un type de payload est r\u00e9utilis\u00e9e pour un autre. Il prend en charge les signatures multiples, permettant des sc\u00e9narios de signature multi-parties.<\/p>\n<h3>Comment in-toto se rapporte \u00e0 SLSA<\/h3>\n<p>La relation est simple : <strong>la provenance SLSA est un type de pr\u00e9dicat in-toto<\/strong>. Lorsqu&rsquo;une plateforme de build conforme \u00e0 SLSA g\u00e9n\u00e8re une provenance, elle produit une attestation in-toto avec <code>predicateType: https:\/\/slsa.dev\/provenance\/v1<\/code>, la signe avec DSSE, et l&rsquo;associe \u00e0 l&rsquo;artefact construit via le champ subject. SLSA d\u00e9finit les exigences et le mod\u00e8le de menace ; in-toto fournit le format de donn\u00e9es et le framework de v\u00e9rification.<\/p>\n<h2>G\u00e9n\u00e9ration de la provenance en CI\/CD<\/h2>\n<p>Parcourons les impl\u00e9mentations pratiques dans les plateformes CI\/CD les plus courantes.<\/p>\n<h3>GitHub Actions : slsa-github-generator<\/h3>\n<p>Le projet <code>slsa-framework\/slsa-github-generator<\/code> fournit des workflows r\u00e9utilisables qui g\u00e9n\u00e8rent une provenance SLSA de niveau 3 sur GitHub Actions. La provenance est g\u00e9n\u00e9r\u00e9e par un workflow h\u00e9berg\u00e9 et isol\u00e9 que le locataire du build ne peut pas alt\u00e9rer.<\/p>\n<p><strong>Pour les artefacts g\u00e9n\u00e9riques :<\/strong><\/p>\n<pre><code>name: SLSA Provenance for Generic Artifacts\non:\n  push:\n    tags:\n      - \"v*\"\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    outputs:\n      digests: ${{ steps.hash.outputs.digests }}\n    steps:\n      - uses: actions\/checkout@v4\n      - name: Build artifact\n        run: |\n          go build -o my-binary .\/cmd\/app\n      - name: Generate subject digest\n        id: hash\n        run: |\n          DIGEST=$(sha256sum my-binary | base64 -w0)\n          echo \"digests=$DIGEST\" &gt;&gt; \"$GITHUB_OUTPUT\"\n      - uses: actions\/upload-artifact@v4\n        with:\n          name: my-binary\n          path: my-binary\n\n  provenance:\n    needs: [build]\n    permissions:\n      actions: read\n      id-token: write\n      contents: write\n    uses: slsa-framework\/slsa-github-generator\/.github\/workflows\/generator_generic_slsa3.yml@v2.1.0\n    with:\n      base64-subjects: ${{ needs.build.outputs.digests }}\n      upload-assets: true<\/code><\/pre>\n<p><strong>Pour les images de conteneurs :<\/strong><\/p>\n<pre><code>name: SLSA Provenance for Container Images\non:\n  push:\n    tags:\n      - \"v*\"\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    outputs:\n      image: ${{ steps.build.outputs.image }}\n      digest: ${{ steps.build.outputs.digest }}\n    permissions:\n      packages: write\n    steps:\n      - uses: actions\/checkout@v4\n      - name: Log in to GHCR\n        uses: docker\/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n      - name: Build and push\n        id: build\n        uses: docker\/build-push-action@v5\n        with:\n          push: true\n          tags: ghcr.io\/${{ github.repository }}:${{ github.ref_name }}\n\n  provenance:\n    needs: [build]\n    permissions:\n      actions: read\n      id-token: write\n      packages: write\n    uses: slsa-framework\/slsa-github-generator\/.github\/workflows\/generator_container_slsa3.yml@v2.1.0\n    with:\n      image: ${{ needs.build.outputs.image }}\n      digest: ${{ needs.build.outputs.digest }}\n      registry-username: ${{ github.actor }}\n    secrets:\n      registry-password: ${{ secrets.GITHUB_TOKEN }}<\/code><\/pre>\n<h3>Attestations d&rsquo;artefacts GitHub<\/h3>\n<p>GitHub propose d\u00e9sormais des attestations d&rsquo;artefacts natives via <code>actions\/attest-build-provenance<\/code>. C&rsquo;est plus simple que le g\u00e9n\u00e9rateur SLSA et produit des attestations sign\u00e9es par Sigstore stock\u00e9es dans l&rsquo;API d&rsquo;attestation de GitHub.<\/p>\n<pre><code>name: Build and Attest\non:\n  push:\n    branches: [main]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: write\n      contents: read\n      attestations: write\n    steps:\n      - uses: actions\/checkout@v4\n      - name: Build binary\n        run: go build -o my-binary .\/cmd\/app\n      - name: Attest build provenance\n        uses: actions\/attest-build-provenance@v2\n        with:\n          subject-path: my-binary\n      - name: Attest container image\n        uses: actions\/attest-build-provenance@v2\n        with:\n          subject-name: ghcr.io\/${{ github.repository }}\n          subject-digest: ${{ steps.push.outputs.digest }}\n          push-to-registry: true<\/code><\/pre>\n<h3>GitLab CI : G\u00e9n\u00e9ration de m\u00e9tadonn\u00e9es de provenance<\/h3>\n<p>GitLab ne dispose pas encore d&rsquo;un g\u00e9n\u00e9rateur de provenance SLSA natif au m\u00eame niveau de maturit\u00e9 que celui de GitHub, mais vous pouvez g\u00e9n\u00e9rer et signer des m\u00e9tadonn\u00e9es de provenance en utilisant directement les outils du framework SLSA.<\/p>\n<pre><code>stages:\n  - build\n  - provenance\n\nbuild:\n  stage: build\n  image: golang:1.22\n  script:\n    - go build -o my-binary .\/cmd\/app\n    - sha256sum my-binary &gt; checksums.txt\n  artifacts:\n    paths:\n      - my-binary\n      - checksums.txt\n\ngenerate-provenance:\n  stage: provenance\n  image: ghcr.io\/slsa-framework\/slsa-generator-generic:v2.1.0\n  needs: [build]\n  script:\n    - |\n      cat &gt; provenance.json &lt;&lt;PROV\n      {\n        \"_type\": \"https:\/\/in-toto.io\/Statement\/v1\",\n        \"subject\": [\n          {\n            \"name\": \"my-binary\",\n            \"digest\": {\n              \"sha256\": \"$(sha256sum my-binary | awk '{print $1}')\"\n            }\n          }\n        ],\n        \"predicateType\": \"https:\/\/slsa.dev\/provenance\/v1\",\n        \"predicate\": {\n          \"buildDefinition\": {\n            \"buildType\": \"https:\/\/gitlab.com\/gitlab-ci\",\n            \"externalParameters\": {\n              \"repository\": \"${CI_PROJECT_URL}\",\n              \"ref\": \"${CI_COMMIT_SHA}\"\n            }\n          },\n          \"runDetails\": {\n            \"builder\": {\n              \"id\": \"https:\/\/gitlab.com\/${CI_PROJECT_PATH}\/-\/runners\/${CI_RUNNER_ID}\"\n            },\n            \"metadata\": {\n              \"invocationId\": \"${CI_PIPELINE_URL}\",\n              \"startedOn\": \"${CI_PIPELINE_CREATED_AT}\"\n            }\n          }\n        }\n      }\n      PROV\n    - cosign attest-blob --predicate provenance.json --type slsaprovenance my-binary\n  artifacts:\n    paths:\n      - provenance.json<\/code><\/pre>\n<h3>Stockage de la provenance dans les registres OCI<\/h3>\n<p>Pour les images de conteneurs, les attestations de provenance sont g\u00e9n\u00e9ralement stock\u00e9es aux c\u00f4t\u00e9s de l&rsquo;image dans le registre OCI en utilisant le mod\u00e8le d&rsquo;attestation Cosign. L&rsquo;attestation est stock\u00e9e comme un artefact OCI s\u00e9par\u00e9 li\u00e9 \u00e0 l&rsquo;image par son digest :<\/p>\n<pre><code># Attacher la provenance \u00e0 une image de conteneur dans le registre\ncosign attest --predicate provenance.json \\\n  --type slsaprovenance \\\n  --key cosign.key \\\n  ghcr.io\/myorg\/myimage@sha256:abc123...\n\n# Pour la signature sans cl\u00e9 avec Sigstore\ncosign attest --predicate provenance.json \\\n  --type slsaprovenance \\\n  --yes \\\n  ghcr.io\/myorg\/myimage@sha256:abc123...<\/code><\/pre>\n<p>Cette approche tire parti de l&rsquo;API referrers de la sp\u00e9cification de distribution OCI, qui permet aux clients de d\u00e9couvrir les attestations associ\u00e9es \u00e0 un manifeste d&rsquo;image donn\u00e9. Des outils comme <code>cosign<\/code> et <code>crane<\/code> peuvent alors r\u00e9cup\u00e9rer et v\u00e9rifier ces attestations lors du d\u00e9ploiement.<\/p>\n<h2>V\u00e9rification de la provenance<\/h2>\n<p>G\u00e9n\u00e9rer la provenance n&rsquo;est que la moiti\u00e9 de l&rsquo;histoire. Les consommateurs \u2014 qu&rsquo;il s&rsquo;agisse d&rsquo;op\u00e9rateurs humains ou de syst\u00e8mes automatis\u00e9s \u2014 doivent v\u00e9rifier la provenance avant de faire confiance \u00e0 un artefact.<\/p>\n<h3>CLI slsa-verifier<\/h3>\n<p>L&rsquo;outil <code>slsa-verifier<\/code> v\u00e9rifie la provenance SLSA g\u00e9n\u00e9r\u00e9e par des builders de confiance (actuellement les builders bas\u00e9s sur GitHub Actions).<\/p>\n<pre><code># V\u00e9rifier un artefact g\u00e9n\u00e9rique\nslsa-verifier verify-artifact my-binary \\\n  --provenance-path my-binary.intoto.jsonl \\\n  --source-uri github.com\/myorg\/myrepo \\\n  --source-tag v1.2.3\n\n# V\u00e9rifier une image de conteneur\nslsa-verifier verify-image ghcr.io\/myorg\/myimage@sha256:abc123... \\\n  --source-uri github.com\/myorg\/myrepo \\\n  --source-tag v1.2.3<\/code><\/pre>\n<p>Le v\u00e9rificateur contr\u00f4le les \u00e9l\u00e9ments suivants :<\/p>\n<ul>\n<li>La signature de la provenance est valide et remonte \u00e0 une racine de confiance (Sigstore pour les builders GitHub Actions).<\/li>\n<li>L&rsquo;identit\u00e9 du builder correspond \u00e0 un builder de confiance connu.<\/li>\n<li>Le d\u00e9p\u00f4t source correspond au d\u00e9p\u00f4t attendu.<\/li>\n<li>Le digest de l&rsquo;artefact correspond au sujet dans la provenance.<\/li>\n<\/ul>\n<h3>cosign verify-attestation<\/h3>\n<p>Pour une v\u00e9rification plus flexible, <code>cosign verify-attestation<\/code> vous permet de v\u00e9rifier les attestations in-toto attach\u00e9es aux images de conteneurs avec filtrage par type :<\/p>\n<pre><code># V\u00e9rifier l'attestation de provenance SLSA\ncosign verify-attestation \\\n  --type slsaprovenance \\\n  --certificate-identity \"https:\/\/github.com\/myorg\/myrepo\/.github\/workflows\/release.yml@refs\/tags\/v1.2.3\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myimage@sha256:abc123...\n\n# V\u00e9rifier avec une politique CUE\ncosign verify-attestation \\\n  --type slsaprovenance \\\n  --policy policy.cue \\\n  ghcr.io\/myorg\/myimage@sha256:abc123...\n\n# V\u00e9rifier avec une politique Rego\ncosign verify-attestation \\\n  --type slsaprovenance \\\n  --policy policy.rego \\\n  ghcr.io\/myorg\/myimage@sha256:abc123...<\/code><\/pre>\n<h3>gh attestation verify<\/h3>\n<p>Pour les artefacts attest\u00e9s avec la fonctionnalit\u00e9 d&rsquo;attestation native de GitHub, le CLI <code>gh<\/code> fournit une v\u00e9rification int\u00e9gr\u00e9e :<\/p>\n<pre><code># V\u00e9rifier un artefact local\ngh attestation verify my-binary \\\n  --owner myorg\n\n# V\u00e9rifier une image de conteneur\ngh attestation verify oci:\/\/ghcr.io\/myorg\/myimage@sha256:abc123... \\\n  --owner myorg\n\n# T\u00e9l\u00e9charger et inspecter le bundle d'attestation\ngh attestation download my-binary \\\n  --owner myorg \\\n  --output attestation.jsonl<\/code><\/pre>\n<h3>Provenance dans les contr\u00f4leurs d&rsquo;admission<\/h3>\n<p>Pour les portes de d\u00e9ploiement en production, les contr\u00f4leurs d&rsquo;admission peuvent appliquer automatiquement des politiques de provenance. Voici un exemple utilisant le policy-controller de Sigstore dans un cluster Kubernetes :<\/p>\n<pre><code>apiVersion: policy.sigstore.dev\/v1beta1\nkind: ClusterImagePolicy\nmetadata:\n  name: require-slsa-provenance\nspec:\n  images:\n    - glob: \"ghcr.io\/myorg\/**\"\n  authorities:\n    - keyless:\n        url: https:\/\/fulcio.sigstore.dev\n        identities:\n          - issuer: https:\/\/token.actions.githubusercontent.com\n            subject: \"https:\/\/github.com\/myorg\/*\"\n      attestations:\n        - name: must-have-slsa-provenance\n          predicateType: https:\/\/slsa.dev\/provenance\/v1\n          policy:\n            type: cue\n            data: |\n              predicateType: \"https:\/\/slsa.dev\/provenance\/v1\"\n              predicate: buildDefinition: {\n                buildType: =~\"^https:\/\/github.com\/slsa-framework\/slsa-github-generator\/\"\n              }<\/code><\/pre>\n<h3>Que v\u00e9rifier lors de la validation<\/h3>\n<p>Quel que soit l&rsquo;outil utilis\u00e9, la v\u00e9rification de la provenance doit confirmer :<\/p>\n<ul>\n<li><strong>Identit\u00e9 du builder :<\/strong> L&rsquo;artefact a-t-il \u00e9t\u00e9 construit par une plateforme de build de confiance ? V\u00e9rifiez l&rsquo;identifiant du builder dans la provenance par rapport \u00e0 une liste blanche connue.<\/li>\n<li><strong>D\u00e9p\u00f4t source :<\/strong> La provenance fait-elle r\u00e9f\u00e9rence au d\u00e9p\u00f4t source et au commit attendus ? Cela emp\u00eache les artefacts provenant de forks ou de d\u00e9p\u00f4ts non autoris\u00e9s d&rsquo;\u00eatre d\u00e9ploy\u00e9s.<\/li>\n<li><strong>D\u00e9clencheurs de build :<\/strong> Le build a-t-il \u00e9t\u00e9 d\u00e9clench\u00e9 par un \u00e9v\u00e9nement attendu (push vers un tag de release, merge vers main) ? Cela d\u00e9tecte les artefacts construits \u00e0 partir de branches ou d&rsquo;\u00e9v\u00e9nements inattendus.<\/li>\n<li><strong>Digest de l&rsquo;artefact :<\/strong> L&rsquo;artefact que vous v\u00e9rifiez correspond-il au digest du sujet dans la provenance ? C&rsquo;est la v\u00e9rification fondamentale d&rsquo;int\u00e9grit\u00e9.<\/li>\n<li><strong>Fra\u00eecheur de la provenance :<\/strong> La provenance est-elle r\u00e9cente ? Une provenance obsol\u00e8te pour d&rsquo;anciens builds peut ne pas refl\u00e9ter la posture de s\u00e9curit\u00e9 actuelle.<\/li>\n<\/ul>\n<h2>D\u00e9fis pratiques<\/h2>\n<p>La provenance et SLSA sont des concepts puissants, mais l&rsquo;adoption dans le monde r\u00e9el s&rsquo;accompagne de d\u00e9fis significatifs. Une \u00e9valuation honn\u00eate aide les \u00e9quipes \u00e0 planifier des strat\u00e9gies d&rsquo;adoption r\u00e9alistes.<\/p>\n<h3>Atteindre le niveau SLSA 3+ est difficile<\/h3>\n<p>Le niveau SLSA 3 exige des environnements de build renforc\u00e9s et isol\u00e9s \u2014 et c&rsquo;est l\u00e0 que la plupart des organisations rencontrent des frictions. Les builds herm\u00e9tiques signifient que chaque d\u00e9pendance doit \u00eatre explicitement d\u00e9clar\u00e9e et r\u00e9cup\u00e9r\u00e9e via des canaux contr\u00f4l\u00e9s. Pas de t\u00e9l\u00e9chargement de packages al\u00e9atoires depuis Internet pendant le build. Pas d&rsquo;acc\u00e8s r\u00e9seau \u00e0 des services non d\u00e9clar\u00e9s.<\/p>\n<p>Pour de nombreux projets, cela n\u00e9cessite des changements fondamentaux dans le fonctionnement des builds. Les langages avec des \u00e9cosyst\u00e8mes de packages riches (Node.js, Python, Go) ont souvent des processus de build qui t\u00e9l\u00e9chargent implicitement des d\u00e9pendances. Passer \u00e0 un mod\u00e8le herm\u00e9tique signifie vendoriser les d\u00e9pendances, utiliser des fichiers de verrouillage avec des v\u00e9rifications d&rsquo;int\u00e9grit\u00e9, ou ex\u00e9cuter les builds derri\u00e8re un proxy de d\u00e9pendances qui applique une liste blanche.<\/p>\n<p>Les builders isol\u00e9s ajoutent un co\u00fbt op\u00e9rationnel. Les environnements de build \u00e9ph\u00e9m\u00e8res qui sont d\u00e9truits apr\u00e8s chaque build emp\u00eachent la contamination crois\u00e9e mais augmentent les temps de build et les d\u00e9penses d&rsquo;infrastructure. Les runners auto-h\u00e9berg\u00e9s sur GitHub Actions, par exemple, ne fournissent pas les m\u00eames garanties d&rsquo;isolation que les runners h\u00e9berg\u00e9s par GitHub.<\/p>\n<h3>Maturit\u00e9 de l&rsquo;outillage et lacunes de l&rsquo;\u00e9cosyst\u00e8me<\/h3>\n<p>L&rsquo;\u00e9cosyst\u00e8me SLSA m\u00fbrit rapidement mais pr\u00e9sente encore des lacunes :<\/p>\n<ul>\n<li><strong>Les builders de confiance sont limit\u00e9s.<\/strong> \u00c0 ce jour, les g\u00e9n\u00e9rateurs de provenance SLSA de niveau 3 existent principalement pour GitHub Actions. GitLab, Jenkins, CircleCI et d&rsquo;autres plateformes disposent de solutions moins matures ou maintenues par la communaut\u00e9.<\/li>\n<li><strong>L&rsquo;outillage de v\u00e9rification est fragment\u00e9.<\/strong> Diff\u00e9rents outils v\u00e9rifient diff\u00e9rents formats de provenance, et il n&rsquo;existe pas de commande universelle \u00ab v\u00e9rifier toute provenance \u00bb. Les \u00e9quipes ont souvent besoin de plusieurs outils dans leur pipeline de v\u00e9rification.<\/li>\n<li><strong>Les langages de politique varient.<\/strong> Certains outils utilisent CUE, d&rsquo;autres utilisent Rego, et les contr\u00f4leurs d&rsquo;admission Kubernetes ont chacun leur propre format de politique. La standardisation est encore en cours.<\/li>\n<\/ul>\n<h3>Provenance pour les artefacts non-conteneurs<\/h3>\n<p>Alors que la provenance des images de conteneurs dispose d&rsquo;un mod\u00e8le clair de stockage et de distribution (registres OCI et referrers), d&rsquo;autres types d&rsquo;artefacts font face \u00e0 des d\u00e9fis :<\/p>\n<ul>\n<li><strong>Packages npm :<\/strong> npm prend en charge la provenance depuis mai 2023, g\u00e9n\u00e9r\u00e9e automatiquement pour les packages publi\u00e9s depuis GitHub Actions. Cependant, l&rsquo;outillage de v\u00e9rification c\u00f4t\u00e9 consommateur est encore limit\u00e9.<\/li>\n<li><strong>Packages Python (PyPI) :<\/strong> PyPI travaille sur le support des attestations avec les Trusted Publishers, mais l&rsquo;\u00e9cosyst\u00e8me en est encore au d\u00e9but de l&rsquo;adoption.<\/li>\n<li><strong>Artefacts Maven :<\/strong> La provenance de l&rsquo;\u00e9cosyst\u00e8me Java est moins mature. Des projets comme Sigstore pour Java \u00e9mergent, mais une adoption g\u00e9n\u00e9ralis\u00e9e n\u00e9cessite le support des registres.<\/li>\n<li><strong>Binaires g\u00e9n\u00e9riques :<\/strong> Pour les binaires autonomes, la provenance est g\u00e9n\u00e9ralement livr\u00e9e sous forme de fichier annexe (.intoto.jsonl) aux c\u00f4t\u00e9s du binaire dans les assets de release. Cela fonctionne mais n\u00e9cessite que les consommateurs sachent o\u00f9 la trouver et comment la v\u00e9rifier.<\/li>\n<\/ul>\n<h3>\u00c9quilibrer la rigueur et la v\u00e9locit\u00e9 des d\u00e9veloppeurs<\/h3>\n<p>Des exigences strictes de provenance peuvent ralentir les workflows de d\u00e9veloppement :<\/p>\n<ul>\n<li><strong>D\u00e9veloppement local :<\/strong> Les d\u00e9veloppeurs ont besoin de tester les builds localement, mais les builds locaux ne peuvent pas produire une provenance SLSA de niveau 2+. Les \u00e9quipes doivent distinguer les \u00ab builds de d\u00e9veloppement \u00bb des \u00ab builds de release \u00bb sans cr\u00e9er un processus si complexe que les d\u00e9veloppeurs le contournent.<\/li>\n<li><strong>Adoption incr\u00e9mentale :<\/strong> Passer de z\u00e9ro provenance au niveau SLSA 3 en une seule \u00e9tape est rarement faisable. Les \u00e9quipes qui essaient abandonnent souvent l&rsquo;effort. Une approche progressive \u2014 niveau 1 d&rsquo;abord, puis niveau 2, puis niveau 3 pour les chemins critiques \u2014 est plus durable.<\/li>\n<li><strong>Reproductibilit\u00e9 des builds :<\/strong> La provenance vous dit comment quelque chose a \u00e9t\u00e9 construit, mais elle ne garantit pas que les m\u00eames entr\u00e9es produisent toujours la m\u00eame sortie. Les builds non reproductibles rendent plus difficile la v\u00e9rification ind\u00e9pendante des affirmations de provenance.<\/li>\n<li><strong>D\u00e9ploiements d&rsquo;urgence :<\/strong> Dans les sc\u00e9narios de r\u00e9ponse aux incidents, les \u00e9quipes peuvent avoir besoin de d\u00e9ployer rapidement \u00e0 partir de chemins de build non standards. Les politiques de provenance ont besoin de m\u00e9canismes d&rsquo;\u00e9chappement (avec une journalisation et des pistes d&rsquo;audit appropri\u00e9es) pour \u00e9viter de bloquer les correctifs critiques.<\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>La provenance des artefacts comble une lacune fondamentale dans la s\u00e9curit\u00e9 de la cha\u00eene d&rsquo;approvisionnement logicielle. Alors que les signatures prouvent <em>qui<\/em> a approuv\u00e9 un artefact, la provenance prouve <em>comment il a r\u00e9ellement \u00e9t\u00e9 construit<\/em>. Combin\u00e9e au mod\u00e8le de maturit\u00e9 du framework SLSA et au format d&rsquo;attestation d&rsquo;in-toto, nous disposons d\u00e9sormais d&rsquo;une approche pratique et standardis\u00e9e pour l&rsquo;int\u00e9grit\u00e9 des builds.<\/p>\n<p>Les points cl\u00e9s pour les \u00e9quipes qui d\u00e9butent ce parcours :<\/p>\n<ul>\n<li><strong>Commencez au niveau SLSA 1.<\/strong> G\u00e9n\u00e9rez des m\u00e9tadonn\u00e9es de provenance pour vos builds, m\u00eame si elles ne sont pas encore sign\u00e9es par la plateforme de build. Cela vous donne l&rsquo;auditabilit\u00e9 et \u00e9tablit la pratique.<\/li>\n<li><strong>Passez au niveau 2 avec des builders h\u00e9berg\u00e9s.<\/strong> Utilisez GitHub Actions, Google Cloud Build ou une autre plateforme h\u00e9berg\u00e9e qui peut signer la provenance en votre nom. C&rsquo;est \u00e0 ce stade que la provenance devient significativement v\u00e9rifiable.<\/li>\n<li><strong>Visez le niveau 3 pour les chemins critiques.<\/strong> Pour vos artefacts les plus sensibles \u2014 images de conteneurs de production, releases sign\u00e9es, biblioth\u00e8ques critiques pour la s\u00e9curit\u00e9 \u2014 investissez dans les builds herm\u00e9tiques et les environnements de build isol\u00e9s.<\/li>\n<li><strong>V\u00e9rifiez la provenance dans votre pipeline de d\u00e9ploiement.<\/strong> G\u00e9n\u00e9rer la provenance sans la v\u00e9rifier est du th\u00e9\u00e2tre de s\u00e9curit\u00e9. Ajoutez la v\u00e9rification \u00e0 vos contr\u00f4leurs d&rsquo;admission, scripts de d\u00e9ploiement ou workflows GitOps bas\u00e9s sur le pull.<\/li>\n<li><strong>Adoptez les attestations in-toto comme format de m\u00e9tadonn\u00e9es.<\/strong> Le format d&rsquo;attestation in-toto est en passe de devenir le standard pour les m\u00e9tadonn\u00e9es de la cha\u00eene d&rsquo;approvisionnement, prenant en charge non seulement la provenance SLSA mais aussi les SBOM, les analyses de vuln\u00e9rabilit\u00e9s et les pr\u00e9dicats personnalis\u00e9s.<\/li>\n<\/ul>\n<p>La s\u00e9curit\u00e9 de la cha\u00eene d&rsquo;approvisionnement n&rsquo;est pas un outil unique ou un contr\u00f4le unique. C&rsquo;est une approche en couches o\u00f9 chaque contr\u00f4le \u2014 int\u00e9grit\u00e9 de la source, int\u00e9grit\u00e9 du build, provenance, v\u00e9rification \u2014 renforce les autres. La provenance est le tissu conjonctif qui rend l&rsquo;ensemble du syst\u00e8me auditable et v\u00e9rifiable. Commencez \u00e0 la g\u00e9n\u00e9rer d\u00e8s aujourd&rsquo;hui, et it\u00e9rez vers le haut.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction La signature de code est depuis longtemps un pilier de la s\u00e9curit\u00e9 logicielle. Lorsque vous v\u00e9rifiez une signature, vous savez qui a sign\u00e9 un artefact. Mais savoir qui a sign\u00e9 quelque chose ne vous dit pas comment il a \u00e9t\u00e9 construit, o\u00f9 il a \u00e9t\u00e9 construit, ni quel code source a \u00e9t\u00e9 utilis\u00e9. Un &#8230; <a title=\"Provenance des Artefacts et Attestations : De SLSA \u00e0 in-toto\" class=\"read-more\" href=\"https:\/\/secure-pipelines.com\/fr\/ci-cd-security\/artifact-provenance-attestations-slsa-in-toto-2\/\" aria-label=\"En savoir plus sur Provenance des Artefacts et Attestations : De SLSA \u00e0 in-toto\">Lire la suite<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49,50],"tags":[],"post_folder":[],"class_list":["post-489","post","type-post","status-publish","format-standard","hentry","category-ci-cd-security","category-software-supply-chain"],"_links":{"self":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/489","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/comments?post=489"}],"version-history":[{"count":1,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/489\/revisions"}],"predecessor-version":[{"id":490,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/489\/revisions\/490"}],"wp:attachment":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/media?parent=489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/categories?post=489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/tags?post=489"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/post_folder?post=489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}