security-audit

Der Sicherheits-Check vor Deploys, Commits und Kunden-Uebergaben. Antwortet eine konkrete Frage: was wuerde ein Angreifer ausnutzen koennen, wenn ich das jetzt rauslasse?

Nicht zu verwechseln mit Hardening-Wunschlisten (“hier koennte man noch X”) oder Code-Style-Reviews. Ein Finding muss eine Exploit-Skizze haben — wenn die Skizze nicht plausibel ist, ist es kein Finding sondern eine Nice-to-have-Notiz.

Wann triggern

  • Vor Deploys eines MCP-Servers nach av-production (Fargate).
  • Vor Commit/Push eines neuen Repos auf GitHub (oder Wechsel von private auf public).
  • Vor Kunden-Uebergabe eines Mono-MCP-Connectors (Scalekit-OAuth, Custom Connector).
  • Periodisch ueber den Vault + Plugin-Repo (Skill-Supply-Chain, weil regelmaessig Skills nachinstalliert werden).
  • Nach Skill/Plugin-Installation aus externer Quelle (gstack, marketplace etc.) — Phase 8 als Schnell-Check.

Zwei Modi

ModusKonfidenz-GateWann
schnell (default)8/10 — nur was ich klar zeigen kannDaily / vor Commits / Quick-Check
tief2/10 — alles mit Tentative-LabelPre-Release, Pre-Kunden-Uebergabe, Pre-Public-Repo, periodischer Audit

Marvin kann den Modus mit “tief” / “comprehensive” / “voller audit” anfordern, sonst schnell.

Phasen-Filter

nur <phase> ueberspringt alles andere. Sinnvoll wenn ein konkreter Verdacht da ist:

  • nur secrets → nur Phase 2
  • nur supply-chain → Phase 3 + 8
  • nur llm → Phase 7
  • nur infra → Phase 5 + 4
  • nur webhook → Phase 6

Phase 0: Stack-Detect + Mental Model

Bevor du suchst, verstehe was vor dir liegt. Nicht Checklist abarbeiten — Architektur skizzieren.

Stack-Detection

# Python (MCPs, einige Lambdas)
ls pyproject.toml requirements.txt 2>/dev/null && echo "STACK: Python"
grep -l "fastmcp\|FastMCP" pyproject.toml requirements.txt 2>/dev/null && echo "FRAMEWORK: FastMCP"
 
# Node/TS (agents-platform, Plugin-Repo, evtl. Frontend)
ls package.json 2>/dev/null && echo "STACK: Node/TS"
grep -q "aws-cdk-lib" package.json 2>/dev/null && echo "FRAMEWORK: AWS CDK"
 
# Hugo (av-website + Landing-Pages)
ls config.toml hugo.toml config.yaml hugo.yaml 2>/dev/null && echo "STACK: Hugo"
 
# Vault (Markdown only, eigener Threat-Model — siehe _meta/security.md)
[ -f CLAUDE.md ] && grep -q "Agentic Ventures" CLAUDE.md 2>/dev/null && echo "STACK: AV-Vault"
 
# Infra
find . -maxdepth 5 -name "Dockerfile*" 2>/dev/null
find . -maxdepth 5 -name "*.tf" -o -name "*.tfvars" 2>/dev/null
find . -maxdepth 3 -path '*/cdk/*' -name "*.ts" 2>/dev/null | head -3
ls cdk.json 2>/dev/null

Mental Model

Lies CLAUDE.md, README, Top-Level-Config-Files. Skizziere kurz:

  • Was ist das? (MCP / Lambda-Cron / Web-App / Vault / Plugin)
  • Wer schickt Input? (claude.ai-Pro-User via OAuth, claude-Desktop-User stdio, Cron, Marvin selbst via Git, externe HTTP-Caller)
  • Wer hat Output-Zugriff? (Logs CloudWatch, S3-Bucket, Vault committed nach git, Email rausgeschickt)
  • Wo sind Trust-Boundaries? (OAuth-Layer, Network-Edge Cloudflare, IAM-Role-Grenze, MCP-Tool-Schema)

