Connect with us

Entwicklung & Code

Deutsche Fachsprache, englischer Code: Wo verläuft die Grenze?


close notice

This article is also available in
English.

It was translated with technical assistance and editorially reviewed before publication.

Am Ende eines Modellierungsworkshops sieht das dafür genutzte Whiteboard oft beeindruckend aus. Zettel in mehreren Farben kleben darauf, Pfeile dazwischen verweisen auf Zusammenhänge, und auf den Pfeilen stehen die Begriffe, um die drei Tage lang gerungen wurde: „Rechnungsstellung“, „Mahnlauf“, „Teilzahlung“, „Storno“. Die Fachabteilung nickt, die Entwicklerinnen und Entwickler nicken, und alle haben zum ersten Mal seit Monaten das Gefühl, über dieselbe Sache zu sprechen.

Weiterlesen nach der Anzeige

Eine Woche später öffne ich das Repository, und die erste Klasse heißt InvoiceService. Nicht aus Trotz, nicht nach einer Diskussion, sondern weil es sich beim Tippen so angefühlt hat, wie Code eben aussieht. Zwischen Whiteboard und Repository liegt eine Entscheidung, die niemand getroffen hat, und um die es in diesem Beitrag geht.

Ich halte diesen Reflex durchaus für nachvollziehbar. Immerhin: Alles, woraus Entwicklerinnen und Entwickler ihr Handwerk lernen, ist englisch: die Schlüsselwörter der Sprache, die Signaturen der Standardbibliothek, die Dokumentation der Frameworks, die Antworten auf Stack Overflow. Wer den ganzen Tag „for“, „return“ und „Repository“ liest, schreibt beim nächsten Bezeichner nicht plötzlich auf Deutsch weiter.

Dazu kommt ein Argument, das in jeder dieser Diskussionen fällt: die internationale Lesbarkeit. Wenn morgen jemand aus einem anderen Land ins Team kommt, soll der Code lesbar und verständlich bleiben. Das Argument ist nicht falsch, es ist nur in den meisten Fällen unbelegt, weil das betreffende Team seit acht Jahren aus denselben sechs Personen in derselben Stadt besteht und sämtliche Anforderungen seit jeher auf Deutsch bekommt.


the next big thing – Golo Roden

the next big thing – Golo Roden

Golo Roden ist Gründer und CTO von the native web GmbH. Er beschäftigt sich mit der Konzeption und Entwicklung von Web- und Cloud-Anwendungen sowie -APIs, mit einem Schwerpunkt auf Event-getriebenen und Service-basierten verteilten Architekturen. Sein Leitsatz lautet, dass Softwareentwicklung kein Selbstzweck ist, sondern immer einer zugrundeliegenden Fachlichkeit folgen muss.

Es gibt außerdem noch einen Grund, den allerdings kaum jemand ausspricht: Englisch im Code sieht nach Professionalität aus. Ein Bezeichner wie createInvoice wirkt wie Software, rechnungErstellen wirkt wie ein Provisorium aus dem Rechnungswesen. Dieses Gefühl ist unter Entwicklerinnen und Entwicklern durchaus real und verbreitet. Und zugleich ist es der schwächste aller Gründe, weil es über die Fachlichkeit rein gar nichts aussagt.

Vor allem aber gelten diese Gründe für die Technik. Dass HttpClient nicht HttpKlient heißen sollte, wird wohl niemand bestreiten, und ich persönlich möchte eine solche Umbenennung auch nicht. Der Reflex wird erst dort teuer, wo er auf Fachlichkeit trifft, und dieser Übergang ist so fließend, dass er im Alltag nicht auffällt.

Weiterlesen nach der Anzeige

Sobald das Thema nach der zu verwendenden (natürlichen) Sprache aufkommt, kippt die Diskussion üblicherweise binnen weniger Minuten in einen Streit über Geschmack. Jemand schreibt rechnungErstellen auf das Whiteboard, jemand anderes verzieht das Gesicht, und ab da geht es um Denglisch, um Umlaute in Bezeichnern und um die Frage, ob das nicht furchtbar aussehe. Genau diese Diskussion ist die Ursache dafür, dass sich an der Sprachfrage nie etwas ändert. Sie verbraucht die gesamte Aufmerksamkeit für den unwichtigsten Teil des Problems.

Deshalb möchte ich einen Test voranstellen, der die beiden Ebenen sauber trennt. Übersetzen Sie einen Namen und prüfen Sie danach, ob sich mit dem Vokabular noch genau dieselben Unterscheidungen ausdrücken lassen wie vorher. Ist das so, handelt es sich um eine Stilfrage. Fehlt hinterher eine Unterscheidung, ist es eine Modellierungsfrage.

