PAT-Proxy
Im Teamscale-Dogu nimmt der Go-Proxy HTTP-Anfragen auf Port 8080 entgegen.
Der Proxy leitet an einen separaten Teamscale-Adapter über den Unix-Socket
/tmp/teamscale-pat/adapter.sock weiter. Teamscale lauscht intern auf 127.0.0.1:8081. Die Setup- und Backup-Aufrufe
verwenden diesen internen Port. Auch nach dem Wiederherstellen einer alten
Konfiguration werden Port und Bind-Adresse vor dem Teamscale-Start gesetzt. Der externe Dogu-Nginx und der TCP-Healthcheck
verwenden weiterhin Port 8080. Die Port- und Bind-Einstellungen stehen in
config/teamscale.properties, siehe Teamscale-Dokumentation.
Für /teamscale/api und /teamscale/api/… gilt:
- Bei Basic Auth und einem Passwort mit dem Präfix
pat_sendet der Proxy einen GET-Request mit dem ursprünglichen Authorization-Header anhttps://<fqdn>/cas/api/pats/validate?scope=/teamscale. Den FQDN liest das Startskript mitdoguctl config --global fqdnaus. - Nur HTTP 200 gilt als erfolgreiche Validierung. Erst danach übergibt der Proxy die validierte Identität an den Adapter. Dort liest der Go-Adapter
über
doguctl config -edas Ersatzpasswort unterpat/storedkey/<username>aus. Für den Schlüssel wird jedes Zeichen außerhalb vonA–Z,a–z,0–9und_durch_ersetzt, beispielsweisealice@example/teamdurchalice_example_team. Fehlt der Key, erzeugt und speichert der Adapter ihn über die Teamscale-API. Der Benutzername im Authorization-Header bleibt unverändert. Fehler beim erstmaligen Auslesen oder ein leeres Passwort führen zu HTTP 502 ohne Weiterleitung an Teamscale. - HTTP 400 oder 401 von CAS werden mit demselben Status an den Client beantwortet. Andere Statuscodes, Verbindungsfehler und ein Validierungs-Timeout nach fünf Sekunden führen zu HTTP 502. Diese Anfragen erreichen Teamscale nicht.
Andere Pfade sowie Anfragen ohne Basic Auth oder ohne pat_-Passwort werden ohne
CAS-Prüfung weitergeleitet. Pfad, Query, Methode und Body bleiben erhalten;
HTTP-Verbindungsheader werden für die jeweilige Verbindung neu verwaltet.
Der Proxy protokolliert keine Zugangsdaten und folgt keinen CAS-Redirects.
Validierungsergebnisse werden nicht gecacht.
Konfiguration
Das Startskript übergibt die Konfiguration als CLI-Parameter:
fqdn="$(doguctl config --global fqdn)"
/usr/local/bin/pat-proxy --listenAddress 0.0.0.0:8080 \
--upstreamSocket /tmp/teamscale-pat/adapter.sock --apiPath /teamscale/api \
--casUrl "https://${fqdn}/cas/api/pats/validate" --scope /teamscale \
--validationTimeout 5 --validationEnabled=true --casInsecure=true--casInsecure=true deaktiviert die TLS-Zertifikatsprüfung für die bisherige
Testinstallation. Mit passendem Zertifikat --casInsecure=false verwenden.
Der Scope wird vom Proxy an die CAS-URL angehängt.
Das gespeicherte Ersatzpasswort muss von Teamscale für den jeweiligen Benutzer
akzeptiert werden. Der Prozessbenutzer teamscale benötigt Zugriff auf die
entsprechenden doguctl-Konfigurationswerte. Die Passwortabfrage wird nicht gecacht.
Proxy, Adapter und Teamscale laufen als Benutzer teamscale. Beim Ende eines der drei
Prozesse werden auch die anderen beendet und der Container beendet sich mit Fehlerstatus.
SIGTERM/SIGINT werden an alle drei Prozesse weitergegeben.
Tests
Die Stage Setup im Jenkinsfile aktiviert pat/enabled in CAS
über ecoSystem.setup(registryConfig: ...). Sie erzeugt pro Build gemeinsame
technische API-Zugangsdaten für CAS und Usermgt und übergibt diese über
registryConfigEncrypted unter experimental/totp/api_user_name und
experimental/totp/api_user_password. Das Setup schreibt die Werte verschlüsselt,
bevor die Dogus starten. Eine TOTP-Aktivierung ist für diese PAT-Tests nicht nötig;
Usermgt benötigt für seinen PAT-Endpunkt keinen eigenen pat/enabled-Wert.
Die API-Zugangsdaten authentifizieren Usermgt gegenüber CAS; der PAT-Eigentümer
wird weiterhin aus der angemeldeten Testuser-Session bestimmt.
Die provisionierten CAS- und Usermgt-Versionen müssen PAT-Unterstützung enthalten.
Das Jenkinsfile installiert standardmäßig die veröffentlichten official-Abhängigkeiten;
die benachbarten lokalen Repositories werden dadurch nicht automatisch gebaut.
make -C pat-proxy testDie Adapter-Tests verwenden lokale Teamscale-Testserver und simulierte Konfigurationsablagen; echte PATs oder ein laufendes CAS sind nicht nötig. Sie prüfen unter anderem Erneuerung, einmaligen Retry, Requests mit Body, parallele Erneuerungen und das Logging.
Diagnose bei Bad Gateway
Der Proxy schreibt JSON-Logs nach stderr, sichtbar in den Container-Logs:
docker logs -f <containername>
# Bei Kubernetes:
kubectl logs -f <podname> -c <containername>Die Anfrageereignisse des Proxys enthalten component: "pat-proxy", requestId, event und
elapsedMs. Vom Proxy erzeugte Fehlerantworten enthalten dieselbe ID im Header
X-Pat-Proxy-Request-Id. Es werden keine Benutzernamen, Zugangsdaten,
Request-URLs, Bodies oder ungefilterten Fehlermeldungen ausgegeben.
| Ereignis / Code | Bedeutung |
|---|---|
cas_validation_ok |
CAS hat HTTP 200 geliefert; anschließend wird das Ersatzpasswort ausgelesen |
cas_validation_rejected |
CAS-Status steht in casStatus, der Client-Status in responseStatus |
cas_validation_error / CAS_TIMEOUT |
CAS hat innerhalb von fünf Sekunden keine Antwortheader geliefert |
cas_validation_error / CAS_CONNECTION_ERROR |
Verbindung zu CAS fehlgeschlagen, z. B. wegen DNS, Verbindungsablehnung oder TLS |
upstream_connection_error |
Verbindung zum Teamscale-Adapter über den Unix-Socket fehlgeschlagen; Antwort HTTP 502 |
upstream_response |
Der Adapter hat HTTP 4xx/5xx geliefert (upstreamStatus); die Antwort kann von Teamscale oder vom Adapter stammen |
Der Adapter schreibt ebenfalls JSON-Logs nach stderr, mit component: "teamscale-adapter".
Sein Mindestlevel folgt beim Containerstart der Dogu-Einstellung logging/root
(Standard WARN), über TEAMSCALE_LOGLEVEL und den expliziten Parameter --logLevel.
DEBUG, INFO, WARN und ERROR sind zulässig. Fehler beim Verbindungsaufbau, Key-Zugriff,
Erneuern oder Retry verwenden ERROR und bleiben auch bei WARN sichtbar. Erfolgreiche
Abläufe verwenden INFO. Der separate PAT-Proxy übernimmt diese Einstellung derzeit nicht.
Seine Anfrageereignisse verwenden dieselben Felder, aber eigene Request-IDs. Diese werden
nicht mit den Proxy-IDs abgeglichen. upstream_connection_error bezeichnet beim Adapter
die Verbindung zu Teamscale auf Port 8081; ein fester Fehlercode grenzt die Ursache ein.
Dieses Ereignis beendet den Adapter nicht und kann während des Teamscale-Starts auftreten.
upstream_response enthält den endgültigen Teamscale-Status ab HTTP 400.
Die Erneuerung wird durch stored_access_key_rejected, access_key_renewed,
access_key_renewal_failed, access_key_retry_failed und access_key_retry_skipped sichtbar.
Die vollständige Ereignistabelle steht in der
Adapter-Dokumentation.
Der Go-Proxy liegt im Image unter /usr/local/bin/pat-proxy. Der Docker-Build lädt
das durch PAT_PROXY_VERSION bestimmte Release-Archiv und prüft PAT_PROXY_SHA256SUM.
Der Teamscale-Adapter wird in einer eigenen Docker-Build-Stage aus diesem Repository
kompiliert. Nach Änderungen das Image neu bauen.
Code-Struktur
- Eigenständiges Repository
cloudogu/pat-proxy: CAS-PAT-Proxy. pat-proxy/: Go-Teamscale-Adapter, gebaut als/usr/local/bin/teamscale-adapter.pat-proxy/store.go: Konfigurationszugriff über externedoguctl config -e-Aufrufe.pat-proxy/accessor.go: Liest gespeicherte Keys oder erzeugt und speichert sie über die Teamscale-API.pat-proxy/renewal.go: Erneuert abgelehnte Keys und wiederholt wiederholbare Anfragen höchstens einmal.
Fehlt der gespeicherte Key (NO_STORED_KEY), liest der Adapter
config_admin_username und config_admin_access_key über doguctl config -e. Anschließend
erzeugt ein authentifizierter POST an
http://127.0.0.1:8081/teamscale/api/users/<username>/access-key einen Access-Key.
Die JSON-Antwort wird als Ersatzpasswort gespeichert. Vorhandene Keys werden
wiederverwendet; Fehler beim erstmaligen Key-Zugriff führen zu HTTP 502.
Lehnt Teamscale einen gespeicherten Key bei einer validierten PAT-Anfrage mit HTTP 401 ab, erneuert der Adapter den Key über die Admin-Zugangsdaten und überschreibt den gespeicherten Wert. Parallele Erstzugriffe und Erneuerungen sind pro Konfigurationsschlüssel innerhalb des Adapter-Prozesses synchronisiert. Ein inzwischen erneuerter Key wird wiederverwendet. HTTP 403 und Anfragen ohne validierte PAT-Identität lösen keine Erneuerung aus.
Anfragen ohne Body werden höchstens einmal mit dem neuen Key wiederholt. Request-Bodies
werden nicht gepuffert: Ohne vorhandene GetBody-Funktion bleibt die aktuelle Antwort HTTP 401,
und der neue Key steht beim nächsten Aufruf bereit. Scheitern Erneuerung oder Speicherung,
bleibt ebenfalls die ursprüngliche 401-Antwort erhalten. Ein Verbindungsfehler beim Retry liefert 502.
Der Adapter benötigt Go 1.26.8 und das ausführbare doguctl im PATH.
Classic- und Multinode-Konfiguration sowie Verschlüsselung übernimmt doguctl.
In Multinode muss /var/ces/config für lokal gespeicherte Keys persistent eingebunden sein.
Weitere CLI-Optionen stehen in pat-proxy/README.md.
Interne Übergabe und Wiederverwendung
Der Proxy entfernt eingehende Header mit dem Präfix X-Internal-Auth- bei jeder
Anfrage. Nach CAS-Erfolg entfernt er den ursprünglichen Authorization-Header und
setzt X-Internal-Auth-Method: cas-pat sowie X-Internal-Auth-User mit dem
Base64-kodierten ursprünglichen Benutzernamen. Base64 dient nur der sicheren
Header-Kodierung. Vertrauen entsteht durch den internen Transport, nicht durch
Base64. Der Adapter entfernt diese Metadaten vor der Weiterleitung an Teamscale.
Das Socket-Verzeichnis hat Modus 0700, der Socket 0600; Prozesse desselben
Systembenutzers gehören damit zur Vertrauensgrenze.
Der eigenständige Proxy enthält keine Teamscale-spezifischen Pfade oder CAS-URL.
--apiPath legt den zu prüfenden Pfad einschließlich Unterpfaden fest
(Standard /). Bei aktiver Validierung muss --casUrl gesetzt sein.
--validationEnabled=false deaktiviert die CAS-Prüfung und erzeugt keine
Validierungsmarkierung. --upstreamSocket legt einen internen Unix-Socket
fest; alternativ gelten --upstreamHost (Standard 127.0.0.1) und
--upstreamPort (Standard 8081). Ein Empfänger validierter Identitäten
muss über einen vertrauenswürdigen internen Transport erreichbar sein.
Im Teamscale-Dogu setzt das Startskript Pfad, CAS-URL und Socket-Verbindung.
TEAMSCALE_ADAPTER_SOCKET überschreibt den gemeinsamen Socket-Pfad. Der Go-Adapter
liest und erzeugt Keys direkt gegen Teamscale auf Port 8081. Der Konfigurationszugriff erfolgt über doguctl-Prozesse; Logs enthalten keine Zugangsdaten.