Das ist Reasoning, kein Bullet-Output. Aber halte es bereit — die Findings spaeter sind nur sinnvoll wenn man das Bild im Kopf hat.

Auf den eigenen Stack bezogen

Schau ergaenzend in:

  • mcp-hosting-aws-ecs-express” — wie MCPs gehostet sind (Fargate + cloudflared-Sidecar)
  • security” — eigenes Threat-Model fuer den Vault
  • agents-platform” — wie Cron-Lambdas Secrets bekommen (Inference-Profile-ARN, Secrets-Manager)

Phase 1: Attack Surface Census

Was sieht ein Angreifer? Code-Surface + Infra-Surface getrennt zaehlen.

Code-Surface (per Grep, Stack-spezifisch)

  • MCP-Server (FastMCP): Wie viele @mcp.tool Funktionen? Welche brauchen Auth-Header? Welche schreiben Daten (POST/DELETE), welche nur lesen?
    grep -rn "@mcp.tool\|@tool" --include="*.py" .
    grep -rn "@mcp.resource\|@resource" --include="*.py" .
  • agents-platform / Lambda: Welche Event-Sources? (EventBridge-Cron, API-Gateway, S3-Trigger, SNS)
    grep -rn "EventBridge\|api_gateway\|S3EventSource\|SnsEventSource" --include="*.ts" .
  • Hugo-Site: Forms? Embed-Skripte? Dritt-Party-JS? (Plausible, Cloudflare-Insights etc.)
  • Vault: Welche Files haben visibility: internal? Gibt es welche die committed sind und privat sein sollten?

Infra-Surface

find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null
ls .env .env.* 2>/dev/null
find . -maxdepth 5 -name "Dockerfile*" 2>/dev/null
grep -rn "Bucket\|BucketPolicy" cdk/ --include="*.ts" 2>/dev/null | head -10

Output

Schreibe das als kurzen Block (nicht Tabelle, der Audit ist nicht fuer Reporting nach oben sondern fuer eine Entscheidung):

SURFACE: <Repo-Name>
- MCP-Tools: <N> (davon <X> Write, <Y> Read)
- Lambda-Endpoints: <N> (Cron/API/Event)
- Public-Endpoints: <N> (Hugo-Site / claude.ai-OAuth-Endpunkt)
- Github-Actions: <N>
- Secrets-Stores: <Liste> (env / Secrets-Manager / Parameter-Store / hardcoded)
- Trust-Boundary: <Liste> (Cloudflare-Edge / Scalekit-OAuth / IAM-Role / MCP-Tool-Schema-Validation)

Phase 2: Secrets-Archaeology

Wo MCP-API-Keys, AWS-Credentials, Claude-API-Keys, M365-Service-Principal-Secrets, Papierkram-Keys etc. potenziell leaken.

Git-History scannen

# AWS
git log -p --all -S "AKIA" 2>/dev/null | head -50
# Anthropic
git log -p --all -G "sk-ant-" 2>/dev/null | head -50
# Generisch
git log -p --all -G "password|secret|token|api_key|api-key" -- "*.env*" "*.yml" "*.yaml" "*.json" "*.toml" "*.py" "*.ts" "*.js" 2>/dev/null | head -100
# Papierkram-Key-Format
git log -p --all -G "papierkram.*token" 2>/dev/null | head -30
# Scalekit
git log -p --all -G "skc_\|SCALEKIT_" 2>/dev/null | head -30

.env-Files

# Was ist getrackt das nicht sollte?
git ls-files | grep -E '\.env$|\.env\.[^e]|\.env\.local$|\.env\.production$'
 
# Ist .env in .gitignore?
grep -E "^\.env|^\.env\.local|^\.env\..*" .gitignore 2>/dev/null

Inline-Secrets in committed Code

# Hardcoded keys (Python + TS)
grep -rn 'sk-ant-[a-zA-Z0-9_-]\{40,\}' --include="*.py" --include="*.ts" --include="*.js" --include="*.md" . 2>/dev/null
grep -rn 'AKIA[A-Z0-9]\{16\}' --include="*.py" --include="*.ts" --include="*.js" . 2>/dev/null
# Allgemeines Pattern fuer "key = "longstring""
grep -rn -E '(api_key|secret|token|password)\s*=\s*["\047][a-zA-Z0-9_-]{20,}' --include="*.py" --include="*.ts" --include="*.js" . 2>/dev/null

