Skip to content

ADR-0002: Auth-Proxy PgBouncer mTLS

  • Status: accepted (CN-Mapping superseded durch ADR-0031; Proxy/mTLS bleibt)
  • Datum: 2026-08-26
  • Phase: P-SEC
  • Lastenheft: INF-04, INF-05, INF-06, Q-05

Kontext

QGIS spricht das Postgres-Wire-Protokoll. Zuvor: gemeinsames Passwort, plain TCP :3401 hinter WireGuard. Apps (Editor, Dashboard) brauchen Postgres nicht öffentlich. Design: Datenbankzugang.

Entscheidung

PgBouncer 1.24.x (edoburu/pgbouncer:v1.24.1-p1 per Digest, nicht :latest) als mTLS-Auth-Proxy:

  • client_tls_sslmode=verify-full, client_tls_protocols=secure (TLS 1.2/1.3)
  • interne CA; Client-Zertifikat pro Person/Gerät
  • Mapping CN → Mandanten-Rolle {slug}_edit / {slug}_read (ADR-0031); Control-DB behält linetra_edit / linetra_read
  • keine per-Person-Postgres-Rollen
  • Passwort-Auth von außen aus; Audit loggt CN
  • PostGIS unpublished (nur Compose-Netz)

QGIS: sslmode=verify-full + Client-Zertifikat + CA. Development-API auf der Workstation darf denselben Proxy nutzen (ADR-0013); Production-FastAPI bleibt intern postgres:5432.

Begründung

Es gibt bereits genau zwei GRANT-Profile. Geteiltes Passwort ist das Problem, nicht die zwei Rollen. Widerruf = Zertifikat sperren, nicht DROP ROLE. PgBouncer spricht libpq/SSLRequest korrekt; Traefik-TLS auf 3401 nicht.

Verworfene Alternativen

Alternative Warum verworfen
Teleport Database Access Zusätzliche Identity-Plattform für ein kleines Team; Betriebskosten ohne Mehrwert solange zwei Rollen reichen
Login-Rolle pro Person (INHERIT) RLS/GRANT personenscharf ist nicht nötig; Pflege von Dutzenden Rollen
Traefik-TLS auf TCP :3401 libpq sendet SSLRequest, kein TLS-ClientHello — silent failure
Passwort + TLS öffentlich Geteiltes linetra_edit, brute-force, kein Gerätebezug
Nur API, kein Live-Postgres für QGIS INT-01-Export reicht nicht für den Übergang; QGIS bleibt Produktions-Write-UI bis P3 abgenommen

Folgen

Compose-Profil mtls ist der live QGIS-Pfad. Traefik TCP :3401 auf wg0 ist zu (ADR-0003). FastAPI verbindet weiter intern nach postgres:5432. TLS steckt in PgBouncer, nicht in Traefik.