docs 🔑 CF-Zugang unmissverständlich: MCP read-only vs CF_API_TOKEN-Write (fix fresh-session permission-trap)

Frische Sonnet-Delegations-Session lief in die '10000 Authentication error'-Falle:
sie versuchte CF-Writes über den read-only MCP. Root Cause: .claude.json referenziert
nur die MCP-URL, NIE den Token in mcp/cloudflare/.env → kalter Agent kennt den Write-Pfad nicht.

- Handoff-Prompt: prominenter 'CF-KOMMUNIKATION'-Block (2 getrennte Pfade, exakte curl-
  Kommandos, '10000 = kein Rechteproblem, Pfad wechseln'-Hinweis im Ablauf).
- cf-tunnel-mapping.md §11: gleiche Klarstellung als SSoT-Callout inkl. Verifikation
  (no-op vnet-PATCH: MCP→10000, curl→success). 'Claude hat zig Tunnel erstellt' = immer
  via curl+Token, NIE via MCP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 14:38:19 +02:00
parent 8665902de7
commit 2e13594bd5
2 changed files with 37 additions and 5 deletions

View File

@@ -285,6 +285,13 @@ Tokens: nur im Container-Env + jederzeit via `GET /accounts/…/cfd_tunnel/<id>/
- Zero-downtime: neue Connectoren parallel hoch → CNAMEs → alte Container/Tunnel weg. Verifiziert: gitea/omada/vw/ds-bf 200, grafana 302, pve-mcp 400 (MCP-Bare-GET), bf-nas 2 Connectoren healthy.
- **Writes gehen NUR über `CF_API_TOKEN` (curl/Bearer)** — der `cloudflare`-MCP (OAuth) ist read-only (Create-Tunnel → `10000 Authentication error`).
> ⚠️ **CF-Zugang für frische Sessions — die häufigste Stolperfalle (2× reproduziert 2026-07-17):** Es gibt **zwei getrennte** CF-Zugänge, und `~/.claude.json` verweist NUR auf den read-only-MCP (`https://mcp.cloudflare.com/mcp`), **nicht** auf den Write-Token → ein frischer Agent weiß nichts vom Token und meldet fälschlich „fehlende Permissions".
> - **`cloudflare`-MCP** (`mcp__cloudflare__docs/search/execute`, OAuth): **strikt read-only**. Reads/Spec-Suche/Batch super; **jeder** Write → `10000: Authentication error` (erwartet, KEIN echtes Rechteproblem).
> - **`CF_API_TOKEN` in `mcp/cloudflare/.env`** (scoped, `valid & active`): **der Write-Pfad.** Damit wurde das komplette 3-Tunnel-HA gebaut. Verifiziert 2026-07-17 mit identischem no-op-vnet-PATCH: MCP → `10000`, curl+Token → `success:True`.
> - **Muster:** `cd ~/dev/bf-network-r6/mcp/cloudflare && set -a; . ./.env; set +a` → dann `curl -H "Authorization: Bearer $CF_API_TOKEN" …/accounts/$CF_ACCOUNT_ID/<pfad>`. Keys im .env: `CF_API_TOKEN/CF_ACCOUNT_ID/CF_ZONE_ID/CF_{BF,PVE,MM}_TUNNEL_ID`.
> - Alle Calls über `api.cloudflare.com` → **WARP-unabhängig** (Rollback klappt auch bei totem Privatpfad).
> - **Klarstellung „Claude hat doch zig Tunnel erstellt/geändert":** ja — aber immer über curl+Token, **nie** über den MCP. Der MCP war nie der Write-Pfad.
**hass-400 (2026-07-12 präzisiert):** `hass`/`vw`/`gitea` sind aktuell wieder auf **`bypass`** (App „hass, vw, gitea") → der 400 ist **rein** der Origin-Layer, **nicht Access**. HA-Log: „Received X-Forwarded-For header from an untrusted proxy **10.40.20.10**". Die reziproken bf-pve-Connectoren (macmini `.20.167`, NAS `.20.10`) fehlen in HAs `http.trusted_proxies`. **Fix** = beide IPs + `use_x_forwarded_for: true` + Core-Restart. **Kein SSH-Key auf HA `.20.105` → user-gated** (oder Zugang geben). Access-Härtung (bypass→WARP) bleibt der zweite, device-gated Schritt.
---

View File

@@ -27,13 +27,35 @@ Weg: nativer WireGuard-Mesh-Node auf ap1 (kein Container/LXC/neue HW), vnet-Rout
10.40.0.0/16 (Route-ID 5546dcb6-5901-4da6-8d91-b17f94703f71) von bf-pve auf den
Mesh-Node umhängen. Rollback = 1 PATCH zurück auf f7fdf3a6 (bf-pve).
‼️ CLOUDFLARE-KOMMUNIKATION — ZUERST LESEN, SONST LÄUFST DU GEGEN DIE WAND ‼️
Es gibt ZWEI getrennte CF-Zugänge. Verwechseln = die "fehlende Permissions"-Falle:
A) Der `cloudflare`-MCP (Tools mcp__cloudflare__docs/search/execute), registriert in
~/.claude.json als https://mcp.cloudflare.com/mcp. Der ist OAuth-basiert und STRIKT
READ-ONLY. Reads/Spec-Suche/Batch-Lesen: super. JEDER Write (POST/PUT/PATCH/DELETE)
scheitert mit "10000: Authentication error". Das ist ERWARTET, KEIN echtes Rechte-
problem und KEIN Grund aufzugeben oder Christoph nach Permissions zu fragen.
⚠️ .claude.json enthält NUR die MCP-URL, KEINEN Verweis auf den Token — der Token
lebt komplett getrennt (siehe B). Ein frischer Agent weiß das NICHT von selbst.
B) Der scoped API-Token CF_API_TOKEN in mcp/cloudflare/.env — DAS ist der Write-Pfad.
Damit wurde das gesamte TP16-3-Tunnel-HA (Tunnel erstellt/geändert/gelöscht) gebaut.
Verifiziert 2026-07-17: MCP-PATCH → 10000-Fehler, identischer curl-PATCH → success:True.
REGEL: Reads gern via MCP (schnell, batchbar). ALLE Writes via curl+CF_API_TOKEN, so:
cd ~/dev/bf-network-r6/mcp/cloudflare && set -a; . ./.env; set +a
curl -s -X POST -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" \
--data '{...}' "https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/<pfad>"
Verfügbare Env-Keys (Namen, keine Werte): CF_API_TOKEN, CF_ACCOUNT_ID, CF_ZONE_ID,
CF_BF_TUNNEL_ID, CF_PVE_TUNNEL_ID, CF_MM_TUNNEL_ID.
Neuen Mesh-Node-Token holen: GET /accounts/$CF_ACCOUNT_ID/warp_connector/<id>/token via curl+Token.
Alle CF-API-Calls gehen über api.cloudflare.com → WARP-UNABHÄNGIG (Rollback klappt auch,
wenn der private Pfad gerade tot ist). SSoT-Detail: cf-tunnel-mapping.md §11.
RAHMENBEDINGUNGEN:
- Christoph ist ZUHAUSE (physischer ap1-Zugriff → Recovery via Power-Cycle möglich).
- ap1 = einziger Edge/SPOF; MikroMCP live (mcp__mikromcp__*). Writes IMMER erst
plan_changes/dryRun, dann apply_plan. ap1 device-mode=home → kein Scheduler/fetch.
- CF-Writes NUR via CF_API_TOKEN (curl/Bearer) — der cloudflare-MCP ist read-only.
Token/IDs in mcp/cloudflare/.env. Alle CF-API-Calls laufen über api.cloudflare.com,
also WARP-unabhängig (Rollback geht auch wenn der private Pfad tot ist).
- wgcf-connector läuft als Docker-Einmal-Call auf macmini oder pve (ssh macmini / pve-mcp).
- PrivateKey aus der .conf → ~/.secrets bzw. mcp/cloudflare/.env, NICHT committen.
@@ -58,9 +80,12 @@ SCHON GEKLÄRT (nicht nochmal aufrollen):
Nur nach dem Scharfschalten Ping gegenprüfen (§4.5).
- IPv6 bewusst NICHT (v4-only; Mesh-site-to-site-v6 laut Guide broken).
ABLAUF: Plan-Gate zuerst (POST warp_connector → wenn Free-Plan das ablehnt: STOPP,
LXC-auf-pve-Fallback, §6). Dann §4.1→§4.5 des Runbooks. Bei jedem Schritt reversibel
ABLAUF: Plan-Gate zuerst — POST /accounts/$CF_ACCOUNT_ID/warp_connector {"name":"bf-ap1-mesh"}
via curl+CF_API_TOKEN (NICHT via MCP — der kann nicht schreiben!). Wenn Free-Plan das ablehnt:
STOPP, LXC-auf-pve-Fallback, §6. Dann §4.1→§4.5 des Runbooks. Bei jedem Schritt reversibel
halten; die 2 User-Gates oben mit Christoph koordinieren.
⚠️ Falls du irgendwo "10000: Authentication error" siehst: du hast versehentlich den MCP zum
Schreiben benutzt. Kein Rechteproblem — auf curl+CF_API_TOKEN wechseln (siehe CF-KOMMUNIKATION oben).
ROUTE-UMZUG (§4.4) — Weg A zuerst, Weg B als Fallback:
- Weg A: PATCH /accounts/…/teamnet/routes/5546dcb6… {tunnel_id: <mesh_node_id>}