Vault-spezifisch

Im AV-Vault gibt es eine Sonderregel: _meta/security.md definiert was rein darf. Pruefe:

grep -rn -E '(sk-ant-|AKIA|xoxb-|ghp_)' --include="*.md" . 2>/dev/null | grep -v "_meta/security\|example\|placeholder"

Severity / FP

  • CRIT: echte Schluessel-Prefixe (sk-ant-, AKIA, ghp_, xoxb-) in History oder current code, nicht als Beispiel/Placeholder.
  • HIGH: .env getrackt von git, Inline-Credentials in GitHub-Actions-yml.
  • MED: generische api_key = "..." mit langem Wert in non-test code.
  • FP: “your_key_here”, “changeme”, “TODO”, "", offensichtliche Beispiele in *.example / Doku. Auch: rotierte Schluessel sind trotzdem CRIT (waren mal exposed).

Phase 3: Dependency Supply Chain

Audit pro Stack

# Python
[ -f pyproject.toml ] && (uv tree 2>/dev/null || pip list --format json) 2>&1 | head -50
# Node
[ -f package.json ] && (bun audit 2>/dev/null || npm audit --json 2>/dev/null) | head -100

Install-Scripts in Prod-Deps (Node)

# Welche prod-deps haben install/preinstall/postinstall?
find node_modules -maxdepth 3 -name package.json -not -path "*/node_modules/*/node_modules/*" 2>/dev/null | \
  xargs grep -l '"preinstall"\|"postinstall"\|"install"' 2>/dev/null | head -20

Lockfile-Integritaet

# Lockfile vorhanden + getrackt?
ls package-lock.json yarn.lock bun.lock pnpm-lock.yaml uv.lock 2>/dev/null
git ls-files | grep -E '(package-lock\.json|yarn\.lock|bun\.lock|pnpm-lock\.yaml|uv\.lock)$'

Severity / FP

  • CRIT: Direkte Prod-Dep mit High/Critical-CVE die wir wirklich callen.
  • HIGH: Install-Script in einer nicht-vertrauten Prod-Dep.
  • MED: Abandoned package, no-fix CVE, fehlende Lockfile in App-Repo.
  • FP: devDep-CVEs (max MED), node-gyp/cmake Install-Scripts.

Phase 4: CI/CD Pipeline

GitHub-Actions in den eigenen Repos (mcp-*, agents-platform, agentic-ventures-plugin, av-website).

for f in $(find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null); do
  echo "=== $f ==="
  cat "$f"
done

Pruefe pro Workflow:

  • Unpinned third-party Actions: uses: actor/action@v1 statt @<sha>. Marvin: bei eigenen Repos sind first-party (actions/checkout etc.) MED, dritt-party HIGH.
  • pull_request_target mit Checkout des PR-Codes → CRIT.
  • Script-Injection: ${{ github.event.pull_request.body }} direkt in run: → CRIT.
  • Secrets als env-Vars ohne ***-Maskierung in Logs → HIGH.

Phase 5: Infra Shadow Surface

Eigener Stack — viel davon ist relevant.

Dockerfile / ECS Task-Def

find . -maxdepth 5 -name "Dockerfile*" -exec sh -c '
  echo "=== {} ==="
  grep -nE "USER |ARG |COPY .*\.env" "{}"
' \;

Pruefe:

  • Laeuft als root? (USER fehlt oder USER root)
  • .env ins Image kopiert?
  • Secrets als ARG (sichtbar in docker history)?

CDK (agents-platform + sonstige)

grep -rn "AccessControl.PUBLIC\|publicReadAccess: true\|publicAccessBlock" cdk/ --include="*.ts" 2>/dev/null
grep -rn 'actions: \["\*"\]\|resources: \["\*"\]' cdk/ --include="*.ts" 2>/dev/null
grep -rn 'PolicyStatement.*allow.*\*' cdk/ --include="*.ts" 2>/dev/null

