Tienduizend sterren en één commit
Op 14 juli publiceerde xAI de broncode van Grok Build onder Apache 2.0, en vanochtend stond de repository op ruim tienduizend sterren. De release volgde op een test op netwerkniveau waaruit bleek dat versie 0.2.93 van de tool een getrackte repository uploadde, samen met de volledige git-historie als bundle, naar cloudopslag die xAI beheert. Daar zat ook een repository bij die de assistent juist niet mocht lezen. Wij schreven op 14 juli over die bevinding, en de instructie luidde toen: roteer elk geheim dat de tool ooit heeft gezien. Die instructie geldt nog steeds.
De code publiceren oogt als het sterkst denkbare antwoord op zo'n bevinding. Het is de zet die een engineeringorganisatie doet wanneer zij ervan overtuigd is dat de stukken haar vrijpleiten, en zo wordt het ook gelezen. De nuttige vraag is dus niet of xAI er goed aan deed om te publiceren. Die vraag is nauwer en praktischer: als u nu naar die repository gaat om vast te stellen wat de tool op uw machines heeft gedaan, wat kunt u dan feitelijk hard maken?
Bitter weinig, zo blijkt, en de redenen zijn eerder structureel dan kwaadwillend. De repository bevat één commit, op 16 juli om 05:46 UTC aangemaakt door een bot, met als boodschap dat hiermee de harness en de TUI open source gaan. Één commit betekent geen historie. Er is geen eerdere staat, geen diff, geen reeks wijzigingen, niets om mee te vergelijken. Tienduizend sterren op een repository zonder historie zijn tienduizend mensen die een gebaar onderschrijven.
Wat de repository u niet kan vertellen
Begin bij de ene vraag die de bevinding werkelijk opwierp: waar ging de code naartoe? De uploads gingen naar een bucket in Google Cloud Storage die in de uitgeleverde binary bij naam wordt genoemd. In de gepubliceerde broncode komt die naam niet voor. Hij wordt gelezen uit een omgevingsvariabele die bij het compileren wordt gezet en pas bij de build wordt ingevuld. Wie de release compileert, levert de bestemming aan, en de broncode zwijgt over waar de uitgeleverde build op was gericht. De gepubliceerde code kan de vraag niet beantwoorden, in geen van beide richtingen.
Kijk vervolgens naar de functie die het uploaden deed. Die zit er nog, in de shell-crate, en ze doet niets meer. Ze neemt haar parameters aan, markeert die als ongebruikt, wacht op het kanaal, gooit het resultaat weg en geeft een foutmelding terug dat het uploaden van de sessiestatus niet beschikbaar is. De body is eruit gehaald terwijl alles eromheen bleef staan: de aanroepen zijn intact, het manifest noemt de dependencies nog, de storage-helpers worden nog steeds meegecompileerd. Wat u kunt lezen is het geraamte van het mechanisme, met het mechanisme eruit.
Dit is bovendien de tweede keer dat de fix zit op een plek die u niet kunt inspecteren. De oorspronkelijke uploads werden op 13 juli stilgelegd met een flag aan de serverkant, niet met een clientrelease, en dat was het scherpste deel van het eerste verhaal: de binary die uw team beoordeelde en vastpinde, was nooit het onderdeel dat bepaalde wat de machine verliet. Nu is de code openbaar, en nog altijd is de bestemming een invoer bij de build en zit de schakelaar op de server. De laag die te auditen valt en de laag die beslist, zijn niet dichter bij elkaar gebracht.
Vier bestanden verhuisden, één kwam niet aan
Er is nog één detail, en dat vraagt om zorgvuldige formulering, want het laat zich makkelijk overinterpreteren. De strings in de uitgeleverde 0.2.93-binary noemen een crate met de naam xai-data-collector, met daarin vijf bronbestanden: de storage client, de laag voor cloudopslag, de queue, een circuit-breaker-observer en een file access tracker. De gepubliceerde repository bevat geen crate met die naam. Dezelfde verzameling bestanden zit in een crate die xai-file-utils heet, en vier van de vijf komen overeen. De vijfde, de file access tracker, zit helemaal niet in de gepubliceerde broncode.
Wat dat wel en niet aantoont, is precies waar het om draait. Opzet toont het niet aan. Een crate hernoemen van iets dat het verzamelen van data beschrijft naar iets dat het verwerken van bestanden beschrijft, is precies wat een team doet bij het opruimen rond een release, en een module laten vallen die nergens meer aan hangt, is doodgewoon onderhoud. Er is hier geen bewijs van verhulling en wij beweren dat ook niet. Het is verder de moeite waard om de asymmetrie in het bewijsmateriaal zelf te noemen: de kant van de binary steunt op de string-extractie van een derde partij, terwijl de kant van de broncode te verifiëren is door iedereen die de repository kloont.
Wat het wél aantoont, is dat de release niet als dossier kan dienen. De component waarvan de naam het meest rechtstreeks het volgen van de bestandstoegang van een gebruiker beschrijft, ontbreekt, de verwanten ervan staan er wel onder een andere naam, en er is geen commithistorie waarin een van beide feiten valt te onderzoeken. Onschuldige verklaringen en schuldige verklaringen leveren een identieke repository op. Dat is het probleem met een publicatie als bewijs behandelen: dat werkt alleen als het artefact de twee uit elkaar kan houden, en dit artefact kan dat niet.
De claim die nooit is gemaakt
Geef de onderzoeker krediet, want de discipline aan die kant van dit verhaal is de reden dat het standhoudt. De analyse op netwerkniveau is gedaan met een onderscheppende proxy op een vastgepinde binary, op een wegwerprepository met canary-bestanden erin, en ze is reproduceerbaar: er is een publieke harness, en iedereen kan die draaien. De meting was ondubbelzinnig. Een repository van twaalf gigabyte leverde 5,10 gibibyte aan uploadverkeer op, tegenover 192 kilobyte aan werkelijke modelconversatie, een verhouding van bijna achtentwintigduizend tegen een. Het canary-bestand dat de assistent niet mocht lezen, kwam ongeschonden uit de vastgelegde bundle tevoorschijn.
En vervolgens schreef de onderzoeker op wat de test niet bewees. Dat uploaden geen trainen is, want alleen de verzending is gemeten. Dat één capture bij drie gigabyte niet bewaard is gebleven. Dat een eerdere conclusie onjuist was, omdat een netwerkmeting op procesniveau uploads had gemist die rechtstreeks naar Google-adressen gingen, en die conclusie is ingetrokken. Een bevinding die haar eigen grenzen en haar eigen rectificatie publiceert, is een bevinding waar u wat aan hebt.
Zet dat naast de reacties. xAI heeft gezegd dat het diep om privacy geeft, dat het de keuze van de klant respecteert en dat er voor teams die zero data retention gebruiken nooit trace- of codedata worden bewaard. Elon Musk zei dat alle gebruikersdata die tot nu toe zijn geüpload volledig en volstrekt zullen worden verwijderd, en dat er helemaal niets van zal overblijven. Het kan allemaal waar zijn. Geen van die uitspraken is controleerbaar, en de verwijdering valt van buitenaf niet te verifiëren. Het patroon door deze hele episode heen is consistent: de claims die te toetsen zijn, kwamen van de persoon met de proxy, en de claims die dat niet zijn, kwamen van de leverancier.
Drie vragen voordat u het als opgelost beschouwt
De algemene les heeft niets met xAI te maken, en ze zal binnen de maand opnieuw nodig zijn. Open source maken is een standaardreactie op een beveiligingsbevinding geworden, en het is een goede reactie wanneer het artefact bewijs draagt. Dat is het niet automatisch. Leg een leverancier die een bevinding over uw data beantwoordt door code te publiceren dus drie vragen voor, voordat het ticket dichtgaat.
Kan ik de historie inzien? Een squashed eerste commit is een foto, geen dossier. Als de repository begint op de dag van publicatie, kan hij niet laten zien wat er is veranderd, en juist een verandering is het onderwerp van onderzoek. Komt het gepubliceerde artefact overeen met de uitgeleverde binary? Als gedrag dat ertoe doet bij de build wordt vastgelegd of op een server wordt bewaard, dan beschrijft de broncode een mogelijkheid en niet wat er op uw machines heeft gedraaid. Zit de component die de bevinding noemde in de code? Als het specifieke onderdeel dat is aangetroffen niet in de repository zit, is die afwezigheid geen antwoord, wat de oorzaak ervan ook is.
Niets hiervan pleit ervoor om code gesloten te houden, en niets hiervan is een beschuldiging. Het pleit voor een onderscheid dat uw inkoopproces waarschijnlijk nog niet maakt: publicatie is een daad van openbaarmaking, en een audit is een proces dat een conclusie oplevert. Het een vervangt het ander niet, ze zijn niet eens naaste verwanten, en een leverancier die het eerste heeft gedaan, heeft het tweede niet gedaan. Teams die een link naar een repository behandelen als een gesloten zaak, maken een categoriefout, en dat is het soort fout dat pas achteraf zichtbaar wordt, na de volgende bevinding.
Lees hierna: Sprout overtrof de prognose en schrapte 20% op dezelfde dag | Niemand verbood het. De filter weigerde toch.



