TP49 behoben: login_method:github von include nach require
Christophs zweiter GitHub-Account kam durch — der Ursprungsfund war echt. Die
vormittägliche Schliessung als "Phantom" war ein Fehlschluss (Google-Test
ungeprueft auf GitHub uebertragen) und ist hiermit zurueckgenommen.
Fix: login_method:github aus include raus, in require -> email AND github.
Gesetzt via PUT /accounts/{id}/access/policies/{policy_id} (der App-Pfad gibt
12130 fuer reusable Policies), zurueckgelesen ueber beide Endpunkte.
Sweep ueber alle Apps: login_method nur noch in Terpenfinder v3 — christoph
(github+onetimepin) und geli (nur onetimepin, harmlos). Scope geprueft: die
reusable Policy haengt nur an dieser einen App, kein Kollateral.
Drei neue Gotchas: 12130 (reusable nur unter /access/policies/{id}, der alte
Merkatz meinte das Detach, nicht das Aendern), MCP read-only (1010), 32-Hex-IDs.
Grenze dokumentiert: die Absicht war Kopplung an den GitHub-Username — den
Selector gibt es nicht. Identity-provider-group braucht SCIM (hier disabled,
scim/groups -> 500/12158). email AND github ist das vollstaendige Moegliche.
Aktenhistorie des Umwegs bleibt in allen drei Dateien stehen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,61 +1,75 @@
|
||||
# Startauftrag — TP49: CF-Access `login_method`-Include entfernen ❌ NICHT AUSFÜHREN — gegenstandslos
|
||||
# Startauftrag — TP49: CF-Access `login_method`-Include ✅ ERLEDIGT (2026-10-06)
|
||||
|
||||
> **Geschlossen am 2026-10-06.** Gitea #76, Prosa in `docs/teilprojekte.md` → `### TP49`.
|
||||
> **Abgeschlossen.** Gitea #76, Prosa in `docs/teilprojekte.md` → `### TP49`.
|
||||
>
|
||||
> 🔴 **Dieser Auftrag ist ungültig. Er basiert auf einer falschen Prämisse, die am 2026-10-06
|
||||
> widerlegt wurde. Nicht ausführen.** Die Datei bleibt als Beleg stehen, damit die Prämisse
|
||||
> nicht in einer künftigen Session wieder als Auftrag auftaucht.
|
||||
> 🔴 **Diese Datei nicht mehr als Auftrag lesen — der ist ausgeführt.** Sie bleibt als Nachweis
|
||||
> stehen: Lage, Vorgehen und die Fehlschläge auf dem Weg dorthin.
|
||||
|
||||
## Warum gegenstandslos
|
||||
## Der Auftrag (erledigt)
|
||||
|
||||
Der Auftrag verlangte, `login_method:github` aus der Policy `christoph` der App
|
||||
`420.teilzeitladen.xyz` zu entfernen, weil **„ein beliebiger GitHub-Account"** hineinkäme.
|
||||
`login_method:github` aus dem `include` der Policy `christoph` der CF-Access-App
|
||||
`420.teilzeitladen.xyz` entfernen — nach Rücksprache, wen der Zugang treffen soll.
|
||||
|
||||
**Das ist falsch.** Christoph hat am 2026-10-06 mit `testus@emsenhuber.com` getestet:
|
||||
die Adresse wurde **abgelehnt**. Nur explizit freigeschaltete Adressen kommen durch — die
|
||||
E-Mail-Bindung der Policy gilt, `login_method` hebelt sie nicht aus.
|
||||
## Ausgeführt (2026-10-06)
|
||||
|
||||
## Wie der Fehler entstand
|
||||
`github` von `include` nach **`require`** verschoben ⇒ **`email AND github`**.
|
||||
|
||||
Die Doku-Aussage zu `login_method` („asks which identity service was used for authentication")
|
||||
wurde so gelesen, als **ersetze** der Include die danebenstehende `email`-Zeile.
|
||||
`include` ist ein **OR** — die Zeilen sind Alternativen, nicht Bedingungen. Aus
|
||||
„GitHub ist eine Alternative zur E-Mail" wurde fälschlich „GitHub allein genügt".
|
||||
**Belegt war das nie**; es stand trotzdem als Tatsache in Auftrag und Prosa-Abschnitt.
|
||||
|
||||
## Belegte Gegenlage (live geprüft 2026-10-06)
|
||||
|
||||
| IdP | Typ | `config` |
|
||||
| | vorher | jetzt |
|
||||
|---|---|---|
|
||||
| `72c1291b…` | github | `client_id`, `redirect_url` — **kein** Domain-Filter |
|
||||
| `c7571880…` | google | `client_id`, `redirect_url` — **kein** Domain-Filter |
|
||||
| `9024c7a6…` | onetimepin | `redirect_url` |
|
||||
| `include` | email · **github** · onetimepin | email · onetimepin |
|
||||
| `require` | — | **github** |
|
||||
|
||||
**Kein** IdP trägt eine Domain-/Tenant-Bindung (`GET /accounts/{id}/access/identity_providers`).
|
||||
Die Einschränkung kann also **nur** aus der Policy kommen — und sie greift nachweislich.
|
||||
Google ist auf GitHub übertragbar, weil beide IdPs konfigurationsgleich sind.
|
||||
Gesetzt über **`PUT /accounts/{id}/access/policies/{policy_id}`**, zurückgelesen über **beide**
|
||||
Endpunkte (App-Pfad + reusable-Pfad) — identisch. Der `success:true` der API wurde **nicht**
|
||||
geglaubt, sondern die Policy neu gelesen.
|
||||
|
||||
⚠️ **Grenze:** der GitHub-Pfad wurde **nicht** separat gemessen. Die Aussage ist
|
||||
„Google→GitHub geschlossen", nicht „GitHub getestet". Das ist der einzige Grund, den Eintrag
|
||||
nicht als bewiesen sauber zu führen — **kein** Grund für eine Änderung.
|
||||
**App-ID** `e6a7991f-466c-4d1d-bac6-4b30fafccce4` · **Policy (reusable)** `8e44f5d1-8257-443e-a797-b3de939952ee`
|
||||
**github-IdP** `72c1291b…` · **onetimepin** `9024c7a6…`
|
||||
|
||||
## Ergebnis
|
||||
**Sweep über alle Apps** (`login_method` in include/require/exclude): genau zwei Treffer, beide in
|
||||
`Terpenfinder v3` — `christoph` (github+onetimepin) und `geli` (nur onetimepin, harmlos).
|
||||
Interne Apps/Wildcard: sauber (TP41).
|
||||
|
||||
**Kein Schreibzugriff auf die Terpenfinder-Policy ist erfolgt.** `420.teilzeitladen.xyz`
|
||||
gehört zum Projekt **blaueblüten**; es wurde nichts angefasst.
|
||||
## 🔴 Gotchas — live bestätigt, alle drei neu am 2026-10-06
|
||||
|
||||
## Was aus diesem TP erhalten bleibt
|
||||
1. **Reusable Policies ändern geht NICHT über den App-Pfad.**
|
||||
`PUT …/access/apps/{app}/policies/{pol}` → **`12130 can not update reusable policies through
|
||||
this endpoint`**. Korrekt: **`PUT …/access/policies/{policy_id}`**.
|
||||
⚠️ Der ältere Merksatz „Reusable Policy nur per App-PUT detachbar" meint das **Detach** vom
|
||||
App-`policies`-Array — **nicht** das Ändern des Inhalts. Zwei verschiedene Operationen.
|
||||
2. **Der `cloudflare`-MCP ist strikt read-only.** Write-Probe: no-op-PUT (byte-identischer Body)
|
||||
→ **`1010: undefined`**. Writes nur via `CF_API_TOKEN`/curl
|
||||
(`cd mcp/cloudflare && set -a; . ./.env; set +a`). Token **nie** ausgeben.
|
||||
3. **Access-App-IDs sind 32 Hex** — Kurzform `16aaec78` → `12045 invalid_application_id`.
|
||||
|
||||
Nur die **Gotchas** — sie sind unabhängig vom widerlegten Fund und live bestätigt:
|
||||
## ⚠️ Was `login_method` nicht kann
|
||||
|
||||
1. **Access-App-IDs sind 32 Hex.** Kurzform `16aaec78` → `12045 invalid_application_id`.
|
||||
2. 🔴 **Der `cloudflare`-MCP ist strikt read-only.** Write-Probe 2026-10-06: no-op-PUT
|
||||
(byte-identischer Body) → **`1010: undefined`**. Writes nur via `CF_API_TOKEN`/curl.
|
||||
3. **Reusable Policy** nur per **App-PUT** detachbar (`policies:[{id,precedence}]`),
|
||||
nicht per `/policies`-DELETE.
|
||||
Die ursprüngliche Absicht war eine Kopplung **an den GitHub-Username**. Das gibt Access nicht her:
|
||||
`login_method` prüft die **Methode**, nicht den Nutzer; einen Username-Selector gibt es nicht.
|
||||
Der einzige GitHub-bezogene Identitäts-Selector ist **„Identity provider group"** — der braucht
|
||||
**SCIM**, und am hiesigen GitHub-IdP ist `scim_config.enabled = false`
|
||||
(`GET …/scim/groups` → `500 (12158)`). **Weg zu.**
|
||||
⇒ `email AND github` ist die vollständige Umsetzung des hier Möglichen, keine Notlösung.
|
||||
Eine echte Org-Kopplung bräuchte SCIM aktiviert — **eigener TP**.
|
||||
|
||||
## Lehre
|
||||
## Aktenhistorie — der Umweg (nicht löschen)
|
||||
|
||||
**Eine Sicherheitsaussage über fremde Infrastruktur braucht einen Test, nicht eine Ableitung.**
|
||||
Der Befund stand fünf Tage (2026-07-10 → 2026-10-06) als „🔴 ABSOLUTE PRIORITÄT" in der Akte,
|
||||
gestützt allein auf einen Lese-Schluss. Der Test dauerte zwei Minuten.
|
||||
Zwischenzeitlich wurde TP49 als **Phantom geschlossen** — auf Basis eines **Google**-Tests plus
|
||||
eines **Schlusses** auf GitHub. Beides falsch:
|
||||
|
||||
1. **Lese-Schluss als Befund verkauft.** „`include` ist ein OR" + „Google bindet die Adresse"
|
||||
⇒ „GitHub bindet auch". Nie gemessen, aber als Tatsache in Akte und Issue geschrieben.
|
||||
2. **Der Gegenbeweis war keiner.** Der Google-Test zeigt nur Googles Verhalten. Die IdP-Configs
|
||||
sind konfigurationsgleich — das unterscheidende Feld steht **nicht** in der Config.
|
||||
|
||||
Christoph hat mit einem **zweiten GitHub-Account** getestet: er kam durch. Damit war der
|
||||
Ursprungsfund bestätigt und der Fix nötig.
|
||||
|
||||
**Lehre: pro IdP einzeln messen, nicht den ersten Test auf den zweiten übertragen.**
|
||||
|
||||
## Verifikation
|
||||
|
||||
- [x] Policy über beide Endpunkte zurückgelesen — `require` trägt github, `include` nicht mehr
|
||||
- [x] Sweep: keine weiteren `login_method` in `include` außer den bekannten
|
||||
- [x] Scope: reusable Policy nur an diese eine App gebunden (kein Kollateral)
|
||||
- [ ] **Offen:** Bestätigungstest, dass ein fremder GitHub-Account jetzt **abgewiesen** wird
|
||||
|
||||
Reference in New Issue
Block a user