rechnungErstellen und createInvoice bezeichnen exakt denselben Vorgang, und es geht keine Unterscheidung verloren. Deshalb ist das eine Stilfrage, also eine Teamkonvention, und darüber lohnt keine lange Debatte. Wenn dagegen „Verfügbarkeit“ und „Einsatzbereitschaft“ im Code beide zu availability werden, dann hat sich das Modell verändert.

Nebenbei erledigt derselbe Test die Umlautfrage, die sonst garantiert als erstes aufkommt. Ob im Code Verfügbarkeit oder Verfuegbarkeit steht, ändert keine einzige Unterscheidung. Insofern fällt auch das unter Stil und Konvention, ist also die Diskussion nicht wert.

Der Verlust, um den es hier inhaltlich geht, ist deshalb so schwer zu bemerken, weil das englische Wort durchaus existiert und auf den ersten Blick vollkommen passend wirkt: „availability“ ist keine schlechte Übersetzung von „Verfügbarkeit“, sondern im Gegenteil sogar eine gute. Es ist nur leider zugleich auch eine gute Übersetzung von „Einsatzbereitschaft“, und in einer Domäne, in der ein Fahrzeug verfügbar sein kann, ohne einsatzbereit zu sein, hängen an diesem Unterschied später wichtige fachliche Entscheidungen.

Am häufigsten sehe ich das Muster bei Vorgängen, die im Deutschen fein aufgefächert sind. „Auftrag“, „Bestellung“ und „Abruf“ sind in vielen Unternehmen drei verschiedene Dinge mit drei verschiedenen Rechtsfolgen, drei verschiedenen Beteiligten und drei verschiedenen Zeitpunkten. Im Code heißen sie dann alle order, und zwar nicht, weil jemand die drei für dasselbe hielte, sondern weil das englische Wort auf alle drei anwendbar ist.

Der Moment des Verlusts ist dabei unsichtbar, und das macht ihn so heimtückisch. Er tritt zum Beispiel ein, wenn eine einzelne Person spät am Abend noch schnell eine Klasse anlegt und dafür ein Wort wählt. Es gibt keine Diskussion, kein Review hakt nach, und die Fachabteilung bekommt den Namen ohnehin nie zu sehen. Erst wenn Monate später der zweite der drei Vorgänge modelliert werden soll, stellt sich heraus, dass der beste Name bereits vergeben ist, und dann heißt der zweite eben specialOrder.

Schlimmer als der Hinweg ist der Rückweg. Solange nur übersetzt wird, weiß das Team noch, was gemeint war; das Wissen sitzt in den Köpfen derjenigen, die im Workshop dabei waren. Zwei Jahre später aber liest jemand order im Code, die Fachabteilung liest „order“ im Bericht, und beide Seiten raten, welcher der drei Vorgänge gemeint ist.

Nicht selten raten beide Seiten falsch und der Fehler gehört leider zu der Sorte, die keinen Test rot werden lässt. Er zeigt sich als Auswertung, die nicht stimmt, als Prozess, der an einer Stelle hakt, oder als Diskussion darüber, ob eine Zahl im Report die richtige ist. Ich habe an anderer Stelle darüber geschrieben, wie stark die Wortwahl bestimmt, ob ein System eine Geschichte erzählt oder einen Polizeibericht. Die Sprachwahl liegt jedoch noch eine Ebene darüber. Sie entscheidet, welche Wörter überhaupt zur Auswahl stehen.

Es gibt Domänen, in denen diese Abwägung gar nicht erst stattfindet, weil die Sprache vorgegeben ist. „Umsatzsteuer“ ist nicht „VAT“. Die beiden Begriffe beschreiben ähnliche Konzepte, sie sind aber in unterschiedlichen Rechtsordnungen definiert, und sobald es um Sätze, Fristen, Ausnahmen und Meldepflichten geht, laufen sie auseinander.

Zur „Vorsteuer“ gibt es überhaupt kein Gegenstück, das ein englischer Begriff in einem Wort einfängt. Ein „Mahnbescheid“ ist kein „reminder“, eine „Kündigungsfrist“ (im arbeitsrechtlichen Sinn) keine „notice period“, und ein „Betriebsrat“ ist kein „works council“ mit denselben Befugnissen. Wer solche Begriffe übersetzt, macht sie nicht ungenauer, sondern falsch.

Hier ist die Domänensprache nicht Ausdruck einer Vorliebe, sondern Teil der Anforderung. Das Gesetz definiert den Begriff, die Fachabteilung verwendet ihn, die Prüferinnen und Prüfer fragen danach. Ein Modell, das an dieser Stelle übersetzt, weicht nicht vom Geschmack ab, sondern von der Rechtslage.