Pruefe:

  • IAM-Wildcards (actions: ["*"] oder resources: ["*"]).
  • S3-Bucket publicReadAccess: true.
  • Public Subnets fuer Compute das nichts public sein muss.

S3-Bucket-ACLs

# Per AWS-CLI (Profil av-prod = av-production-Admin laut [[reference_aws_accounts]])
aws s3api get-bucket-acl --bucket <bucket> --profile av-prod 2>/dev/null
aws s3api get-public-access-block --bucket <bucket> --profile av-prod 2>/dev/null

Cross-Ref: “buckets” — Bucket-Map. Pruefe ob jeder Bucket dem dokumentierten Public/Privat-Status entspricht.


Phase 6: Webhook + MCP-Endpoint-Auth

Eigene MCP-Server. Fuer jedes mcp-* Repo:

FastMCP-Auth-Check

# Wird FastMCP mit Auth-Provider eingehaengt?
grep -rn "ScalekitProvider\|OAuthProvider\|auth=\|verify_token\|require_auth" --include="*.py" .
# Welche Tools sind unauthenticated?
grep -B2 "@mcp.tool" --include="*.py" -r . | grep -A1 "auth\s*=\s*False"

Pattern fuer hosted MCPs (claude.ai Pro Custom Connector): MUSS hinter ScalekitProvider haengen (siehe mcp-vf-hosted). Localhost-only-MCPs (stdio) brauchen keine Auth.

TLS-Verify disabled?

grep -rn "verify=False\|verify_ssl=False\|NODE_TLS_REJECT_UNAUTHORIZED" --include="*.py" --include="*.ts" --include="*.js" . 2>/dev/null

Severity

  • CRIT: Hosted MCP-Tool das Schreibzugriff hat ohne Scalekit-OAuth.
  • HIGH: TLS-Verify in Prod-Code disabled, OAuth-Scopes zu breit.
  • MED: Lokaler MCP der mehr macht als noetig (z.B. Buchhaltung mit Loesch-Tools fuer einen Read-Only-Use-Case).

Phase 7: LLM-Security

Marvin baut LLM-Tools — diese Kategorie ist ueberdurchschnittlich relevant.

Prompt-Injection-Vektoren

# User-Input in System-Prompt-Konstruktion?
grep -rn -E '(system_prompt|system_message)\s*=\s*f["\047]' --include="*.py" . 2>/dev/null
grep -rn -E 'system_prompt.*\+.*user|user.*\+.*system_prompt' --include="*.py" --include="*.ts" . 2>/dev/null
 
# Tool-Schemas mit dynamischen Strings?
grep -rn -E 'description\s*=\s*f["\047]|description\s*:\s*`\${' --include="*.py" --include="*.ts" . 2>/dev/null

LLM-Output unsanitized als HTML

grep -rn "dangerouslySetInnerHTML\|v-html\|innerHTML\|\.html(" --include="*.tsx" --include="*.jsx" --include="*.vue" . 2>/dev/null

Tool-Call ohne Validation

Bei MCP-Tools: pruefe ob Input-Parameter typed sind (Pydantic-Models bei FastMCP automatisch — wenn Any oder raw strings: Verdacht).

grep -rn -E ': Any\b|kwargs:\s*Any' --include="*.py" . | grep -B5 "@mcp.tool"

Cost/Resource-Attacks

Pruefe Tools die LLM-Calls ausloesen — kann ein User unbounded Calls triggern?


Phase 8: Skill + MCP Supply-Chain

Wichtigster Phase fuer den AV-Vault-Operator-Standpunkt — du installierst regelmaessig Skills + MCPs. Snyk-Forschung: 36% der published Skills haben Security-Flaws, 13.4% sind outright malicious.

Eigene Plugin-Skills

# Welche Skills laeuft das Plugin?
ls ~/.claude/plugins/marvinkuehlmann/agentic-ventures-plugin/skills/ 2>/dev/null
# Oder im Vault selbst:
ls /Users/marvinkuehlmann/source/agentic-ventures/intern/capabilities/skills/

Pro eigener Skill: Schau ueber das SKILL.md drueber — Eigenschaden ist akzeptabel, aber curl ... | bash aus externer Quelle nicht.

