Montagmorgen. In einem der größten Rails-Monolithen der Welt liegt ein Pull Request, den niemand aus dem Team geschrieben hat. Er enthält einen Integrationstest: zwei Mandanten, Daten des einen, geschützte Route des anderen. Der Test protokolliert, dass die Antwort fremde Datensätze zurückgibt. Dazu eine kurze Begründung, warum das ausnutzbar ist, und ein Patch, der die Abfrage auf die eigene Mandanten-ID einschränkt. Der Entwickler muss den PR nur lesen und entscheiden.
Dahinter steckt, was Shopifys Application-Security-Team über Monate gebaut hat: ein agentisches Sicherheits-Harness. Es partitioniert Code, sucht Kandidaten für Schwachstellen, prüft sie mit echten Tests und macht daraus einen Patch. Das Team hat seine Erfahrungen aus fünf Monaten veröffentlicht, mit Kosten und Zahlen. Aufschlussreicher als die Funde der Modelle ist die Infrastruktur drumherum.
Der Vergleich im Text ist eine Fertigungsstraße. Ein Modell ist die Werkzeugmaschine an einer Station: schnell und leistungsfähig, aber ohne Führung, Takt und Qualitätskontrolle produziert sie vor allem Ausschuss. Das Fließband bleibt, wenn die Maschine getauscht wird. Darin liegt die Ingenieursleistung.
Dreißig Kandidaten, keine kritischen Funde
Fünf Monate lang hat das Team security-tuned Frontier-Modelle im eigenen Harness gegeneinander laufen lassen. Das Ergebnis war zweischneidig. Die besten Kandidaten fanden mehr echte Probleme als die Basislinie, produzierten aber auch mehr Fälle, die erst bestätigt werden mussten. In einem Audit kam ein Modell auf über dreißig angebliche Schwachstellen. Nach der Prüfung war jede einzelne entweder niedrig oder mittel, ein Fehlalarm oder eine Härtungsempfehlung.
Das ist das Muster, kein Ausreißer. Ein besseres Modell ist vor allem ein besserer Jäger. Wer mehr jagt, bringt mehr Beute mit, und nicht alles davon ist essbar. Der wichtigste Satz im Bericht: Ein Fehlalarm, der beim Entwickler landet, ist schlimmer als kein Fund. Er kostet Zeit und beschädigt das Vertrauen der Leute, die solche Funde bewerten.
Die Frage verschiebt sich. Nicht: Welches Modell ist das beste? Sondern: Wie sieht eine Umgebung aus, in der auch ein mittelmäßiges Modell nur das weitergibt, was es belegen kann?
Dispatch: eine dünne Ruby-Schicht für viele Agenten
Der Orchestrator heißt intern Dispatch und ist bewusst klein: ein schlanker Ruby-Client, der Autoren von Scans die Komplexität des verteilten Scannens abnimmt. Wer ein neues Jagdszenario für eine Fehlerklasse bauen will, beschreibt es. Dispatch führt es aus, stellt ein Test-Orakel bereit und öffnet für Funde einen Pull Request. Das Multi-Agenten-System ist damit kein einzelner großer Prompt, sondern eine feste Abfolge von Stationen.
Beim ersten Lauf gegen eine Anwendung baut die Pipeline Partitionen: thematisch zusammenhängende Dateigruppen nach Größe und Reichweite. Danach laufen für jede Partition Hunting-Agenten parallel. Nebenbei entstehen wiederverwendbare Artefakte: eine Dokumentation der APIs und Datenmodelle, die den nachgelagerten Agenten als verdichteter Kontext dient. Deren Kontextfenster bleibt so frei für die eigentliche Arbeit. Alle Scans und Artefakte landen in einem eigenen Rails-Backend und werden bei späteren Läufen aktuell gehalten.
Bei Folgeläufen vergleicht die Pipeline den letzten Commit mit dem vorherigen und scannt nur die Änderungen. Das sind die diff-basierten Code-Scans mit KI, die den Unterschied zwischen bezahlbarem Dauerbetrieb und gelegentlichem Großangriff ausmachen. Partitionen und Dokumentation werden mit den Diff-Informationen fortgeschrieben. Aufwand und Abdeckung bleiben in einem Verhältnis, das sich über Monate trägt.
Die Reihenfolge der Stationen ist kein Zufall: erst prüfen, ob die Testsuite läuft, dann die Architektur dokumentieren, dann Dateien katalogisieren, dann partitionieren, dann jagen, dann verifizieren, dann deduplizieren und Schweregrade berechnen, dann berichten, am Ende reparieren. Die Verifikation läuft sequenziell und mit einem anderen Modell als die Jagd. Parallel würden sich Ports, Datenbanken und Fixtures in die Quere kommen. Das zweite Modell wirkt als Gegenanwalt gegen die Fehler des ersten.
Das Test-Orakel: aus einem Verdacht wird ein Beweis
Bei Speicherfehlern gibt es ein bequemes Orakel: Der Compiler meckert, oder das Programm stürzt ab. Bei Web-Schwachstellen fehlt diese Instanz. Ob eine fehlerhafte Zugriffskontrolle ausnutzbar ist, hängt an Berechtigungen, Zwischenschichten und Datenmodellen. Shopify kann auf eine gewachsene Testkultur zurückgreifen: Integration-, Unit- und Funktionstests existieren in den Zielanwendungen bereits, gepflegt von einem eigenen Umgebungsteam. Der Verifier-Agent schreibt seine Prüfungen nicht daneben, sondern in diese Suiten hinein.
Für fehlerhafte Objektberechtigung, gemeinhin IDOR, hat das Team Regeln kodiert, die konkret sind. Der Agent arbeitet sich von öffentlichen Aufrufstellen rückwärts vor, legt Fixtures für zwei Mandanten an und achtet darauf, dass die Tests möglichst viel des öffentlichen Stacks durchlaufen. Ein Unit-Test auf Modellebene genügt nicht, um Ausnutzbarkeit zu belegen. Der Test muss Daten des anderen Mandanten extrahieren; ein Boolean oder eine nackte ID führt höchstens zu einem niedrigen Schweregrad. Und der Agent muss prüfen, ob stromaufwärts oder stromabwärts Kontrollen greifen, die den Fund entschärfen. Diese Kontrollen darf er nicht wegstubben.
Was diesen Regeln folgt, wird zum Fund. Was ihnen nicht folgt, fliegt raus oder rutscht auf niedrig bis mittel. Das klingt nach Bürokratie, ist aber der Grund, warum die Ergebnisse brauchbar sind: Der Beweis entscheidet, nicht die Überzeugungskraft des Modells. Ein Test, der rot wird, sobald man die Lücke schließt, ist eine belastbare Aussage. Ein Absatz flüssig formulierter Sicherheitsprosa ist es nicht.
Partitionen, Token-Budgets, 50 bis 300 Dollar pro Scan
Die teuerste Art, agentische Risikosuche zu betreiben, ist ein vollständiger Agentenlauf über jede Datei eines Repositories, aufgeteilt nach Fehlerklassen. Die billigste ist ein einzelner Agent über das ganze Repository mit dem Auftrag, irgendetwas zu finden. Der Unterschied liegt in Kosten und Geschwindigkeit auf der einen, Genauigkeit und Trefferquote auf der anderen Seite. Das Team hat einen Mittelweg gewählt und die Repositories in Partitionen von etwa zwanzig bis dreißig Prozent des Kontextfensters geschnitten. Genug Platz für Erkundung und Werkzeugnutzung, gruppiert nach Domäne, Zweck oder Feature, mit den wichtigsten geteilten Dateien in jeder Partition.
Um zu prüfen, ob das trägt, wurden Benchmarks gebaut: zuvor bestätigte Schwachstellen kamen lokal zurück in den Code, dann liefen partitionierte und unpartitionierte Verfahren gegeneinander. Die partitionierte Variante war genauer und fand mehr, ohne die Kosten aus dem Ruder laufen zu lassen. Damit hören automatisierte Sicherheitsscans für einen Rails-Monolithen auf, ein Experiment zu sein, und werden zur Betriebsfrage.
Die Zahlen stützen das. In etwa sechs Wochen liefen Tausende Scans über mehr als achtzig Anwendungen, darunter der Kern-Monolith. Dabei kamen über dreihundert Funde zusammen, von Härtungsempfehlungen bis zu bereits abgeschlossenen Sicherheitsvorfällen. Konservativ bewertet entspricht das mehr als 400.000 Dollar an Bug-Bounty-Auszahlungen. Zwei Funde hätten nach dem internen Rechner den Schweregrad kritisch erreicht. Ein vollständiger Scan kostet je nach Modell und Anwendungsgröße zwischen 50 und 300 Dollar, ein inkrementeller Diff-Scan zwischen 5 und 50. Diese Beträge sind Angaben des Unternehmens und nicht unabhängig geprüft. Die Größenordnung erklärt, warum von Läufen die Rede ist, die stattfinden, während alle schlafen.
Generalisten, Spezialisten und deterministische Skripte
Der naheliegende erste Versuch war ein Generalist: ein Multi-Agenten-Verfahren ohne feste Fehlerklasse, manuell gegen Repositories gefahren. Es gab echte Treffer, daneben aber ein hohes Volumen an theoretischen Problemen, die in der Praxis niemanden interessierten, und Vorschläge, die oft falsch waren. Die Ergebnisse schwankten von Lauf zu Lauf. Ohne klare Zielvulnerabilität füllten die Modelle ihr Kontextfenster mit einer ungeordneten Liste von Möglichkeiten, bis sie aufgaben oder verdichtet werden mussten, und verpassten dabei den eigentlichen Fehler. Das Team beschreibt dies als den am wenigsten effektiven Weg, aus einem Modell verlässliche Resultate zu holen.
Mit strikt kodierten Leitplanken hat ein Generalist trotzdem seinen Platz: als Lückenfüller für das, was die Spezialisten übersehen. Seine Ergebnisse gehören auf den Prüfstand, nicht direkt in den Posteingang eines Entwicklers. Das ist keine neue Erkenntnis und in fast jeder Softwarearchitektur wiederzufinden: Ein System, das eine Aufgabe eng zuschneidet, ist verlässlicher als eines, das alles gleichzeitig können soll.
Dazu kommt die Frage, welche Arbeit ein Agent überhaupt selbst machen sollte. Wo strukturierte Ein- und Ausgaben gebraucht werden, sind deterministische Skripte die bessere Wahl. Statt einen Agenten ein JSON-Dokument nach Gefühl formulieren zu lassen, gibt man ihm ein kleines Werkzeug, das das Schema erzwingt, und lässt ihn nur die Inhalte befüllen. Das Harness behält die Kontrolle über Credentials, Git und Speicherung, statt diese Verantwortung an ein Modell zu delegieren, das beim nächsten Update anders denkt. Das gibt weniger kaputte Ausgaben, prüfbare Ergebnisse und ein System, dessen Fehler an definierten Stellen auftreten.
Was die Umgebung leisten muss, wenn das Modell besser wird
Alle paar Monate erscheint ein neues Frontier-Modell, und jedes findet mehr Kandidaten als das vorige. Das ist Fortschritt, verschiebt das Problem aber nur. Ein besserer Jäger produziert auch überzeugender klingendes Rauschen, und dieses Rauschen landet bei Menschen, die entscheiden müssen. Die dauerhafte Stärke liegt deshalb nicht im Modell, sondern in der Umgebung: ein Test-Orakel, das Ausnutzbarkeit mit einem echten Integrationstest belegt, eine Partitionierung, die Kosten und Trefferquote in Balance hält, eine modellübergreifende Prüfung, bei der ein Modell die Fehler des anderen abfängt, und deterministischer Code für alles, was keine Kreativität braucht.
Für Teams, die Ähnliches aufbauen wollen, heißt das: Der erste Schritt ist nicht die Modellauswahl, sondern die Frage, wie ihr einen Fund beweisen würdet. Wer diese Antwort hat, kann Modelle austauschen, ohne die Pipeline neu zu erfinden. Wer sie nicht hat, bekommt bei jedem Modellwechsel eine neue Runde Fehlalarme und irgendwann keine Lust mehr. Ein agentisches Harness für Sicherheitsprüfungen ist Infrastruktur, kein Werkzeug. Vergleichbar mit einer CI-Kette: Im Betrieb fällt es kaum auf. Im Ergebnis zählt es.
Der Montagmorgen aus dem ersten Absatz: ein Pull Request mit einem Test, der einen Fehler zeigt, einer Erklärung, warum er zählt, und einem Patch, der ihn behebt. Dass dieser PR entstehen konnte, liegt nicht an einem besonders klugen Modell. Es liegt an einer Umgebung, die kluge Modelle nur das weitergeben lässt, was sie beweisen können.
Quelle: shopify.engineering
