Dix mille étoiles et un seul commit
Le 14 juillet, xAI a publié le code source de Grok Build sous licence Apache 2.0, et ce matin le dépôt dépassait les dix mille étoiles. La publication faisait suite à un test au niveau du réseau qui avait constaté que la version 0.2.93 de l'outil téléversait un dépôt suivi, ainsi que l'intégralité de son historique git sous forme de bundle, vers un stockage cloud contrôlé par xAI, y compris un dépôt que l'assistant avait reçu l'instruction de ne pas lire. Nous avons traité ce constat le 14 juillet, et la consigne était alors de renouveler tous les secrets que l'outil avait pu voir. Cette consigne tient toujours.
Publier le code ressemble à la réponse la plus forte que l'on puisse apporter à un constat de ce genre. C'est le geste que fait une organisation d'ingénierie lorsqu'elle est convaincue que le dossier la disculpe, et c'est ainsi qu'il est reçu. La question utile n'est donc pas de savoir si xAI a bien fait de publier. Elle est plus étroite et plus concrète. Si vous alliez aujourd'hui sur ce dépôt pour vous assurer de ce que l'outil a fait sur vos machines, que pourriez-vous réellement établir ?
Pas grand-chose, en définitive, et pour des raisons structurelles plutôt que malveillantes. Le dépôt ne compte qu'un seul commit, créé par un bot le 16 juillet à 05:46 UTC, avec pour message qu'il publie le harnais et le TUI en open source. Un seul commit, cela veut dire aucun historique. Pas d'avant, pas de diff, pas de suite de modifications, rien à comparer. Dix mille étoiles sur un dépôt sans historique, ce sont dix mille personnes qui approuvent un geste.
Ce que le dépôt ne peut pas vous dire
Commencez par la seule question que le constat soulevait vraiment. Où le code est-il parti ? Les téléversements aboutissaient dans un bucket Google Cloud Storage dont le nom figure dans le binaire distribué. Dans le code source publié, ce nom n'apparaît pas. Il est lu depuis une variable d'environnement fixée à la compilation, résolue au moment où le binaire est construit. Celui qui compile la publication fournit la destination, et la source reste muette sur ce vers quoi le build distribué pointait. Le code publié ne peut pas répondre à la question, ni dans un sens ni dans l'autre.
Regardez ensuite la fonction qui effectuait le téléversement. Elle est toujours là, dans le crate du shell, et elle ne fait plus rien. Elle prend ses paramètres, les marque comme inutilisés, attend sur le canal, jette le résultat et renvoie un échec indiquant que l'envoi de l'état de session est indisponible. Le corps a été retiré, les abords sont restés. Les points d'appel sont intacts, le manifeste liste toujours les dépendances, les utilitaires de stockage sont toujours compilés. Ce que vous pouvez lire, c'est le squelette du mécanisme, le mécanisme en moins.
C'est aussi la deuxième fois que le correctif est posé à un endroit que vous ne pouvez pas inspecter. Les téléversements d'origine ont été arrêtés le 13 juillet par un drapeau côté serveur, pas par une version cliente, et c'était le point le plus tranchant de la première affaire. Le binaire que votre équipe avait relu et épinglé n'a jamais été ce qui décidait de ce qui quittait la machine. Aujourd'hui le code est public, la destination reste une entrée fixée à la compilation et l'interrupteur reste sur le serveur. La surface auditable et la surface qui décide ne se sont pas rapprochées d'un pouce.
Quatre fichiers ont suivi, un n'est pas arrivé
Il reste un détail, et il faut l'énoncer avec soin, car il se surinterprète facilement. Les chaînes contenues dans le binaire 0.2.93 distribué nomment un crate appelé xai-data-collector, qui contient cinq fichiers source. Le client de stockage, la couche de stockage cloud, la file d'attente, un observateur de circuit breaker et un traceur d'accès aux fichiers. Le dépôt publié ne contient aucun crate de ce nom. Le même ensemble de fichiers vit dans un crate appelé xai-file-utils, et quatre des cinq correspondent. Le cinquième, le traceur d'accès aux fichiers, ne figure nulle part dans le code source publié.
Ce que cela établit et ce que cela n'établit pas, c'est tout l'enjeu. Cela n'établit aucune intention. Rebaptiser un crate dont le nom décrivait la collecte de données en un nom qui décrit la manipulation de fichiers est exactement ce que fait une équipe pendant un nettoyage de publication, et retirer un module qui n'est plus branché à rien relève de l'entretien courant. Il n'y a ici aucune preuve de dissimulation et nous n'en alléguons aucune. Il vaut aussi la peine de noter l'asymétrie des éléments eux-mêmes. Le côté binaire repose sur l'extraction de chaînes par un tiers, tandis que le côté source peut être vérifié par quiconque clone le dépôt.
Ce que cela établit, c'est que la publication ne peut pas tenir lieu de trace. Le composant dont le nom décrit le plus directement le suivi des accès aux fichiers d'un utilisateur est absent, les quatre autres fichiers du même crate sont présents sous un autre nom, et il n'existe aucun historique de commits où examiner l'un ou l'autre de ces faits. Les explications innocentes et les explications coupables produisent un dépôt identique. C'est le problème que pose une publication érigée en preuve. Cela ne marche que si l'artefact permet de distinguer les deux, et celui-ci ne le permet pas.
L'affirmation qui n'a jamais été faite
Rendons au chercheur ce qui lui revient, car c'est la rigueur de ce côté-ci de l'affaire qui fait tenir l'ensemble. L'analyse au niveau du réseau a été menée avec un proxy d'interception face à un binaire épinglé, sur un dépôt jetable garni de fichiers canari, et elle est reproductible. Il existe un harnais public, et n'importe qui peut l'exécuter. La mesure était nette. Un dépôt de douze gigaoctets a produit 5,10 gibioctets de trafic de téléversement contre 192 kilo-octets de conversation réelle avec le modèle, soit un rapport proche de vingt-huit mille pour un. Le fichier canari que l'assistant avait reçu l'instruction de ne pas lire est ressorti intact du bundle capturé.
Et puis le chercheur a écrit noir sur blanc ce que son test ne prouvait pas. Que téléverser n'est pas entraîner, puisque seule la transmission a été mesurée. Qu'une capture à trois gigaoctets n'a pas été conservée. Qu'une conclusion antérieure était fausse, parce qu'une lecture du réseau limitée au périmètre du processus avait manqué des téléversements partant directement vers des adresses Google, et cette conclusion a été retirée. Un constat qui publie ses propres limites et sa propre rétractation est un constat exploitable.
Mettez cela en regard des réponses. xAI a déclaré tenir profondément à la confidentialité, respecter le choix de ses clients et, pour les équipes en rétention de données nulle, ne jamais conserver la moindre trace ni la moindre donnée de code. Elon Musk a dit que toutes les données utilisateur téléversées jusqu'à maintenant seront complètement et intégralement supprimées, et qu'il n'en restera absolument rien. Ces affirmations sont peut-être vraies. Aucune n'est vérifiable, et la suppression ne peut pas être contrôlée de l'extérieur. Le schéma est constant sur tout l'épisode. Les affirmations que l'on pouvait tester venaient de la personne qui avait le proxy, et celles que l'on ne pouvait pas tester venaient du fournisseur.
Trois questions avant de déclarer l'affaire réglée
La leçon généralisable n'a rien à voir avec xAI, et vous en aurez de nouveau besoin d'ici la fin du mois. Ouvrir le code est devenu une réponse standard à un constat de sécurité, et c'en est une bonne quand l'artefact porte des preuves. Il ne le fait pas automatiquement. Alors, quand un fournisseur répond à un constat qui concerne vos données en publiant du code, posez-lui trois questions avant de fermer le ticket.
Puis-je voir l'historique ? Un commit initial écrasé est une photographie, pas un enregistrement. Si le dépôt commence le jour de la publication, il ne peut pas montrer ce qui a changé, et ce qui est sous examen est précisément un changement. L'artefact publié correspond-il au binaire distribué ? Si le moindre comportement qui compte se règle à la compilation ou se tient sur un serveur, la source décrit une possibilité, pas ce qui a tourné sur vos machines. Le code contient-il le composant que le constat a nommé ? Si la chose précise qui a été trouvée n'est pas dans le dépôt, son absence n'est pas une réponse, quelle qu'en soit la cause.
Rien de tout cela ne plaide pour garder le code fermé, et rien de tout cela n'est une accusation. Cela plaide pour une distinction que votre processus d'achat ne fait probablement pas encore. Une publication est un acte de divulgation, un audit est un processus qui produit une conclusion. Ce ne sont pas des substituts, ce ne sont même pas des cousins proches, et un fournisseur qui a fait le premier n'a pas fait le second. Les équipes qui prennent un lien vers un dépôt pour un dossier clos commettent une erreur de catégorie, et c'est le genre d'erreur qui ne se voit qu'après coup, une fois tombé le constat suivant.
À lire ensuite: Sprout a dépassé ses chiffres et coupé 20% le même jour | Personne ne l'a interdit. Le filtre a refusé quand même.



