AWS Org Security-Audit — 2026-05-15

Scope: AV-Org o-p197skdqva mit 4 Accounts. Modus: tief. Tool: aws-api MCP (call_aws) mit SSO-Profilen mgmt, av-prod, becker, mk-priv.

Account-Stand vs. Doku

AccountRolesUsersBuckets liveBuckets in VaultDrift
mgmt (343241684374)113550 ✅
av-production (425924867359)400734 nicht dokumentiert ⚠️
av-becker (084400305827)111440 ✅
mk-privat (210948569534)80110 ✅

Nicht-dokumentierte av-prod-Buckets: av-dashboard-data-425924867359, av-dashboard-frontend-425924867359, av-production-terraform-state, openwebui-vf-uploads-425924867359-eu-central-1.


Check-Ergebnisse

1. S3 Public Access — ⚠️

17 Buckets geprüft. Public-Access-Block aktiv auf 15 von 17. Zwei bewusst public:

  • marvinkuehlmann.com (PolicyStatus IsPublic=true) — Website-Hosting via Bucket-Policy
  • videos.marvinkuehlmann.com (PolicyStatus IsPublic=true) — Website-Hosting via Bucket-Policy

Beides Soll-Zustand (Hosting), aber buckets.md Regel 5 sagt: „Static-Website-Hosting via CloudFront-OAC, nicht via Bucket-Policy.” Findet hier nicht statt → Drift zur Doku.

2. IAM Wildcards / Custom-Policies — ✅

Custom-Policies pro Account: mgmt=3 (alle Service-Linked Lambda-Exec, AttachmentCount=0, ungenutzt), av-prod=0, becker=0, mk-priv=0. Keine Action:*/Resource:*-Wildcards in Custom-Policies. Admin-Rollen sind die SSO-Reserved-Roles (AWSReservedSSO_AdministratorAccess_*) plus OrganizationAccountAccessRole — beides Org-Standard, OK.

3. Root-Account-Usage — 🛑

  • mgmt: AccountAccessKeysPresent=1Root-Access-Keys existieren. AccountMFAEnabled=1 (root MFA da), aber Root-Keys gehören gelöscht.
  • av-production: AccountMFAEnabled=0 → Root hat keine MFA.
  • av-becker: AccountMFAEnabled=0 → Root hat keine MFA.
  • mk-privat: AccountMFAEnabled=0 → Root hat keine MFA.

4. CloudTrail — ✅

Org-Trail av-mgmt-trail aktiv (IsLogging=true, letzte Delivery 2026-05-15 11:41 CEST, multi-region, all-events, LogFileValidationEnabled=true, IsOrganizationTrail=true). Propagiert sauber in alle 4 Accounts. Logs in av-cloudtrail-logs-343241684374 (mgmt), Public-Access-Block aktiv.

5. GuardDuty — ⚠️

  • mgmt: nicht aktiviert
  • av-production: nicht aktiviert
  • av-becker: aktiviert (Detector cecf0b6d9fd55eeeed523b1f0f3a7870, alle DataSources außer EKS-Runtime + Lambda-Network-Logs + ECS-Runtime ENABLED). 0 Findings in den letzten 30 Tagen.
  • mk-privat: nicht aktiviert

6. Access Analyzer — 🛑

Keine Analyzer in keinem Account. Org-Analyzer fehlt komplett.

7. IAM Identity Center — n/a (Tool-Issue)

SSO-Login mit mkuehlmann über agentic (Mgmt) — funktioniert für alle 4 Accounts mit AdministratorAccess. External-User-Listing via identitystore list-users durch CLI-Escape-Issue im Tool nicht geprüft, manuell nachholen.

8. Secrets Manager — ⚠️

av-prod: 25 Secrets (alle CDK/Terraform-managed, sauber benannt). Keine Rotation aktiviert an irgendeinem Secret (LastChangedDate = CreatedDate plus manuelle put-secret-value, kein RotationLambdaARN sichtbar). Mgmt/becker/mk-priv: 0 Secrets.

Auffällig:

  • tmp/owui-admin-key — Prefix „tmp” suggeriert temporär, aber existiert seit 2026-05-12 und wird täglich gelesen (LastAccessedDate 2026-05-14).
  • agent-platform/github-pat — Fine-Grained PAT, manuell rotierbar, letzte Rotation 2026-05-12.

9. ECS/Fargate Tasks — ⚠️

