Software-Lieferkette unter Kontrolle: The Go Way

Software-Lieferkette unter Kontrolle: The Go Way
By Matthias Petermann / on 28.10.2025

Einführung

Digitale Souveränität beginnt nicht erst beim Betriebssystem oder der Cloud-Infrastruktur, sondern schon im Build-Prozess. Wer Software schreibt, hängt unweigerlich an externen Quellen – Bibliotheken, Paketregistern, Toolchains.

Nach Rust stellt sich uns auch für Go die Frage: 👉 Wie souverän kann man damit eigentlich entwickeln?

Go gilt als pragmatisch, einfach und zuverlässig – aber auch hier läuft der typische Build zunächst online. go get lädt Pakete aus dem Internet, go build zieht Abhängigkeiten aus dem Standard-Proxy proxy.golang.org. Das ist bequem – aber solange der Buildprozess auf Netzwerkzugriff angewiesen ist, bleibt er nicht vollständig autonom.


Warum Lieferkettensouveränität auch in Go zählt

Die Risiken sind dieselben wie in anderen Ökosystemen:

  • Ein Modul verschwindet aus der Registry.
  • Eine Version ändert sich unbemerkt.
  • Die CI-Pipeline bricht, wenn kein Internet verfügbar ist.

Wenn die Toolchain auf Online-Quellen angewiesen bleibt, ist sie kein geschlossenes System – und damit auch keine vollständig überprüfbare Lieferkette.

Souveränität bedeutet hier:

Jede Abhängigkeit, jede Version, jeder Buildschritt ist lokal vorhanden, nachvollziehbar und reproduzierbar.


Exkurs: Go’s Baukasten für reproduzierbare Builds

Go bringt im Kern schon fast alles mit, was man für eine souveräne Lieferkette braucht:

  • Go Modules (go.mod, go.sum) → definieren exakte Versionen aller Abhängigkeiten und sichern deren Integrität über Checksummen.

  • Vendoring (go mod vendor) → kopiert alle Abhängigkeiten ins Projektverzeichnis.

  • Offline-Builds (-mod=vendor) → bauen komplett ohne Netzwerkzugriff.

Damit lässt sich das gesamte Ökosystem isolieren und reproduzierbar halten – ähnlich wie bei Rusts cargo vendor.


Beispiel: Eine kleine REST-API mit Go

Als Beispiel dient eine minimalistische Echo-API auf Basis von Gin, einem populären HTTP-Framework.

Projektstruktur

myapi/
├── go.mod
├── go.sum
├── vendor/
└── main.go

Datei: go.mod

module example.com/myapi

go 1.23

require (
    github.com/gin-gonic/gin v1.10.0
)

Datei: main.go

package main

import (
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()

    r.POST("/echo", func(c *gin.Context) {
        var payload map[string]interface{}
        if err := c.BindJSON(&payload); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        c.JSON(http.StatusOK, payload)
    })

    r.Run(":3000")
}

Bis hierhin ein klassisches Online-Setup – beim ersten Build lädt Go die Dependency aus dem Internet:

go mod tidy
go build

Schritt 1: Alle Abhängigkeiten lokal spiegeln

Jetzt wird’s interessant: Mit einem einzigen Befehl lässt sich das gesamte Dependency-Ökosystem lokal einfrieren:

go mod vendor

Das erzeugt ein vendor/-Verzeichnis mit allen benötigten Paketen aus go.mod – einschließlich transitive Dependencies.


Schritt 2: Offline-Build erzwingen

Ab jetzt kann das Projekt komplett ohne Internet gebaut werden:

go build -mod=vendor

Go nutzt nur noch die Quellen aus vendor/. Kein Download, kein externer Zugriff, keine Registry-Abhängigkeit.

Wer ganz sicher gehen will, löscht den Modulcache vorher:

go clean -modcache
go build -mod=vendor

Wenn der Build trotzdem funktioniert → ✅ 100 % offline-fähig.


Schritt 3: Lieferkette einfrieren

Damit ist die komplette Software-Lieferkette nachvollziehbar:

  • go.mod und go.sum sichern exakte Versionen und Checksummen.
  • vendor/ enthält den Quellcode aller Abhängigkeiten.
  • Der Build ist reproduzierbar – sogar Jahre später.

