Secrets mit Claude Code verwalten: von .env bis Rotation in Produktion
Praxisguide für .env, CI/CD-Secrets, Cloud-Tresore, redigierte Logs und sichere Claude-Code-Grenzen.
API-Keys, Datenbank-URLs, OAuth client secrets und Cloud-Zugangsdaten für Deployments gehören zu fast jeder echten Anwendung. Gleichzeitig sind es genau die Werte, die nach einem unbedachten Copy-and-paste in Git-Historie, CI-Logs, Screenshots, Tickets, README-Dateien oder Artikelentwürfen bleiben. Wenn du Claude Code für Debugging, Migration, Deployment oder Dokumentation nutzt, braucht es zuerst eine klare Grenze: Claude Code darf beim Aufbau des Sicherheitssystems helfen, soll aber echte Secrets nicht sehen, ausgeben, speichern oder wiederverwenden.
Secrets Management ist mehr als ein Passwort-Tresor. Es trennt Konfiguration vom Code, isoliert lokale, Entwicklungs-, Staging- und Produktionswerte, setzt minimale Rechte durch, validiert Werte beim Start, maskiert Logs und macht Rotation möglich, bevor ein Incident den Zeitplan diktiert. Das Config-Prinzip von The Twelve-Factor App bleibt der richtige Ausgangspunkt: Konfiguration kommt aus der Umgebung, nicht aus dem Repository. In der Praxis brauchst du zusätzlich .gitignore, .env.example, einen validierten Config Loader, CI/CD-Secrets, einen Cloud Secret Store und eine Rotations-Checkliste.
flowchart LR
Dev["Local .env"] --> Loader["Validated config loader"]
CI["CI/CD secrets"] --> Deploy["Deployment runtime"]
Store["AWS / GCP / Azure secret store"] --> Deploy
Deploy --> App["Application process"]
App --> Logs["Redacted logs"]
1. Vorher entscheiden, was wohin gehört
Der typische Anfängerfehler ist, alle Umgebungsvariablen gleich zu behandeln. Die praktische Frage lautet: Kann jemand mit diesem Wert Geld ausgeben, E-Mails senden, Daten lesen oder schreiben, Code deployen oder Nutzer imitieren? Dann ist es ein Secret. Öffentliche Base-URLs, Feature-Flag-Namen oder OAuth client IDs sind meistens weniger kritisch, weil sie allein keine Berechtigung vergeben.
| Use Case | Beispiele | Lokal | Produktion |
|---|---|---|---|
| E-Mail und APIs | SendGrid API key, Stripe secret key, GitHub token | Test- oder Sandbox-Keys in .env | Aus CI/CD secrets oder Secret Store injizieren |
| Datenbank | DATABASE_URL, Benutzer, Passwort | Lokaler oder dev-only Benutzer | Lese-/Schreibrechte trennen und rotieren |
| Cloud Deployment | AWS/GCP/Azure-Zugangsdaten | Keine langlebigen lokalen Keys | OIDC oder deploy-only Role |
| OAuth und Webhooks | OAUTH_CLIENT_SECRET, webhook signing secret | Eigene lokale App-Registrierung | Prod-Secrets außerhalb des Repos |
Wichtig ist die Trennung der Umgebungen. Verwende keinen produktiven Stripe-Key lokal. Lege keinen persönlichen GitHub Token mit breitem Organisationszugriff in CI ab. Gib einem Deployment-Key keine Adminrechte, wenn Deploy-Rechte reichen. Das ist Least Privilege: nur der nötige Scope, nur in der passenden Umgebung und möglichst zeitlich begrenzt.
2. Die Form committen, nie den Wert
.env ist für lokale Entwicklung nützlich, gehört aber nicht ins Repository. Committe stattdessen .env.example, um Variablennamen, Formate, Quellen und Zweck zu dokumentieren. Für Onboarding passt dazu der Guide zum Umgebungsvariablen-Management, damit neue Teammitglieder nicht jede Variable einzeln erfragen müssen.
# Local secrets
.env
.env.*
!.env.example
!.env.test.example
# Logs and generated output that may contain tokens
npm-debug.log*
yarn-debug.log*
coverage/
dist/
# .env.example - placeholders only, never real values
NODE_ENV=development
APP_BASE_URL=http://localhost:3000
# Use a local database user, not production credentials.
DATABASE_URL=postgres://app_user:replace-me@localhost:5432/app_dev
# Use test/sandbox keys for local development.
SENDGRID_API_KEY=SG.xxxxxx
STRIPE_SECRET_KEY=sk_test_xxxxxx
GITHUB_TOKEN=ghp_xxxxxx
# OAuth secrets must be separated by environment.
OAUTH_CLIENT_ID=local-client-id
OAUTH_CLIENT_SECRET=replace-me
# Deployment reads these from CI or a cloud secret store.
AWS_REGION=ap-northeast-1
DEPLOY_ROLE_ARN=arn:aws:iam::123456789012:role/app-deploy-dev
Wenn Claude Code mitarbeitet, formuliere die Grenze explizit: .env.example, Deployment-Manifeste, package scripts und Variablennamen sind erlaubt; .env öffnen, echte Werte in den Chat kopieren oder Zugangsdaten in Dokumentation schreiben ist verboten. Wenn ein echter Wert gebraucht wird, setzt du ihn lokal, in CI oder im Secret Store und nennst Claude Code nur den Variablennamen.
3. Beim Start validieren und Logs maskieren
Eine Anwendung sollte sofort fehlschlagen, wenn ein Secret fehlt oder falsch formatiert ist. Sie sollte es außerdem schwer machen, Tokens aus Versehen ins Debug-Log zu schreiben. Dieser Node.js Loader nutzt dotenv und envalid zur Validierung und stellt redactConfig für Logs, Health Checks und Support-Ausgaben bereit.
import { config as loadDotenv } from "dotenv";
import { cleanEnv, str, url } from "envalid";
const envFile = process.env.NODE_ENV === "test" ? ".env.test" : ".env";
loadDotenv({ path: envFile });
const secretKeyPattern = /(KEY|TOKEN|SECRET|PASSWORD|DATABASE_URL|PRIVATE)/i;
const env = cleanEnv(process.env, {
NODE_ENV: str({
choices: ["development", "test", "staging", "production"],
default: "development",
}),
APP_BASE_URL: url({ default: "http://localhost:3000" }),
DATABASE_URL: url(),
SENDGRID_API_KEY: str(),
STRIPE_SECRET_KEY: str(),
GITHUB_TOKEN: str(),
OAUTH_CLIENT_ID: str(),
OAUTH_CLIENT_SECRET: str(),
AWS_REGION: str({ default: "ap-northeast-1" }),
DEPLOY_ROLE_ARN: str(),
});
export function appConfig() {
return Object.freeze({
nodeEnv: env.NODE_ENV,
appBaseUrl: env.APP_BASE_URL,
databaseUrl: env.DATABASE_URL,
sendgridApiKey: env.SENDGRID_API_KEY,
stripeSecretKey: env.STRIPE_SECRET_KEY,
githubToken: env.GITHUB_TOKEN,
oauthClientId: env.OAUTH_CLIENT_ID,
oauthClientSecret: env.OAUTH_CLIENT_SECRET,
awsRegion: env.AWS_REGION,
deployRoleArn: env.DEPLOY_ROLE_ARN,
});
}
export function redactValue(key, value) {
if (!secretKeyPattern.test(key)) return value;
if (!value) return "<empty>";
const text = String(value);
if (text.length <= 8) return "<redacted>";
return `${text.slice(0, 4)}...${text.slice(-4)}`;
}
export function redactConfig(config) {
return Object.fromEntries(
Object.entries(config).map(([key, value]) => [key, redactValue(key, value)]),
);
}
if (process.argv[1] === new URL(import.meta.url).pathname) {
console.log(redactConfig(appConfig()));
}
Ein häufiger Fehler: Während eines Incidents wird console.log(process.env) ergänzt und der CI-Log anschließend in ein Ticket oder einen Chat kopiert. Wenn Claude Code diese Rohlogs zusammenfassen soll, können Secrets erneut in Tests, Dokumentation oder Artikel geraten. Erst redigieren, dann fragen. Dasselbe gilt für Screenshots: Tokens vor dem Upload ausschneiden oder unkenntlich machen.
4. Claude Code klare Grenzen geben
Claude Code braucht fast nie echte Werte. Es braucht Namen, Formate, redigierte Fehlermeldungen und den Zweck der Berechtigungen. Für Security-, Deployment- und Debugging-Aufgaben kannst du diesen Block an den Anfang setzen.
You may inspect .env.example, package.json, deployment manifests, and secret names.
Do not open, print, summarize, store, or copy .env, CI/CD secret values, cloud credentials, production dumps, or screenshots containing tokens.
When you need a value, ask me to set it outside chat and confirm only the variable name.
If a secret appears in command output, stop, redact it, and report which file or command exposed it.
Before changing permissions, explain the least-privilege scope and ask for approval.
Do not paste real secrets into prompts, logs, documentation, code comments, tests, tickets, or articles.
Schränke auch Befehle ein. printenv, cat .env, Cloud-CLI-Ausgaben mit Zugangsdaten, komplette CI-Logs und Screenshots sollten Bestätigung erfordern. Mit .env.example, Typen, maskierten Fehlern und offizieller Dokumentation kann Claude Code die meisten Änderungen ohne reale Werte umsetzen.
5. CI/CD-Secrets und Cloud Secret Stores bewusst nutzen
Eine praktikable Aufteilung: .env lokal, CI/CD-Secrets für Pipelines, Cloud Secret Store für den Produktions-Runtime. Auf AWS nutzt du AWS Secrets Manager, auf Google Cloud Secret Manager, auf Azure Key Vault. In GitHub-Repositories sollte secret scanning aktiv sein, um versehentlich veröffentlichte Tokens schnell zu finden.
name: deploy
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
env:
NODE_ENV: production
AWS_REGION: ap-northeast-1
steps:
- uses: actions/checkout@v4
- name: Validate required secret names
run: test -n "${{ secrets.DEPLOY_ROLE_ARN }}" && test -n "${{ secrets.DATABASE_URL }}"
- name: Deploy without echoing secrets
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
DEPLOY_ROLE_ARN: ${{ secrets.DEPLOY_ROLE_ARN }}
run: npm run deploy
Die CI-Falle lautet: “Wir echoen es kurz zur Kontrolle.” GitHub Actions maskiert viele exakte Secret-Werte, schützt aber nicht zuverlässig abgeleitete Strings, kodierte URLs, JSON-Blobs, Screenshots oder Werte, die nie als Secret registriert wurden. Lass Claude Code Variablennamen und Validierungsschritte ausgeben, nicht Werte. Wenn breite Rechte vorgeschlagen werden, verlange eine Begründung und reduziere den Scope.
6. Rotation vor dem Ernstfall üben
Rotation sollte normale Wartung sein, nicht nur Incident Response. SendGrid-, Stripe- und GitHub-Keys, Datenbankpasswörter, OAuth client secrets, webhook signing secrets und Cloud-Trust-Policies brauchen Owner, Umgebung, Konsumentenliste, letztes Rotationsdatum und nächste Review.
## Secret rotation checklist
- [ ] Identify owner, environment, consumers, and business impact.
- [ ] Create a new secret with the smallest required scope.
- [ ] Store it in CI/CD secrets or the cloud secret store.
- [ ] Deploy one service or job with the new value.
- [ ] Confirm logs and metrics without printing the secret.
- [ ] Revoke the old secret.
- [ ] Scan Git history, tickets, docs, screenshots, and chat snippets.
- [ ] Record the rotation date and next review date.
Claude Code ist gut darin, diese Liste in Issue Templates, Runbooks oder Migrationspläne zu verwandeln. Gib aber weder alten noch neuen Secret-Wert weiter. Frage stattdessen: “Finde alle Referenzen auf SENDGRID_API_KEY und erstelle einen sicheren Rollout-Plan für den v2-Key.”
7. Fehlerfälle vor Release prüfen
Stoppe Veröffentlichung oder Deployment, wenn einer dieser Punkte zutrifft:
.envoder.env.productionwurde committet und der exponierte Key nicht widerrufen.- Screenshots, CI-Logs, Error Reports oder Artikelbeispiele enthalten Tokens, DB-URLs oder OAuth secrets.
- Ein Cloud-Key hat Adminrechte, obwohl Deploy-Rechte reichen.
- Produktionszugangsdaten für Stripe, SendGrid, DB oder GitHub werden lokal wiederverwendet.
- OAuth client secrets oder webhook signing secrets haben keinen Owner und kein Rotations-Runbook.
- Eine KI bekam echte Werte und hat sie später in README, Tests, Tickets oder Entwürfen wiederverwendet.
Security-Incidents entstehen oft aus Prozesslücken. Nutze die Security-Audit-Checkliste, lies die Security-Failure-Cases, verbinde das mit dem API-Development-Guide und prüfe bei SendGrid oder transaktionalen E-Mails auch den Artikel zur E-Mail-Automatisierung.
8. Schrittweise im Team einführen
Beginne nicht damit, alle Services in einer Woche zu migrieren. Wähle eine Anwendung und bringe den gesamten Pfad zum Laufen: .gitignore, .env.example, validierter Loader, maskierte Logs, CI/CD-Secrets, Produktions-Secret-Store und Rotationsregister. Danach migrierst du die wiederkehrenden Typen: SendGrid, Stripe, GitHub token, DATABASE_URL, OAuth client secret und Deployment-Zugangsdaten.
ClaudeCodeLab Trainings und Consulting arbeiten mit der echten Struktur deines Repositories, aber ohne echte Secret-Werte. Wir definieren, welche Dateien Claude Code sehen darf, entwerfen CI/CD-Secret-Grenzen, aktivieren GitHub secret scanning, planen AWS/GCP/Azure Secret Stores und hinterlassen wiederverwendbare Prompts und Runbooks. Das ist nützlicher als eine abstrakte Schulung, weil das Team die Vorlage am nächsten Tag im Review einsetzen kann.
Kurz gesagt: Secrets Management ist nicht nur das Verstecken von Strings. Es trennt Werte vom Code, isoliert Umgebungen, validiert beim Start, maskiert Logs, reduziert Rechte und übt Rotation. Claude Code kann dieses System bauen und prüfen, darf aber kein weiterer Speicherort für Secrets werden.
Beim Test in Masas Beispiel-App mit Node.js fand der Config Loader fehlende Werte, redactConfig hielt Datenbank-URL und API-Keys aus den CI-Logs heraus, und der Deploy-Workflow brauchte keine breiten write-Rechte mehr. Überraschend war ein alter Screenshot mit sichtbarem Stripe-Test-Key; der Key wurde vor Veröffentlichung neu erstellt. Die praktische Lehre: Logs, Bilder und Entwürfe genauso kritisch prüfen wie Quellcode.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude Code Permission Safety Ladder: Zugriff kontrolliert erweitern
Von read-only zu begrenzten Änderungen, Prüfbefehlen und Deploy-Checks mit klarer Kontrolle.
Claude Code Small PR Proof Pack: kleine Änderungen reviewbar machen
Ein Proof Pack für Claude-Code-PRs: Diff, Checks, öffentliche URL, CTA-Pfad und Rollback.
Claude-Code-Review-Gate vor dem Commit
Vor dem Commit mit Claude Code prüfen: Diff, Build, öffentliche URL, Gumroad-Links, Beratung-CTA, fehlende Tests und fremde Dateien.