av-production: 2 Cluster, 7 Services live:

  • inference-service-prod/inference-service-prod
  • default/mcp-vf-hosted
  • default/McpWhatsappHosted-...
  • default/McpCalcomHosted-...
  • default/open-webui-vf
  • default/presenton-vf

Mgmt/becker/mk-priv: keine ECS-Cluster. Alle Services im Vault grundsätzlich erwähnt, aber presenton-vf und inference-service-prod (icking-rebuild) sind nicht in intern/capabilities/apps/ als laufende Production-Apps gelistet — Drift gegen Inventar.

10. Security Groups — ✅

SGs mit 0.0.0.0/0 Inbound auf allen drei Accounts (av-prod, becker, mgmt) geprüft — Result: leer. Keine offenen SGs außer den implizit von Fargate/ALB-Patterns (HTTPS=443) genutzten. Default-VPC in av-prod existiert (vpc-0dceeb366e80ac4e0 172.31.0.0/16, IsDefault=true) — nicht problematisch, aber Doku-Cleanup-Kandidat.


Findings (tief-Modus, Confidence ≥ 2/10)

CRIT-01 — IAM-User mkuehlmann mit 2 alten Access-Keys ohne MFA

  • Account: mgmt (343241684374), Org-Master
  • Status: VERIFIED
  • Confidence: 10/10
  • Exploit-Skizze: mkuehlmann ist Source-Profile für AssumeRole-Fallback in alle Sub-Accounts. Wer den AccessKey kompromittiert (AKIAU72WMOWLJQXXCNVV von 2025-08-28, älter als 8 Monate, nie rotiert), kann ohne MFA OrganizationAccountAccessRole in JEDEN Account assumieren = volle Org-Kontrolle. Keys sind potenziell in ~/.aws/credentials, alten Backups, evtl. shell-history.
  • Fix: (a) MFA-Device für IAM-User anlegen, (b) MFA-required-Condition in der AssumeRole-Trust-Policy aller OrganizationAccountAccessRole-Trusts setzen, (c) den alten Key (2025-08-28) deaktivieren + nach 7d löschen, (d) langfristig: IAM-User-Auth komplett raus, nur noch SSO.

CRIT-02 — Root-Access-Keys auf Mgmt-Account

  • Account: mgmt
  • Status: VERIFIED (AccountAccessKeysPresent=1)
  • Confidence: 10/10
  • Exploit-Skizze: Root-Keys umgehen CloudTrail-Org-Trail-Bindung nicht, aber Root hat unbegrenzte Permissions inkl. Account-Close, Billing, MFA-Bypass. Ein kompromittierter Root-Key = Org-Übernahme.
  • Fix: In AWS-Console → Root-User → Security Credentials → vorhandene Access-Keys deaktivieren + löschen. Sofort. CIS Benchmark 1.4 erzwingt das.

HIGH-01 — Root-MFA fehlt auf 3 von 4 Accounts

  • Accounts: av-production, av-becker, mk-privat
  • Status: VERIFIED (AccountMFAEnabled=0)
  • Confidence: 10/10
  • Exploit-Skizze: Root-Login per E-Mail + Passwort-Reset. Plus-Aliase (aws+av-production@agenticventures.de, aws+privat@marvinkuehlmann.com) gehen auf Marvins Postfächer — wer dort Mail-Zugriff hat (Phishing, Token-Diebstahl Gmail), kann Root-Password-Reset und Account übernehmen ohne weiteren Faktor.
  • Fix: Pro Account einmal als Root einloggen (Console), Hardware-MFA oder Authenticator-App anlegen.

HIGH-02 — GuardDuty fehlt in 3 von 4 Accounts

  • Accounts: mgmt, av-production, mk-privat
  • Status: VERIFIED
  • Confidence: 9/10
  • Exploit-Skizze: Compromised Credentials, anomale API-Calls, S3-Exfil — nichts davon wird detektiert. av-production hostet alle MCPs, Open WebUI, inference-service-prod (Kunden-Pipeline) — gerade dort blind. Becker hat es richtig.
  • Fix: Org-weit aktivieren via Delegated Admin (security-prod oder mgmt selbst als delegated admin → aws guardduty enable-organization-admin-account). Etwa 2-5 USD/Account/Monat.

