# Reproductibilite de l'extension SYAGA Audit - le code livre est celui de notre depot source

> Etat au 18/10/2026, dit tel quel : le depot source de SYAGA n'est PAS public. Le code execute est inclus en
> clair dans le paquet installe et s'y lit tel quel. La SEULE procedure de verification publique est celle du
> paquet : `sha256sum -c SHA256SUMS`, decrite plus bas. Les outils du depot source ne sont pas fournis au client :
> ils sont nommes en fin de document, sans instruction.
> "Publie" et "ouvert" ne s'appliqueront qu'une fois le depot rendu public, ce qui n'est pas fait.

## Le point fort : il n'y a AUCUN CODE a reconstruire
L'extension est ecrite en JavaScript LISIBLE, **non bundle, non minifie** (<!--chiffre:lignes_js-->19 368 lignes<!--/chiffre--> livrees dans le
paquet <!--chiffre:version-->0.0.56<!--/chiffre--> ; ce chiffre est RENDU depuis la mesure du paquet, puis confronte a cette
meme mesure par des controles internes du depot). Aucun fichier
de code n'est compile ni transforme : chacun est, octet pour octet, le fichier de ce depot (non public a ce jour). On ne compare
pas une source a un binaire minifie genere (le cas difficile habituel), on compare des fichiers identiques.

## L'unique etape d'emballage, et ce qu'elle change
Il existe UNE etape avant l'envoi a la boutique (script interne du depot), et elle ne modifie que deux fichiers :
`manifest.json` et `mode_paquet.mjs`. Dans `manifest.json`, deux transformations, pas une de plus :

1. retrait de la cle de developpement `key` (le Chrome Web Store refuse un paquet qui en contient une) ;
2. retrait de toute origine en `http://` NON ASSUMEE, dans chacun des champs qui declarent une origine
   (`host_permissions`, `permissions`, `optional_host_permissions`, `externally_connectable.matches`).
   La liste des origines assumees est nominative et ne contient que
   `http://localhost/*`, qui RESTE dans le paquet : le retour de la connexion Exchange se fait sur cette adresse, imposee
   par l application Microsoft fb78d390 ; sans elle le scan se figeait a 44 %. Aucune autre origine `http://` ne passe.

Dans `mode_paquet.mjs`, une seule valeur change : `"developpement"` devient `"boutique"`, pour que le paquet de la
boutique refuse la cle de signature de developpement (seules les cles de production, nees dans les YubiKeys de SYAGA,
y verifient la liste des controles).

