WhatsApp-Token-Rotate

Standard-Prozess fuer Meta-Token-Rotation. Erste Anwendung 2026-05-19 fuer Friseur-im-Sueden (Token expired 18.05. abends, 401 in Logs erkannt durch /receptionist-smoke).

Wann triggert der Skill

  • „401 von graph.facebook.com” (CloudWatch-Symptom)
  • „whatsapp token rotieren”
  • „token expired”
  • „meta access token erneuern”
  • „friseur bot sendet nicht mehr”
  • Auto-Folge wenn /receptionist-smoke Vor-Check 4 (Token-Health) failed

Sicherheits-Regeln

  • Token NIE in Files schreiben (keine .env, keine Vault-Docs, keine Run-Logs)
  • Token NIE in Bash-Logs echoen — sofort per aws secretsmanager put-secret-value in das Secret, dann aus Shell-History loeschen (history -d)
  • Token NIE in CloudWatch loggen — Brain-/MCP-Code log-sanitized

Ablauf

Phase 1 — Marvin durch Meta-UI fuehren

Frage Marvin:

  • Welcher Channel? (Default Friseur-im-Sueden, Account 889608426871476)
  • Hat er gerade Browser auf? Wenn nicht: gib Direkt-Link

Schritte fuer Marvin (kopierbar als Anweisung):

  1. https://business.facebook.com/business/settings → linke Sidebar System Users
  2. Business-Portfolio waehlen: Friseur im Sueden (oder den gewuenschten)
  3. System User pruefen: existiert einer fuer mcp-whatsapp? (z.B. mcp-whatsapp-friseur, Role Admin)
    • Falls NEIN: Add → Name mcp-whatsapp-<customer-slug>, Role Admin → Create
  4. Auf den System User klicken → Generate New Token
  5. App waehlen: 988192143605811 (mcp-whatsapp App im Friseur-Portfolio)
  6. Token Expiration: Never (Permanent Token)
  7. Permissions/Scopes haken:
    • whatsapp_business_messaging (Senden)
    • whatsapp_business_management (Templates, Phone-Info, etc.)
  8. Generate Token → Token wird einmalig angezeigt
  9. Token kopieren (langer String, beginnt typisch mit EAAOK... oder EAAX...)
  10. Token Marvin in den Chat pasten (NICHT in Datei)

Phase 2 — Token in AWS Secret schreiben

Sobald Marvin Token gepastet hat, sofort:

# Token in Shell-Variable (nicht echoen!)
NEW_TOKEN='<paste>'
 
# Bestehenden Secret-JSON holen und ACCESS_TOKEN-Key updaten
aws --profile av-production --region eu-central-1 secretsmanager get-secret-value \
  --secret-id mcp-whatsapp-hosted/whatsapp-config \
  --query SecretString --output text | jq --arg t "$NEW_TOKEN" '.ACCESS_TOKEN = $t' > /tmp/wa-config.json
 
aws --profile av-production --region eu-central-1 secretsmanager put-secret-value \
  --secret-id mcp-whatsapp-hosted/whatsapp-config \
  --secret-string file:///tmp/wa-config.json
 
# /tmp aufraeumen
rm /tmp/wa-config.json
 
# Shell-History bereinigen
history -d $(history 1 | awk '{print $1}') 2>/dev/null || true

Wichtig: NEW_TOKEN='<paste>' Zeile darf nie im Persistent-Log landen. Bei manueller Ausfuehrung Marvin direkt anweisen, NICHT als Bash-Tool-Call mit command: NEW_TOKEN='...' machen — der Inhalt geht in den Tool-Result-Stream. Stattdessen Marvin sagen: „Paste Token, ich schreibe in Secret” und Token-Variable separat setzen via einer Methode die sicherstellt der Token nicht im Tool-Use-Output landet (z.B. Marvin setzt env vor Skill-Run und Skill liest $WHATSAPP_NEW_TOKEN).

Phase 3 — ECS Force-Deploy

ECS reloaded Secrets nicht zur Laufzeit (Lesson aus 2026-05-15). Force-deploy noetig:

aws --profile av-production --region eu-central-1 ecs update-service \
  --cluster default \
  --service McpWhatsappHosted-ServiceD69D759B-HuB3n6EMF0qS \
  --force-new-deployment \
  --query 'service.{Status:status,Desired:desiredCount,Deployment:deployments[0].rolloutState}' \
  --output table

Phase 4 — Warte auf neuen Task healthy (~60-90 Sek)

# Poll bis Deployment COMPLETED ist
until aws --profile av-production --region eu-central-1 ecs describe-services \
  --cluster default --services McpWhatsappHosted-ServiceD69D759B-HuB3n6EMF0qS \
  --query 'services[0].deployments[0].rolloutState' --output text | grep -q COMPLETED; do
  echo "Waiting..."
  sleep 10
done

Optional via Bash run_in_background damit andere Vor-Checks parallel laufen koennen.

Phase 5 — Verify

Test ob neuer Token wirkt. Pruefe Logs ob get_phone_info oder ein Send-Tool durchgeht ohne 401:

# Health-Check + last log lines (kein Token-Reveal)
curl -sS https://mcp-whatsapp.agenticventures.de/health
aws --profile av-production --region eu-central-1 logs tail \
  /aws/ecs/default/mcp-whatsapp-hosted --since 2m 2>&1 | tail -10

Erwartet: /health 200, keine neuen 401-Lines.

Aktiver Smoke (besser als Logs-passiv): Marvin schickt eine Test-WA an den Channel → wir warten auf neue 200-Log-Line von graph.facebook.com. Wenn 200 → Token funktioniert.

Phase 6 — Doku-Update

Folgende Vault-Files updaten:

  • intern/capabilities/mcps/whatsapp.md: letzte Token-Rotation-Datum als Hinweis
  • intern/projekte/friseur-im-sueden-bot/_index.md: Verlauf-Eintrag „Token rotiert YYYY-MM-DD”

Optional: bei wiederholten Token-Expiry-Vorfaellen pruefen ob der erzeugte Token wirklich Permanent ist (Meta hat manchmal Quirks wo „Never expires” trotzdem nach 60 Tagen ablaeuft bei nicht-business-verified Apps).

Multi-Channel-Fall

Bei Mehr-Customer-Setup spaeter (Icking, weitere Salons): Skill braucht --channel <slug> Parameter und mapped auf:

  • Secret-Name: mcp-whatsapp-hosted/whatsapp-config-<slug> (oder per-Customer Secret-Naming-Convention noch zu definieren)
  • ECS-Service: ggf. eigene Service pro Channel
  • Meta-Account-ID + App-ID aus receptionist-customers DDB-Row

Aktuell single-channel hardcoded — ergaenzen wenn 2. Customer onboarden.

Was der Skill NICHT macht

  • Erstellt KEINEN System User auf Meta (manueller Schritt, einmalig)
  • Aktiviert KEINE neuen Permissions (Marvin haakt manuell)
  • Loggt den Token NICHT (siehe Sicherheits-Regeln)
  • Setzt KEINE Telegram-Push beim erfolgreichen Rotate (koennte optional spaeter)

Bei FAILURE

SymptomWahrscheinlicher GrundFix
put-secret-value AccessDeniedAWS-Profil nicht av-productionaws sts get-caller-identity checken, Profil setzen
update-service AccessDeniedgleicher Grundgleich
Token wieder 401 nach RotationScopes nicht gesetztPhase 1, Schritt 7 wiederholen mit Haken
Token erkennt Phone-Number nichtToken aus falschem App generiert (nicht 988192143605811)Phase 1, Schritt 5 wiederholen mit richtiger App
Task nicht healthy nach 5 MinContainer-Bug bei Startup, nicht TokenCloudWatch-Logs Container-CrashLoop pruefen
  • SKILL — triggert diesen Skill bei Token-Health-Failure
  • whatsapp — MCP-Doku inkl. Meta-App-Setup
  • mcp-hosting-fargate-tunnel — Hosting-Pattern inkl. „ECS reloaded Secrets nicht zur Laufzeit” Lesson
  • _index — Customer 1, Erstanwendung