Warum AWS Secrets Manager statt Hardcoding? DB-Passwörter sicher verwalten
Ein privates Repository fühlt sich sicher an — bis ein Entwickler versehentlich einen Screenshot teilt, ein CI/CD-Token kompromittiert wird oder ein ehemaliger Kollege noch Zugriff hat. Hardcodierte Datenbankpasswörter im Anwendungscode sind einer der häufigsten Einstiegspunkte für Datenpannen, und 'das Repo ist privat' ist kein Sicherheitskonzept. AWS Secrets Manager löst genau dieses Problem mit zentralisierter Geheimnisverwaltung und automatischer Rotation.
TL;DR — Secrets Manager vs. Hardcoding im Vergleich
| Kriterium | Hardcoding im Code | AWS Secrets Manager |
|---|---|---|
| Angriffsfläche | Jeder mit Repo-Zugriff sieht das Passwort | Zugriff nur über IAM-Berechtigungen zur Laufzeit |
| Rotation | Manuell, fehleranfällig, selten gemacht | Automatisch, konfigurierbar, ohne Downtime |
| Audit-Trail | Kein Nachweis wer das Passwort wann verwendet hat | Vollständiges CloudTrail-Logging jedes API-Aufrufs |
| Notfall-Reaktion | Passwort ändern → alle Deployments neu bauen | Neues Secret erstellen → Anwendung liest automatisch |
| Compliance | Schwer nachweisbar (PCI-DSS, SOC2) | Nachweisbare Zugriffskontrolle und Rotation |
Wie Secrets Manager intern funktioniert
Bevor die Diagnose- und Einrichtungsschritte Sinn ergeben, muss das Grundprinzip klar sein: Secrets Manager ist kein einfacher Key-Value-Store. Er kombiniert verschlüsselte Speicherung, IAM-basierte Zugriffskontrolle, versionierte Geheimnisse und Lambda-gesteuerte Rotation in einem einzigen Service.
(ECS / EC2 / Lambda)"] -->|GetSecretValue API| SM["Secrets Manager"] SM -->|IAM pruefen| IAM["IAM-Autorisierung"] IAM -->|erlaubt| KMS["KMS Entschluesselung"] KMS -->|entschluesselt| SM SM -->|JSON-Wert| App SM -->|speichert verschluesselt| Store["Verschluesselter Secret-Store"] CT["CloudTrail"] -.->|protokolliert jeden Zugriff| SM
- Anwendung zur Laufzeit: Die Anwendung ruft
GetSecretValueüber die AWS SDK auf — kein Passwort im Code. - IAM-Autorisierung: Die IAM-Rolle der Anwendung (z.B. EC2 Instance Profile oder ECS Task Role) muss explizit
secretsmanager:GetSecretValuefür das spezifische Secret erlauben. - KMS-Entschlüsselung: Secrets Manager entschlüsselt den Wert mit dem konfigurierten KMS-Schlüssel und gibt ihn zurück. Ohne
kms:Decrypt-Berechtigung schlägt der Aufruf fehl — auch wennGetSecretValueerlaubt ist. - Versionierung: Jedes Secret hat Versionen mit Staging-Labels (
AWSCURRENT,AWSPENDING,AWSPREVIOUS). Rotation arbeitet mit diesen Labels, ohne den alten Wert sofort zu löschen.
Warum 'privates Repo' keine Sicherheitsstrategie ist
Die Annahme ist verständlich: Das Repo ist privat, nur das Team hat Zugriff, also ist das Passwort sicher. In der Praxis scheitert dieses Modell an mehreren Stellen gleichzeitig.
Git-History ist dauerhaft. Ein Passwort, das einmal committed wurde, bleibt in der History — auch nach einem git rm. Tools wie git-secrets oder truffleHog finden solche Geheimnisse in Sekunden. Wenn das Repo jemals öffentlich wird, auch nur kurz, ist das Passwort kompromittiert.
CI/CD-Systeme klonen das Repo. Jenkins, GitHub Actions, GitLab CI — alle bekommen eine vollständige Kopie des Codes inklusive aller Geheimnisse. Jeder Build-Agent, jeder Cache, jedes Artifact-Log ist ein potenzieller Leckagepunkt.
Ein Passwort im Code ist wie ein Hausschlüssel unter der Fußmatte: Alle, die wissen wo sie suchen müssen, finden ihn — und das sind mehr Leute als man denkt.
Das eigentliche Problem: Rotation. Ein hardcodiertes Passwort wird selten geändert, weil jede Änderung ein Deployment erfordert. Das bedeutet, dasselbe Passwort läuft oft jahrelang — ein ideales Ziel für Credential-Stuffing-Angriffe.
Secrets Manager einrichten — Schritt für Schritt
Schritt 1: Secret erstellen
Ein neues Datenbankgeheimnis anlegen. Secrets Manager unterstützt strukturierte JSON-Werte, was für Datenbank-Credentials praktisch ist — Benutzername und Passwort in einem einzigen Secret-Abruf.
aws secretsmanager create-secret \
--name prod/myapp/db \
--description 'PostgreSQL-Credentials fuer Produktionsumgebung' \
--secret-string '{"username":"dbadmin","password":"InitialesPasswort123!"}' \
--region us-east-1
Die Ausgabe enthält die Secret-ARN — diese wird für IAM-Policies benötigt. Das Secret wird standardmäßig mit dem AWS-verwalteten KMS-Schlüssel für Secrets Manager verschlüsselt. Für stärkere Kontrolle kann ein kundenverwalteter KMS-Schlüssel angegeben werden.
Schritt 2: IAM-Policy für die Anwendung erstellen
Die Anwendung braucht minimale Berechtigungen — nur Lesezugriff auf genau dieses Secret. Kein Wildcard, kein Zugriff auf andere Secrets. Das ist der entscheidende Unterschied zu Umgebungsvariablen: Der Zugriff ist auf Ressourcenebene kontrollierbar.
🔽 IAM-Policy für Secrets Manager Lesezugriff (aufklappen)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LeseDBSecret",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/db-*"
},
{
"Sid": "KMSEntschluesselung",
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:us-east-1:123456789012:key/DEIN-KMS-SCHLUESSEL-ID"
}
]
}
Wichtig: Der ARN-Suffix für Secrets Manager enthält einen zufälligen 6-stelligen Anhang (z.B. prod/myapp/db-AbCdEf). Der Wildcard -* am Ende des ARN ist deshalb notwendig, um die korrekte Ressource zu matchen, ohne den exakten Suffix hardcoden zu müssen.
Schritt 3: Secret zur Laufzeit abrufen
Die Anwendung ruft das Secret beim Start oder bei Bedarf ab. Kein Passwort in Konfigurationsdateien, kein Passwort in Umgebungsvariablen, kein Passwort im Code.
aws secretsmanager get-secret-value \
--secret-id prod/myapp/db \
--region us-east-1 \
--query SecretString \
--output text
In einer Python-Anwendung sieht das typischerweise so aus:
import boto3
import json
def get_db_credentials():
client = boto3.client('secretsmanager', region_name='us-east-1')
response = client.get_secret_value(SecretId='prod/myapp/db')
secret = json.loads(response['SecretString'])
return secret['username'], secret['password']
Schritt 4: Automatische Rotation konfigurieren
Automatische Rotation ist das Kernfeature, das Secrets Manager von einfachen Secret-Stores unterscheidet. Für unterstützte Datenbanken (Amazon RDS, Amazon Aurora, Amazon Redshift, Amazon DocumentDB) stellt AWS vorgefertigte Lambda-Rotationsfunktionen bereit.
- Rotation auslösen: Secrets Manager ruft die Lambda-Rotationsfunktion auf — entweder nach einem konfigurierten Zeitplan oder manuell.
- AWSPENDING erstellen: Lambda generiert ein neues Passwort und speichert es unter der
AWSPENDING-Version. - Datenbank aktualisieren: Lambda setzt das neue Passwort direkt in der Datenbank.
- Testen: Lambda verifiziert, dass die Verbindung mit dem neuen Passwort funktioniert.
- Label wechseln:
AWSPENDINGwird zuAWSCURRENT, das alteAWSCURRENTwird zuAWSPREVIOUS.
Während der gesamten Rotation ist die Anwendung weiterhin erreichbar — sie liest AWSCURRENT, und das alte Passwort bleibt als AWSPREVIOUS noch kurz gültig.
aws secretsmanager rotate-secret \
--secret-id prod/myapp/db \
--rotation-rules AutomaticallyAfterDays=30 \
--region us-east-1
Für RDS-Datenbanken kann die Rotation mit einer verwalteten Rotationsfunktion aktiviert werden, ohne eine eigene Lambda-Funktion schreiben zu müssen. Die genaue Konfiguration hängt vom Datenbanktyp und der Netzwerkkonfiguration ab — die offizielle AWS-Dokumentation zur Rotation enthält die aktuellen Voraussetzungen.
Das klassische Fehlermuster: 'Es funktioniert lokal, aber nicht in Produktion'
Ein typisches Szenario: Die Anwendung läuft lokal mit einem hardcodierten Passwort in einer .env-Datei. In Produktion soll Secrets Manager verwendet werden. Der Entwickler konfiguriert GetSecretValue, deployed — und bekommt einen AccessDeniedException.
Die erste Reaktion: 'Die IAM-Policy ist falsch.' Also wird die Policy auf "Resource": "*" erweitert. Immer noch derselbe Fehler.
Der tatsächliche Grund: Die ECS-Task-Definition verwendet eine alte Task-Role, die noch keine Secrets-Manager-Berechtigungen hat. Die neue Policy wurde an eine andere Rolle angehängt. Das lässt sich mit folgendem Befehl prüfen:
aws ecs describe-tasks \
--cluster prod-cluster \
--tasks TASK-ID \
--region us-east-1 \
--query 'tasks[0].taskDefinitionArn'
aws ecs describe-task-definition \
--task-definition TASK-DEFINITION-ARN \
--region us-east-1 \
--query 'taskDefinition.taskRoleArn'
Dann prüfen, welche Policies an diese spezifische Rolle angehängt sind:
aws iam list-attached-role-policies \
--role-name TASK-ROLE-NAME
Meistens stellt sich heraus: Die Policy wurde an die Execution Role angehängt, nicht an die Task Role. Bei ECS sind das zwei verschiedene Rollen mit unterschiedlichen Zwecken — die Execution Role zieht das Container-Image und sendet Logs, die Task Role ist die Identität des laufenden Containers.
Secrets Manager vs. Parameter Store — wann was?
AWS Systems Manager Parameter Store ist eine häufig genannte Alternative. Die Entscheidung ist nicht kompliziert, wenn man die Unterschiede kennt.
| Merkmal | Secrets Manager | Parameter Store (SecureString) |
|---|---|---|
| Automatische Rotation | Ja, nativ für unterstützte Dienste | Nein, muss selbst implementiert werden |
| Kosten | Pro Secret und API-Aufruf (Preise variieren — aktuelle AWS-Dokumentation prüfen) | Kostenlos für Standard-Parameter, Kosten für Advanced |
| Cross-Account-Zugriff | Ja, über Resource-based Policy | Eingeschränkt |
| Versionierung | Automatisch mit Staging-Labels | Manuell über Versionshistorie |
| Anwendungsfall | Datenbankpasswörter, API-Keys mit Rotation | Konfigurationswerte, Feature-Flags, nicht-rotierende Secrets |
Faustregel: Wenn das Geheimnis rotiert werden muss oder cross-account geteilt wird, ist Secrets Manager die richtige Wahl. Für statische Konfigurationswerte reicht Parameter Store.
Bestehende Anwendungen migrieren — ohne Downtime
Der häufigste Einwand gegen die Migration: 'Wir können nicht einfach alle Deployments gleichzeitig ändern.' Das stimmt — und Secrets Manager macht das auch nicht notwendig.
Eine sichere Migrationsstrategie läuft in drei Phasen. Zuerst das Secret in Secrets Manager anlegen, parallel zum bestehenden hardcodierten Wert. Dann die Anwendung so anpassen, dass sie versucht, das Secret aus Secrets Manager zu lesen, und bei Fehler auf den hardcodierten Wert zurückfällt. Schließlich, nach erfolgreicher Verifikation, den Fallback entfernen und das hardcodierte Passwort aus dem Code löschen.
# Pruefen ob das Secret korrekt abgerufen werden kann
aws secretsmanager get-secret-value \
--secret-id prod/myapp/db \
--version-stage AWSCURRENT \
--region us-east-1
# CloudTrail-Events fuer Secret-Zugriffe pruefen
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=GetSecretValue \
--region us-east-1 \
--max-results 10
CloudTrail protokolliert jeden GetSecretValue-Aufruf mit Zeitstempel, aufrufender Identität und Quell-IP. Das ist der Audit-Trail, den ein hardcodiertes Passwort niemals liefern kann.
Wrap-up: Secrets Manager ist kein Luxus
Hardcodierte Passwörter in privaten Repos sind kein akzeptables Sicherheitsmodell — nicht wegen theoretischer Risiken, sondern weil die Angriffsvektoren (Git-History, CI/CD-Systeme, kompromittierte Entwickler-Accounts) in der Praxis regelmäßig ausgenutzt werden. AWS Secrets Manager löst das Problem mit zentralisierter Speicherung, IAM-basierter Zugriffskontrolle, vollständigem Audit-Trail und automatischer Rotation.
Der Einstieg ist geringer als erwartet: Ein Secret anlegen, eine IAM-Policy anpassen, drei SDK-Zeilen im Code ändern. Die Rotation für RDS-Datenbanken lässt sich ohne eigene Lambda-Implementierung aktivieren.
Nächste Schritte:
- Offizielle Dokumentation: AWS Secrets Manager User Guide
- Rotation für RDS: Automatische Rotation konfigurieren
- Bestehende Anwendungen auf Hardcoding prüfen: Tools wie
git-secretsodertruffleHogscannen die Git-History auf versehentlich committete Credentials.
Glossar
| Begriff | Bedeutung |
|---|---|
| Secret | Ein verschlüsselt gespeicherter Wert in Secrets Manager, z.B. ein Datenbankpasswort oder API-Key |
| Staging Label | Bezeichnung einer Secret-Version (AWSCURRENT, AWSPENDING, AWSPREVIOUS) — steuert welche Version aktiv ist |
| Rotation | Automatischer Prozess zum Ersetzen eines Secrets durch einen neuen Wert, ohne manuelle Deployments |
| Task Role | IAM-Rolle, die einem laufenden ECS-Container zugewiesen ist und dessen Berechtigungen für AWS-API-Aufrufe definiert |
| Resource-based Policy | IAM-Policy, die direkt an eine Ressource (hier: ein Secret) angehängt wird und cross-account Zugriff ermöglicht |
Kommentare
Kommentar veröffentlichen