Globale Skills aus anderen Plugins

ls ~/.claude/plugins/ 2>/dev/null
find ~/.claude/plugins -name "SKILL.md" 2>/dev/null | head -50

Bei externen Skills (compound-engineering, anthropic-skills, gstack falls installiert) pruefe per Grep auf:

# Network-Exfiltration in Skill-Definitionen
grep -rln -E '(curl|wget|fetch)\b.*\$(\{|\()' ~/.claude/plugins/<external>/skills/ 2>/dev/null
 
# Credential-Reads in Skill-Bash
grep -rln -E 'ANTHROPIC_API_KEY|process\.env\.|cat.*\.env' ~/.claude/plugins/<external>/skills/ 2>/dev/null
 
# Prompt-Injection-Attempts
grep -rln -E 'IGNORE PREVIOUS|disregard\b|forget your instructions' ~/.claude/plugins/<external>/skills/ 2>/dev/null

MCP-Server in ~/.claude.json

jq '.mcpServers' ~/.claude.json 2>/dev/null

Pro MCP: ist die command / url aus einer Quelle die du kennst? Lokal selbst gebaut (in ~/source/mcp-*) ist OK, externer npx-Aufruf braucht Pruefung.

Severity / FP

  • CRIT: Credential-Exfiltration-Attempt, Prompt-Injection in Skill-File, MCP der unbekannte URL als Quelle hat.
  • HIGH: curl ... | sh aus externer Quelle in Skill-Bash, MCP mit zu breiten Tool-Permissions.
  • MED: Skill aus unverifiziertem Marketplace, nicht reviewed.
  • FP: eigene Skills im AV-Plugin, gstack/anthropic-skills/compound-engineering (etablierte Quellen, vorausgesetzt initial-reviewed).

Phase 9: OWASP-Mini

Statt voller OWASP-Top-10-Tour: gezielte Checks fuer deinen Stack.

A01 — Broken Access Control (MCP-relevant)

Bei hosted MCPs (Mono-MCP): kann User A das Papierkram-Konto von User B sehen? Pruefe Scalekit-OAuth-Scope und FastMCP-ctx.user_id-Usage.

grep -rn "ctx.user_id\|principal\.id" --include="*.py" .

A03 — Injection (Python + MCP-spezifisch)

# SQL-Injection (selten in seinem Stack, aber pruefen)
grep -rn -E 'execute\(.*%s.*\)|f["\047].*SELECT.*\{' --include="*.py" .
# Command-Injection
grep -rn -E 'os\.system|subprocess.*shell=True|exec\(|eval\(' --include="*.py" .

A05 — Misconfiguration (FastMCP)

# Debug-Mode in Prod?
grep -rn "DEBUG\s*=\s*True\|fastmcp.*debug=True" --include="*.py" .
# CORS-Wildcard?
grep -rn "allow_origins=\[\"\*\"\]" --include="*.py" .

A07 — Auth-Failures

OAuth-Setup pruefen (Scalekit) — JWT-Expiry, Refresh-Token-Rotation, MFA wenn Admin.


Phase 10: STRIDE — fuer kritische Komponenten

Nur fuer hosted MCPs + Production-Lambdas. Pro Komponente kurz durchgehen (eine Zeile pro STRIDE-Buchstabe):

KOMPONENTE: mcp-vf-hosted (Fargate)
  S: Kann ein anderer User die Tokens von vf-User spoofen? → Scalekit-OAuth-Scope-Check
  T: Kann ein Man-in-the-Middle Tool-Calls modifizieren? → Cloudflare-Edge-TLS, intern HTTPS-Only?
  R: Kann vf abstreiten dass er die Aktion ausgeloest hat? → Audit-Log in CloudWatch?
  I: Kann ein anderer User vf-Daten sehen? → Multi-Tenant-Isolation in Tool-Code
  D: Kann ein User die Fargate-Task lahmlegen? → Rate-Limit auf Scalekit-Layer / Fargate-Auto-Scaling
  E: Kann ein User Tool-Permissions ausweiten? → MCP-Tool-Schema-Validation

Phase 11: DSGVO-Daten-Klassifikation

