Files
llm-wiki/raw/branch-notes/feature-keycloak-traefik-forwardauth-alternative.md

285 lines
27 KiB
Markdown

---
title: branch / feature-keycloak-traefik-forwardauth-alternative (AP4, legacy P1A — Traefik ForwardAuth 대안 비교)
source_type: branch-note
status: raw
id: BR-KEYCLOAK-CHILD-35B79487
kind: branch-child
project: keycloak-patterns-overview
work_item: WI-KEYCLOAK-PATTERNS-OVERVIEW-014
inherits: [DEC-KEYCLOAK-PATTERNS-OVERVIEW-EDGE-FORWARDAUTH-001@1, DEC-KEYCLOAK-PATTERNS-OVERVIEW-ACCEPTANCE-001@1]
refines: []
overrides: []
depends_on: [WI-KEYCLOAK-PATTERNS-OVERVIEW-012]
contract_packet: 1
branch: feature-keycloak-traefik-forwardauth-alternative
parent_branch: feature-keycloak-header-spoofing-defense
related_projects: [keycloak-patterns]
tags: [branch, keycloak-patterns, p1a, traefik, forwardauth, ingress-route, middleware]
created: 2026-05-25
target_merge:
status_label: in-progress
contract_packet_sha256: 3f03d8906adb2a9bc3ac464995fbf1c04de09ab5d7ca341ea578cd8ab7ece490
---
# branch: feature-keycloak-traefik-forwardauth-alternative (AP4, legacy P1A — Traefik ForwardAuth 대안 비교)
> Layer: `raw/branch-notes/` — [[raw/branch-notes/feature-keycloak-header-spoofing-defense]]의 WI014 child branch. single-EC2는 배포 축이며 인증 패턴 ID를 AP1/P3A로 바꾸지 않는다.
> 부모 sub-branch가 oauth2-proxy + nginx 조합을 중심으로 다뤘다면, 본 sub-sub는 **Traefik `forwardAuth` middleware** 단독 또는 oauth2-proxy 조합 시의 차이를 환경별(K8s mesh / Traefik IngressRoute / standalone Docker)로 비교.
> 본 sub-sub-branch는 **문서까지만** (`documented-only`).
> `status_label`: `in-progress`
<!-- section-id: branch-parent -->
## 부모 (필수)
[[raw/branch-notes/feature-keycloak-header-spoofing-defense]]
<!-- GENERATED: branch-contract:start -->
<!-- section-id: branch-contract-packet -->
## 브랜치 계약 패킷
- **생성 시 프로젝트 개정**: `1`
- **패킷 스키마**: `contract_packet: 1`
- **완료 조건**: forwarded-user spoofing 우회를 재현하고 network isolation 후 차단한다
<!-- section-id: inherited-project-decisions -->
### 상속한 프로젝트 결정
| Decision Ref | Project Summary | Branch Application | Source |
|---|---|---|---|
| `DEC-KEYCLOAK-PATTERNS-OVERVIEW-EDGE-FORWARDAUTH-001@1` | AP4는 oauth2-proxy ForwardAuth를 사용한다 | AP4 baseline과 Traefik ForwardAuth 대안의 경계를 비교한다 | [[raw/project-notes/keycloak-patterns-overview]] |
| `DEC-KEYCLOAK-PATTERNS-OVERVIEW-ACCEPTANCE-001@1` | done-bar는 E2E success와 signature security failure 재현·해결 evidence다 | parent의 spoofing defense verification contract를 승계한다 | [[raw/project-notes/keycloak-patterns-overview]] |
<!-- section-id: branch-local-decisions -->
### 브랜치 지역 결정
> 기존 branch-local 결정은 아래 `## Decision Evidence Map`의 D-row가 소유하며 이 packet에서 복제하지 않는다.
| Decision ID | Decision | Relation | Supporting Claims | Status |
|---|---|---|---|---|
<!-- section-id: declared-overrides -->
### 선언한 예외
| Override ID | Overrides | Reason | Approval | Status |
|---|---|---|---|---|
없음.
<!-- GENERATED: branch-contract:end -->
<!-- section-id: branch-goal -->
## 목표
P1A 패턴을 실 운영에 도입한다면 ingress 선택지는 크게 둘이다:
1. **Ingress-Nginx + oauth2-proxy**: nginx `auth_request` directive로 oauth2-proxy 호출.
2. **Traefik + ForwardAuth middleware**: Traefik의 `forwardAuth` middleware로 oauth2-proxy 또는 다른 auth server 호출 (또는 Traefik 자체 OIDC plugin).
본 sub-sub는 환경별(K8s with Traefik IngressRoute / standalone VM with docker-compose) 선택 기준을 정리하고, oauth2-proxy와의 결합 방식 차이(`authResponseHeaders` / `authRequestHeaders` / `tls.insecureSkipVerify`)를 분리해서 본다.
핵심 질문:
1. Traefik `forwardAuth` middleware의 **응답 contract**는 nginx `auth_request`와 어떻게 다른가? (둘 다 2xx=allow / 4xx=deny이지만 redirect 처리 위치가 다름)
2. K8s에서 Traefik IngressRoute CRD를 쓰면 어떤 trade-off가 발생하는가? (vendor-specific CRD vs 표준 Ingress 호환성)
3. standalone Docker (단일 VM) 환경에서는 어느 쪽이 단순한가? → docker-compose label-based Traefik 라우팅이 우위.
4. Traefik 자체에 OIDC plugin (community / enterprise)을 쓰면 oauth2-proxy 없이 1-hop으로 줄일 수 있는가? trade-off는?
- 이슈:
- PR:
<!-- section-id: branch-scope -->
## 범위
### 포함 범위
- Traefik `forwardAuth` middleware 의 응답 contract·헤더 forwarding·TLS 옵션을 nginx `auth_request` 대비로 정리 (D3~D8, vendor doc 근거)
- oauth2-proxy 결합 시 Traefik 측 헤더 주입/필터 방식 차이 (D4·D5·D6)
- Traefik 이 oauth2-proxy 없이 OIDC 를 자체 수행할 수 있는가 3-way 비교: oauth2-proxy(baseline) / community in-process plugin / Traefik Hub(유료) (D10)
- K8s 부착 방식 개념 비교: 표준 Ingress+annotation vs IngressRoute+Middleware CRD (D9, **문서 비교만**)
- 환경별 선택 기준 매트릭스 (K8s / 단일 VM docker-compose / 학습·PoC)
### 제외 범위
- 실 K8s / Traefik 클러스터 구성·배포 — 프로젝트 실 구현은 single-EC2 docker-compose + nginx 로 고정([[raw/project-notes/keycloak-patterns-overview]] F5). D9 는 개념 비교까지만.
- Traefik Hub 유료 구독 실사용 및 실 가격 확인 (GET PRICING gated)
- community plugin 의 production 채택 — PoC 수준 검토만 (single-maintainer·production 사례 0건)
- Kubernetes Gateway API (HTTPRoute) 경로 — Plan Gap, 별도 후속 sub-branch 후보
- 모든 hands-on 실측(discovery cache TTL / token refresh 타이밍 / ArgoCD health 오탐 / redirect 호환) → `## Claims To Verify` 로 이월
## 근거 (필수, 최소 1개+)
> 부모 sub-branch 인용 자료 재참조 + 2026-07-18 `/branch-spec` 자동조사(D9·D10)로 Traefik Hub·community plugin 공식 자료 신규 archive.
- [[raw/official-docs/traefik-forwardauth-middleware-official]] — Traefik ForwardAuth middleware 공식 (K8s 환경 대안)
- [[raw/official-docs/traefik-hub-oidc-middleware-official]] — Traefik OIDC 미들웨어 공식. **Traefik Hub(유료) 전용**임을 확정 — D10 근거 (community/OSS 에는 native OIDC 없음)
- [[raw/official-docs/traefik-oidc-community-plugin-lukaszraczylo-official]] — Traefik Hub(유료) 대신 검토할 수 있는 **community Yaegi plugin** (`lukaszraczylo/traefikoidc`, MIT, single-maintainer). oauth2-proxy 를 제거하고 Traefik in-process 로 OIDC 를 수행하는 대안 경로 존재를 근거화하되, Traefik Labs 무보증 + production 사례 0건의 유지보수 리스크를 named failure mode 로 문서화 — D10 근거
- (재참조) [[raw/official-docs/oauth2-proxy-overview-config-official]] — oauth2-proxy와의 비교 기준
- (재참조) [[raw/official-docs/oauth2-proxy-nginx-integration-official]] — nginx 조합 대비 비교 기준
## TODO
각 항목 옆에 증거 등급 표기.
- [ ] Traefik `forwardAuth` middleware 설정 정리 (`address`, `authResponseHeaders`, `authRequestHeaders`, `trustForwardHeader`, `tls.insecureSkipVerify`) — 등급: `planned`
- [ ] K8s 환경에서 Traefik IngressRoute CRD + Middleware CRD 예제 작성 — 등급: `planned`
- [ ] IngressRoute CRD의 vendor lock-in 정리 (표준 Ingress 리소스와의 호환성, ArgoCD 운영 차이) — 등급: `planned`
- [ ] standalone Docker compose 환경에서 Traefik label-based 라우팅 + ForwardAuth middleware 예제 — 등급: `planned`
- [ ] oauth2-proxy vs Traefik ForwardAuth + (Traefik OIDC plugin / oauth2-proxy 결합) 비교표 — 등급: `planned`
- [ ] 비교 항목: 응답 헤더 propagation 방식 / redirect 처리 위치 / cookie/세션 관리 주체 / K8s native 정도 / 운영 복잡도 / 커뮤니티 활성도 — 등급: `planned`
- [ ] Traefik의 `authResponseHeaders`가 동작하지 않는 함정 정리 (regex / 대소문자 / header 이름 정규화) — 등급: `planned`
- [ ] 환경별 권장 정리: K8s mesh 환경 / Traefik IngressRoute 운영 환경 / standalone VM docker-compose — 등급: `planned`
- [ ] Traefik standalone에서 단일 VM docker-compose로 묶을 때의 단순성 정리 (P3A와의 연결점) — 등급: `planned`
- [ ] Traefik 자체 OIDC plugin 옵션 검토 (community plugin / Traefik Hub 유료) — 등급: `planned`
## 진행 중 메모
> 작업하며 떠오른 메모.
- 부모 sub-branch §결정 사항에서 이미 oauth2-proxy(K8s+Ingress-Nginx 환경) vs Traefik ForwardAuth(이미 Traefik 사용 환경 또는 단일 VM compose) 선택 기준을 적어두었음. 본 sub-sub는 그 결정을 **환경별 4-셀 매트릭스**로 분해.
- Traefik ForwardAuth middleware는 `authResponseHeaders`에 명시한 헤더만 backend로 전달. nginx 측 `auth_request_set` + `proxy_set_header` 두 단계와 달리 middleware config 한 줄로 끝나는 단순함.
- 단, 외부 auth service(oauth2-proxy)가 302와 `Location`을 생성하고 Traefik ForwardAuth middleware는 그 non-2XX 응답을 browser에 전달한다. 생성 주체와 전달 주체를 나눠 디버깅한다.
## 결정 사항 (decisions)
- **2026-05-25 (정합 2026-07-18)**: 본 문서는 **AP4 Edge ForwardAuth**의 Traefik 대안 비교다. legacy P1A의 nginx+oauth2-proxy baseline도 AP4이며, P3A/AP1 SPA-direct와는 다른 인증 패턴이다. single-EC2는 어느 패턴에도 적용 가능한 배포 축일 뿐이다.
- **2026-05-25 (decision candidate)**: standalone Docker compose 환경에서 단일 VM에 모두 올릴 경우, Traefik label-based 라우팅이 nginx config 파일 관리보다 단순. 단, 본 학습 프로젝트는 P3A를 nginx로 결정했으므로 본 sub-sub는 학습/비교 목적.
## 결정-근거 매핑
> 각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시. Traefik forwardAuth 자체의 동작은 공식 vendor doc 으로 직접 뒷받침. nginx 대비 운영 단순도 / 환경별 추천은 vendor doc 인용 없는 비교 판단 → 그 부분만 UNSUPPORTED_DECISION.
| Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|---|
| D1 | 본 sub-sub는 AP4의 Traefik ForwardAuth 선택 기준을 정리하고 실 배포는 별도 구현 branch로 분리 | 문서 비교가 목적이면 여기서 종결 / hands-on이 필요하면 AP4 owner 아래 구현 branch로 분리 | [[raw/project-notes/keycloak-patterns-overview]] F1 + organizational decision | `delegated + organizational` | vendor별 hands-on 없이 실제 운영 함정 누락 가능 |
| D2 | AP4 baseline은 nginx+oauth2-proxy, Traefik은 이미 Traefik을 쓰는 환경의 대안 | 인증 패턴은 AP4로 고정하고 ingress 구현체만 선택한다. single-EC2 배포 여부는 별도 축 | [[raw/branch-notes/feature-keycloak-edge-forwardauth-no-google]] D1/D3 | `delegated` | nginx/Traefik 운영 단순도는 실측 없음 |
| D3 | Traefik forwardAuth 응답 contract: 2XX → allow + 원본 요청 진행, 비 2XX → 인증 서버 응답 그대로 client 에 반환 (nginx 의 401/403 specific deny 와 다름) | N/A (vendor spec 사실 — 분기 아님) | `raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C1`, `raw/official-docs/nginx-auth-request-module-official.md#NGAR-C2` (비교 baseline) | `official-vendor-doc` (Traefik 공식 + nginx 공식 양측 verbatim) | 비 2XX 응답이 그대로 client 에 전달되는 동작이 oauth2-proxy 의 302 sign_in redirect 와 완벽 호환된다는 보장 없음 (`TFA-C1` does-not-prove) — 실 시연 검증 필요 |
| D4 | Traefik 은 인증 서버로 5개 헤더 자동 forward: `X-Forwarded-Method`, `X-Forwarded-Proto`, `X-Forwarded-Host`, `X-Forwarded-Uri`, `X-Forwarded-For` | N/A (vendor spec 사실) | `raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C2` | `official-vendor-doc` | oauth2-proxy 가 이 5종 헤더를 모두 인식한다는 보장 없음 — oauth2-proxy 측 `--reverse-proxy=true` 옵션 필요 (별도 검증) |
| D5 | `authResponseHeaders` 한 줄로 user 헤더 주입 가능 (nginx 의 `auth_request_set` + `proxy_set_header` 2-step 대비 단순) | ingress 가 Traefik → `authResponseHeaders` 한 줄 / ingress 가 nginx → `auth_request_set`+`proxy_set_header` 2-step | `raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C3`, `raw/official-docs/nginx-auth-request-module-official.md#NGAR-C5` (비교 baseline) | `official-vendor-doc` (Traefik 공식 + nginx 공식 양측 verbatim) | `authResponseHeaders` 의 replace 동작이 case-insensitive 인지 verbatim 미확정 (`TFA-C3` does-not-prove) — 헤더 이름 정규화 함정 가능 |
| D6 | `authRequestHeaders` 로 인증 서버로 전달할 헤더 필터링 (default empty = 모든 헤더 전달 — production 위험) | production → 명시 화이트리스트 필수 / dev·PoC → default(empty) 허용 가능하나 sensitive header 노출 인지 | `raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C4` | `official-vendor-doc` | default (empty) 가 Authorization 등 sensitive header 까지 인증 서버로 보내 production 위험 — 명시 화이트리스트 필요 |
| D7 | `tls.insecureSkipVerify` 는 dev only — production 금지 (vendor 가 명시적으로 risk 경고) | dev·self-signed cert → true 허용 / production → false + `tls.ca`/`tls.cert` 발급·회전 | `raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C5` | `official-vendor-doc` | self-signed cert 운영 시 `tls.ca` / `tls.cert` 발급 / 회전 운영 비용 발생 |
| D8 | `trustForwardHeader=true` 회피 (deprecated marker) | 신규 구성 → 사용 회피(deprecated) / 기존 구성 마이그레이션 → 대체 옵션 확인 후 전환 | `raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C6` | `official-vendor-doc` | 대체 옵션의 정확한 신규 이름은 본 인용에 없음 — 별도 deprecated 경고 페이지 추가 raw 보존 필요 |
| D9 | K8s ForwardAuth 부착: 표준 Ingress+`router.middlewares` annotation vs IngressRoute+Middleware CRD. **핵심 정정** — 표준 Ingress 도 `@kubernetescrd` 로 Middleware CRD 에 의존 → "완전 vendor-neutral" 아님; 실 차이는 route 객체 이식성 + ArgoCD health 평가 여부 | ArgoCD 운영 가시성·ingress 교체 가능성 우선 → 표준 Ingress+annotation (route skeleton 이 built-in health 대상, 부분 이식) / Traefik 단독 확정 + 구조화 spec·고급 라우팅 우선 → IngressRoute+Middleware CRD (단 ArgoCD custom Lua health check 비용) | researched 2026-07-18 (wiki-decision-researcher) — 근거 URL 확보(archival 후보): Traefik K8s Ingress/CRD 공식 doc, ArgoCD resource-health doc, K8s ingress-controllers doc. **K8s 는 실 구현 범위 밖(F5)이라 raw archival deferred** | UNSUPPORTED_DECISION (research-informed; archival deferred — K8s out of impl scope) | ArgoCD 가 IngressRoute/Middleware CRD 를 health 미평가 → 깨진 route 도 'Healthy' 오탐(silent-failure) 가능. Gateway API(HTTPRoute) 3번째 경로 미검토(Plan Gap). production 채택 빈도 근거 0 |
| D10 | Traefik 자체 OIDC 3-way: oauth2-proxy(외부 서버, 채택 유지) vs community in-process plugin(예 `lukaszraczylo/traefikoidc`, PoC 한정) vs Traefik Hub(1st-party, 유료, 예산 없어 보류). OSS Traefik 에는 native OIDC 없음이 확정됨 | 이식성·성숙도 우선 또는 K8s+nginx → oauth2-proxy 유지 / Traefik 전용 확정 + 학습·PoC → community plugin 스파이크(production 미채택) / 1st-party 지원·SLA + 예산 확보 → Traefik Hub | `raw/official-docs/traefik-hub-oidc-middleware-official.md#THUB-C1` (OSS 에 native OIDC 없음 → Hub 유료 전용 확정), `raw/official-docs/traefik-oidc-community-plugin-lukaszraczylo-official.md#TOIDC-C1~C6` (community in-process 대안 존재·설정·리스크) + UNSUPPORTED (Hub 실 가격 GET PRICING gated) | `official-vendor-doc` (THUB-C1 Hub-exclusive) + `official-vendor-doc (self-published, community, Traefik Labs 무보증)` (community plugin) + UNSUPPORTED (Hub pricing) | community plugin OIDC discovery TTL / token refresh 실측 없음 (자기서술만, `TOIDC-C2`/`TOIDC-C3` does-not-prove) + production 사례 0건 + Traefik 업그레이드 시 plugin 로드 실패 coupling(`TOIDC-C5`) + Hub 실 가격 미확보 |
## 구현 가이드
> 본 sub-sub 는 `documented-only` — "구현"의 산출물은 **비교 문서(매트릭스)** 이다. 아래는 그 deliverable 의 구조 명세이며, 각 표는 위 Decision + Supporting Claim 에서 도출된다(CLAUDE.md §15.5 R1). 실 코드/manifest 예제는 프로젝트 실 구현 범위(single-EC2 docker-compose) 밖이므로 작성하지 않고 개념 비교표로 종결한다(R3 OUT_OF_BRANCH_SCOPE).
### 1. Traefik vs nginx ForwardAuth 대비표 (핵심 deliverable)
> **Trace**: D3(`TFA-C1`)·D4(`TFA-C2`)·D5(`TFA-C3`)·D6(`TFA-C4`)·D7(`TFA-C5`)·D8(`TFA-C6`) — 각 행이 Traefik 공식 claim 으로 종결(nginx 측은 `NGAR-*` baseline).
| 비교 항목 | Traefik forwardAuth | nginx auth_request | 근거 |
|---|---|---|---|
| 응답 contract | 2XX allow / non-2XX 응답 그대로 client 전달 | 401·403 만 deny, 그 외 error | D3 |
| 자동 forward 헤더 | `X-Forwarded-{Method,Proto,Host,Uri,For}` 5종 | 수동 `proxy_set_header` | D4 |
| user 헤더 주입 | `authResponseHeaders` 한 줄 | `auth_request_set`+`proxy_set_header` 2-step | D5 |
| 요청 헤더 필터 | `authRequestHeaders` (empty=전체 전달) | 명시 pass 필요 | D6 |
| 인증서버 TLS | `tls.insecureSkipVerify`(dev only) | `proxy_ssl_verify` | D7 |
| deprecated marker | `trustForwardHeader=true`(deprecated) | — | D8 |
### 2. Traefik 자체 OIDC 3-way 결정표 (D10 deliverable)
> **Trace**: D10 — `THUB-C1`(OSS 에 native OIDC 없음→Hub 유료 전용) + `TOIDC-C1~C6`(community in-process plugin 존재·설정·리스크).
| 옵션 | 아키텍처 | 비용/지원 | 선택 조건 |
|---|---|---|---|
| oauth2-proxy | 외부 서버(extra hop) | 무료·대규모 커뮤니티 | 이식성·성숙도 우선, K8s+nginx (baseline 유지) |
| community plugin | Traefik in-process | 무료·Traefik Labs 무보증·single-maintainer | Traefik 전용 확정 + 학습·PoC (production 미채택) |
| Traefik Hub | Traefik in-process | 유료(GET PRICING)·1st-party SLA | 지원·SLA 필수 + 예산 확보 |
### 3. K8s 부착 방식 비교 (D9) — 개념만
> **Trace**: D9 — research-informed(2026-07-18), UNSUPPORTED(archival deferred).
>
> - **UNSUPPORTED_IMPL_DECISION**: 실 IngressRoute/Ingress manifest 예제는 작성하지 않는다. trade-off — K8s 배포는 cross-cutting 이라 auth 아키텍처를 바꾸지 않고([[raw/project-notes/keycloak-patterns-overview]] F5) 프로젝트 실 구현은 single-EC2 docker-compose 라, 코드 예제 없이 개념 비교표로 충분. 실 시연이 필요해지면 별도 K8s branch 로 분리.
| 부착 방식 | route 객체 이식성 | ArgoCD health | Middleware CRD 의존 |
|---|---|---|---|
| 표준 Ingress+annotation | 부분(route skeleton 표준) | built-in health check 대상 | 남음(`@kubernetescrd`) |
| IngressRoute+Middleware CRD | 없음(전량 Traefik) | 미평가→오탐 위험, custom Lua 필요 | 남음 |
### 4. 환경별 권장 매트릭스 (D1·D2·D9·D10 선택조건 종합)
> **Trace**: D1·D2·D9·D10 의 `선택 조건` cell 종합.
>
> - **UNSUPPORTED_IMPL_DECISION**: "단일 VM docker-compose 에서 Traefik label 라우팅이 nginx config 보다 단순"(D2) 은 정량 baseline 없는 자체 판단 → `## Claims To Verify` 로 실측 이월. 라벨 근거: 사용자 trade-off(학습 프로젝트는 nginx 로 P3A 확정, Traefik 우위는 미검증).
| 환경 | 권장 |
|---|---|
| 이미 Traefik 사용 K8s | Traefik forwardAuth + (oauth2-proxy 또는 Hub OIDC) |
| K8s + 기존 nginx | nginx auth_request + oauth2-proxy (P1A baseline) |
| 단일 VM docker-compose에서 AP4 실행 | nginx+oauth2-proxy baseline. Traefik label 라우팅 우위는 미검증(D2) |
| single-EC2에서 AP1/P3A 실행 | SPA-direct + backend JWT validation이며 oauth2-proxy/ForwardAuth를 추가하지 않음 |
| 학습·PoC + Traefik 전용 | community plugin 스파이크 검토 |
## 엣지·실패·의존
> R4 캡처용. 문서 단계이나, 실 구성 시 부딪힐 실패/엣지와 다른 계약 의존을 미리 열거.
- **실패·엣지 경로**:
- Traefik 이 non-2XX 를 그대로 client 에 전달(D3) → oauth2-proxy 302 sign_in redirect 가 브라우저에 온전히 전달되는지 미검증. 실패 시 로그인 redirect 끊김(백지/CORS).
- `authResponseHeaders` 헤더 이름 정규화(case-insensitive?) 미확정(D5) → user 헤더가 backend 에 안 닿으면 인증 우회가 아니라 인증 실패(403 루프).
- `authRequestHeaders` default empty(D6) → `Authorization`·`Cookie` 등 sensitive 헤더가 인증 서버로 새어나감. production 위험.
- `tls.insecureSkipVerify=true`(D7) 를 production 에 방치 → 인증 서버 구간 MITM.
- community plugin 이 Traefik helm chart release 에 coupling(`TOIDC-C5`) → Traefik 업그레이드 시 plugin 로드 실패 → 인증 전면 중단.
- (K8s, D9) IngressRoute 가 깨져도 ArgoCD 가 'Healthy' 오탐 → 인증 장애가 조용히 방치.
- **다른 계약 의존**:
- [[raw/branch-notes/feature-keycloak-edge-forwardauth-no-google]] **D1**(oauth2-proxy vs Traefik ForwardAuth 선택 기준)·**D3**(Edge ForwardAuth 패턴 채택)에 의존 — 본 branch 의 Traefik 경로는 그 oauth2-proxy contract(`/oauth2/auth` endpoint, `--reverse-proxy=true`)를 consume. 그 결정이 바뀌면 본 노트 D3·D4 영향.
- [[raw/branch-notes/feature-keycloak-header-spoofing-defense]] **D1**(네트워크 경계가 1차 방어, 헤더 검증은 trust-on-message)에 의존 — Traefik 도 헤더 신뢰 모델이라 동일한 network 격리 필요. `X-Forwarded-*` 위조 방어(NetworkPolicy/SG)는 그 branch 가 owner.
- [[raw/project-notes/keycloak-patterns-overview]] F5(실 구현 = single-EC2 docker-compose)에 의존 — D9(K8s 경로)를 실 구현하지 않는 근거.
## 검증해야 할 주장
> 공식 vendor docs 가 옵션의 존재와 contract 를 증명해도 내 학습 / 실 운영 환경에서의 동작은 별개. 다음은 실 K8s 또는 docker-compose 시연 시 실측 필요.
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
| Traefik 의 non-2XX response 그대로 전달 동작이 oauth2-proxy 의 302 sign_in redirect 와 완벽 호환되는지 | `TFA-C1` does-not-prove "302 redirect 가 그대로 브라우저에 전달되어 자연스럽게 Keycloak 로그인으로 이동" | Traefik + oauth2-proxy 결합 후 미인증 브라우저 요청 → Location 헤더 추적 | `needs-confirmation` |
| `authResponseHeaders` 의 헤더 이름 매칭이 case-insensitive 인지 (HTTP spec 은 그렇지만 vendor 별 상이 가능) | `TFA-C3` does-not-prove "case-insensitive 매칭" | `X-Auth-Request-User``x-auth-request-user` 양쪽 시도로 backend 도달 여부 확인 | `planned` |
| Traefik IngressRoute CRD 사용 시 ArgoCD GitOps 운영에서 발생하는 sync drift / plural resource 인식 문제 | `D9` UNSUPPORTED — Traefik 공식의 K8s integration 페이지 verbatim 미확보 | ArgoCD 에 IngressRoute manifest 배포 후 sync status / health 확인 | `planned` |
| standalone docker-compose 환경에서 Traefik label-based 라우팅이 실제로 nginx config 파일 관리보다 단순한가 | `D2` UNSUPPORTED — 비교의 정량적 baseline 없음 | 동일 SPA + API + Keycloak 구성을 nginx config 와 Traefik labels 두 방식으로 작성 후 line count / 변경 빈도 비교 | `planned` |
| Traefik community OIDC plugin 의 discovery cache TTL / token refresh 부하 하 동작 | `TOIDC-C2`("bounded caches")·`TOIDC-C3`(`refreshGracePeriodSeconds`) 는 config knob·자기서술일 뿐 TTL 초 단위·부하 하 동작 미증명 | community plugin 활성화 후 `/.well-known/openid-configuration` 재요청 주기 + near-expiry 토큰 refresh 타이밍 관측 | `planned` |
| `trustForwardHeader=true` deprecated 대체 옵션의 정확한 이름과 동작 | `TFA-C6` does-not-prove "대체 옵션 명" | Traefik 공식 deprecated 경고 페이지 추가 raw 보존 후 신규 옵션명 정확 인용 | `needs-confirmation` |
| Traefik 의 5종 자동 forward 헤더 (`TFA-C2`) 를 oauth2-proxy 가 모두 인식하는지 (특히 `X-Forwarded-Method`) | `D4` 의 Open Risk — oauth2-proxy 가 method 헤더를 routing 결정에 사용하는지 vendor 인용 없음 | oauth2-proxy 로그 + Keycloak 측 access log 에서 method 추출 동작 확인 | `planned` |
| 표준 Ingress+annotation 이 IngressRoute inline middleware 와 기능 100% 동등한지 (옵션 누락 여부) | research residual(`D9`) — annotation 문법만 확인, 기능 동등성 표 미확보 | 동일 ForwardAuth 를 두 방식으로 배포 후 응답 헤더 diff | `planned` |
| IngressRoute/Middleware CRD 가 ArgoCD 에서 깨져도 'Healthy' 오탐(false-positive) 을 실제로 내는지 | `D9` — ArgoCD 공식은 "미평가 CRD=기본 Healthy" 일반 규칙만, Traefik CRD 이름 미언급(적용 추론) | IngressRoute 를 의도적으로 깨뜨린 뒤 `argocd app get` health 상태 확인 | `planned` |
| Traefik Hub OIDC 미들웨어의 본 프로젝트 규모 실 가격 | `THUB`/`D10` — 가격은 GET PRICING gated, JS 렌더로 미확보 | Traefik Labs sales 문의로 견적 | `planned` |
| Kubernetes Gateway API(HTTPRoute)+Traefik provider 가 D9 vendor-lock-in 을 실제로 해소하는지 | Plan Gap — 본 조사 범위 밖(`D9` 2-way 프레이밍) | 별도 sub-branch 로 HTTPRoute+Traefik provider 시연, route 객체 이식성 실측 | `planned` |
## 마주친 문제
- 아직 없음(문서 단계).
## 묶음
<!-- GENERATED: sources:start -->
- [[raw/official-docs/traefik-forwardauth-middleware-official]]
- [[raw/official-docs/traefik-hub-oidc-middleware-official]]
- [[raw/official-docs/traefik-oidc-community-plugin-lukaszraczylo-official]]
<!-- GENERATED: sources:end -->
> 본 sub-sub-branch 는 leaf — 자식 자료 없음. Phase 3 P3A 실 구현 또는 외부 산출물 단계에서 errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.
### 오류 기록 (이 sub-sub-branch 작업 중 발생)
- (없음 — 현재 documented-only 단계)
### 면접 준비 (이 작업에서 나올 수 있는 면접 질문)
- (없음 — Phase 3 실 구현 단계에 누적)
## 관련 일일 노트
## 완료 후 정리
> 본 sub-sub-branch는 **문서까지만**. wiki 추출은 root branch의 비교 매트릭스 시점에 일괄 처리.
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경: 해당 없음 (문서 단계)
- **wiki 추출 대상** (verified만, `wiki/projects/`로만 추출):
- `actually-implemented` 항목: 없음
- `locally-verified` 항목: 없음
- `prod-verified` 항목: 없음
- **추출하지 않을 항목** (planned / documented-only / abandoned):
- 본 sub-sub-branch 전체가 `documented-only` 등급. P1A 부모 sub-branch와 함께 추후 비교 매트릭스 / `wiki/concepts/keycloak-deployment-patterns.md`에 인용되는 형태로만 활용. `wiki/projects/` 직접 승급 없음.