Was in solchen Domänen passiert, wenn trotzdem übersetzt wird, lässt sich gut beobachten. Im Code steht tax, im Gespräch mit der Steuerberatung steht „Umsatzsteuer“, und zwischen beidem sitzt eine Person, die den Übergang im Kopf leistet. Solange diese Person da ist, funktioniert das. Wechselt sie die Stelle oder kommt eine Prüfung ins Haus, muss jemand rekonstruieren, welcher steuerliche Begriff hinter welchem Feld steckt, und diese Rekonstruktion ist reine Archäologie.

Die Schweiz treibt das noch weiter: Dort ist Bundesrecht auf Deutsch, Französisch und Italienisch gleichermaßen verbindlich, drei Fassungen desselben Gesetzes, keine davon ist das alleingültige Original und keine davon ist einfach nur eine Übersetzung. Ein Team, das für diesen Markt entwickelt, hat nicht die Wahl zwischen drei Sprachen, sondern die Aufgabe, drei gleichwertige Vokabulare in einem Modell unterzubringen.

Damit komme ich zu der Frage, die mir in solchen Diskussionen wohl am häufigsten gestellt wird, und sie ist vollkommen berechtigt: Wo genau soll die Grenze verlaufen? Soll wirklich alles im System auf Deutsch geschrieben werden?

Die Antwort darauf lautet nein, und es gibt ein Kriterium, an dem man diese Antwort festmachen kann: Ein Name gehört dann in die Domänensprache, wenn Fachexpertinnen und Fachexperten ihn korrigieren könnten. Legen Sie ihnen RechnungAusgestellt vor, können sie widersprechen: Das heiße im Haus „Rechnungsstellung“ und das sei etwas anderes als „Rechnungsversand“. Legen Sie ihnen HttpClient vor, können sie nichts dazu beitragen, weil der Name in ihrer Domänensprache keine Bedeutung hat.

Praktisch anwenden lässt sich das Kriterium mit einem Vorlesetest. Nehmen Sie die Namen der Events und Commands eines Moduls, lesen Sie sie der Fachabteilung vor und beobachten Sie, was passiert. Kommt Widerspruch, Nachfrage oder ausdrückliche Zustimmung, dann gehören diese Namen in die Domänensprache, unabhängig davon, in welcher sie gerade geschrieben sind. Kommt ein ratloser Blick, sind Sie in der Technik gelandet, und der Name ist dort richtig aufgehoben.

Dieses Kriterium hängt nicht an Schichten, Ordnern oder Namensräumen, sondern daran, wer über den Namen urteilen kann. Deshalb funktioniert es auch in Codebasen, in denen die Schichtung längst aufgeweicht ist. Es liefert eine erstaunlich klare Aufteilung: Aggregate, Events, Commands, fachliche Zustände und fachliche Fehler tragen die Domänensprache, während Frameworks, technische Bausteine, Logs und Metriken englisch bleiben.

Gemischte Bezeichner wie RechnungRepository sind nach diesem Kriterium kein Sündenfall, sondern die sichtbar gewordene Naht zwischen beiden Welten. Der fachliche Teil des Namens sagt, worum es geht, der technische, wie es umgesetzt ist. Ich halte das nicht für einen faulen Kompromiss, sondern für ehrlicher als jede der beiden reinen Varianten. Persönlich gefällt es mir vom Stil her zugegebenermaßen nicht, aber darüber kann ich hinwegsehen, weil ich die dahinterliegende Überlegung für die wichtigere halte.

Kommentare, Commit-Messages und Dokumentation fallen dagegen unter das erste Kriterium: Sie lassen sich übersetzen, ohne dass eine Unterscheidung verloren geht. Damit sind sie Konvention, und jedes Team darf sie regeln, wie es möchte.

Der Fall, an dem sich das Kriterium bewähren muss, ist die Schnittstelle nach außen. Hier bricht die Diskussion regelmäßig neu aus, meist mit dem Argument, eine API müsse selbstverständlich englisch sein. Ich halte die Frage in dieser Form für falsch gestellt.

Die bessere Frage lautet: Ist diese Schnittstelle Teil des Modells oder eine Veröffentlichung davon? Eine API, die ausschließlich andere Systeme derselben Domäne bedient, gehört zum Modell. Sie spricht dessen Sprache, und dort zu übersetzen heißt, genau den Verlust eine Ebene weiter außen einzubauen, den der Kern gerade vermieden hat.

