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:
@@ -303,24 +303,29 @@ Tokens: nur im Container-Env + jederzeit via `GET /accounts/…/cfd_tunnel/<id>/
|
|||||||
|
|
||||||
**🔴 NEUER FUND (wichtiger als vw!) — Wildcard `*.emsenhuber.net` (`16aaec78`) zu offen:** Policy `christoph` hat `include: email:christoph OR login_method:github OR login_method:google`. **`login_method:<idp>` als include matcht JEDEN, der sich via GitHub/Google einloggt** — nicht nur christoph. D.h. **jeder GitHub-/Google-User erreicht nach Login alle internen Dienste** (hass, grafana, portainer, pve, gitea, …). Fix = die zwei `login_method`-Includes raus (nur `email:christoph` + ggf. weitere erlaubte Mails + `non_identity bf4` + `claude-mcp`). **NICHT einseitig geändert** (ändert Login-Verhalten überall) → User-Entscheidung. War im Memory schon als „Policy christoph verschlanken" geflaggt.
|
**🔴 NEUER FUND (wichtiger als vw!) — Wildcard `*.emsenhuber.net` (`16aaec78`) zu offen:** Policy `christoph` hat `include: email:christoph OR login_method:github OR login_method:google`. **`login_method:<idp>` als include matcht JEDEN, der sich via GitHub/Google einloggt** — nicht nur christoph. D.h. **jeder GitHub-/Google-User erreicht nach Login alle internen Dienste** (hass, grafana, portainer, pve, gitea, …). Fix = die zwei `login_method`-Includes raus (nur `email:christoph` + ggf. weitere erlaubte Mails + `non_identity bf4` + `claude-mcp`). **NICHT einseitig geändert** (ändert Login-Verhalten überall) → User-Entscheidung. War im Memory schon als „Policy christoph verschlanken" geflaggt.
|
||||||
|
|
||||||
> ❌ **WIDERLEGT am 2026-10-06 (Christoph, live getestet) — die Behauptung oben ist falsch.**
|
> ✅ **BESTÄTIGT und BEHOBEN am 2026-10-06 — der Fund oben war RICHTIG.**
|
||||||
> `testus@emsenhuber.com` wird **abgelehnt**; nur explizit freigeschaltete Adressen kommen durch.
|
> Christoph hat mit einem **zweiten GitHub-Account** (fremde Adresse) getestet: **er kam durch.**
|
||||||
> **Die E-Mail-Bindung der Policy gilt — `login_method` hebelt sie nicht aus.**
|
> `login_method:github` im **`include`** ist ein **OR** — die danebenstehende `email`-Zeile war
|
||||||
|
> eine **Alternative**, keine Bedingung. Jeder GitHub-Account kam hinein.
|
||||||
>
|
>
|
||||||
> **Der Denkfehler:** `include` ist ein **OR**; die Zeilen sind Alternativen, nicht Bedingungen.
|
> **Fix (ausgeführt):** `login_method:github` von `include` nach **`require`** verschoben
|
||||||
> Aus „GitHub ist eine Alternative zur E-Mail" wurde „GitHub allein genügt" — belegt war das nie.
|
> ⇒ **`email AND github`**. Zurückgelesen über beide Endpunkte, Fix bestätigt.
|
||||||
> Dazu passt, dass **kein** IdP eine Domain-Bindung trägt (live geprüft:
|
> ⚠️ Nebenwirkung: der E-Mail-Einmalcode allein reicht auf GitHub-Seite **nicht mehr**.
|
||||||
> `GET /accounts/{id}/access/identity_providers` — github/google/onetimepin alle nur
|
|
||||||
> `client_id` + `redirect_url`); die Einschränkung kann also nur aus der Policy kommen, und sie greift.
|
|
||||||
>
|
>
|
||||||
> **Es gab hier keine offene Tür.** Der Eintrag stand vom 2026-07-10 bis 2026-10-06 als
|
> 🔴 **Zwischenzeitliche Fehlspur (dokumentiert, weil lehrreich):** eine frühere Fassung dieser
|
||||||
> „wichtiger Fund" in der Akte, gestützt allein auf einen Lese-Schluss — der Test dauerte zwei
|
> Notiz erklärte den Fund am selben Tag für **widerlegt** — auf Basis eines **Google**-Tests
|
||||||
> Minuten. Details + Gotchas: `docs/teilprojekte.md` → `### TP49` (geschlossen, kein Fix).
|
> (`testus@emsenhuber.com` → abgelehnt) plus eines **Schlusses** auf GitHub. Der Schluss war
|
||||||
> ⚠️ **Nicht separat gemessen:** der GitHub-Pfad selbst (Google→GitHub ist geschlossen, nicht
|
> falsch: der Google-Test zeigt nur Googles Verhalten. Die IdP-Configs sind konfigurationsgleich
|
||||||
> getestet) — deshalb „ungetestet", nicht „bewiesen sauber".
|
> (beide nur `client_id` + `redirect_url`) — **das unterscheidende Feld steht nicht in der Config.**
|
||||||
|
> **Lehre: pro IdP einzeln messen, nicht den ersten Test auf den zweiten übertragen.**
|
||||||
>
|
>
|
||||||
> ✅ **Unberührt davon bleibt:** TP41 hat den Wildcard ohnehin auf Access-Groups
|
> **Bleibt gültig:** TP41 hat den internen Wildcard auf Access-Groups (`zt-humans`/`zt-home`/
|
||||||
> (`zt-humans`/`zt-home`/`zt-automation`) umgestellt — dort steht heute kein `login_method` mehr.
|
> `zt-automation`) umgestellt — dort steht heute kein `login_method` mehr. Der Sweep über alle
|
||||||
|
> Apps fand `login_method` nur noch in `Terpenfinder v3` (`christoph`: github+onetimepin;
|
||||||
|
> `geli`: nur onetimepin = harmlos).
|
||||||
|
>
|
||||||
|
> Details, Gotchas (`12130` reusable-Policy-Endpunkt, MCP read-only) und die Grenze
|
||||||
|
> „kein GitHub-Username-Selector" → `docs/teilprojekte.md` → `### TP49`.
|
||||||
|
|
||||||
**⏸️ `hass` 400 / `ha-mcp` — zwei getrennte Layer:**
|
**⏸️ `hass` 400 / `ha-mcp` — zwei getrennte Layer:**
|
||||||
- **Access-Layer (remote):** HA-Companion-App kann kein interaktives Access-Login → Fix = iPhone in **WARP** enrollen (`Warp Login App` `6c32fe23` `allow:christoph` existiert → christoph darf enrollen). Client-seitig, braucht User am Gerät. Vom Heim-Netz (bf4-IP) ohnehin ohne Login erreichbar.
|
- **Access-Layer (remote):** HA-Companion-App kann kein interaktives Access-Login → Fix = iPhone in **WARP** enrollen (`Warp Login App` `6c32fe23` `allow:christoph` existiert → christoph darf enrollen). Client-seitig, braucht User am Gerät. Vom Heim-Netz (bf4-IP) ohnehin ohne Login erreichbar.
|
||||||
|
|||||||
@@ -2578,63 +2578,94 @@ Split-Horizon; Zugang via TP41-**WARP** gelöst (Geli 2026-09-10 via Android). D
|
|||||||
**interne** Namen blieb dabei übersehen — deshalb reopened, s.o.
|
**interne** Namen blieb dabei übersehen — deshalb reopened, s.o.
|
||||||
|
|
||||||
<a id="tp49"></a>
|
<a id="tp49"></a>
|
||||||
### TP49 · Gitea #76 — CF-Access: `login_method`-Includes auf Policy-Ebene — ❌ widerlegt, kein Handlungsbedarf
|
### TP49 · Gitea #76 — CF-Access: `login_method:github` im include der Terpenfinder-Policy — ✅ behoben (require statt include)
|
||||||
|
|
||||||
*(Angelegt 2026-10-06. Fund vom 2026-07-10 (Memory `project_cf_tunnel_1033`),
|
*(Angelegt 2026-10-06. Fund vom 2026-07-10 (Memory `project_cf_tunnel_1033`).
|
||||||
**am 2026-10-06 als Phantom widerlegt und geschlossen.**)*
|
**Am 2026-10-06 zunächst fälschlich als Phantom geschlossen, nach einem echten Test wieder
|
||||||
|
geöffnet und behoben.** Die Irrfahrt steht unten unter „Aktenhistorie" — sie ist lehrreich
|
||||||
|
genug, um sie zu behalten.)*
|
||||||
|
|
||||||
> 🔴 **Der TP beruhte auf einer unbelegten Behauptung — auch der Prosa-Text dieses Abschnitts
|
#### Befund (verifiziert, 2026-10-06)
|
||||||
> selbst war Teil des Fehlers.** Ein früherer Stand dieses Abschnitts sagte, „ein beliebiger
|
|
||||||
> GitHub-Account sieht den Terpenfinder" und stufte TP49 als „🔴 ABSOLUTE PRIORITÄT" ein.
|
|
||||||
> Das war **falsch**. Wer das später liest: die Prämisse stammte nicht aus einem Test,
|
|
||||||
> sondern aus einem Fehlschluss (s. Herkunft).
|
|
||||||
|
|
||||||
#### Herkunft des Fehlers (2026-10-06, damit er nicht wiederkehrt)
|
Policy `christoph` auf App `420.teilzeitladen.xyz` (Terpenfinder v3, `e6a7991f…`, **öffentlich**)
|
||||||
|
trug `login_method:github` im **`include`**. `include` ist ein **OR** — die Zeile „email
|
||||||
|
christoph@emsenhuber.com" daneben war eine **Alternative**, keine Bedingung. Damit kam
|
||||||
|
**jeder GitHub-Account** hinein, unabhängig von seiner E-Mail.
|
||||||
|
|
||||||
Die Doku-Aussage zu `login_method` („asks which identity service was used for authentication")
|
**Belegt durch echten Test (Christoph, 2026-10-06):** ein **zweiter GitHub-Account** mit fremder
|
||||||
wurde so gelesen, als hebe der Include die danebenstehende `email`-Zeile auf. **`include` ist ein
|
Adresse kam durch. Vorher war mit `testus@emsenhuber.com` über den **Google**-IdP getestet worden
|
||||||
**OR** — die Zeilen sind Alternativen, nicht Bedingungen. Aus „GitHub ist eine Alternative zur
|
— und **abgelehnt**; daraus war falsch geschlossen worden, GitHub verhalte sich genauso.
|
||||||
E-Mail" wurde fälschlich „GitHub allein genügt und ignoriert die E-Mail". Belegt war nichts davon;
|
|
||||||
die Formulierung stand trotzdem als Tatsache im Abschnitt.
|
|
||||||
|
|
||||||
#### Gegenbeweis (Christoph, 2026-10-06, live getestet)
|
#### Fix (ausgeführt 2026-10-06)
|
||||||
|
|
||||||
**`testus@emsenhuber.com` wird abgelehnt.** Nur explizit freigeschaltete Adressen kommen durch —
|
`login_method:github` von `include` nach **`require`** verschoben ⇒ **`email AND github`**.
|
||||||
**die E-Mail-Bindung in der Policy gilt, `login_method` hebelt sie nicht aus.** Der Test lief über
|
|
||||||
den **Google**-IdP, ist aber auf GitHub übertragbar, weil beide IdPs **konfigurationsgleich** sind:
|
|
||||||
|
|
||||||
| IdP | Typ | `config` |
|
| | vorher | jetzt |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `72c1291b…` | github | `client_id`, `redirect_url` — **kein** Domain-Filter |
|
| `include` | email · **github** · onetimepin | email · onetimepin |
|
||||||
| `c7571880…` | google | `client_id`, `redirect_url` — **kein** Domain-Filter |
|
| `require` | — | **github** |
|
||||||
| `9024c7a6…` | onetimepin | `redirect_url` |
|
|
||||||
|
|
||||||
Da **keiner** der IdPs eine Domain-/Tenant-Bindung trägt (live per
|
**Zurückgelesen** über **beide** Endpunkte (App-Pfad und reusable-Pfad) — identisch, Fix sitzt.
|
||||||
`GET /accounts/{id}/access/identity_providers` geprüft), kann die Einschränkung nur aus der
|
Fremder GitHub-Account fällt durch (hat die Adresse nicht); Christop's GitHub-Account hat sie als
|
||||||
**Policy** kommen — und sie greift nachweislich. Ein Google-Test mit abweichender Adresse wurde
|
primäre Adresse und kommt durch. `onetimepin` bleibt als Include — **auf GitHub-Login-Seite ist
|
||||||
abgelehnt ⇒ dieselbe Policy-Struktur bindet GitHub genauso.
|
der Einmalcode allein aber nicht mehr ausreichend** (`require` verlangt beides).
|
||||||
|
|
||||||
⚠️ **Grenze der Aussage:** der GitHub-Pfad wurde **nicht** separat getestet (Google→GitHub ist
|
**Sweep über alle Apps:** `login_method` in `include`/`require`/`exclude` — **genau zwei Treffer,
|
||||||
geschlossen, nicht gemessen). Das ist der **einzige** verbleibende Grund, den Eintrag nicht als
|
beide in `Terpenfinder v3`** (`christoph`: github+onetimepin, `geli`: nur onetimepin=harmlos).
|
||||||
bewiesen sauber zu führen — nicht als Grund für eine Änderung.
|
Der interne Wildcard und alle anderen Apps: **kein `login_method` mehr** (TP41). Der Sweep prüfte
|
||||||
|
**alle drei** Regel-Arrays, nicht nur `include` — sonst wäre der Fix hinterher als neuer Treffer
|
||||||
|
aufgetaucht.
|
||||||
|
|
||||||
#### Was bleibt (der einzige haltbare Rest)
|
**Scope-Warnung geprüft:** die Policy `christoph` ist `reusable: true`. Vor dem Schreiben wurde
|
||||||
|
verifiziert, dass sie **nur an diese eine App gebunden** ist ⇒ Fix bleibt lokal, kein Kollateral.
|
||||||
|
|
||||||
Der interne Wildcard `*.emsenhuber.net` (`16aaec78…`) ist sauber — TP41 hat ihn auf Access-Groups
|
#### ⚠️ Was `login_method` NICHT kann (Christophs eigentliche Absicht)
|
||||||
umgestellt (`zt-humans` / `zt-home` / `zt-automation`). ✅ Kein `login_method` an
|
|
||||||
`hass`/`grafana`/`portainer`/`pve`. **Diese Feststellung ist unabhängig vom widerlegten Fund
|
|
||||||
und bleibt gültig.**
|
|
||||||
|
|
||||||
#### Gotchas (live bestätigt — bleiben wertvoll)
|
Die Absicht war, die Berechtigung **an den GitHub-Username** zu koppeln. **Das gibt Access nicht her:**
|
||||||
|
|
||||||
|
- **`login_method` prüft die Methode, nicht den Nutzer.** „hat sich via GitHub angemeldet" — kein
|
||||||
|
Username, keine Org-Zugehörigkeit.
|
||||||
|
- **Es gibt keinen GitHub-Username-Selector** im Selector-Katalog der Doku.
|
||||||
|
- Der **einzige** GitHub-bezogene Identitäts-Selector ist **„Identity provider group"** — der zieht
|
||||||
|
aus **SCIM-Provisionierung**. Am hiesigen GitHub-IdP ist `scim_config.enabled = false`;
|
||||||
|
`GET …/identity_providers/{id}/scim/groups` → **`500 (12158)`**. Der Weg ist daher **zu**.
|
||||||
|
(Zusätzlich ist der Selector für Infrastructure-Apps laut Doku auf *GitHub **organization*** begrenzt.)
|
||||||
|
- **Konsequenz:** `email AND github` ist keine Notlösung, sondern die **vollständige** Umsetzung
|
||||||
|
dessen, was Access hier hergibt. Eine echte Username-/Org-Kopplung bräuchte **SCIM aktiviert**
|
||||||
|
(Org-basiert, kostenpflichtig) — **eigener TP, nicht Teil von TP49.**
|
||||||
|
|
||||||
|
#### Gotchas (live bestätigt — alle drei neu am 2026-10-06)
|
||||||
|
|
||||||
|
- 🔴 **Reusable Policies lassen sich NICHT über den App-Pfad ändern.**
|
||||||
|
`PUT /accounts/{id}/access/apps/{app}/policies/{pol}` → **`12130 can not update reusable policies
|
||||||
|
through this endpoint`**. Korrekt ist **`PUT /accounts/{id}/access/policies/{policy_id}`**
|
||||||
|
(eigener Endpunkt für reusable Policies). Lesen geht über beide Pfade.
|
||||||
|
⚠️ Der bisherige Merksatz „Reusable Policy nur per App-PUT detachbar" beschreibt eine andere
|
||||||
|
Operation (Detach vom App-`policies`-Array) — **nicht** das Ändern ihres Inhalts.
|
||||||
|
- 🔴 **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.
|
||||||
- 🔴 **Access-App-IDs sind 32 Hex** — die Kurzform `16aaec78` liefert `12045 invalid_application_id`.
|
- 🔴 **Access-App-IDs sind 32 Hex** — die Kurzform `16aaec78` liefert `12045 invalid_application_id`.
|
||||||
Volle ID zuerst per `GET /accounts/{id}/access/apps` holen.
|
Volle ID zuerst per `GET /accounts/{id}/access/apps` holen.
|
||||||
- 🔴 **Der `cloudflare`-MCP ist strikt read-only.** Write-Probe 2026-10-06: no-op-PUT (identischer
|
|
||||||
Body) → **`1010: undefined`**. Writes nur via `CF_API_TOKEN`/curl.
|
#### Aktenhistorie (dokumentierter Fehlschlag — nicht löschen)
|
||||||
- Reusable Policy nur per **App-PUT** detachbar, nicht per `/policies`-DELETE.
|
|
||||||
|
Die erste Korrektur dieses Abschnitts (2026-10-06, vormittags) erklärte TP49 zum **Phantom** und
|
||||||
|
schloss es — auf Basis eines **Google**-Tests plus eines **Schlusses** auf GitHub. Zwei Fehler:
|
||||||
|
|
||||||
|
1. **Lese-Schluss als Befund verkauft.** Aus „`include` ist ein OR" + „Google bindet die Adresse"
|
||||||
|
wurde „also bindet GitHub auch" — nie gemessen. Das stand als Tatsache in Akte und Issue.
|
||||||
|
2. **Der Gegenbeweis war keiner.** Der Google-Test zeigt nur, was der Google-IdP liefert —
|
||||||
|
nicht, was GitHub liefert. Die IdP-Configs sind konfigurationsgleich; das Feld, in dem der
|
||||||
|
Unterschied steckt, steht nicht in der Config.
|
||||||
|
|
||||||
|
**Lehre:** bei Aussagen über fremde Infrastruktur **pro IdP einzeln messen**, nicht den ersten
|
||||||
|
Test auf den zweiten IdP übertragen. Der echte Test dauerte Minuten und hätte den Umweg erspart.
|
||||||
|
Details in Memory `feedback_no_guessing`.
|
||||||
|
|
||||||
#### Abgrenzung
|
#### Abgrenzung
|
||||||
**Nicht** TP41 (hat genau diesen Wildcard bereits saniert), **nicht** TP44 (Dokumentation).
|
**Nicht** TP41 (hat den internen Wildcard saniert), **nicht** TP44 (Dokumentation).
|
||||||
⚠️ `420.teilzeitladen.xyz` gehört zum Projekt **blaueblüten** — Projektgrenze beachten.
|
⚠️ `420.teilzeitladen.xyz` gehört zum Projekt **blaueblüten** — Änderung erfolgte mit
|
||||||
|
Christophs ausdrücklicher Freigabe, das Nachbar-Repo wurde **nicht** angefasst.
|
||||||
|
|
||||||
**→ Geschlossen 2026-10-06: kein Fix. Kein Schreibzugriff auf die Terpenfinder-Policy erfolgt.
|
**→ Abgeschlossen 2026-10-06: Fix gesetzt und zurückgelesen. Offen bleibt nur der
|
||||||
Christoph-Entscheid, nachdem er die Prämisse selbst widerlegt hatte.**
|
Bestätigungstest, dass ein fremder GitHub-Account jetzt abgewiesen wird.**
|
||||||
|
|||||||
@@ -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
|
> 🔴 **Diese Datei nicht mehr als Auftrag lesen — der ist ausgeführt.** Sie bleibt als Nachweis
|
||||||
> widerlegt wurde. Nicht ausführen.** Die Datei bleibt als Beleg stehen, damit die Prämisse
|
> stehen: Lage, Vorgehen und die Fehlschläge auf dem Weg dorthin.
|
||||||
> nicht in einer künftigen Session wieder als Auftrag auftaucht.
|
|
||||||
|
|
||||||
## Warum gegenstandslos
|
## Der Auftrag (erledigt)
|
||||||
|
|
||||||
Der Auftrag verlangte, `login_method:github` aus der Policy `christoph` der App
|
`login_method:github` aus dem `include` der Policy `christoph` der CF-Access-App
|
||||||
`420.teilzeitladen.xyz` zu entfernen, weil **„ein beliebiger GitHub-Account"** hineinkäme.
|
`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:
|
## Ausgeführt (2026-10-06)
|
||||||
die Adresse wurde **abgelehnt**. Nur explizit freigeschaltete Adressen kommen durch — die
|
|
||||||
E-Mail-Bindung der Policy gilt, `login_method` hebelt sie nicht aus.
|
|
||||||
|
|
||||||
## 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")
|
| | vorher | jetzt |
|
||||||
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` |
|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `72c1291b…` | github | `client_id`, `redirect_url` — **kein** Domain-Filter |
|
| `include` | email · **github** · onetimepin | email · onetimepin |
|
||||||
| `c7571880…` | google | `client_id`, `redirect_url` — **kein** Domain-Filter |
|
| `require` | — | **github** |
|
||||||
| `9024c7a6…` | onetimepin | `redirect_url` |
|
|
||||||
|
|
||||||
**Kein** IdP trägt eine Domain-/Tenant-Bindung (`GET /accounts/{id}/access/identity_providers`).
|
Gesetzt über **`PUT /accounts/{id}/access/policies/{policy_id}`**, zurückgelesen über **beide**
|
||||||
Die Einschränkung kann also **nur** aus der Policy kommen — und sie greift nachweislich.
|
Endpunkte (App-Pfad + reusable-Pfad) — identisch. Der `success:true` der API wurde **nicht**
|
||||||
Google ist auf GitHub übertragbar, weil beide IdPs konfigurationsgleich sind.
|
geglaubt, sondern die Policy neu gelesen.
|
||||||
|
|
||||||
⚠️ **Grenze:** der GitHub-Pfad wurde **nicht** separat gemessen. Die Aussage ist
|
**App-ID** `e6a7991f-466c-4d1d-bac6-4b30fafccce4` · **Policy (reusable)** `8e44f5d1-8257-443e-a797-b3de939952ee`
|
||||||
„Google→GitHub geschlossen", nicht „GitHub getestet". Das ist der einzige Grund, den Eintrag
|
**github-IdP** `72c1291b…` · **onetimepin** `9024c7a6…`
|
||||||
nicht als bewiesen sauber zu führen — **kein** Grund für eine Änderung.
|
|
||||||
|
|
||||||
## 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`
|
## 🔴 Gotchas — live bestätigt, alle drei neu am 2026-10-06
|
||||||
gehört zum Projekt **blaueblüten**; es wurde nichts angefasst.
|
|
||||||
|
|
||||||
## 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`.
|
Die ursprüngliche Absicht war eine Kopplung **an den GitHub-Username**. Das gibt Access nicht her:
|
||||||
2. 🔴 **Der `cloudflare`-MCP ist strikt read-only.** Write-Probe 2026-10-06: no-op-PUT
|
`login_method` prüft die **Methode**, nicht den Nutzer; einen Username-Selector gibt es nicht.
|
||||||
(byte-identischer Body) → **`1010: undefined`**. Writes nur via `CF_API_TOKEN`/curl.
|
Der einzige GitHub-bezogene Identitäts-Selector ist **„Identity provider group"** — der braucht
|
||||||
3. **Reusable Policy** nur per **App-PUT** detachbar (`policies:[{id,precedence}]`),
|
**SCIM**, und am hiesigen GitHub-IdP ist `scim_config.enabled = false`
|
||||||
nicht per `/policies`-DELETE.
|
(`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.**
|
Zwischenzeitlich wurde TP49 als **Phantom geschlossen** — auf Basis eines **Google**-Tests plus
|
||||||
Der Befund stand fünf Tage (2026-07-10 → 2026-10-06) als „🔴 ABSOLUTE PRIORITÄT" in der Akte,
|
eines **Schlusses** auf GitHub. Beides falsch:
|
||||||
gestützt allein auf einen Lese-Schluss. Der Test dauerte zwei Minuten.
|
|
||||||
|
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