Jeder Pod, der nicht explizit etwas anderes sagt, bekommt beim Start ein API-Credential seines ServiceAccounts gemountet, projiziert als Datei unter /var/run/secrets/kubernetes.io/serviceaccount/token. Für die meisten Workloads, die nie mit der Kubernetes-API sprechen, ist das ein Credential, das einfach herumliegt, ohne dass es jemand bewusst dort platziert hat. Dieser Artikel zeigt, wie du den Automount gezielt abschaltest und wie du Tokens stattdessen mit begrenzter Lebensdauer dort erzeugst, wo sie tatsächlich gebraucht werden.
automountServiceAccountToken: false auf dem ServiceAccount
Der Automount lässt sich direkt am ServiceAccount deaktivieren:
apiVersion: v1kind: ServiceAccountmetadata: name: ci-runner namespace: team-checkoutautomountServiceAccountToken: false
Jeder Pod, der ci-runner als ServiceAccount verwendet, bekommt damit standardmäßig kein Token mehr gemountet. Für Workloads, die ausschließlich bauen, testen oder Artefakte verschieben, ohne die Kubernetes-API anzusprechen, ist das die richtige Grundeinstellung: kein Zugriffsmittel ohne Zweck.
Die Pod-Ebene hat Vorrang
Nicht jeder Pod unter diesem ServiceAccount verhält sich gleich. Ein einzelner Debug- oder Diagnose-Pod braucht vielleicht doch API-Zugriff, ohne dass du dafür den ServiceAccount für alle anderen Pods wieder öffnen willst. Genau dafür lässt sich die Einstellung auf Pod-Ebene setzen, und bei einem Konflikt hat die Pod-Einstellung Vorrang vor der Einstellung am ServiceAccount:
apiVersion: v1kind: Podmetadata: name: debug-pod namespace: team-checkoutspec: serviceAccountName: ci-runner automountServiceAccountToken: true containers: - name: debug image: busybox:1.36 command: ["sleep", "3600"]
Dieser Pod bekommt trotz automountServiceAccountToken: false am ServiceAccount sein Token gemountet, weil die Pod-Spec das explizit überschreibt. Genauso funktioniert es andersherum: Ein ServiceAccount ohne diese Einstellung mountet standardmäßig, ein einzelner Pod kann das für sich gezielt abschalten. Die Regel ist in beide Richtungen nutzbar, nicht nur als globale Sperre. Für die Praxis bedeutet das: Du dokumentierst die Grundeinstellung am ServiceAccount für die Masse der Workloads und setzt den Pod-Override nur für die wenigen, namentlich benannten Ausnahmen, die ihn tatsächlich brauchen.
Das Token überlebt den Pod nicht
Wird ein Pod gelöscht, werden die darüber ausgestellten API-Credentials laut Kubernetes-Dokumentation automatisch entzogen, und zwar ungefähr 60 Sekunden nach dem Setzen des deletionTimestamp. Ein gemountetes Token ist also kein Credential, das nach dem Ende des Pods irgendwo weiterlebt. Das ändert nichts daran, dass es während der Laufzeit des Pods ein vollwertiges Zugriffsmittel ist. Wer es in dieser Zeit aus dem Pod herauskopiert, etwa über eine kompromittierte Anwendung, kann es bis zum Ablauf verwenden. Die automatische Entziehung begrenzt das Zeitfenster, sie schließt es nicht vorab.
Kurzlebige Tokens gezielt erzeugen
Statt dich auf das projizierte, an den Pod gebundene Token zu verlassen, lässt sich für denselben ServiceAccount jederzeit ein eigenständiges, zeitlich begrenztes Token erzeugen:
kubectl create token ci-runner --namespace team-checkout --duration 15m
Dieses Token ist unabhängig von einem laufenden Pod gültig, aber nur für die angegebene Dauer. Für einmalige Vorgänge außerhalb eines Pods, etwa einen manuellen API-Aufruf im Rahmen einer Fehlersuche, ist das die sauberere Variante gegenüber einem dauerhaft gemounteten Token: Du erzeugst exakt das Credential, das du für den konkreten Vorgang brauchst, und nicht mehr. Läuft die Dauer ab, ist das Token ohne weiteren Schritt wertlos, du musst es nicht separat widerrufen oder aufräumen.
Ob das Token danach tatsächlich etwas darf, prüfst du mit kubectl auth can-i --as=system:serviceaccount:team-checkout:ci-runner <verb> <resource>. Wie diese Prüfung im Detail funktioniert, steht bereits im RBAC-Artikel vom 04.09. und wird hier nicht wiederholt.
Abgrenzung zu zwei früheren Beiträgen
Im RBAC-Artikel vom 04.09. ging es um Role- und RoleBinding-Scoping, also darum, was ein ServiceAccount überhaupt darf. Hier geht es um die Token-Ebene selbst: ob ein Token automatisch im Pod landet, wie lange es gilt und wann es verschwindet. Beide Fragen gehören zusammen, sind aber nicht dasselbe.
Im Beitrag Kubernetes-Secrets: warum base64 kein Schutz ist vom 12.06. ging es um die fehlende Verschlüsselung des Secret-Objekts selbst, in dem ein Token historisch häufig gespeichert wurde. Hier geht es um Lebensdauer und Geltungsbereich des Tokens, unabhängig davon, wie oder ob es überhaupt als Secret-Objekt abgelegt ist.
Fazit
Automount abzuschalten und Tokens gezielt mit begrenzter Lebensdauer zu erzeugen sind zwei einfache Stellschrauben gegen eine Angriffsfläche, die in den meisten Clustern standardmäßig offen ist: ein Credential, das in jedem Pod liegt, ohne dass irgendjemand es dort bewusst platziert hat. Beide Stellschrauben kosten nichts außer der Entscheidung, sie zu setzen.
Fragen zur Token-Härtung in deinem Cluster: Schreib mir an mm@mhm-dl.de.
Über das Anmeldeformular für den Newsletter trägst du deine E-Mail-Adresse ein, kreuzt die Einwilligung an und bestätigst die Anmeldung danach per Mail. Mit der Anmeldung willigst du ein, dass der Newsletter unter anderem folgende Themen behandelt: Schulungen zu Docker, Kubernetes, CI/CD, Git-Workflows und DevSecOps-Werkzeugen sowie die Anforderungen aus NIS2, CRA und DORA und deren technische Umsetzung.
Kommentar verfassen