HIGH-03 — Access Analyzer fehlt komplett

  • Accounts: alle 4
  • Status: VERIFIED
  • Confidence: 9/10
  • Exploit-Skizze: Wenn versehentlich eine S3-Bucket-Policy oder IAM-Role-Trust Cross-Account/Public öffnet, gibt es keine Detection. Aktuell ist Public-Access-Block überall aktiv, aber Drift wird nicht alarmiert.
  • Fix: Pro Account aws accessanalyzer create-analyzer --type ACCOUNT (kostenlos). Ideal: Org-Analyzer im mgmt (--type ORGANIZATION).

HIGH-04 — IAM-User mit Access-Keys ohne MFA (3 Stück)

  • Accounts: mgmt (agentic-os-memory-rw, librechat-bedrock-vf), becker (bas-bedrock-pilot)
  • Status: VERIFIED
  • Confidence: 9/10
  • Exploit-Skizze: Service-Accounts mit Long-Lived-Keys. librechat-bedrock-vf hat AmazonBedrockLimitedAccess (BedrockInvoke alle Modelle in der Region) — Key-Leak = freie Bedrock-Nutzung auf Marvins Rechnung bis Quota greift. agentic-os-memory-rw mit Custom Policy S3AgenticOsMemory auf einen Bucket dessen Zweck im Vault explizit als unklar markiert ist (buckets.md Offene Punkte). bas-bedrock-pilot ähnlich für Becker-Daten.
  • Fix: (a) Prüfen ob diese User noch genutzt werden (CloudTrail-Lookup userIdentity.userName). Wenn nein: löschen. (b) Wenn ja: zu IAM-Role + STS-Token umbauen (für lokale Tools) oder zu IRSA/Fargate-Task-Role wenn von Compute aus genutzt. Long-Lived-Keys auf User vermeiden.

MED-01 — Bucket-Drift: 4 av-prod-Buckets nicht in buckets.md

  • Account: av-production
  • Status: VERIFIED
  • Confidence: 10/10
  • Buckets: av-dashboard-data-425924867359, av-dashboard-frontend-425924867359, av-production-terraform-state, openwebui-vf-uploads-425924867359-eu-central-1. Alle haben Public-Access-Block.
  • Exploit-Skizze: Kein direkter Exploit. Aber buckets.md ist die Anti-Wildwuchs-Single-Source-of-Truth (Regel) und Drift hier untergräbt das Konstrukt: nächste neue Bucket wird auch wieder vorbei angelegt, niemand merkt es.
  • Fix: intern/capabilities/aws/buckets.md ergänzen — pro Bucket Zweck, Verzeichnis-Konvention, Encryption, Lifecycle. Gleicher Drift-Eintrag wie becker-bedrock-logs.

MED-02 — Public Static-Website-Buckets via Policy statt CloudFront-OAC

  • Account: mgmt
  • Status: VERIFIED
  • Confidence: 8/10
  • Buckets: marvinkuehlmann.com, videos.marvinkuehlmann.com
  • Exploit-Skizze: Direkter Public-S3-Endpoint umgeht jede WAF/CloudFront-Schutzschicht. Aktuell wird das vermutlich akzeptiert weil es nur Marvins persönliche Domains sind, aber buckets.md Regel 5 verbietet das Pattern explizit (“Static-Website-Hosting via CloudFront-OAC, nicht via Bucket-Policy”). Wenn das Pattern hier OK ist, sollte die Regel angepasst werden, sonst kopiert der nächste neue Bucket es.
  • Fix: CloudFront-Distribution mit OAC vorschalten, Bucket-Policy auf nur-OAC-Principal beschränken. Oder: Regel in buckets.md lockern für Personal-Domains. Entscheidung treffen.

MED-03 — Default-VPC in av-production aktiv

  • Account: av-production
  • Status: VERIFIED
  • Confidence: 6/10
  • Exploit-Skizze: Default-VPC vpc-0dceeb366e80ac4e0 (172.31.0.0/16, IsDefault=true) ist nicht zwingend ein Risk — Fargate-Services laufen vermutlich in dedizierten VPCs oder werden auf die Default geschoben. Aber: Default-VPC enthält default-Security-Group, default-Subnets in jeder AZ; in Default-SG hängenbleibende Tasks erben breite In-VPC-Kommunikation. Empfehlung CIS Benchmark 5.x: Default-VPC löschen wenn nicht aktiv genutzt.
  • Fix: Prüfen ob Services in Default-VPC laufen (aws ecs describe-services pro Service → Network-Config). Wenn nein: Default-VPC löschen. Wenn ja: explizit dokumentieren warum.