Diese Unterscheidung ist deshalb so nützlich, weil sie eine Frage beantwortet, die sich sonst bei jedem einzelnen Feld neu stellt. Ein Team muss nicht für jede Route und jedes Attribut erneut abwägen, sondern einmal je Schnittstelle festlegen, auf welcher Seite der Grenze sie steht. Danach ergibt sich die Sprache von selbst, und die Diskussion verlagert sich von der Namenswahl auf die Frage, wer diese Schnittstelle eigentlich nutzt. Das ist die deutlich produktivere Frage.

Eine API mit fremden, international verteilten Konsumentinnen und Konsumenten ist etwas anderes. Sie ist eine Kontextgrenze, und an Kontextgrenzen ist Übersetzung nicht nur erlaubt, sondern die saubere Lösung. Entscheidend ist, dass sie explizit stattfindet, mit einem dokumentierten Mapping, das jemand lesen und prüfen kann.

Explizit heißt vor allem: Wo zwei Fachbegriffe auf ein englisches Wort fallen würden, müssen sie getrennt bleiben. Ein Fahrzeug, das verfügbar, aber nicht einsatzbereit ist, braucht in der übersetzten Fassung zwei Felder statt einem:


{
  "vehicleId": "8f2c1a",
  "available": true,
  "operational": false
}


Dazu gehört die Festlegung, dass available für die Verfügbarkeit steht und operational für die Einsatzbereitschaft, und zwar dort, wo sie später auch jemand sucht. Fehlt sie, sucht sich in zwei Jahren jede Konsumentin und jeder Konsument eine eigene Deutung, und die Unterscheidung zerfällt genau dort wieder, wo sie mühsam erhalten wurde.

Der Fehler ist also nicht die englische Schnittstelle. Der Fehler ist die stillschweigende Schnittstelle, bei der die Übersetzung im Kopf einer einzelnen Person stattgefunden hat und nirgends aufgeschrieben wurde. Sprachgrenzen sind Kontextgrenzen, und Kontextgrenzen gehören dokumentiert.

Bis hierhin gilt alles Gesagte unabhängig davon, wie ein System seine Daten hält. Es gibt allerdings eine Architektur, in der die Sprachfrage eine deutlich schärfere Form annimmt, und das ist Event Sourcing.

In einem klassischen System, das Zustände überschreibt, ist ein Name eine Refactoring-Entscheidung. Fällt in zwei Jahren auf, dass order drei Vorgänge vermengt, benennt jemand um, passt die Datenbankspalten an, und nach einer Stunde ist die Sache erledigt. Unangenehm, aber ohne Nachwirkung.

Events sind unveränderlich, und das ist ihr Sinn. Ein Event, das vor sieben Jahren als InvoiceIssued geschrieben wurde, heißt in sieben weiteren Jahren immer noch so, und mit ihm ist auch jede Unterscheidung konserviert, die beim Benennen verlorenging. Ob ein bestimmtes order-Event einen Auftrag, eine Bestellung oder einen Abruf meinte, lässt sich nachträglich nicht rekonstruieren, wenn die Information nie im Event stand.

Damit ist der Name eines Events keine Refactoring-Entscheidung mehr, sondern eine Festlegung mit einer Lebensdauer von Jahrzehnten. Ich kenne wenige andere Stellen in der Softwareentwicklung, an denen eine beiläufige Wortwahl so lange nachwirkt. Wer Event Sourcing einsetzt, sollte die Sprachfrage deshalb nicht beiläufig im Code beantworten, sondern bewusst vor dem ersten geschriebenen Event.

Eine allgemeingültige Antwort auf die Sprachfrage gibt es nicht, und ich misstraue jedem, der sie anbietet. Es gibt Domänen, in denen Englisch die richtige Wahl ist, es gibt Teams, für die Deutsch die einzig sinnvolle ist, und es gibt Systeme, in denen beides nebeneinander steht, sauber getrennt an einer dokumentierten Grenze.

Ein klarer Fehler ist es dagegen, die Sprachfrage nie zu stellen. Dann entscheidet sie sich nämlich trotzdem, nur eben nebenbei: durch den ersten Commit, durch die Vorlage eines Frameworks oder durch diejenige Person, die am lautesten für ihre Gewohnheit argumentiert. Wie teuer es wird, wenn Software rein technisch gedacht wird, habe ich an anderer Stelle beschrieben; die Sprachfrage ist ein Musterfall dafür, weil sie technisch aussieht und fachlich ist.

Der Aufwand, es besser zu machen, ist überschaubar. Es braucht eine Stunde im Team, die beiden Kriterien aus diesem Beitrag und die Bereitschaft, das Ergebnis aufzuschreiben. Domain-Driven Design ist an vielen Stellen komplizierter gemacht worden, als es sein müsste. An dieser Stelle ist es tatsächlich einmal einfach.


