BénéficesDoc CLIVersion 0.1Démarrer

Continuum Academy · Chapitre 01

Du code source au logiciel livré : où est la preuve ?

Un fournisseur vous livre payment-service-4.7.2.tar.gz. Vous conservez l’archive, sa version et son SHA-256. Quelques semaines plus tard, quelqu’un demande : « Pouvez-vous démontrer que cette archive a bien été produite à partir du code validé ? » Ouvrons le dossier de livraison et voyons ce qui permettrait de répondre.

1 — Un fichier livré n'emporte pas son histoire avec lui

L’archive est là. Vous pouvez la copier, inspecter son contenu, éventuellement lancer le programme qu’elle contient. Vous disposez d’un résultat de fabrication : un artefact logiciel. Ce pourrait aussi être un binaire, un paquet d’installation ou une image de conteneur.

Son nom suggère un service de paiement en version 4.7.2. Il ne démontre pourtant pas son origine. Une autre archive peut recevoir exactement ce nom. Un fichier de version placé à l’intérieur ajoute une indication, mais quelqu’un a nécessairement écrit cette indication : elle reste à examiner.

Pour retrouver le chemin du code validé jusqu’à cette archive, il manque plusieurs réponses :

  • Quel dépôt a fourni les sources ? Quel commit, c’est-à-dire quelle révision enregistrée du code ?
  • Quel builder, le système qui fabrique le logiciel, a exécuté le travail ? Quel processus de build a-t-il suivi ?
  • Quelles dépendances et quel environnement ont participé à la fabrication ?
  • Qui affirme ces informations ? L’affirmation a-t-elle été modifiée ? Peut-elle être vérifiée indépendamment du système qui l’a produite ?

Un fichier, une histoire à établir

Le nom de l’archive ne répond pas aux questions sur son origine.

Autour du fichier, trois ensembles de questions restent ouverts : les sources utilisées, les conditions de fabrication et la personne ou le système qui porte l’affirmation.

Un lien vers une compilation réussie peut aider à retrouver ces réponses. Mais si l’accès disparaît ou si les journaux sont supprimés, que reste-t-il au destinataire ? Et même avec le lien, comment établir que l’archive sur son disque est bien celle de cette compilation ? Commençons par cette question plus petite.

2 — Commençons par son empreinte

Nous voulons comparer le contenu reçu à un contenu de référence. SHA-256 réalise un calcul sur les octets du fichier et produit une valeur de longueur fixe : son empreinte, appelée aussi hash ou digest.

SHA256(payment-service-4.7.2.tar.gz)
→ 3a16...9f21

Les empreintes de ce chapitre sont fictives et abrégées. Un SHA-256 complet comporte 64 caractères hexadécimaux ; les points de suspension ne sont pas une valeur utilisable pour une vérification réelle.

Le hash répond à la question : est-ce le même contenu ?

Calculez l’empreinte de la copie reçue et comparez-la à la référence. Des valeurs différentes indiquent des contenus différents. Avec SHA-256 utilisé correctement, une correspondance permet en pratique de reconnaître le contenu attendu. Le nom du fichier ne participe pas au calcul de l’empreinte de ses octets.

Même nom, contenu différent

Une modification des octets peut se détecter par comparaison des empreintes. Valeurs fictives et abrégées.

La référence reste 3a16...9f21. Dans cette illustration, l’archive modifiée donne 7b04...e812 : les contenus diffèrent, même si le nom reste identique. Cela ne renseigne pas sur leur origine.

Dans la séquence, le fichier conserve son nom mais un octet change. Le résultat devient 7b04...e812 : la comparaison échoue. Renommer l’archive intacte aurait donné le résultat inverse : un autre nom, mais la même empreinte.

Nous ne savons toujours pas quel code a produit ces octets. Autre limite : si quelqu’un remplace ensemble l’archive et l’empreinte publiée à côté, leur comparaison peut réussir. Le calcul ne choisit pas une référence digne de confiance à notre place.

3 — Nous avons besoin d'une affirmation

Demandons maintenant au fournisseur : « À partir de quoi ce fichier a-t-il été fabriqué ? » Sa réponse pourrait être : « Cet artefact a été produit à partir du dépôt du service de paiement, à la révision approuvée, par notre système de build. »

Cette réponse est une affirmation. Conservons-la dans un document extérieur à l’archive, que le destinataire pourra lire sans exécuter le logiciel. Nous appellerons cette déclaration un statement.

Pour qu’un outil puisse la contrôler, remplaçons les expressions vagues par des valeurs précises. « La version approuvée » devient une révision identifiable. « Ce fichier » devient un contenu désigné par son empreinte. Le document doit permettre de poser des questions auxquelles on peut répondre par comparaison.

Nous construisons ainsi une attestation : un document portant une déclaration sur un artefact identifié. Elle pourra être signée pour authentifier cette déclaration. Un document structuré, même bien présenté, ne prouve pas encore qui l’a écrit ni si son récit est exact.

Le besoin précède donc le format : nous voulons conserver une affirmation précise, la rattacher au bon fichier et donner au destinataire les moyens de l’examiner.

