Nach dem Streichen der Ausnahme durfte die Wortwahl nicht mehr nach sofortiger Einzelrotation klingen. Posten #4 ist anlass- aber weiterhin gebunden; beide Stellen sagen das jetzt explizit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
76 lines
3.3 KiB
Markdown
76 lines
3.3 KiB
Markdown
# TP14.4 — CF-Access-Service-Token für Claude rotieren
|
|
|
|
> **Stand 2026-08-19 · vorbereitet, nicht ausgeführt.** Kurzes Runbook für einen Einmal-Schuss:
|
|
> das Secret ist **genau einmal** sichtbar, danach nie wieder.
|
|
|
|
---
|
|
|
|
## 1. Ist-Stand (verifiziert 2026-08-19)
|
|
|
|
`mcp/cloudflare/.env` enthält **kein** `CF_ACCESS_CLIENT_ID` und **kein** `CF_ACCESS_CLIENT_SECRET`.
|
|
Der TP steht also zu Recht offen — es ist nichts halb erledigt, was man erst zurückbauen müsste.
|
|
|
|
Vorhanden und nutzbar: `CF_API_TOKEN`, `CF_ACCOUNT_ID`, `CF_ZONE_ID` (chmod 600, gitignored).
|
|
Das Token trägt laut TP14.4 bereits die nötigen Scopes **`Access: Service Tokens: Read + Write`**.
|
|
|
|
**Wozu das Ganze:** damit Claude Dienste hinter CF-Access erreichen kann, ohne den interaktiven
|
|
Login-Flow — das ist das „komm schwer durch Tunnel"-Symptom aus Memory `ref_cf_access_claude_profile`.
|
|
|
|
---
|
|
|
|
## 2. Ablauf
|
|
|
|
1. **Token-ID ermitteln:**
|
|
`GET /accounts/{account_id}/access/service_tokens` → den Eintrag `claude-mcp` heraussuchen, `id` notieren.
|
|
2. **Rotieren:**
|
|
`POST /accounts/{account_id}/access/service_tokens/{id}/rotate`
|
|
3. 🔴 **Sofort schreiben.** Die Antwort enthält `client_id` **und** `client_secret` — das Secret wird
|
|
**nur bei der Rotation** ausgegeben. Wer es nicht in diesem Moment wegschreibt, muss erneut rotieren
|
|
(was den alten Wert ungültig macht, also nicht folgenlos ist).
|
|
4. **Ablegen** in `mcp/cloudflare/.env`:
|
|
```
|
|
CF_ACCESS_CLIENT_ID=…
|
|
CF_ACCESS_CLIENT_SECRET=…
|
|
```
|
|
Datei bleibt `chmod 600`; sie ist über `mcp/**/.env` bereits gitignored — **nicht** committen.
|
|
5. **Konsolidieren** nach globaler Konvention: Werte zusätzlich in `~/.secrets/credentials.env`,
|
|
Index-Zeile (Schlüssel → Herkunftspfad) in `~/.secrets/README.md`. Single Source of Truth bleibt
|
|
der Originalort, `~/.secrets/` ist die Nachschlage-Kopie.
|
|
|
|
⚠️ **Beim Ausgeben von Fehlern/Tracebacks maskieren** — Projektregel aus
|
|
`feedback_redact_router_passwords_in_tracebacks`, gilt hier genauso.
|
|
|
|
---
|
|
|
|
## 3. Abnahme
|
|
|
|
Ein Aufruf gegen einen **Access-geschützten** Hostname mit den beiden Headern:
|
|
|
|
```
|
|
CF-Access-Client-Id: <client_id>
|
|
CF-Access-Client-Secret: <client_secret>
|
|
```
|
|
|
|
- **mit** Headern → der Dienst antwortet
|
|
- **ohne** Header → `403`
|
|
|
|
Beides prüfen. Nur der Erfolgsfall allein beweist nichts (der Hostname könnte auf `bypass` stehen —
|
|
`vw` tut das bewusst, s. TP16.2).
|
|
|
|
Danach Memory `ref_cf_access_claude_profile` nachziehen: dort steht bisher „Service-Token-Secret fehlt
|
|
lokal" — das ist nach dieser Rotation nicht mehr wahr.
|
|
|
|
---
|
|
|
|
## 4. Fußnote mit Verfallsdatum
|
|
|
|
⏰ ~~Der `CF_API_TOKEN` selbst läuft am 2027-01-09 ab~~ — **korrigiert 2026-09-21:** das Datum
|
|
gehörte zum längst **revokten** Alt-Token `9984078812bc…`; das **live** `CF_API_TOKEN`
|
|
(id `493ed8bd…`) hat **kein** Ablaufdatum (verifiziert via `/accounts/{id}/tokens/verify`,
|
|
`expires_on: null`). Die Rotation ist damit nicht mehr termin-, sondern **anlassgetrieben**:
|
|
**Anlass** ist der **Leak vom 2026-09-21**. Sie bleibt **gebündelt** in TP30 (Posten #4) und wird
|
|
nicht vorgezogen. Memory `ref_cf_mcp_readonly_token_writes` ist nachgezogen.
|
|
Er ist **account-owned**, verifiziert also über einen anderen Endpoint als ein User-Token — wer das
|
|
verwechselt, hält ein funktionierendes Token für kaputt. Ohne ihn ist auch diese Rotation nicht mehr
|
|
möglich, ebensowenig der TP16.3-Schnitt.
|