(mro)



Source link

Entwicklung & Code

AWS Emulator im Detail: Die ganze Cloud auf dem eigenen Rechner?


close notice

This article is also available in
English.

It was translated with technical assistance and editorially reviewed before publication.

Amazon Web Services (AWS) hat einen eigenen AWS Emulator veröffentlicht. Er bildet die AWS-APIs auf dem eigenen Rechner nach, AWS CLI, SDKs und Coding-Agenten schicken ihre Aufrufe an einen lokalen HTTPS-Endpunkt. Mit seinem Stolz darauf, dass der Emulator vollständig von KI-Agenten entwickelt wurde, setzte sich AWS aber direkt in die Nesseln: Die Rezeption fiel kritisch aus – wie bei hundertprozentig KI-generierter Software zurzeit üblich – und dem Vergleich mit etablierten Drittanbieter-Tools wie LocalStack hält der Emulator wohl noch nicht stand.

Weiterlesen nach der Anzeige

Entwickler könnte er dennoch interessieren: AWS-Anwendungen lassen sich ohne Deployment lokal testen, CI/CD-Pipelines brauchen keine AWS-Zugangsdaten mehr und – was AWS besonders unterstreicht – Coding-Agenten können schneller und risikoärmer Ressourcen anlegen und Ergebnisse prüfen. AWS bringt also agentisch entwickelte Software für die Entwicklung mit Agenten. Es fällt keine Servicegebühr an, ein AWS-Konto braucht es nicht und der Quellcode steht unter der CC0-Lizenz auf GitHub.

iX-plore ist die Online-Serie des iX-Magazins für alle, die neue Tools und Technologien entdecken möchten. In kurzen Beiträgen stellen wir vor, was sie können, wofür sie sich eignen und warum sich ein genauerer Blick lohnen könnte.

Der Emulator ist in Rust geschrieben, die Dienste erzeugt AWS aus denselben API-Modellen, aus denen auch die SDKs entstehen. Kommt ein Dienst oder eine API hinzu, tauchen sie im Emulator auf. Alle Dienste, für die ein Modell im öffentlichen Repository AWS API Models liegt, werden auch unterstützt.

Wie genau der Emulator AWS nachbildet, misst AWS mit Fidelity-Tests. Jeder Test ist ein kurzes Python-Programm, das über das AWS-SDK boto3 einen Ablauf durchspielt, etwa ein Objekt zu speichern, zu lesen und wieder zu löschen. Die Abläufe werden dann gegen die echte Cloud geprüft, als Referenz dient die Region US West (Oregon), während globale Dienste in US East (N. Virginia) geprüft werden. Der Emulator besteht einen Test nur, wenn bei jedem Aufruf Statuscode, Antwort, Fehlercode und Fehlermeldung mit der Cloud übereinstimmen, dasselbe gilt für die Ressourcen und Daten, die der Ablauf erzeugt. Die Testsuite umfasst Zehntausende Tests, ist öffentlich und enthält auch die, die noch scheitern. Mit dem Python-Programm fidelity_tests_runner können Nutzer die Tests lokal gegen den Emulator laufen lassen.

Trotz der hohen API-Abdeckung hat die Emulation aber bewusste Grenzen: Für Sicherheitstests eignet sich das Tool laut AWS nicht, da es weder IAM- noch ressourcenbasierte Richtlinien wie die echte Cloud auswertet. Auch Cross-Account- und Cross-Region-Szenarien bildet es nicht ab, sämtliche Aufrufe laufen unter einer festen Dummy-Konto-ID.

Jede Instanz des Emulators bekommt einen eigenen Port, eigene Schlüssel und einen eigenen Zustand im Arbeitsspeicher. Mehrere Agenten oder CI-Jobs teilen sich also keine Buckets, Tabellen oder Queues und arbeiten parallel, ohne sich gegenseitig Ressourcen zu überschreiben. Nutzer des AWS SDK for Rust können den Emulator außerdem im Embedded-Modus betreiben, wobei er direkt ins Test-Binary kompiliert wird. Er läuft dann im selben Prozess und der Test übergibt dem SDK einen HTTP-Client des Emulators statt des Netzwerk-Connectors. Auch hier sind die Instanzen voneinander isoliert, sodass Tests parallel laufen können.

Weiterlesen nach der Anzeige