4 — Désigner précisément l'artefact

Écrivons d’abord la partie qui indique de quel fichier nous parlons :

{
  "subject": [{
    "name": "payment-service-4.7.2.tar.gz",
    "digest": {
      "sha256": "3a16...9f21"
    }
  }]
}

Ce fragment JSON est pédagogique, incomplet et contient une empreinte abrégée. Il ne faut pas l’envoyer tel quel à un outil de vérification.

subject, le « sujet », contient la liste des artefacts concernés. Nous n’avons qu’une archive, mais un même build pourrait produire plusieurs fichiers. name aide le lecteur à reconnaître celui qu’il cherche. digest associe un algorithme, ici sha256, à l’empreinte attendue.

Le nom facilite la lecture ; l’empreinte permet la comparaison du contenu. Si votre fichier s’appelle désormais livraison.tar.gz, ses octets peuvent toujours correspondre au sujet déclaré. À l’inverse, le nom attendu accompagné d’une autre empreinte signale une différence.

Nous disposons d’un premier lien vérifiable : « cette déclaration concerne ce contenu ». Il ne raconte pas encore la fabrication. Une déclaration authentique qui concerne une autre archive ne répondrait pas à notre question de départ.

5 — Raconter sa fabrication

Ajoutons maintenant les éléments qui permettraient de retrouver le travail du fournisseur. Voici une fiche d’exemple, sans prétendre reproduire le schéma d’un standard :

Information enregistrée Valeur illustrative Question correspondante
Dépôt source https://git.example.org/payments/payment-service Où sont les sources déclarées ?
Commit 7d34a8b4e1f98c2040e9844ab754ae068943bb16 Quelle révision précise ?
Builder payments-release-builder Quel système a fabriqué le logiciel ?
Processus de build release/build.yml, dans cette révision Quelles instructions ont été utilisées ?
Résultat L’archive de digest 3a16...9f21 Quel contenu est sorti du build ?

Relier le résultat à sa fabrication

La déclaration conserve un lien entre les sources, le travail exécuté et l’artefact produit.

Source et commit → build → artefact → statement. Le document associe l’empreinte de l’archive au dépôt, au commit, au builder et au processus déclarés. Cette relation doit encore être authentifiée et évaluée.

La fiche relie des entrées, une exécution et un résultat. Le commit identifie une révision ; il ne dit pas à lui seul qu’elle a été approuvée. Pour cela, le destinataire devra retrouver une décision de validation concernant cette même révision.

Les dépendances et l’environnement comptent aussi. Deux builds du même commit peuvent produire des fichiers différents si le compilateur ou une bibliothèque téléchargée a changé. Un fichier de verrouillage et une version précise de l’environnement peuvent aider à expliquer cet écart.

La bonne question n’est donc pas seulement « y a-t-il un document ? », mais « qu’a-t-il effectivement enregistré ? ». Si une dépendance n’y figure pas, son identité reste inconnue dans ce dossier. Si le document cite un script, il faut pouvoir retrouver la version du script réellement déclarée.

6 — Qui porte cette affirmation ?

Nous pouvons lire le récit du build. Reste à savoir s’il vient bien de l’émetteur attendu et s’il a changé depuis. C’est le rôle d’une signature numérique.

Le signataire utilise une clé privée, qu’il conserve secrète, pour signer le contenu défini par le format. Le destinataire utilise la clé publique correspondante pour contrôler la signature. Il n’a pas besoin de la clé privée et ne doit pas la recevoir.

Vérifier une signature, évaluer une affirmation

La clé privée sert à signer. La clé publique permet au destinataire de contrôler la signature.

Statement → signature avec la clé privée → contrôle avec la clé publique. Une signature valide protège le contenu signé et le relie à une clé ; accepter cette clé exige un modèle de confiance. SIGNED ≠ TRUE : la signature ne garantit pas la vérité de l’affirmation.

Une signature valide établit un lien cryptographique entre le contenu signé et une clé, sous les hypothèses du mécanisme utilisé. Elle permet de détecter une modification de ce contenu. Elle ne confirme pas que l’événement raconté s’est réellement produit.

SIGNED ≠ TRUE — Signé ne signifie pas vrai.

Il faut encore décider quelles clés sont acceptées, pour quel usage et à quelles conditions : c’est un modèle de confiance. Une clé fournie dans le dossier n’est pas automatiquement celle du fournisseur attendu. Son approbation, sa période d’utilisation et les informations de révocation demandent un examen distinct.

Considérez deux modifications. Si quelqu’un remplace le commit dans le document signé, le contrôle de signature peut échouer. Si quelqu’un modifie seulement l’archive, la signature du document intact peut rester valide ; c’est la comparaison des empreintes qui échoue. Ces contrôles répondent à deux questions différentes.

7 — De l'affirmation à la provenance

Revenons au document : il désigne un fichier et décrit les sources, le système et le processus qui l’auraient produit. Cette information sur la fabrication s’appelle la provenance.

La provenance décrit des informations vérifiables sur la manière dont un artefact logiciel a été produit.

