- Update release.yaml to publish :latest and :prerelease-tag for stable and pre-release tags respectively. - Add README section for local testing of registry images with a new script. - Introduce scripts/test-registry-image.sh for end-to-end testing of published images.
7.5 KiB
gitea-mcp-forward-auth
Kleiner Go-basierter Traefik-ForwardAuth-Microservice, der Bearer-Tokens gegen eine konfigurierbare Menge gueltiger Tokens prueft.
Verhalten
- Prueft
Authorization: Bearer <token>. - Validiert Token gegen SHA-256-Hashes aus:
AUTH_PROXY_TOKEN_HASHES_DIR(jede Datei enthaelt genau einen Token-Hash), und/oderAUTH_PROXY_TOKEN_HASHES(kommagetrennte Hash-Liste).
- Antwortet mit:
200(leer) bei gueltigem Token,401bei fehlendem/ungueltigem Header oder ungueltigem Token.
GET /healthzist immer ohne Auth erreichbar.- Loggt jeden Auth-Versuch strukturiert, ohne Klartext-Token.
Sicherheitsaspekte
- Token-Matching erfolgt auf Basis von SHA-256-Digests mit
crypto/subtle.ConstantTimeCompare. - Der Service speichert nur Hashes der erlaubten Tokens, keine Klartext-Tokens in der Konfiguration.
- Token werden nie im Klartext geloggt; es wird nur ein kurzer Fingerprint (
sha256:...) geloggt. - Start bricht fail-fast ab, wenn keine gueltigen Tokens geladen werden konnten.
Konfiguration (ENV)
AUTH_PROXY_LISTEN_ADDR- Default:
:8080 - Beispiel:
:8080
- Default:
AUTH_PROXY_TOKEN_HASHES_DIR- Optional
- Pfad auf ein Verzeichnis, in dem jede Datei einen SHA-256-Token-Hash enthaelt (z. B. Kubernetes Secret Volume)
AUTH_PROXY_TOKEN_HASHES- Optional
- Kommagetrennte Liste von SHA-256-Hashes (64 Hex-Zeichen)
- Hash-Format
abcdef...(64 hex) odersha256:abcdef...(64 hex)
AUTH_PROXY_LOG_LEVEL- Default:
info - Werte wie
debug,info,warn,error
- Default:
Hinweis: Es muss mindestens eine Hash-Quelle (AUTH_PROXY_TOKEN_HASHES_DIR oder AUTH_PROXY_TOKEN_HASHES) konfiguriert sein.
Demo-Daten
Fuer schnelle lokale Tests sind Demo-Hashes im Repo enthalten:
- Verzeichnis:
demo/token-hashes/ - Datei
demo-token-1.sha256entspricht Klartext-Token:demo-token-1 - Datei
demo-token-2.sha256entspricht Klartext-Token:demo-token-2
Die Dateien enthalten nur SHA-256-Hashes und koennen gefahrlos eingecheckt werden.
VS Code Tasks (Run + Debug + Checks)
Im Projekt sind vier Tasks hinterlegt:
Run authproxy (demo hashes)- startet den Server mit
go run ./cmd/authproxy - nutzt automatisch
AUTH_PROXY_TOKEN_HASHES_DIR=${workspaceFolder}/demo/token-hashes
- startet den Server mit
Debug authproxy (delve, demo hashes)- startet den Server im Delve-Debugger (
dlv debug ./cmd/authproxy) - nutzt dieselben Demo-ENV-Werte
- startet den Server im Delve-Debugger (
Check authproxy 200 (demo-token-1)- prueft per
curl, dass ein gueltiger Demo-Token den Status200liefert
- prueft per
Check authproxy 401 (wrong token)- prueft per
curl, dass ein ungueltiger Token den Status401liefert
- prueft per
Starten in VS Code ueber: Terminal -> Run Task...
Zusaetzlich gibt es eine Launch-Konfiguration fuer Breakpoints:
.vscode/launch.json->F5: Debug authproxy (demo hashes)
F5-Flow:
- Fuer normalen Betrieb den Task
Run authproxy (demo hashes)starten. - Fuer Debugging direkt die Konfiguration
F5: Debug authproxy (demo hashes)mitF5starten (ohne vorherigen Run-Task). - Optional die Check-Tasks fuer
200und401ausfuehren.
Go Package Registry (Gitea)
Dieses Repo ist auf die Gitea Go Package Registry ausgerichtet.
- Registry-Muster:
https://<gitea-host>/api/packages/{owner}/go - In dieser Konfiguration:
https://gitea.nehmer.net/api/packages/torben/go
Beispiel lokal:
go env -w GOPROXY="https://gitea.nehmer.net/api/packages/torben/go,https://proxy.golang.org,direct"
Annahme: Deine Angabe https://gitea.example.com/api/packages/{owner}/go ist ein Muster/Template. Implementiert wurde konkret gitea.nehmer.net mit Owner torben.
Healthcheck Security
/healthz muss nicht world-readable sein. Fuer k3s Probes und Prometheus reicht interne Erreichbarkeit im Cluster.
Empfehlung:
- Service als
ClusterIPbelassen (bereits in Referenzmanifesten umgesetzt) - Keine externe Ingress-Route auf
/healthzpublizieren - Zugriff auf Pod/Service-Netzwerkebene einschränken (z. B. NetworkPolicy), falls eure CNI/Policies das bereits vorsehen
Annahme: In eurem Setup ist der ForwardAuth-Service nur intern erreichbar und wird nicht direkt aus dem Internet exponiert.
Lokal bauen und starten
go test ./... -v
go vet ./...
go build ./cmd/authproxy
AUTH_PROXY_TOKEN_HASHES_DIR="./demo/token-hashes" \
AUTH_PROXY_LISTEN_ADDR=":8080" \
go run ./cmd/authproxy
Token-Hashes erzeugen:
echo -n "my-token-1" | sha256sum | awk '{print $1}'
Startbeispiel mit Hashes:
AUTH_PROXY_TOKEN_HASHES_DIR="./demo/token-hashes" \
AUTH_PROXY_LISTEN_ADDR=":8080" \
go run ./cmd/authproxy
Beispielaufrufe
# healthcheck (ohne Auth)
curl -i http://localhost:8080/healthz
# fehlender Token -> 401
curl -i http://localhost:8080/
# ungueltiger Token -> 401
curl -i -H "Authorization: Bearer wrong" http://localhost:8080/
# gueltiger Token -> 200
curl -i -H "Authorization: Bearer demo-token-1" http://localhost:8080/
Docker
Das Projekt enthaelt ein Multi-Stage-Dockerfile mit statisch gelinktem Binary (CGO_ENABLED=0) und non-root Runtime auf Distroless.
docker build -t gitea-mcp-auth-proxy:dev .
docker run --rm -p 8080:8080 \
-e AUTH_PROXY_TOKEN_HASHES="<sha256-hash-1>,<sha256-hash-2>" \
gitea-mcp-auth-proxy:dev
Registry-Image lokal testen
Fuer einen End-to-End-Test gegen die veroeffentlichte Gitea-Container-Registry gibt es das Script scripts/test-registry-image.sh.
Es orientiert sich am Gitea-Flow aus der Container-Registry-Doku:
- Login gegen
gitea.nehmer.net - Pull von
gitea.nehmer.net/torben/gitea-mcp-auth-proxy:<tag> - lokaler Start des gezogenen Images mit den eingecheckten Demo-Hashes
- HTTP-Pruefungen fuer
200und401
Default-Verhalten:
- User:
torben - Tag:
latest - Runtime: automatisch
docker, sonstpodman
Der Registry-Login fragt das Passwort oder einen PAT interaktiv und unsichtbar ab.
Beispiel:
./scripts/test-registry-image.sh
Bestimmten Tag testen:
./scripts/test-registry-image.sh --tag v1.2.3
Optional auf vorhandene Image-Labels pruefen:
./scripts/test-registry-image.sh \
--require-label org.opencontainers.image.source \
--require-label org.opencontainers.image.title=gitea-mcp-auth-proxy
Hinweis: Das Script validiert optionale Labels erst nach dem Pull. Aktuell definiert dieses Repo selbst noch keine OCI-Image-Labels im Build.
CI/CD (Gitea Actions)
- Build-Workflow:
.gitea/workflows/build.yaml- Push auf beliebige Branches
go vet,go test,go build- Kein Registry-Push
- Release-Workflow:
.gitea/workflows/release.yaml- Trigger auf Tags
v*.*.* - Buildx-Remote-Builder und Push in Registry
latestnur fuer stabile TagsvX.Y.Z- Pre-Releases (z. B.
v1.2.3-rc1) werden nicht alslatestmarkiert
- Trigger auf Tags
Wichtig: Dieses Repository baut und pusht nur Images. Das eigentliche Kubernetes-Deployment erfolgt separat ueber FluxCD Image Automation in einem anderen Repository.
Kubernetes-Referenzmanifeste
Referenzbeispiele fuer lokale Verifikation liegen unter:
deploy/k3s/deployment.yamldeploy/k3s/service.yamldeploy/k3s/networkpolicy.yaml
Diese Manifeste sind bewusst minimal und nicht als produktive FluxCD-Quelle gedacht.
Annahmen
- Annahme: Go-Version ist
1.26. - Annahme: Release-Build pusht initial nur
linux/amd64. - Annahme: Remote BuildKit ist im Runner-Netz unter
tcp://<default-gateway>:1234erreichbar. - Annahme: Registry-Pfad ist
gitea.nehmer.net/torben/gitea-mcp-auth-proxy. - Annahme: Traefik laeuft in
kube-systemmit Labelapp.kubernetes.io/name=traefik. - Annahme: Prometheus laeuft in
monitoringmit Labelapp.kubernetes.io/name=prometheus.