ADR-0055: Persönliche QGIS-Cert-Rollen (hartes Binding)
- Status: accepted
- Datum: 2026-09-04
- Phase: P-SEC / QGIS Plugin
- Bezug: ADR-0002, ADR-0031, ADR-0013
- Lastenheft: INF-05, Punkt 7 (Zertifikat → DB-Rolle)
Kontext
Bisher war der Cert-CN die Mandanten-Rolle {slug}_edit / {slug}_read. Jeder Editor einer Orga bekam kryptografisch denselben CN — fremde ZIPs öffneten denselben PgBouncer-Login. INF-05 verlangt persönliche, widerrufbare Client-Zertifikate; ADR-0002/0031 hatten „keine Postgres-Rolle pro Person“ gewählt und damit eine Backdoor gelassen.
Entscheidung
{slug}_edit/{slug}_readbleiben GRANT-Träger und FastAPI-LOGIN direkt aufpostgres:5432(Production unverändert).- Persönlicher LOGIN pro QGIS-fähigem
app_users-Konto:{slug}_u_{user_id_hex8}mitINHERITundGRANT {slug}_edit|read TO …. - Cert-CN = persönlicher LOGIN. Subject enthält zusätzlich
UID={user_id}fürs Plugin. client_cert_grants: PK = Zertifikat-Fingerprint; Spaltenuser_id(nullable für Ops),common_name,db_role(edit/read),revoked_at.pgbouncer.get_authliefert HMAC nur für Rollen mit aktivem Grant (revoked_at IS NULL). Shared-CN-Zertifikate am Proxy sind tot./auth/me→qgis_connection:username= persönlicher CN;user_id= Web-User.- Plugin: Multi-Cert-Store, Match CN/
user_id, Popup wenn fehlend — siehe Plugin-Briefing.
Begründung
PgBouncer auth_type=cert setzt den Postgres-User = CN. Ohne einzigartigen CN gibt es kein hartes Binding. Gruppenrollen halten GRANT-Pflege klein; persönliche LOGINs erben Rechte. get_auth-Filter schließt alte Shared-CN-Zips ohne FastAPI zu brechen.
Verworfene Alternativen
| Alternative | Warum verworfen |
|---|---|
| Nur Plugin-Match, Shared-CN bleibt | Manuelles QGIS-Profil = Backdoor |
| CN = Web-Username | Kollisionen, Rename-Brüche, kein Mandanten-Prefix |
| RLS pro Person | Unnötig für Isolationseinheit Mandant; Pflegeaufwand |
| Shared-CN + Fingerprint in PgBouncer | PgBouncer mappt nicht Fingerprint → User |
Folgen
- Breaking: bestehende QGIS-Cert-ZIPs neu ausstellen; alte Shared-CN-Certs am Proxy unbrauchbar.
- ADR-0002 / ADR-0031 / Lastenheft Punkt 7: „keine Rolle pro Person“ ist für QGIS-Proxy-Logins aufgehoben; Mandanten-Paar
{slug}_edit/readbleibt für API und GRANTs. - ADR-0013 Workstation: aktiven
client_cert_grants-Eintrag für das Ops-Cert anlegen (sonst keinget_auth). - Deaktivieren/Löschen eines Users: Grant revoken, persönliche Rolle
NOLOGINoderDROP.