#!/usr/bin/env bash # Venv-Audit (monatlich, 17.07.2026): die Python-Nebendienste (Mem0, Voice) altern # eingefroren — kein Auto-Update-Kanal deckt sie ab. Dieser Audit MELDET nur # (bewusst kein Auto-Update: Python-Deps brechen gern): # je venv: veraltete Pakete zählen (pip list --outdated) + bekannte # Sicherheitslücken prüfen (pip-audit gegen den eingefrorenen Stand). # Werkzeug: eigenes Audit-venv (~/.venv-audit, wird beim Erstlauf angelegt) — die # Dienst-venvs selbst werden NICHT angefasst. CVE-Funde → Kanban-Karte (triage, # idempotent je Monat). Läuft als Hermes-Cron --no-agent (stdout = Telegram). set -uo pipefail VENVS=("$HOME/.mem0/venv:mem0" "$HOME/.voice/venv:voice") AUDIT_VENV="$HOME/.venv-audit" HERMES="$HOME/.local/bin/hermes" MONAT="$(date '+%Y-%m')" TMP="$(mktemp -d /tmp/venv-audit.XXXXXX)" trap 'rm -rf "$TMP"' EXIT briefkasten() { curl -sf -m 5 -X POST "${MC_ANNOUNCE_URL:-http://127.0.0.1:9001/api/voice/announce}" \ -H 'Content-Type: application/json' \ --data "$(python3 - "$1" <<'PY' import json, sys print(json.dumps({"text": sys.argv[1], "subject": "Venv-Audit", "source": "venv-audit", "priority": "silent"})) PY )" >/dev/null 2>&1 || true } # ---------- Werkzeug-venv sicherstellen (einmalig) ---------- if [ ! -x "$AUDIT_VENV/bin/pip-audit" ]; then python3 -m venv "$AUDIT_VENV" >/dev/null 2>&1 || true "$AUDIT_VENV/bin/pip" install -q --upgrade pip pip-audit >/dev/null 2>&1 || true fi ZEILEN=() CVE_DETAILS="" CVES_GESAMT=0 for EINTRAG in "${VENVS[@]}"; do VENV="${EINTRAG%%:*}"; NAME="${EINTRAG##*:}" # uv-venvs haben KEIN eigenes pip (Befund Erstlauf 17.07.) → das Audit-venv # inspiziert deren site-packages von außen (pip --path); Dienst-venvs bleiben unberührt. SP="$("$VENV/bin/python" -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])' 2>/dev/null || true)" if [ -z "$SP" ] || [ ! -d "$SP" ]; then ZEILEN+=("$NAME: venv fehlt/unlesbar unter $VENV — bitte prüfen") continue fi # Veraltete Pakete (Anzahl reicht fürs Lagebild) ALT_N="$("$AUDIT_VENV/bin/pip" list --outdated --path "$SP" 2>/dev/null | tail -n +3 | grep -c '' || echo 0)" # CVE-Prüfung gegen den eingefrorenen Stand (lokale Pfade/Editables ausfiltern) "$AUDIT_VENV/bin/pip" list --format=freeze --path "$SP" 2>/dev/null \ | grep -vE ' @ |^-e |^#' > "$TMP/$NAME.txt" || true CVE_N=0 if [ -x "$AUDIT_VENV/bin/pip-audit" ] && [ -s "$TMP/$NAME.txt" ]; then AUDIT_OUT="$("$AUDIT_VENV/bin/pip-audit" -r "$TMP/$NAME.txt" --progress-spinner off 2>&1 || true)" if printf '%s' "$AUDIT_OUT" | grep -qi 'No known vulnerabilities'; then CVE_N=0 else CVE_N="$(printf '%s\n' "$AUDIT_OUT" | grep -cE '^[a-zA-Z0-9_.-]+ +[0-9][^ ]* +(GHSA|PYSEC|CVE)' || echo 0)" if [ "${CVE_N:-0}" -gt 0 ]; then CVE_DETAILS="${CVE_DETAILS} == ${NAME} == $(printf '%s\n' "$AUDIT_OUT" | grep -E '^[a-zA-Z0-9_.-]+ +[0-9][^ ]* +(GHSA|PYSEC|CVE)' | head -10)" fi fi else ZEILEN+=("$NAME: pip-audit nicht verfügbar (Audit-venv kaputt oder offline?) — nur Outdated-Zählung") fi CVES_GESAMT=$(( CVES_GESAMT + ${CVE_N:-0} )) ZEILEN+=("$NAME: ${ALT_N} Pakete veraltet · ${CVE_N:-0} bekannte Sicherheitslücken") done # ---------- Bericht ---------- if [ "$CVES_GESAMT" -eq 0 ]; then echo "Commander, monatlicher Venv-Audit der Python-Nebendienste — keine bekannten Sicherheitslücken:" printf '• %s\n' "${ZEILEN[@]}" echo "(Veraltete Pakete sind nur ein Lagebild; aktualisiert wird bewusst nur mit Anlass.)" briefkasten "Venv-Audit grün: $(printf '%s · ' "${ZEILEN[@]}")" else echo "⚠️ Commander, der monatliche Venv-Audit hat ${CVES_GESAMT} bekannte Sicherheitslücken gefunden:" printf '• %s\n' "${ZEILEN[@]}" echo "Details liegen als Karte in der Ideen-Queue — Update bleibt dein Entscheid." if [ -x "$HERMES" ]; then "$HERMES" kanban create "Venv-Audit ${MONAT}: ${CVES_GESAMT} Sicherheitslücken in Python-Diensten" \ --body "Automatischer monatlicher Audit (restore-/venv-Kreislauf 17.07.). Funde (pip-audit): ${CVE_DETAILS} Empfehlung: betroffene Pakete gezielt aktualisieren (venv-weise, mit Dienst-Restart + Postcheck) — KEIN pauschales Upgrade." \ --triage --created-by venv-audit --idempotency-key "venv-audit-${MONAT}" >/dev/null 2>&1 || true fi briefkasten "⚠️ Venv-Audit: ${CVES_GESAMT} Sicherheitslücken — Karte liegt in der Queue." exit 1 fi