Blog

Abrufen von Secrets in Kubernetes mit dem AWS Secrets Manager Agent Sidecar

29.04.2026
Lesezeit: 5 Minuten.
Zuletzt aktualisiert: 01 .07.2026

Inhaltsübersicht

Verwaltung von Geheimnissen in Kubernetes kann einfach klingen – bis man es tatsächlich in großem Maßstab umsetzt. Zu den gängigen Ansätzen gehören das Einbinden von Kubernetes-Geheimnissen als Umgebungsvariablen, die Verwendung eines externen Secrets-Operators oder der direkte Aufruf von Cloud-SDKs aus dem Anwendungscode heraus. Jede Option bringt Kompromisse in Bezug auf Caching, Auditing, Sicherheitsgrenzen und Anwendungskopplung mit sich.

In diesem Beitrag stellen wir ein alternatives Muster vor: den Betrieb des AWS Secrets Manager-Agenten als Sidecar-Container. Bei diesem Ansatz ruft Ihre Anwendung Geheimnisse über einen lokalen HTTP-Aufruf ab – ein AWS SDK ist nicht erforderlich – und profitiert gleichzeitig von integrierter Zwischenspeicherung, SSRF-Schutz und einer klaren Trennung der Zuständigkeiten.

Wir werden die Einrichtung anhand eines kleinen Go-Dienstes veranschaulichen, aber dieses Sidecar-Muster funktioniert mit jeder Sprache und jeder Laufzeitumgebung.

Der Secrets Manager Agent läuft als separater Container im selben Pod. Ihre Anwendung kommuniziert mit ihm über localhost:2773, was mehrere Vorteile bietet:

  • Keine AWS-SDK-Abhängigkeit in Ihrer App – nur eine einfache HTTP-GET-Anfrage
  • Integriertes Caching mit konfigurierbarer TTL (Geheimnisse werden automatisch aktualisiert, ohne dass der Pod neu gestartet werden muss)
  • SSRF-Token-Schutz: Nur Container, die über das Token verfügen, können Geheimnisse abrufen
  • Verbesserte Portabilität – zum Wechseln der geheimen Backends muss lediglich der Sidecar aktualisiert werden
  • Bessere Überwachung – in Verbindung mit OpenTelemetry-Trace-IDs können Sie genau nachverfolgen, welcher Endpunkt auf welches Geheimnis zugegriffen hat

Die Nachteile sind ein zusätzlicher Container pro Pod und ein lokaler HTTP-Aufruf. In der Praxis verursachen beide nur einen vernachlässigbaren Mehraufwand.

AWS Secrets Manager-Agent

Beim Start des Pods generiert der Agent ein zufälliges SSRF-Token, schreibt es in ein gemeinsames In-Memory-Volume und exportiert es als Umgebungsvariable.
Der Anwendungscontainer liest dasselbe Token aus dem gemeinsamen Volume und fügt es in jede Anfrage an den Agenten ein.

AWS stellt den Agenten als Rust-Projekt auf GitHub zur Verfügung. Wir erstellen ihn aus dem Quellcode und fixieren ihn zur Gewährleistung der Reproduzierbarkeit auf ein Release-Tag.

