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.modundgo.sumsichern 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.