Coding-Agenten können den Emulator mit dem Skill aws-emulator direkt installieren, starten und verbinden, dafür braucht es allerdings die AWS CLI ab Version 2.35.0. Solche Skills sind im Prinzip Markdown-Anleitungen, die der Agent bei Bedarf lädt. Der Befehl aws agent-toolkit add-skill in der AWS CLI installiert sie für alle Agenten, die es auf dem Rechner findet. Unter Linux gibt es RPM- und Debian-Pakete, unter Windows und macOS einen Docker-Container. Ein fertiges Docker-Image gibt es nicht, das müssen Nutzer aus einem kurzen Dockerfile aus der Dokumentation zusammenbauen. Standardmäßig sendet der Emulator anonymisierte Nutzungsdaten an AWS, was sich jedoch per Start-Flag oder Umgebungsvariable abschalten lässt.

Wer den Emulator selbst kompiliert, braucht Linux auf x86_64 oder aarch64, eine Rust-Toolchain, einen C-Compiler und mindestens 100 GByte freien Speicherplatz für die Build-Artefakte. Jeder emulierte Dienst ist ein eigenes Rust-Paket (Crate), weshalb schon ein Debug-Build sehr groß wird. Das gilt auch für den Embedded-Modus, denn der erste cargo test-Lauf kompiliert sämtliche Service-Crates des Emulators mit. AWS empfiehlt, das Build-Verzeichnis in der CI zu cachen und den Emulator auf einen Release-Commit festzulegen.

Matthew Goldberg, Senior Principal Engineer im Developer-Tools-Team von AWS, setzt mit dem Emulator eine KI-Duftnote: Nicht nur ist die Software vor allem auf das schnelle Testen von agentischer KI zugeschnitten, sondern sie ist laut Amazons Firmenblog auch ausschließlich von autonomen Agenten geschrieben. Das Team hat den Code weder verfasst noch geprüft. Goldberg beschreibt, wie ihn der autonome Bau eines C-Compilers von Agenten dazu inspirierte und der Emulator aus einem simplen Wochenendprojekt hervorging. Ein Team von Agenten pflegt die Testsuite, ein zweites sucht Abweichungen von der echten Cloud, ein drittes setzt die Korrekturen um. Jede Änderung muss zudem vor dem Merge ein automatisiertes Quality Gate passieren, an dem weitere Agenten unter anderem die Sicherheit des Codes kontrollieren.

Die autonome Entwicklung lässt sich in den Repository-Verzeichnissen issues/things-that-now-work und issues/things-that-do-not-work nachvollziehen, in die die Agenten hineinschreiben. Menschliche Hilfe von außen ist dabei nicht vorgesehen: Zwar können Nutzer auf GitHub Fehler melden, Pull-Requests nimmt AWS für das Projekt aber nicht an. Ganz unabhängig von dem Tool an sich ist hier also anschaulich zu sehen, in welche Richtung Softwareentwicklung gerade steuert – und wie die großen Systemhäuser versuchen, Vibe-Coding sinnvoll anzugehen.


(kki)



Source link

Weiterlesen

Entwicklung & Code

Gestohlene Token: Secret-Stealer in Tausenden GitHub-Repositories


Mit gestohlenen Zugriffstoken für GitHub-Konten schleusen unbekannte Angreifer seit Dienstag Schadcode in Repositories ein, der die Secrets aus GitHub Actions und Cloudzugangsdaten abgreift.

Weiterlesen nach der Anzeige

Das Sicherheitsunternehmen Aikido zählt im Rahmen der auf den Namen wfx-loot getauften Kampagne bereits 4837 übernommene Konten, über die die Angreifer 61.764 Repositories attackiert haben. In mehr als 1800 Fällen sollen Workflows den Schadcode bereits ausgeführt haben.

Die Angreifer nutzen anscheinend keine Lücke in GitHub Actions aus, sondern missbrauchen die Schreibrechte gestohlener Token. Woher diese stammen, ist nur teilweise geklärt. Laut Fly.io wurden Token seiner GitHub-App missbraucht, die aus öffentlich erreichbaren .git/config-Dateien stammten; der Hoster widerruft sie. Eine Stellungnahme von GitHub liegt noch nicht vor.

Das Sicherheitsunternehmen SafeDep hat Schadcode-Commits bereits in über 8000 öffentlichen Repositories gefunden. Noch am Donnerstagmittag listete die GitHub-Suche mehr als 66.000 der typischen Test-Pull-Requests, rund 4300 davon vom selben Tag.

