AWS SSM Parameter Store — Secrets-Konvention
Statt 1Password (haben wir nicht) nutzen wir AWS Systems Manager Parameter Store als zentralen Secrets-Vault. AWS-nativ, gratis fuer Standard-Parameter, KMS-encrypted bei SecureString, IAM-kontrolliert.
Wann SSM, wann woanders
SSM Parameter Store fuer:
- AWS-Service-Account-Credentials (Access Key ID + Secret Access Key)
- Drittanbieter-API-Tokens die Apps in AWS brauchen (Anthropic, Replicate, Runway, Papierkram, TicketPAY)
- DB-Connection-Strings fuer App-zu-DB
- OAuth-Client-Secrets fuer hosted MCPs
Lokal .env.local (gitignored) fuer:
- MCP-Server-Tokens auf Marvins Laptop (Papierkram, TicketPAY, M365, etc.)
- Dev-Credentials die nur lokal gebraucht werden
- Schnelle Iteration ohne SSM-Roundtrip
macOS Keychain fuer:
- Persoenliche Browser-Saved-Logins (kein Vault-relevantes Material)
- macOS-System-Credentials
Naming-Konvention
/agentic-ventures/<account-slug>/<service>/<key-name>
<account-slug>— AWS-Account-Alias aus _index:av-mgmt,av-production,av-becker,mk-privat<service>— Tool/Service:bas-bedrock-pilot,papierkram,ticketpay,replicate,mcp-vf-hosted<key-name>— konkreter Wert:access-key-id,secret-access-key,api-token,oauth-client-secret,db-connection-string
Beispiele:
| Pfad | Type |
|---|---|
/agentic-ventures/av-becker/bas-bedrock-pilot/access-key-id | String |
/agentic-ventures/av-becker/bas-bedrock-pilot/secret-access-key | SecureString |
/agentic-ventures/av-production/papierkram/api-token | SecureString |
/agentic-ventures/av-mgmt/scalekit/owner-credentials | SecureString |
Schreiben
# String (nicht-sensible Werte wie Account-IDs, Key-IDs)
aws ssm put-parameter \
--name "/agentic-ventures/av-becker/bas-bedrock-pilot/access-key-id" \
--value "AKIA..." \
--type String \
--region eu-central-1 \
--profile av-becker
# SecureString (alles geheime)
aws ssm put-parameter \
--name "/agentic-ventures/av-becker/bas-bedrock-pilot/secret-access-key" \
--value "<paste hier, NICHT in Chat>" \
--type SecureString \
--region eu-central-1 \
--profile av-beckerSecureString nutzt automatisch den AWS-managed KMS-Key alias/aws/ssm — gratis. Eigener KMS-Key nur wenn fuer Compliance noetig.
Lesen
# Direkt
aws ssm get-parameter \
--name "/agentic-ventures/av-becker/bas-bedrock-pilot/secret-access-key" \
--with-decryption \
--query Parameter.Value \
--output text \
--region eu-central-1 \
--profile av-becker
# In Shell-Variable
export BEDROCK_SECRET=$(aws ssm get-parameter --name "..." --with-decryption --query Parameter.Value --output text)
# In .env.local automatisch generieren
aws ssm get-parameters-by-path --path "/agentic-ventures/av-becker/bas-bedrock-pilot/" --with-decryption \
--query "Parameters[*].[Name,Value]" --output text | \
awk -F/ '{print toupper($NF)"="$2}' > .env.localApp-Integration
Boto3 (Python):
import boto3
ssm = boto3.client("ssm", region_name="eu-central-1")
secret = ssm.get_parameter(
Name="/agentic-ventures/av-becker/bas-bedrock-pilot/secret-access-key",
WithDecryption=True
)["Parameter"]["Value"]AWS SDK (Node.js):
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";
const ssm = new SSMClient({ region: "eu-central-1" });
const { Parameter } = await ssm.send(new GetParameterCommand({
Name: "/agentic-ventures/av-becker/bas-bedrock-pilot/secret-access-key",
WithDecryption: true,
}));ECS/Lambda Env-Var-Injection: ECS Task Definition oder Lambda Environment kann SSM-Parameter direkt als ENV mounten — kein Code-Change noetig:
"secrets": [{
"name": "BEDROCK_SECRET_KEY",
"valueFrom": "arn:aws:ssm:eu-central-1:<account>:parameter/agentic-ventures/av-becker/bas-bedrock-pilot/secret-access-key"
}]IAM-Permissions
Reader-Pattern fuer Apps (Service-Account/Lambda/ECS):
{
"Effect": "Allow",
"Action": ["ssm:GetParameter", "ssm:GetParameters", "ssm:GetParametersByPath"],
"Resource": "arn:aws:ssm:eu-central-1:<account>:parameter/agentic-ventures/<account-slug>/*"
}KMS-Decrypt zusaetzlich noetig wenn SecureString:
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:eu-central-1:<account>:key/aws/ssm"
}Keine Wildcards ueber Account-Boundaries — pro Account-Service-Pair eigene Reader-Policy.
Rotation
- Quartalsweise (alle 90 Tage): API-Tokens (Papierkram, TicketPAY, M365-Secret, Replicate, Runway). Siehe token-hygiene.
- AWS Access Keys: alle 90 Tage rotieren oder bei Verdacht. Two-key-Pattern fuer no-downtime: neuen Key erstellen → Apps umstellen (SSM-Wert ueberschreiben) → alten Key deaktivieren → 24h warten → alten Key loeschen.
- OAuth-Refresh-Tokens (Google): keine Rotation noetig wenn Consent-Screen “Published”.
Bei Token-Leak
- Sofort widerrufen beim Anbieter (AWS IAM → Access Key deaktivieren, Papierkram → API-Settings, Google → Drittanbieter-Zugriff)
- Neuen Token generieren, in SSM ueberschreiben (gleicher Pfad → automatisches Versioning, alte Version bleibt fuer Audit)
- Apps neustarten wenn ENV-injected, sonst neu lesen
- Postmortem in
intern/runs/dokumentieren
Was gehoert NICHT in SSM
- Kunden-PII (Email-Adressen, Telefonnummern, Adressen) — separates Pattern (verschluesselt unter
~/source/.secrets/<repo>-pii/, gemaess t5-pii-in-repo—backup) - Beleg-PDFs / Vertraege — kommen nach
assets/finanzen/<jahr>/(gitignored) bzw.extern/inbound/vertraege/ - Secrets fuer reine Dev-Maschine ohne AWS-Bezug —
.env.localreicht
Migrationspfad fuer existierende Secrets
Wenn neue Service-Credentials anfallen, direkt in SSM. Bestehende lokale .env.local-Werte muessen nicht migriert werden, ausser sie werden auch von Cloud-Apps gebraucht.
Aktueller Migrations-Backlog (Stand 2026-05-08):
| Secret | Aktuell wo | Soll-SSM-Pfad |
|---|---|---|
| BAS Bedrock Pilot Access Key | TODO migrieren | /agentic-ventures/av-becker/bas-bedrock-pilot/{access-key-id,secret-access-key} |
| Papierkram-Token | .env.local lokal | spaeter, wenn Cloud-App das braucht |
| TicketPAY-Key | .env.local lokal | spaeter |
Related
- _index — AWS-Account-Inventar
- aws-multi-account-strategie — warum Multi-Account
- security — Threat-Model + Hygiene
- AWS-Doku: Parameter Store