From 4f93a5c92a794dc0c9835655b72e1f11c14daf9b Mon Sep 17 00:00:00 2001 From: donghyeon-ka Date: Sat, 25 Jul 2026 16:50:52 +0900 Subject: [PATCH] feat: add validated Traefik ForwardAuth alternative --- deploy/traefik/dynamic.yml | 35 ++++++++++++++++++++ deploy/traefik/traefik.yml | 14 ++++++++ docs/traefik-forwardauth-alternative.md | 22 ++++++++++++ scripts/verify-traefik-forwardauth-config.sh | 28 ++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 deploy/traefik/dynamic.yml create mode 100644 deploy/traefik/traefik.yml create mode 100644 docs/traefik-forwardauth-alternative.md create mode 100755 scripts/verify-traefik-forwardauth-config.sh diff --git a/deploy/traefik/dynamic.yml b/deploy/traefik/dynamic.yml new file mode 100644 index 0000000..b8fa627 --- /dev/null +++ b/deploy/traefik/dynamic.yml @@ -0,0 +1,35 @@ +http: + routers: + oauth: + entryPoints: + - web + rule: PathPrefix(`/oauth2/`) + service: oauth2-proxy + priority: 100 + application: + entryPoints: + - web + rule: PathPrefix(`/`) + middlewares: + - keycloak-forward-auth + service: application + + middlewares: + keycloak-forward-auth: + forwardAuth: + address: http://oauth2-proxy:4180/oauth2/auth + trustForwardHeader: false + authResponseHeaders: + - X-Auth-Request-User + - X-Auth-Request-Email + - Set-Cookie + + services: + oauth2-proxy: + loadBalancer: + servers: + - url: http://oauth2-proxy:4180 + application: + loadBalancer: + servers: + - url: http://app:8081 diff --git a/deploy/traefik/traefik.yml b/deploy/traefik/traefik.yml new file mode 100644 index 0000000..538a423 --- /dev/null +++ b/deploy/traefik/traefik.yml @@ -0,0 +1,14 @@ +entryPoints: + web: + address: ":8080" + +providers: + file: + filename: /etc/traefik/dynamic.yml + watch: false + +api: + dashboard: false + +log: + level: INFO diff --git a/docs/traefik-forwardauth-alternative.md b/docs/traefik-forwardauth-alternative.md new file mode 100644 index 0000000..55d9003 --- /dev/null +++ b/docs/traefik-forwardauth-alternative.md @@ -0,0 +1,22 @@ +# Traefik ForwardAuth alternative + +Traefik의 `forwardAuth` middleware는 nginx `auth_request`와 같은 정책 지점을 +제공한다. 예제는 `/oauth2/auth`를 oauth2-proxy에 위임하고 성공 응답의 +허용된 identity headers만 application request로 복사한다. + +중요한 차이: + +- ForwardAuth 자체는 OIDC client나 session manager가 아니다. 이 예제에서도 + oauth2-proxy가 code 교환과 cookie를 담당한다. +- `trustForwardHeader=false`로 외부 forwarded header를 신뢰하지 않는다. +- `/oauth2/` router는 callback/start 경로를 oauth2-proxy에 연결해야 한다. +- nginx의 `error_page 401 -> /oauth2/start`와 같은 로그인 redirect UX는 + Traefik errors middleware 또는 oauth2-proxy의 forward-auth redirect + profile을 추가로 설계해야 한다. +- Docker socket label discovery 대신 file provider를 사용해 socket 노출을 + 피했다. Kubernetes에서는 Middleware/IngressRoute CRD라는 vendor-specific + 운영 객체가 추가된다. + +이 repository의 실제 AP4 baseline은 학습 가시성이 높은 nginx 조합을 +유지한다. `verify-traefik-forwardauth-config.sh`는 대안 파일을 Traefik +binary로 로드하고 즉시 발생하는 provider/config 오류가 없는지 확인한다. diff --git a/scripts/verify-traefik-forwardauth-config.sh b/scripts/verify-traefik-forwardauth-config.sh new file mode 100755 index 0000000..a3b931e --- /dev/null +++ b/scripts/verify-traefik-forwardauth-config.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env sh +set -eu + +config_dir="$PWD/deploy/traefik" +output_file="$(mktemp)" +cleanup() { + rm -f "$output_file" +} +trap cleanup EXIT + +status=0 +timeout 4 docker run --rm \ + -v "$config_dir:/etc/traefik:ro" \ + traefik:v3.5.3 \ + --configFile=/etc/traefik/traefik.yml >"$output_file" 2>&1 || status=$? + +if [ "$status" -ne 0 ] && [ "$status" -ne 124 ]; then + cat "$output_file" >&2 + exit "$status" +fi +if rg -qi 'error|failed' "$output_file"; then + cat "$output_file" >&2 + exit 1 +fi + +grep -q 'trustForwardHeader: false' deploy/traefik/dynamic.yml +grep -q 'X-Auth-Request-User' deploy/traefik/dynamic.yml +echo "Traefik file provider and ForwardAuth configuration verified"