Ähnlich wie zuletzt beim Wurm testmetest erreichen Angreifer laut Aikido über Mitwirkenden- und Organisationsrechte mit über 10.000 Test-Pull-Requests auch Repositories, die den übernommenen Konten nicht selbst gehören. Damit können auch Organisationen betroffen sein, deren eigene Zugangsdaten gar nicht gestohlen wurden. Dürfen die Workflows eines Repositorys auf AWS oder Azure zugreifen, nutzt der Schadcode die erbeuteten Zugänge, um Hintertüren in den Cloudkonten einzurichten.

Die Angreifer lassen ihren Opfern kaum Zeit zu reagieren. Sie öffnen zunächst einen Pull Request, um die Schreibrechte zu bestätigen. Dann folgt der eigentliche Schadcode: ein Shellskript, das die Angreifer in einen bestehenden Workflow einfügen, als neuen Workflow ablegen oder in npm-Projekten bei jeder Installation starten lassen.

Meist schon innerhalb einer Minute machen die Angreifer die Änderungen rückgängig und löschen den Workflow-Lauf samt Logs. Oft weist nur eine fehlende Laufnummer auf den Angriff hin. Eine Branch-Protection für vorgeschriebene Status-Checks kann das Skript mit gefälschten Erfolgsmeldungen aushebeln. Aikido zufolge setzt das Skript solche gefälschten Status-Checks tatsächlich ab; in den von SafeDep untersuchten Proben war diese Funktion dagegen nicht aktiviert.


Mit einem gestohlenen Token testen die Angreifer zuerst ihre Schreibrechte, bevor sie den Stealer auf einem von drei Wegen einschleusen und die Änderung wieder zurücknehmen.

Mit einem gestohlenen Token testen die Angreifer zuerst ihre Schreibrechte, bevor sie den Stealer auf einem von drei Wegen einschleusen und die Änderung wieder zurücknehmen.

Mit einem gestohlenen Token testen die Angreifer zuerst ihre Schreibrechte, bevor sie den Stealer auf einem von drei Wegen einschleusen und die Änderung wieder zurücknehmen.

(Bild: SafeDep)

Neben Token für KI-Dienste wie OpenAI, Anthropic oder Cursor fischt das eingeschleuste Skript insbesondere die Secrets aus GitHub Actions ab, außerdem Zugangsdaten für Clouddienste, Container-Umgebungen, Paketregister und SSH.

Weiterlesen nach der Anzeige

Haben die Bedrohungsakteure erst einmal Zugang zu Sitzungen bei AWS, Google Cloud und Azure, geht der Angriff weiter: Bei AWS öffnet das Skript eine IAM-Rolle für jedes AWS-Konto, in Azure trägt es zusätzliche Anmeldewege für Workflows aus dem kompromittierten Repository ein. Erbeutete Daten schickte das Skript laut Aikido in dieser Kampagne per HTTP an Server der Angreifer. SafeDep fand in untersuchten Payloads zudem eine Exfiltration über Telegram.

Entwicklerinnen und Entwickler, die seit Dienstag einen Branch wfx-docs, den Pull-Request docs: dependency audit notes oder Commits wie ci: refresh build cache, chore: add ci helper und chore: add dependency audit workflow in ihren Repositories finden, sollten das zugehörige Konto als kompromittiert ansehen, auch wenn noch kein Schadcode folgte. Verdächtig sind laut den Sicherheitsforschern von Aikido zudem kurzlebige Branches, die mit chore/ beginnen und auf acht Zufallszeichen enden. Betroffene sollten Token, OAuth-Freigaben und SSH-Schlüssel ihres Kontos widerrufen.

Wurde bereits Schadcode ausgeführt, müssen Betroffene neben dem Austausch der Secrets auch die Hintertüren eigens entfernen, etwa AWS-Rollen, die jedem Konto vertrauen, oder in Azure Federated Credentials mit dem Präfix wfx-ci-. Wer npm install auf einem betroffenen Commit ausgeführt hat, muss auch den eigenen Rechner als kompromittiert betrachten.

Der Schadcode gelangte auch in Paketdistributionen. Aikido nennt das Packagist-Paket digitalelvis/neuronai-studio 3.14.3 sowie die Go-Modul-Versionen github.com/onuragtas/docker-env v1.0.278 und v1.0.280. SafeDep führt darüber hinaus github.com/onuragtas/redock, eine weitere docker-env-Version und eine über den Go-Modul-Proxy verfügbare Pseudo-Version von github.com/vkuznet/gocurl auf. Bei den Go-Modulen liegt der Schadcode in einer GitHub-Actions-Workflow-Datei; ein gewöhnlicher Go-Build führt diese nicht aus. Wer ein solches Modul lediglich als Go-Abhängigkeit einbindet, ist dadurch wahrscheinlich nicht betroffen.


(mro)



Source link

Weiterlesen

Entwicklung & Code