Elle **n'ajoute aucune permission**, n'en elargit aucune, et **ne modifie aucun autre fichier**. Elle ecarte du
paquet ce qui ne sert pas au client (documentation, scripts, tests, sauvegardes de travail, harnais d'essai) :
ces fichiers restent dans le depot, lisibles.

Dire "sans etape de build" serait faux, et une promesse fausse est pire qu'une promesse modeste : on la
remplace par une promesse verifiable -- **deux fichiers du paquet ne sont pas la copie exacte du depot, et une
controle interne du depot recalcule leur transformation**.

**Mesure du 06/08/2026 au soir : ROUGE, puis VERTE apres reconstruction.**
Un controle interne du depot sortait 1 : le paquet `0.0.20` livrait `pseudonymize.mjs` et
`pseudo_whitelist.mjs` dans un etat anterieur au depot (tous deux modifies apres la construction du paquet
et apres l'ecriture des empreintes). Ce paquet n'etait pas publiable en l'etat.

Correction faite le meme soir, et elle n'est pas cosmetique : reconstruire CHANGE le contenu, donc le
numero. La version est passee a **0.0.21**, les empreintes ont ete regenerees, le paquet reconstruit, puis fige
au registre. Le controle interne sort desormais 0 (53 fichiers identiques octet pour octet au depot +
`manifest.json` egal au recalcul de la transformation publiee). Cote client, la procedure publique donne, sur le
paquet, toutes les lignes `OK` de `SHA256SUMS` sauf `manifest.json` (voir plus bas).

Le defaut de fond n'etait pas la derive elle-meme mais le fait que RIEN ne la signalait : ces gardes ne
se declenchaient que sur une publication etiquetee, et aucune n'a jamais ete faite. Elles tournent maintenant a
chaque poussee, dans l'integration continue interne du depot.

## Verifier le paquet : la seule procedure publique
1. Telechargez `SHA256SUMS` (publie a cote de cette page, a l'adresse `/preuve/SHA256SUMS`), ailleurs que dans le
   dossier de l'extension.
2. Placez-vous dans le dossier du paquet decompresse (le dossier de l'extension installee sur votre poste) et lancez :
   ```bash
   sha256sum -c SHA256SUMS
   ```
   (si le fichier telecharge est ailleurs, donnez son chemin a la place de `SHA256SUMS`). Toutes les lignes doivent
   afficher `OK`, sauf **une** : `manifest.json`. Mesure du 18/10/2026 sur un paquet construit localement depuis le
   depot : 70 lignes, 69 `OK`, la seule en echec est `manifest.json`.
3. Pourquoi `manifest.json` echoue, et c'est voulu : `SHA256SUMS` porte l'empreinte de la SOURCE du manifeste, et le
   paquet livre sa forme DERIVEE (retrait de la cle de developpement et des origines `http://` non assumees, voir plus
   haut). `mode_paquet.mjs`, lui, est deja en forme boutique dans `SHA256SUMS` : son empreinte tombe juste. **Toute
   autre ligne en echec signifie que le code livre n'est pas celui de notre depot.**
4. Lisez le code (inclus en clair dans le paquet installe ; les fichiers qui portent la promesse : manifest.json,
   background.js, auth.js, collect.js, pseudonymize.mjs, pseudo_whitelist.mjs, innocuity_proof.mjs).
5. Observez l'egress en live (outils developpeur du SERVICE WORKER, pas ceux d'une page : edge://extensions, Mode
   developpeur, ligne "Inspecter les vues", lien "service worker", onglet Reseau) : vers syaga.eu partent des jetons
   et des valeurs de configuration non personnelles, vers dns.google les noms de domaine.

Ce que cette procedure ne dit PAS : elle compare le paquet a un fichier d'empreintes que nous publions nous-memes ;
la comparaison avec un depot source public viendra quand celui-ci le sera.

## Outils internes du depot, non fournis (aucune instruction a suivre)
Pour memoire seulement, et pour ne rien cacher : ces controles vivent dans le depot source, qui n'est pas public, et
ne sont ni dans le paquet ni sur cette page. Un client n'en a pas besoin pour la verification ci-dessus.
- un script d'emballage (`build-store.py`) et un generateur d'empreintes ;
- un controle qui rejoue la transformation du manifeste depuis le depot et exige l'egalite octet pour octet avec le
  manifeste livre (une permission ajoutee, une origine elargie, une cle reinjectee, ou la moindre alteration d'un
  `.js` le fait echouer) ;
- un controle qu'un numero de version designe un contenu et un seul ;
- un script de verification du depot (`verify.sh`), qui rejoue l'emballage de `mode_paquet.mjs` avant de comparer.

C'est aussi pour ca qu'on reste en JS et pas en WebAssembly : un binaire WASM serait opaque et romprait
l'egalite source == livre.

## Empreintes (SHA-256) : ce qu'elles couvrent exactement
`SHA256SUMS` liste les empreintes des fichiers **du depot** destines au paquet (la liste est decidee par le script
d'emballage interne, jamais ecrite a la main). Pour tous sauf `manifest.json`, cette empreinte est aussi celle du
fichier livre : c'est ce que le client constate avec `sha256sum -c SHA256SUMS` dans le dossier du paquet. Pour
`manifest.json`, `SHA256SUMS` porte l'empreinte de la SOURCE et non du derive : le paquet livre le resultat de la
transformation decrite plus haut, que seul un controle interne du depot rejoue.

Un registre interne des versions complete ces empreintes (non fourni) : la ou `SHA256SUMS` empreinte des fichiers,
il empreinte un PAQUET ENTIER sous son numero de version, par `sha256` de la concatenation, pour chaque fichier trie
par nom, de `sha256_hex(octets) + "  " + nom + "\n"`. Il ignore les dates que l'archive embarque et change des
qu'un fichier est ajoute, retire ou modifie.

## Chaine de preuve CONTINUE (a chaque version) - PREVUE, NON ACTIVE a ce jour
Elle suppose une integration continue PUBLIQUE, donc un depot public : rien de ce qui suit n'est en service.
- Build (ici : copie verbatim du code + assainissement du seul manifest) execute en CI PUBLIQUE -> attestation SLSA + signature keyless sigstore
  (Fulcio) + entree append-only dans le log de transparence Rekor. Verifiable par l'outil d'attestation de GitHub, une fois cette chaine active.
- Le hash de CHAQUE version est publie a un endroit inviolable (Rekor) + en facade utilisateur facon
  Code Verify -> une mise a jour malveillante ne peut pas passer en douce.

## Limites honnetes (preuve avant slogan)
- **Firefox AMO** impose deja la revue de source + le diff "no differences" par version : canal de preuve
  fort. **Chrome Web Store ne verifie AUCUNE source** -> sur Chrome on s'appuie uniquement sur ces
  empreintes + l'attestation, et on le DIT.
- Le store re-emballe le paquet (`_metadata/`, signatures du store) -> le .zip/.xpi n'est pas byte-identique
  a l'archive d'origine. On prouve l'egalite des FICHIERS JS executes (ce qui compte), pas de l'enveloppe.
- SLSA/sigstore prouvent l'ORIGINE du build, pas l'absence de faille dans la source : la lecture du code
  (rendue facile par l'absence de minification) reste necessaire. C'est pour cela que le code est livre lisible
  dans le paquet ; l'ouverture du depot source reste a decider.