Speziell fuer hosted MCPs + agents-platform Cron-Lambdas die mit Kundendaten arbeiten.

RESTRICTED (Breach = rechtliche Haftung):
  - Kundendaten in Papierkram (Rechnungen, Bankverbindungen)
  - Kundendaten in M365 (Emails, Kalender)
  - TicketPAY-Daten (Order-PII, Email-Adressen)
  → Wo gespeichert? Was wird geloggt? Wie lange?

CONFIDENTIAL (Breach = Business-Schaden):
  - API-Keys von Kunden-Tools (Papierkram, TicketPAY, M365)
  - Eigene Anthropic/AWS/Scalekit-Keys
  → Secrets-Manager / Parameter-Store / .env.local? Rotation-Policy?

INTERNAL:
  - System-Logs (CloudWatch)
  - Vault-Daten mit visibility: internal

PUBLIC:
  - Hugo-Sites Content, Public-MCP-Tool-Beschreibungen

Cross-Ref: ”anthropic-datenschutz”, ”_index”.


Phase 12: FP-Filter + Active Verification

Bevor irgendwas reported wird, filtere.

Auto-Discard (Hard-Exclusions)

  1. DoS / Rate-Limit-Fehlen (Ausnahme: LLM-Cost-Amplification aus Phase 7).
  2. Speicher/CPU-Exhaustion ohne konkreten Exploit.
  3. Input-Validation auf nicht-Sicherheits-Feldern ohne nachgewiesenen Impact.
  4. Memory-Safety in Python/Go/Rust/TS.
  5. Files die nur Tests/Fixtures sind und nicht importiert.
  6. Log-Spoofing (unsanitized Input in Logs ist keine Vuln).
  7. Race-Conditions ohne konkreten Exploit-Pfad.
  8. Veraltete Deps ohne known Exploit (gehoeren in Phase 3-Report, nicht als Einzel-Finding).
  9. Markdown-Doku-Files (*.md) — AUSNAHME: SKILL.md sind executable Prompt-Code, Phase-8-Findings drin sind KEIN FP.
  10. Fehlende Audit-Logs — Abwesenheit ist keine Vuln.
  11. Git-History-Secrets die im selben Initial-Setup-PR wieder removed wurden.

Konfidenz-Gate

  • schnell-Modus: Nur Findings ab 8/10 reporten. 1-7 → discard.
  • tief-Modus: Ab 2/10 reporten, aber Findings 2-7 als TENTATIVE labeln.

Active Verification (pro Finding)

Pro Finding das das Gate ueberlebt: versuche zu beweisen.

  • Secrets: Format-Check (richtige Praefix + Laenge). NIE gegen live API testen.
  • Webhook/MCP-Auth-Miss: Trace Handler-Code → existiert irgendwo Auth-Check (Middleware, Parent-Router, Cloudflare-Edge)? Code-Trace, NIE live-Request.
  • CDK-IAM-Wildcard: Parse den Stack — ist es wirklich * oder ein scoped Resource der nur so aussieht?
  • Supply-Chain: Ist die vulnerable Function direkt importiert? Wenn JA → VERIFIED, wenn NEIN → UNVERIFIED.
  • LLM-Prompt-Injection: Trace user-Input-Flow — landet er im System-Prompt oder im Tool-Schema?

Marker pro Finding:

  • VERIFIED — Code-Trace bestaetigt
  • UNVERIFIED — nur Pattern-Match
  • TENTATIVE — tief-Modus, Konfidenz 2-7

Parallel-Verification

Bei mehr als 3 Findings: Launch einen Agent (subagent_type general-purpose) pro Finding parallel. Verifier-Prompt:

Lies den Code bei file:line. Bewerte unabhaengig: ist hier eine echte, ausnutzbare Vulnerability? Score 1-10. Begruende. Wenn unter 8, sag warum das kein echtes Issue ist.

Findings die der unabhaengige Verifier auf < 8 (schnell) bzw < 2 (tief) bewertet → discard.


Phase 13: Findings-Report

Pro Finding (Format)

## Finding N: <kurztitel> — <file:line>