# Build stage - compile the Rust binary
FROM rust:1.82-bookworm AS builder
RUN apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/*

WORKDIR /build
# Clone the agent repo (pin to a release tag for reproducibility)
RUN git clone --branch v2.0.0 --depth 1 https://github.com/aws/aws-secretsmanager-agent.git .
RUN cargo build --release

# Runtime stage - minimal image with just the binary
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /build/target/release/aws_secretsmanager_agent ./secrets-manager-agent
COPY startup.sh .
COPY config.toml .
RUN chmod +x startup.sh secrets-manager-agent
ENTRYPOINT ["./startup.sh"]

Agent-Konfiguration (config.toml)

log_level = "INFO"
log_to_file = false
http_port = 2773
ttl_seconds = 300
cache_size = 1000

Die Einstellung `ttl_seconds = 300` bedeutet, dass Geheimnisse fünf Minuten lang zwischengespeichert werden. Danach ruft der Agent automatisch neue Werte ab – ein Neustart des Pods ist nicht erforderlich.

Startskript und Umgang mit SSRF-Token

#!/bin/bash
set -e

# Generate a random SSRF token, write to shared volume and export as env var
TOKEN=$(head -c 32 /dev/urandom | base64 | tr -d '=+/')
echo -n "$TOKEN" > /shared/awssmatoken
chmod 444 /shared/awssmatoken
export AWS_TOKEN="$TOKEN"

# Start the agent with logging to stdout
exec ./secrets-manager-agent --config config.toml 2>&1

Das Token wird bei jedem Start des Pods temporär generiert, ausschließlich im Arbeitsspeicher gespeichert und zusammen mit dem Pod gelöscht. Es gibt nichts, was rotiert oder dauerhaft gespeichert werden müsste.

Erstellen und an ECR übertragen (in diesem Beispiel arm64 für Graviton-Knoten):

docker buildx build --platform linux/arm64 \ -t <account>.dkr.ecr.us-east-1.amazonaws.com/aws-secrets-manager-agent:lates\--push ./secrets-manager-agent

Die Anwendung nutzt nicht das AWS SDK. Stattdessen führt sie einen HTTP-GET-Aufruf an den lokalen Agenten aus und übergibt das SSRF-Token in einem Request-Header.

func sidecarHandler(w http.ResponseWriter, r *http.Request) {
   secretName := os.Getenv("secret")
   if secretName == "" {
       writeJSON(w, http.StatusOK, map[string]string{"message": "no secret env var set"})
       return
   }

   agentURL := os.Getenv("SECRETS_MANAGER_AGENT_URL")
   if agentURL == "" {
       agentURL = "http://localhost:2773"
   }

   tokenBytes, err := os.ReadFile("/shared/awssmatoken")
   if err != nil {
       writeJSON(w, http.StatusInternalServerError,
           map[string]string{"error": "failed to read SSRF token: " + err.Error()})
       return
   }

   req, err := http.NewRequestWithContext(
       r.Context(),
       http.MethodGet,
       agentURL+"/secretsmanager/get?secretId="+secretName,
       nil,
   )
   if err != nil {
       writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
       return
   }

   req.Header.Set("X-Aws-Parameters-Secrets-Token", string(tokenBytes))

   resp, err := http.DefaultClient.Do(req)
   if err != nil {
       writeJSON(w, http.StatusBadGateway, map[string]string{
           "error":  "failed to reach secrets manager agent sidecar",
           "detail": err.Error(),
       })
       return
   }
   defer resp.Body.Close()

   var secretResp struct {
       SecretString string `json:"SecretString"`
   }

   if err := json.NewDecoder(resp.Body).Decode(&secretResp); err != nil {
       writeJSON(w, http.StatusInternalServerError,
           map[string]string{"error": "failed to decode secret response"})
       return
   }

   var secretData map[string]string
   if err := json.Unmarshal([]byte(secretResp.SecretString), &secretData); err != nil {
       writeJSON(w, http.StatusOK, map[string]string{"secret_value": secretResp.SecretString})
       return
   }

   writeJSON(w, http.StatusOK, secretData)
}

Wichtige Details zur Umsetzung:

  • Geheime Namen stammen aus Umgebungsvariablen und sind niemals fest codiert
  • Das SSRF-Token wird aus dem gemeinsam genutzten In-Memory-Volume gelesen
  • Der Agent gibt eine JSON-Nutzlast zurück, die „SecretString“ enthält, die von der App ausgewertet wird

Bei dieser Bereitstellung werden zwei Container in einem einzigen Pod ausgeführt, die sich ein In-Memory-Volume für das SSRF-Token teilen.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-demo
  template:
    metadata:
      labels:
        app: go-demo
    spec:
      serviceAccountName: go-demo
      containers:
        - name: go-demo
          image: <account>.dkr.ecr.<region>.amazonaws.com/go-demo:latest
          ports:
            - containerPort: 8080
          env:
            - name: secret
              value: "demo-secret"
          volumeMounts:
            - name: ssrf-token
              mountPath: /shared
              readOnly: true
        - name: secrets-manager-agent
          image: <account>.dkr.ecr.<region>.amazonaws.com/aws-secrets-manager-agent:latest
          ports:
            - containerPort: 2773
          volumeMounts:
            - name: ssrf-token
              mountPath: /shared
      volumes:
        - name: ssrf-token
          emptyDir:
            medium: Memory

Wichtige Hinweise:

  • Das „emptyDir“-Volume nutzt das Medium „Memory“, sodass das Token niemals auf die Festplatte geschrieben wird
  • Die Anwendung bindet das Volume schreibgeschützt ein
  • Der Sidecar wird im Lese- und Schreibmodus gemountet, um das Token zu generieren

Vermeiden Sie es, das freigegebene Volume unter /var/run einzuhängen. Kubernetes benötigt diesen Pfad für das Token des Dienstkontos, und eine Überschreibung führt zu Fehlern bei den Pods – insbesondere bei distroless-Images.

Der Agent gleicht das SSRF-Token mit einer dieser Umgebungsvariablen ab:

  • AWS_TOKEN
  • AWS_SESSION_TOKEN
  • AWS_CONTAINER_AUTHORIZATION_TOKEN

Wenn keine festgelegt sind, kann der Agent nicht gestartet werden.

Deshalb schreibt das Startskript das Token sowohl auf die Festplatte als auch exportiert es als AWS_TOKEN.

  1. Pod wird gestartet und der Sidecar führt die Datei „startup.sh“ aus
  2. Es wird ein zufälliges 32-Byte-Token generiert
  3. Das Token wird in /shared/awssmatoken geschrieben und als AWS_TOKEN exportiert
  4. Der Agent gleicht eingehende Anfragen mit dem Token ab
  5. Die Anwendung liest das Token aus und sendet es als HTTP-Header
  6. Der Agent überprüft das Token und gibt das Geheimnis zurück

Das Token ist kurzlebig, auf die Lebensdauer des Pods beschränkt und wird niemals extern gespeichert.

Durch den Einsatz des AWS Secrets Manager-Agenten als Kubernetes-Sidecar bleibt der Anwendungscode übersichtlich und auf das Wesentliche konzentriert. Anstatt Cloud-SDKs einzubinden, Anmeldedaten zu verwalten und Caching-Logik zu implementieren, führt die Anwendung lediglich einen einfachen lokalen HTTP-Aufruf durch.

Der Makler kümmert sich um:

  • Verstecktes Zwischenspeichern mit TTL
  • Authentifizierung über IRSA
  • SSRF-Schutz von Haus aus

Wichtigste Erkenntnisse:

  • Binde freigegebene Volumes nicht unter /var/run ein
  • Exportiere das SSRF-Token für den Agenten stets als Umgebungsvariable
  • Erstellen Sie den Agenten für Ihre Zielarchitektur (arm64 für Graviton-Knoten)
  • Geheime Namen aus Umgebungsvariablen beziehen – keine fest codierten Werte

Dieser auf Sidecars basierende Ansatz bietet eine sichere, wartungsfreundliche und portable Möglichkeit, Geheimnisse in Kubernetes-Umgebungen zu verwalten.

Weitere Blogbeiträge findest duhier.

Newsletter für Tech-Experten

Signal, kein Rauschen –

direkt in Ihren Posteingang.

Schließen Sie sich mehr als 12.000 Ingenieuren und Führungskräften aus der Wirtschaft an, die Praxisberichte zu SRE, DevOps und Cloud-nativer Zuverlässigkeit erhalten.

Tech-Blogs mit tiefgehenden Einblicken und Fallstudien
Neue Technologien, sorgfältig ausgewählt

Ihre geschäftliche E-Mail-Adresse

Wir gehen respektvoll mit Ihrem Posteingang um. Lesen Sie unsere Datenschutzerklärung.

Mehr Beiträge

Die sichere Verwaltung von Geheimnissen in Kubernetes stellt eine entscheidende Herausforderung für moderne Cloud-native Umgebungen dar. Anmeldedaten für Anwendungen, Zertifikate, private Schlüssel und Passwörter müssen auf sichere und nachverfolgbare Weise verwaltet werden, ...
Lesen
Da die Verbreitung von IPv6 weiter zunimmt, benötigen Unternehmen, die Workloads auf AWS ausführen, zunehmend Netzwerkarchitekturen, die sowohl IPv4- als auch IPv6-Datenverkehr unterstützen. AWS bietet zwar native IPv6-Funktionen, doch die Integration...
Lesen
Kontakt aufnehmen
ITGix bietet Ihnen fachkundige Beratung und maßgeschneiderte DevOps-Services, um Ihr Unternehmenswachstum zu beschleunigen.
Newsletter für
Technik-Experten
Schließen Sie sich 12.000+ Geschäftsführern und Ingenieuren an, die Blogs, e-Books und Fallstudien Fallstudien über neue Technologie erhalten.