Empfohlen wird, das vendor/-Verzeichnis ins Versionskontrollsystem aufzunehmen:

git add vendor/
git commit -m "Vendored all dependencies for offline build"

So lässt sich der Stand des gesamten Ökosystems archivieren.


Bonus: Vollständige Isolation im CI/CD

In einer sicheren Umgebung (z. B. ohne Internetzugang) lässt sich der Build deterministisch ausführen:

# Keine Netzwerkverbindungen erlaubt
export GOPROXY=off
go build -mod=vendor ./...

Damit verlässt der Buildprozess nie die eigene Infrastruktur – ideal für sicherheitskritische, abgeschottete Systeme.


Rust vs. Go – zwei Wege zur Souveränität

Aspekt Rust Go
Buildsystem Cargo (integriert) Go Modules
Registry crates.io (Registry + Source Storage) proxy.golang.org (Quelltext-Mirror + SumDB)
Lokalisierung cargo vendor go mod vendor
Offline-Build cargo build --offline go build -mod=vendor
Standard-Toolchain Komplett integriert Komplett integriert
Reproduzierbarkeit Sehr hoch Sehr Hoch

Beide Ökosysteme zeigen, dass digitale Souveränität kein Luxus, sondern eine technische Option ist – wenn man sie bewusst aktiviert.

Hinweis: Der Go-Proxy liefert keine Binärartefakte, sondern Quelltext-Snapshots (ZIP-Archive), deren Integrität über die öffentliche Checksum-Database kryptografisch abgesichert ist. Das Modell ist zentral organisiert, aber quelloffen spezifiziert und kann selbst betrieben werden (z. B. mit Athens).


Weiterführende Gedanken

Lizenz- und Abhängigkeitsanalyse

Tools wie go-licenses oder cyclonedx-gomod können auch offline eine vollständige SBOM (Software Bill of Materials) erzeugen – inklusive Lizenzinformationen.

Reproduzierbare Toolchain

Mit go install golang.org/dl/go1.23.1@latest lässt sich jede Go-Version lokal pinnen. So kann man Builds exakt auf Compiler-Ebene reproduzieren.

Archivierung & Langzeitverfügbarkeit

Ein vendor/-Archiv plus Go-Binary ergibt eine langfristig lauffähige Einheit – unabhängig von Registry-Verfügbarkeit oder Toolchain-Updates.


Einordnung: Wo die Lieferkette wirklich beginnt

Natürlich endet die Betrachtung einer souveränen Software-Lieferkette nicht beim Anwendungscode. Sie beginnt viel früher – bei der Firmware, dem Betriebssystem, der Toolchain und letztlich beim Compiler selbst. Jede dieser Ebenen ist Teil der Vertrauenskette und kann zum Schwachpunkt werden, wenn sie nicht nachvollziehbar oder reproduzierbar ist.

Im Rahmen einer professionellen Risikobewertung sollte daher immer auch geprüft werden, welche Bestandteile der Entwicklungs- und Ausführungsumgebung tatsächlich unter eigener Kontrolle stehen. Es schadet nicht, die Werkzeuge im eigenen Werkzeugkasten so weit zu beherrschen, dass sie im Zweifelsfall selbst reproduziert oder unabhängig bereitgestellt werden können.

So weit wollen wir hier nicht gehen – doch Projekte wie NetBSD mit pkgsrc zeigen eindrucksvoll, dass es möglich ist, komplette System- und Build-Umgebungen deterministisch und quelloffen aufzubauen. Ein Blick dorthin lohnt sich für alle, die die Souveränität ihrer Lieferkette wirklich zu Ende denken wollen.


Fazit: Go beweist, dass sich auch pragmatische Sprachen souverän nutzen lassen. Mit Modulen, exakter Versionierung und konsequentem Vendoring entsteht eine kontrollierte, reproduzierbare und offline-fähige Lieferkette – ein kleiner Schritt für Go, aber ein großer für digitale Selbstbestimmung.


Bildnachweis: Thumbnail-Illustration inspiriert vom Go Gopher, entworfen von Renée French. Verwendet unter der CC BY 3.0-Lizenz.