Severity: CRIT | HIGH | MED
Confidence: N/10
Status: VERIFIED | UNVERIFIED | TENTATIVE
Phase: <N — Phasenname>
Category: <Secrets | Supply-Chain | CI/CD | Infra | Webhook-Auth | LLM | Skill-Chain | OWASP-Axx | STRIDE-Y>

Was ist das Problem
<2-4 Saetze, technisch, ohne Floskeln.>

Exploit-Skizze
<Step-by-step wie ein Angreifer das ausnutzen wuerde. Wenn das nicht plausibel zu schreiben ist → war das ueberhaupt ein Finding?>

Fix
<Konkreter Vorschlag, idealerweise Diff-Skizze oder 1-2-Befehl.>

Quelle / Beleg
<Konkreter Code-Snippet, Git-Hash, oder CDK-Konstrukt.>

Findings-Tabelle (Header)

#   Sev    Conf   Status      Category         Title                            Phase   File
──  ────   ────   ──────      ────────         ─────                            ─────   ────
1   CRIT   9/10   VERIFIED    Secrets          AWS-Key in git history           P2      .env:3 (commit abc1234)
...

Baseline + Regression

Speichere am Ende intern/runs/<datum>-security-audit-<scope-slug>/baseline.json:

{
  "date": "YYYY-MM-DD",
  "scope": "<repo-name oder vault>",
  "mode": "schnell | tief",
  "findings": [
    {"id": "F001", "severity": "CRIT", "category": "Secrets", "verified": true, "fixed": false}
  ]
}

Beim naechsten Lauf: lade Baseline, vergleiche (welche Findings sind gefixt? Welche neu?). Append ## Regression an Report.

Top-3-Block

Am Ende: die drei Findings die zuerst gefixt werden muessen. Nicht 10. Drei.


Run-Log

Lege fuer jeden Lauf an: intern/runs/<YYYY-MM-DD>-security-audit-<scope>/ mit report.md + baseline.json. Cross-Ref in _index.

Bei MCP-Audits zusaetzlich Pflicht: mcp-audit-findings-cross-repo updaten — neue Pro-MCP-Sektion + Vergleichs-Matrix-Spalte. Wenn ein Finding zum 2+ten Mal auftaucht: als W-Pattern (wiederkehrend) hochziehen und Skeleton-Lessons-Tabelle erweitern. Der Tracker ist die Quelle dafuer dass wir Patterns ins Skeleton lernen statt jedes neue MCP wieder dieselben Issues zu produzieren.

Letzter Voll-Lauf: 2026-05-15-security-audit-full — Modus tief, 7 Scopes parallel, 24 Findings (5 CRIT/7 HIGH/12 MED). Goldstandard fuer parallele Sub-Agent-Audits: das Pattern dort (ein Agent pro Scope, jeder schreibt direkt in den Run-Ordner) hat sich bewaehrt.

Recurrence

Scheduled-Task security-audit-biweekly (~/.claude/scheduled-tasks/security-audit-biweekly/SKILL.md) laeuft alle 14 Tage (1. + 15. des Monats, 06:00) im schnell-Modus mit Baseline-Diff gegen den letzten Voll-Lauf.

Wann manuell triggern (ausser cron):

  • Vor jedem neuen Production-Deploy (mode: schnell, nur das deployende Repo als Scope)
  • Bei neuen Kunden-MCPs oder neuer hosted MCP (mode: tief, das Repo + AWS-Org als Scope)
  • Nach Skill-Install aus externem Plugin (mode: schnell, nur Phase 8)
  • Quartalsweise: Voll-Lauf wie 2026-05-15 (mode: tief, alle Scopes parallel)

Cron-Setup-Befehl (falls neu aufzusetzen, z.B. neue Maschine):

mcp__scheduled-tasks__create_scheduled_task taskId=security-audit-biweekly cronExpression="0 6 1,15 * *"

Verwandte Capabilities

Quelle

Methodik adaptiert von garrytan/gstack /cso — die Phasen-Struktur, Konfidenz-Calibration und FP-Filter-Liste sind dort drueben deutlich ausfuehrlicher. Hier komprimiert + auf den AV-Stack (FastMCP, CDK, Vault, Hugo, Scalekit-OAuth) zugeschnitten.