htop für die Grafikkarte: GPU Taskman leuchtet den Grafikspeicher aus


close notice

This article is also available in
English.

It was translated with technical assistance and editorially reviewed before publication.

Mit GPU Taskman hat Microsoft-Vizepräsident und Softwareentwickler Scott Hanselman einen quelloffenen Task-Manager für Grafikkarten veröffentlicht. Das auf GitHub entwickelte Programm läuft unter Windows, Linux einschließlich WSL und macOS auf Apple Silicon. Seine Terminaloberfläche verbindet eine Prozessliste mit Gerätedaten zu Speicherbelegung, Auslastung, Temperatur, Leistungsaufnahme und Taktraten. Zu einzelnen Prozessen liefert es außerdem Hinweise auf erkannte Runtimes und Modelle. Welche Messwerte verfügbar sind, hängt von Betriebssystem, GPU, Treiber und Zugriffsrechten ab.

Weiterlesen nach der Anzeige

GPU Taskman liest dafür nicht beliebige Inhalte des Grafikspeichers aus, sondern kombiniert mehrere Informationsquellen. Unter Windows stammen die prozessbezogenen Speicher- und Aktivitätswerte aus den Performance-Countern des Betriebssystems, Nvidias NVML und AMDs ADL ergänzen Gerätedaten. Geladene Bibliotheken geben Hinweise auf die Runtime. Per Memory-Mapping eingebundene Dateien und Kommandozeilenargumente helfen bei der Modellerkennung. Unterstützte lokale Server-APIs liefern zusätzliche Angaben.

Bei Modellen im GGUF-Format kann das Programm unter anderem Modellname, Parameterzahl und Quantisierung anzeigen sowie den Speicherbedarf von Gewichten und KV-Cache abschätzen. Der KV-Cache hält bereits berechnete Key- und Value-Vektoren der Attention-Schichten vor. Ein größeres Kontextfenster kann deshalb mehr Speicher erfordern, obwohl die Modellgewichte unverändert bleiben. GPU Taskman stellt solche Schätzungen dem gemessenen Speicherverbrauch des Prozesses gegenüber.

Dabei kennzeichnet das Tool die Herkunft seiner Angaben: Messungen, Schlussfolgerungen, Schätzungen und Angaben einer Laufzeitumgebung sind nicht gleichzusetzen. Eine Modelldatei auf der Festplatte beweist beispielsweise noch nicht, dass ein Prozess sie gerade verwendet. Nicht verfügbare Zähler erscheinen als unbekannt, nicht als null Speicherverbrauch. In Summen gehen nur gemessene Speicherwerte ein.

Laut den Release Notes ergänzte Version 0.3.5 die Unterstützung für Intel-GPUs unter Linux mit den Treibern i915 und xe. Hinzu kamen eine Übersicht für CPU- und RAM-Auslastung sowie entsprechende Spalten je Prozess. Der Befehl gputaskman record zeichnet in regelmäßigen Abständen JSON-Snapshots auf. Damit lässt sich zum Beispiel verfolgen, wie sich die Speicherbelegung während eines Testlaufs verändert.

Version 0.4.0 ergänzt unter Linux weitere Intel-Messwerte: die Auslastung der GPU und ihrer Video-Engine sowie die Leistungsaufnahme integrierter Intel-GPUs. Für diese zusätzlichen Messwerte benötigt das Programm unter Linux Root-Rechte. Ohne sie zeigt es die betreffenden Werte als nicht verfügbar an und nennt den Grund. Außerdem bringt das jüngste Update ein Linux-Backend für Huaweis Ascend-NPUs vom Typ 310P. Über npu-smi erfasst es jetzt Geräte- und Prozessspeicher sowie Aktivitätsdaten der KI-Beschleuniger.

GPU Taskman ist in Python geschrieben und steht unter der MIT-Lizenz. Für die Installation als Python-Paket setzt es Python 3.11 oder neuer voraus. Mit uv tool install gputaskman oder pipx install gputaskman lässt es sich in einer isolierten Umgebung installieren. Anschließend startet es mit gputaskman oder gtm.

Weiterlesen nach der Anzeige

Für Windows bietet das Projekt außerdem portable ZIP-Pakete für x64 und ARM64, die keine separate Python-Installation benötigen. Beim Entpacken muss das vollständige Paket einschließlich des Verzeichnisses _internal erhalten bleiben. Die Entwickler bezeichnen das Programm ausdrücklich als frühe, experimentelle Software – insbesondere die Modellzuordnungen und berechneten Speicheraufteilungen sind keine direkten Messungen.


(fo)



Source link

Weiterlesen

Beliebt