Wer in einem Docker-Build einen Token braucht, greift schnell zu ARG und --build-arg. Das funktioniert, hat aber einen Haken: der Wert landet in der Build-Historie und oft auch in einem Layer. Wer das Image später zieht, kann ihn auslesen. BuildKit löst das mit Secret-Mounts, die nur zur Build-Zeit sichtbar sind und in keinem Layer stehen. Ich zeige, wie das konkret aussieht.

Warum Build-Args und COPY Secrets durchreichen

Ein ARG ist kein Geheimnis. Er steht im Klartext in den Image-Metadaten und lasst sich mit einem einzigen Befehl wieder herausholen. Dasselbe gilt, wenn eine Datei mit Zugangsdaten in einen fruhen Layer kopiert und in einem spateren Schritt geloscht wird: der Layer mit der Datei bleibt erhalten, das spatere rm uberdeckt ihn nur.

docker build --build-arg NPM_TOKEN=geheim -t app .
docker history --no-trunc app | grep NPM_TOKEN
# der Token steht im Klartext in der History

Der Mechanismus: –mount=type=secret

BuildKit hangt ein Secret nur fur die Dauer eines einzelnen RUN-Schritts in das Dateisystem ein, standardmassig unter /run/secrets/. Nach dem Schritt ist es weg und wird nie Teil eines Layers. Die erste Zeile im Dockerfile aktiviert die passende Syntax.

# syntax=docker/dockerfile:1.7
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) npm ci
COPY . .

Der Token wird innerhalb des RUN-Schritts aus /run/secrets/npm_token gelesen und als Umgebungsvariable an npm ci gegeben. Er existiert nur in diesem einen Prozess.

Build aufrufen

Das Secret wird beim Build ubergeben, entweder aus einer Datei oder direkt aus einer Umgebungsvariable des Build-Hosts. Der Wert taucht danach nirgends im Image auf.

# aus einer Datei
docker build --secret id=npm_token,src=$HOME/.npm_token -t app .
# aus einer Umgebungsvariable
export NPM_TOKEN=geheim
docker build --secret id=npm_token,env=NPM_TOKEN -t app .

SSH-Zugriff als Sonderfall

Fur private Git-Repos im Build gibt es einen eigenen Mount-Typ, der den SSH-Agent des Hosts durchreicht, ohne den Schlussel selbst ins Image zu bringen.

# syntax=docker/dockerfile:1.7
FROM alpine/git
RUN --mount=type=ssh git clone git@github.com:firma/privates-repo.git
docker build --ssh default -t app .

Prufen, ob wirklich nichts im Image liegt

Zwei Kontrollen reichen. Die History darf das Secret nicht enthalten, und ein Blick in die Layer bestatigt, dass keine Datei mit dem Wert zuruckbleibt.

docker history --no-trunc app | grep -i token # sollte leer sein
docker run --rm app printenv | grep -i token # sollte leer sein

Wer es genauer will, nutzt dive und geht die Layer einzeln durch. Wenn der Token weder in History noch in einem Layer noch in der Laufzeit-Umgebung steht, ist er sauber aus dem Image draussen.

Grenzen

Secret-Mounts schutzen das fertige Image, nicht den Build-Host. Wer dort die Umgebungsvariable oder die Token-Datei liest, hat den Wert weiterhin. Der Build-Runner braucht also die gleiche Least-Privilege-Disziplin wie jeder andere Ort, an dem Zugangsdaten liegen. Und ein Secret-Mount ersetzt keine Rotation: ein einmal geleakter Token bleibt gultig, bis er gedreht wird.

Wie Secret-Handling im Build in eine durchgehende Pipeline passt, zusammen mit Signieren und Scan, habe ich auf digital-business.blog ausfuhrlicher beschrieben.

3 Antworten zu „BuildKit-Secret-Mounts statt Build-Args: Secrets aus den Image-Layern halten“

  1. […] Control im Cluster), BuildKit-Secret-Mounts, damit Zugangsdaten erst gar nicht im Image landen (14.08.). Dieser Post erklärt Kyverno/Policy-Controller-Setup nicht erneut, sondern baut die dort […]

  2. […] Workflows abgrenzt, liest du im Post vom 17.08.. Wie du Secrets aus Build-Layern heraushältst, im Post vom 14.08.. Wie ephemere Runner die Isolation zwischen Läufen sauber halten, im Post vom […]

  3. […] er so lange weiter, bis jemand den Diebstahl bemerkt und den Key widerruft. Genau dieses Muster, gespeicherte, langlebige Credentials in der Pipeline, ist der wiederkehrende Fund in Berichten zu […]

Hinterlasse einen Kommentar

Diese Seite verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden..