Langlebige Authentifizierungs-Tokens sind eine tickende Zeitbombe. Jeder weiß, dass sie ein Risiko sind, doch Bequemlichkeit (»war halt der einfachste Weg«) oder technische Altlasten halten sie am Leben. Zugegeben, sie wirken harmlos und sind einfach zu handhaben. Aber sie sind ein Albtraum für jede:n IT-Verantwortliche:n: Was passiert beim Offboarding? Ist wirklich jeder Token rotiert? Wie weisen wir beim nächsten Audit lückenlos nach, wer wann Zugriff hatte? Dieses Risiko schlummert im Verborgenen, bis es zu spät ist.
Die gute Nachricht: Es gibt einen besseren Weg, der modernen CI/CD Security Best Practices entspricht. Der Wechsel zu kurzlebigen, dynamischen Credentials via OIDC-Trust mit AWS und GitLab eliminiert dieses Risiko und automatisiert den Zugriff. Und das ganz ohne manuelles Passwort-Jonglieren.
- Autor
- David Roth
- Datum
- 23. Oktober 2025
- Lesedauer
- 11 Minuten
Das Elend mit den langlebigen Tokens
Ob wir ein Paket auf NuGet veröffentlichen, eine Ressource in der Cloud anlegen oder auf einen Container verteilen wollen – der schnellste Weg ist oft, einen Token vom Zielsystem anzufordern und ihn als »Secret« zu hinterlegen. Das Kernproblem: Dieser Token wird oft ohne Ablaufdatum erstellt und danach nie wieder angefasst. Daraus ergeben sich einige Probleme:
Hoher Wert, ewige Gültigkeit: Ein gestohlener Token ist wie ein Generalschlüssel, der oft nie ausgetauscht wird. Angreifer haben damit potenziell über Monate oder Jahre hinweg vollen Zugriff auf die Ressource.
Mangelnde Nachvollziehbarkeit: Wer hat den Token wann und wofür genutzt? Bei einem statischen Token ist das kaum nachzuvollziehen. Es ist wie eine geteilte Schlüsselkarte – man weiß, dass jemand im Gebäude war, aber nicht, wer.
Manueller Verwaltungsaufwand: Im Idealfall müssten Tokens regelmäßig manuell rotiert werden. Das ist fehleranfällig, aufwändig und wird in der Hektik des Alltags schnell »vergessen«.
Offboarding-Realität: Verlässt ein:e Mitarbeiter:in das Unternehmen oder endet die Zusammenarbeit mit einem externen Partner, beginnt die große Jagd: Alle potenziell kompromittierten Tokens müssen gefunden und ausgetauscht werden. Ein großer und oft unvollständiger Aufwand.
Supply-Chain-Angriffe: Gerade Angriffe auf Repositories wie NPM haben gezeigt, wie verletzlich CI/CD-Pipelines sein können. Ein bösartiges Paket kann vermeintlich sicher abgelegte Tokens abgreifen und nach außen senden.
Der Klassiker: Kubernetes Deployment mit Service Account Tokens
Traditionell war der gängige Weg für ein Kubernetes-Deployment so: Man erstellt einen langlebigen Kubernetes Service Account, gibt ihm über RBAC die nötigen Rechte und packt den zugehörigen Token in die CI/CD-Variablen von GitLab. Um die Sache etwas sicherer zu machen, werden im besten Fall separate Tokens für Staging und Production angelegt und der Zugriff über »Protected Branches« eingeschränkt.
Das funktioniert, ist aber in der Praxis nicht der beste Weg: Die Tokens zu rotieren ist mühsam, besonders bei vielen Projekten. Bei jedem neuen Projekt müssen die Tokens wieder von Hand hinterlegt werden. Und wird ein Token trotz aller Vorsicht abgegriffen, hat ein Angreifer potentiell einen unentdeckten Langzeitzugriff auf den Cluster.
Kurz gesagt: Dieser Ansatz ist ein Relikt und ein Paradebeispiel für veraltetes Secrets Management Kubernetes. Glücklicherweise gibt es eine elegante, standardisierte Lösung für dieses Problem.
Die Lösung: Passwortloses Deployment mit OIDC Trust
Wie können wir also von GitLab sicher auf Kubernetes deployen, ohne auch nur einen einzigen langlebigen Token zu verwenden? Was zunächst wie Magie klingt (»Authentifizierung ohne Schlüssel?«), wird durch einen weitverbreiteten Standard möglich: OpenID Connect (OIDC).
OIDC ist eine Identitätsebene auf dem OAuth 2.0 Protokoll. Jeder, der schon mal auf »Mit Google anmelden« geklickt hat, hat OIDC verwendet. Dabei bürgt Google gegenüber einer anderen Anwendung für deine Identität. Dieses Prinzip lässt sich wunderbar von Menschen auf die Maschine-zu-Maschine-Kommunikation übertragen. Glücklicherweise ist Google nicht der einzige OIDC Identity Provider. Gitlab bietet ebenfalls einen OIDC Identity Provider an, der uns vielseitige Möglichkeiten eröffnet.
Schritt 1: GitLab bei AWS als OIDC Provider bekannt machen
Wie bringen wir AWS dazu, einem GitLab-Deploy-Job zu vertrauen, und zwar nur unserem spezifischen Job? Zuerst müssen wir AWS beibringen, wer GitLab überhaupt ist.
GitLab agiert als öffentlicher OIDC Provider, der signierte ID-Tokens ausstellen kann. Unsere erste Aufgabe ist es also, AWS in die Lage zu versetzen, die Echtheit dieser Tokens zu überprüfen. In AWS geschieht dies über die Einrichtung eines Identity Providers im IAM-Service.
Wir legen also im AWS IAM einen neuen Identity Provider vom Typ »OpenID Connect« an. Als Provider-URL geben wir gitlab.com an und definieren eine »Audience« (Zielgruppe), z.B. gitlab-aws-deploy. Diese Audience ist wie ein Codewort, das sicherstellt, dass der Token auch wirklich für diesen Zweck ausgestellt wurde.
Die erste Hürde ist damit genommen. AWS und GitLab sind sich nun grundsätzlich bekannt und AWS weiß, wie es von GitLab ausgestellte OIDC-Tokens validieren kann. Bisher wurde aber noch keinerlei Zugriff gewährt. Wir haben lediglich das Tor für die Authentifizierung einen Spalt breit geöffnet.
Schritt 2: Die Trust Relationship, das Herzstück des Vertrauens
Als Nächstes brauchen wir eine IAM-Rolle in AWS, die unsere GitLab-Pipeline annehmen darf. Diese Rolle enthält die eigentlichen Berechtigungen. Nennen wir sie gitlab-deployer. Das Besondere an dieser Rolle ist ihre Trust Relationship (Vertrauensrichtlinie). Sie legt fest, wer oder was diese Rolle annehmen darf.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/gitlab.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"gitlab.com:aud": "gitlab-aws-deploy"
},
"StringLike": {
"gitlab.com:sub": "project_path:my_group/my-fancy_project:ref_type:branch:ref:production"
}
}
}
]
}
Schauen wir uns das mal genauer an:
Principal: Erlaubt Identitäten vom OIDC Provider
gitlab.com.Action: Gestattet die Aktion
AssumeRoleWithWebIdentity, also das Annehmen der Rolle mittels eines Web-Identity-Tokens.Condition: Das hier ist der wichtigste Teil. Hier definieren wir die wichtigen Regeln:
Der Token muss für unsere Audience (
gitlab-aws-deploy) ausgestellt sein.Der
sub(Subject) Claim des Tokens muss einem bestimmten Muster entsprechen. Im Beispiel darf nur ein Job aus dem Projektpfadmy_group/my-fancy_projectund demproduction-Branch diese Rolle annehmen.
Diese sub-Information wird von GitLab direkt und fälschungssicher in den Token geschrieben. Ein Angreifer kann also nicht einfach behaupten, er komme von unserem Projekt.
Ein Wort zur GitLab-Sicherheit: Vertrauen ist gut, Kontrolle ist besser
Die OIDC-Trust-Beziehung zu AWS ist nur eine Seite der Medaille. Damit das ganze System wirklich sicher ist, müssen wir sicherstellen, dass auch innerhalb von GitLab die Spielregeln klar definiert sind. Denn was nützt die sicherste Tür, wenn jeder den Schlüssel dafür in die Hand bekommen kann?
Die feingranulare Condition in unserer IAM-Rolle, die den Zugriff auf einen bestimmten Branch wie production beschränkt, ist der Dreh- und Angelpunkt. Das bedeutet aber auch, dass du diesen Branch in GitLab mit Argusaugen bewachen musst. Hier sind die unverzichtbaren Hausaufgaben in GitLab:
Protected Branches: Der
production- odermain-Branch muss als »Protected Branch« konfiguriert werden. Das erlaubt es, genau festzulegen, wer dorthin pushen oder mergen darf. Im Idealfall darf niemand direkt pushen – alles muss über einen Merge Request laufen.Granulare Rollen für Umgebungen: In der Praxis solltest du für jede Umgebung eine eigene IAM-Rolle erstellen. Richte eine
production-deployer-Rolle ein, die nur vomproduction-Branch angenommen werden darf, und eine separatestage-deployer-Rolle, die an denstage-Branch gebunden ist. Das stellt sicher, dass ein Job aus einem Feature-Branch niemals versehentlich in die Produktion deployen kann.Merge Request Policies & Approvals: Definiere klare Regeln für Merge Requests. Erzwinge Code-Reviews von mindestens einem oder zwei Teammitgliedern, bevor Code in einen geschützten Branch gelangen kann. Das Vier-Augen-Prinzip ist eine der effektivsten Maßnahmen gegen fehlerhaften oder bösartigen Code.
Nur wenn die Prozesse in GitLab selbst sauber und sicher konfiguriert sind, kann der OIDC-Trust-Mechanismus sein volles Sicherheitspotenzial entfalten. So wird sichergestellt, dass nur verifizierter und freigegebener Code den Weg in die Infrastruktur findet.
Schritt 3: Den OIDC-Token im GitLab-Job anfordern
Jetzt wird's konkret in unserer .gitlab-ci.yml. GitLab macht es uns super einfach, einen OIDC-Token zu generieren:
deploy_job:
id_tokens:
GITLAB_OIDC_TOKEN:
aud: "gitlab-aws-deploy"
script:
- # Magie passiert hier
Mit diesem kleinen id_tokens-Block wird in der Pipeline-Variable GITLAB_OIDC_TOKEN ein gültiger, signierter JWT (JSON Web Token) bereitgestellt. Dieser Token enthält Claims wie die Audience (aud) und den entscheidenden Subject (sub), z.B.: »sub«: »project_path:my_group/my-fancy_project:ref_type:branch:ref:production«.
In der Pipeline tauschen wir diesen GitLab-Token nun gegen einen temporären AWS-Token ein:
export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" \
$(aws sts assume-role-with-web-identity \
--role-arn "${EKS_ROLE_ARN}" \
--role-session-name "GitLabRunner-${CI_PIPELINE_ID}" \
--web-identity-token "${GITLAB_OIDC_TOKEN}" \
--duration-seconds 900 \
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \
--output text))
Das Ergebnis: Wir haben für 15 Minuten gültige AWS-Credentials, die an unsere gitlab-deployer-Rolle gebunden sind. Für ein EKS-Deployment reicht dieser Rolle oft schon die Berechtigung eks:DescribeCluster.
Schritt 4: Der letzte Händedruck von IAM zu Kubernetes
Wir haben jetzt also einen temporären AWS-Zugriff. Aber wie kommen wir damit in unseren Kubernetes-Cluster? Amazon EKS bietet hierfür einen eleganten Weg über EKS Access Entries. Damit können wir IAM-Rollen direkt Berechtigungen im Kubernetes-Cluster zuweisen, ohne die alte aws-auth-configmap manuell pflegen zu müssen.
Wir legen also einen Access Entry für unsere IAM-Rolle gitlab-deployer an und weisen ihr eine passende Access Policy zu, zum Beispiel AmazonEKSEditPolicy für einen bestimmten Namespace wie production.
Der moderne Weg ist EKS Access Entries:
# Konfiguration für kubectl einrichten:
aws eks update-kubeconfig --name "mein-cluster" --region "eu-central-1"
kubectl config set-context --current --namespace="production"
# Ship it:
kubectl apply -f deployment.yaml
Was passiert hier eigentlich im Hintergrund?
Der Befehl aws eks update-kubeconfig ist mehr als nur ein einfacher Konfigurations-Eintrag. Er richtet kubectl so ein, dass es bei jeder Anfrage der Befehl aws eks get-token ausführt. Dieser Prozess ist der entscheidende Übersetzer zwischen der AWS- und der Kubernetes-Welt:
Signierte Anfrage:
kubectlruftaws eks get-tokenauf. Dieses Tool nutzt die temporären IAM-Credentials aus der Pipeline, um eine Anfrage an den AWS Security Token Service (STS) zu erstellen. Diese Anfrage wird kryptografisch signiert und enthält die Identität unserer IAM-Rolle (gitlab-deployer).Validierung durch EKS: Die signierte Anfrage wird an den Kubernetes API-Server des EKS-Clusters gesendet. Ein spezielles Authentifizierungs-Webhook auf dem EKS-Server empfängt diese Anfrage und validiert die Signatur gegen den AWS STS. So wird fälschungssicher bestätigt: »Ja, diese Anfrage kommt wirklich von der IAM-Rolle
gitlab-deployer.«Mapping auf Kubernetes-Identität: Nachdem die AWS-Identität bestätigt ist, muss Kubernetes wissen, wer dieser »Besucher« ist und was er darf. Hier gibt es zwei Wege:
Der klassische Weg:
aws-auth-configmap: In älteren EKS-Setups existiert im Namespacekube-systemeineConfigMapnamensaws-auth. Darin wird manuell festgelegt, welche IAM-Rolle welchem Kubernetes-Benutzer oder welcher Gruppe zugeordnet ist. Das ist funktional, aber fehleranfällig und schlecht zu skalieren.Der moderne Weg: EKS Access Entries: Dies ist die neuere, elegantere Lösung von AWS. Statt einer
ConfigMapim Cluster werden die Mappings direkt über die EKS-API verwaltet. Wir legen einen »Access Entry« für unsere IAM-Rollegitlab-deployeran und weisen ihr direkt eine vordefinierte Kubernetes-Berechtigung (z.B.AmazonEKSEditPolicy) oder eine spezifische Kubernetes-Gruppe zu. Das ist sauberer, besser per Infrastructure-as-Code (IaC) zu verwalten und der empfohlene Standard.
Durch diesen nahtlosen Prozess wird unsere temporäre IAM-Rolle in eine vollwertige, berechtigte Kubernetes-Identität übersetzt. Und das alles, ohne ein einziges langlebiges Secret zu speichern.
Fazit: OIDC als Schlüssel zur passwortlosen Zukunft
Dieser Einblick zeigt, wie mächtig OIDC als Werkzeug für eine sichere, passwortlose Authentifizierung ist. Das Beste daran: Dieser Ansatz funktioniert nicht nur für AWS und Kubernetes. Ob es darum geht, Secrets aus einem Vault abzurufen oder Pakete via Trusted Publishing auf NuGet zu veröffentlichen – die Möglichkeiten sind vielseitig.
Es ist an der Zeit für einen Frühjahrsputz in unseren Systemkonfigurationen. Verbannen wir die langlebigen Tokens endgültig und setzen auf eine sicherere, automatisierte Zukunft!
Bringen deine Deployments auf das nächste Level
Fühlst du dich inspiriert, aber unsicher, wo du anfangen sollst? Die Umstellung auf moderne, sichere CI/CD-Prozesse kann eine Herausforderung sein. Aber keine Sorge, genau hier kommen wir ins Spiel.
Als Experten für DevOps-Consulting haben wir genau solche Transformationen bereits für zahlreiche Kunden erfolgreich umgesetzt. Wir helfen dir, die Fallstricke zu vermeiden, die richtigen Technologien auszuwählen und moderne CI/CD Security Best Practices zu implementieren, um Pipelines nicht nur sicherer, sondern auch effizienter zu machen
Lass uns unverbindlich darüber sprechen, wie wir deine DevOps-Prozesse fit für die Zukunft machen können.