« Vérifiables » ne signifie pas que chaque événement peut être observé de nouveau. Le destinataire peut contrôler la signature, le lien au fichier et la correspondance des valeurs déclarées avec ses attentes. La fiabilité de l’enregistrement reste une hypothèse à examiner.

SLSA Provenance fournit un format commun pour certaines de ces informations. Au lieu d’inventer une fiche différente pour chaque fournisseur, des outils peuvent échanger une description structurée du build. Utiliser ce format ne démontre pas, à lui seul, un niveau SLSA. Nous étudierons ce standard dans un chapitre dédié.

8 — Où intervient in-toto ?

Nous avons construit une déclaration avant de lui donner un format d’échange. Le cadre d’attestation in-toto fournit notamment une structure appelée Statement. Pour commencer, retenons trois éléments :

Champ Rôle dans notre exemple
subject Désigne l’archive par son empreinte.
predicateType Indique quelle sorte d’affirmation le document contient.
predicate Porte les informations propres à cette affirmation, ici la fabrication.

Le Statement in-toto et la signature sont des couches distinctes. Reconnaître ces champs dans du JSON n’équivaut pas à vérifier une signature. Le chapitre 03 détaillera leur assemblage ; le guide in-toto existant constitue une référence complémentaire sur l’échange de reçus.

9 — Ce que nous pouvons maintenant vérifier

Notre dossier contient davantage qu’une archive et son nom. Chaque élément répond à une question particulière :

Éléments disponibles Ce qu’ils apportent au contrôle
Artefact seul Un contenu à examiner, avec peu d’informations d’origine établies par lui-même.
Artefact + hash de référence Une comparaison d’identité et d’intégrité du contenu, si la référence est fiable.
Artefact + attestation Une affirmation structurée qui désigne le contenu concerné.
Attestation + signature Une affirmation contrôlable cryptographiquement selon un modèle de confiance.
Provenance Des informations structurées sur la fabrication, à confronter aux attentes du destinataire.

Reprenons la demande : « cette archive vient-elle du code validé ? ». Il faut comparer son empreinte au sujet déclaré, vérifier la signature avec une clé acceptée, puis rapprocher le commit déclaré du commit approuvé. Il faut aussi avoir une raison de faire confiance au système qui a enregistré le build.

Un résultat utile pourrait dire : « empreinte correspondante ; signature valide ; commit différent de celui approuvé ». Les deux premiers contrôles réussissent, mais la livraison ne répond pas à l’attente. Vérifier ne consiste pas seulement à obtenir une coche verte.

Ces contrôles peuvent s’exécuter sans accès au système de build si les documents, les fichiers et les éléments de confiance nécessaires ont été conservés. Leur indépendance opérationnelle ne rend pas l’enregistrement du fournisseur infaillible.

10 — Ce que nous n'avons PAS prouvé

Même avec des empreintes correspondantes, une signature valide et le commit attendu, nous n’avons pas automatiquement prouvé :

  • L’absence de vulnérabilités. Le code approuvé peut contenir une faille.
  • L’absence de compromission du builder. Un système compromis peut enregistrer une fabrication trompeuse.
  • La vérité absolue des informations déclarées. La signature protège une affirmation ; elle ne constate pas les événements à notre place.
  • La sécurité des dépendances. Connaître l’identité d’une bibliothèque ne démontre pas qu’elle est sûre.
  • La conformité réglementaire. Celle-ci dépend d’exigences et d’éléments que ce document ne couvre pas nécessairement.
  • La confiance intrinsèque dans le signataire. Accepter sa clé est une décision, pas une conséquence automatique du calcul cryptographique.

La cryptographie peut rendre une affirmation vérifiable. Elle ne transforme pas une affirmation en vérité.

La portée du résultat doit rester explicite : quel fichier, quelle déclaration, quelle clé, quelles attentes, quels contrôles ? « Les contrôles définis pour cette livraison réussissent » est une conclusion examinable. Elle ne signifie pas « ce logiciel est sûr dans tous les contextes ».

11 — Et Continuum Attest ?

Continuum Attest automatise l’enregistrement d’étapes de fabrication et des empreintes des entrées et sorties déclarées dans un reçu. La signature s’active explicitement. Le reçu peut être conservé et transmis avec la livraison, puis vérifié par son destinataire avec ses clés approuvées et les fichiers nécessaires aux contrôles choisis.

Le périmètre déclaré reste déterminant : un reçu ne couvre pas spontanément tous les fichiers que le build pourrait lire. Le format natif possède aussi ses propres règles d’empreinte ; notre SHA-256 simplifié n’en constitue pas une description complète. La référence CLI et le format du reçu documentent la mise en pratique exacte.

Pour prolonger la réflexion, l’article Trust is not evidence est une lecture complémentaire, indépendante du parcours Academy. Il n’est pas un prérequis pour poursuivre.

12 — À retenir

L’artefact donne le contenu ; son hash permet de le comparer. Le statement formule une affirmation, l’attestation la rattache à un sujet, et la signature permet d’en contrôler l’intégrité et le lien à une clé. La provenance décrit la fabrication. Vérifier consiste à examiner ces liens selon des attentes explicites, sans transformer une déclaration signée en vérité absolue.