MED-04 — Sekret-Rotation nicht aktiv (25 Secrets)

  • Account: av-production
  • Status: VERIFIED
  • Confidence: 7/10
  • Exploit-Skizze: Long-Lived-API-Keys (papierkram, m365-ServicePrincipal, ticketpay, Cloudflare-API-Token, Telegram-Bot, GitHub-PAT, WhatsApp-Access-Token, Cal.com-API-Key) werden bei Leak unbegrenzt nutzbar. Bei MCPs in Production: ein Container-Compromise = volle Upstream-API-Kontrolle bis manuell rotiert.
  • Fix: Pro Secret-Typ prüfen ob Provider Rotation unterstützt. Für externe APIs (Papierkram, M365, Cloudflare): manuelle Rotation-Routine ins Quarterly-Review aufnehmen. Für tmp/owui-admin-key: entweder TTL-Tag setzen + Lambda-Cleanup, oder umbenennen.

MED-05 — App-Inventar-Drift: inference-service-prod + presenton-vf fehlen in capabilities/apps/

  • Account: av-production
  • Status: VERIFIED
  • Confidence: 9/10
  • Exploit-Skizze: Indirekt — wenn ein laufender Service nicht im Vault dokumentiert ist, fehlt er beim nächsten Audit-Lauf, beim DR-Plan, beim Cost-Review. inference-service-prod ist die Icking-Kunden-Pipeline (Festpreis-Projekt 5.500 EUR), presenton-vf ein interner Slide-Builder — beides Production-Workloads in Kunden-Sphäre.
  • Fix: intern/capabilities/apps/ um beide Apps ergänzen mit Frontmatter, Domain, Cloudflare-Tunnel-ID, Secret-Refs.

LOW-01 — 3 ungenutzte Custom-Policies in mgmt

  • Account: mgmt
  • Status: VERIFIED (AttachmentCount=0)
  • Confidence: 10/10
  • Policies: AWSLambdaBasicExecutionRole-231598f3-..., AWSAmplifyCodeCommitExecutionPolicy-d1phvcxa1oj2pj, AWSLambdaBasicExecutionRole-f5332268-.... Alle aus 2023/2025 (vor-AV-Org), AttachmentCount=0.
  • Fix: aws iam delete-policy --policy-arn … für alle 3. Kein Risk, aber Cleanup.

Top-3 Sofort-Aktionen

  1. CRIT-02 + CRIT-01 zusammen: Mgmt-Account-Auth härten — Root-Access-Keys löschen, IAM-User-mkuehlmann MFA anlegen, alten Access-Key (2025-08-28) deaktivieren. Effekt: Org-Übernahme via Mgmt-Key-Leak unterbrochen.
  2. HIGH-01: Root-MFA für av-production, av-becker, mk-privat — Drei Logins als Root, drei Authenticator-Devices, in 30 Min erledigt. Effekt: E-Mail-Phishing-Pfad zur Account-Übernahme zu.
  3. HIGH-02 + HIGH-03: Detection-Layer einschalten — GuardDuty Org-weit aktivieren (Delegated Admin) + Access-Analyzer pro Account (kostenlos). Effekt: anomale Aktivität wird sichtbar, Public-Drift wird alarmiert. ~10 USD/Monat Gesamtkosten für die Org.

Methodik

Phasen aus [[../../capabilities/skills/security-audit/SKILL]]: Phase 5 (Infra) + Phase 11 (DSGVO/Datenklassifikation). Modus tief = Confidence-Gate 2/10. Alle Checks parallel über die 4 SSO-Profile, ~80 AWS-API-Calls. Output kann als Baseline für Regression-Diff (nächster Lauf) dienen.

Was NICHT geprüft wurde (Scope-Cut):

  • Cross-Region-Resources außer eu-central-1 (Org ist EU-only, andere Regionen sollten leer sein — manuell verifizieren mit --region *)
  • DSGVO-Klassifikation der S3-Bucket-Contents (Phase 11) — würde Object-Tagging-Review oder Sample-Read brauchen
  • CloudTrail-Insight-Selectors / Anomalie-Trends
  • Identity-Center-External-Users (CLI-Escape-Issue im aws-api-Tool — identitystore list-users muss manuell laufen)
  • Bedrock-Invocation-Logging-Inhalt
  • Kosten-Anomalien (CloudWatch-Alarme statt Security-Lens)