Files
llm-wiki/raw/branch-notes/feature-keycloak-edge-forwardauth-no-google.md
T

30 KiB

title, source_type, status, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, branch, parent_branch, related_projects, tags, created, target_merge, status_label, contract_packet_sha256
title source_type status id kind project work_item inherits refines overrides depends_on contract_packet branch parent_branch related_projects tags created target_merge status_label contract_packet_sha256
branch / feature-keycloak-edge-forwardauth-no-google (P1A Edge Forward Auth, no Google) branch-note raw BR-KEYCLOAK-CHILD-12F5B5DA branch-child keycloak-patterns-overview WI-KEYCLOAK-PATTERNS-OVERVIEW-020
DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1
1 feature-keycloak-edge-forwardauth-no-google feature-keycloak-patterns
keycloak-patterns
branch
keycloak-patterns
auth
oauth2
oidc
2026-05-25 in-progress e8d7d4e1b0766c23adb5879a98225689106a683f5882dd49a3b4b24b5fc18f08

branch: feature-keycloak-edge-forwardauth-no-google (P1A Edge Forward Auth, no Google)

Layer: raw/branch-notes/ — Keycloak 패턴 P1A 한정 sub-branch. Ingress(nginx auth_request 또는 Traefik forwardAuth)가 외부 auth service(oauth2-proxy baseline)에 인증을 위임하고 백엔드는 인증 코드를 갖지 않는 패턴. Google federation 없음(=P1B는 별도 sub-branch). 본 sub-branch는 문서까지만(=documented-only). 실제 ingress/Traefik 환경 구축은 root branch의 P3A 한정. status_label: in-progress

부모 (필수)

브랜치 계약 패킷

  • 생성 시 프로젝트 개정: 1
  • 패킷 스키마: contract_packet: 1
  • 완료 조건: project governance hub가 AP1~AP4 taxonomy와 child progress index를 유지한다

상속한 프로젝트 결정

Decision Ref Project Summary Branch Application Source
DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1 canonical 분류축은 AP1~AP4 인증 통합 아키텍처와 cross-cutting 변형이다 no-Google Edge ForwardAuth를 AP4 비교 자료로 분류한다 raw/project-notes/keycloak-patterns-overview

브랜치 지역 결정

Decision ID Decision Relation Supporting Claims Status
D1 ingress 축과 auth-service 축을 분리한다 local raw/project-notes/keycloak-patterns-overview proposed
D2 upstream identity header naming을 고정한다 local raw/project-notes/keycloak-patterns-overview proposed
D3 backend authentication을 edge ForwardAuth에 위임한다 local raw/project-notes/keycloak-patterns-overview proposed
D4 ingress-only traffic으로 header spoofing을 방어한다 local raw/project-notes/keycloak-patterns-overview proposed

선언한 예외

Override ID Overrides Reason Approval Status

없음.

목표

Edge forward-auth 패턴이 무엇이고, 왜 이 배치를 택하는지를 컴포넌트 다이어그램 + 토큰 교환 sequence + 신뢰 경계 수준으로 정리. 백엔드 코드에서 인증 로직을 제거하고 edge proxy 단일 지점에서 zero-trust ingress 를 강제하는 흐름을 면접에서 설명할 수 있어야 함.

핵심 질문 두 개에 답할 수 있어야 한다:

  1. 왜 백엔드에 JWT validator를 두지 않고 edge proxy에 인증을 위임하는가? → 다중 서비스에 일관 인증 + 인증 코드 0줄.
  2. edge proxy를 신뢰하는 대신 잃는 것은? → 백엔드는 헤더만 보고 사용자를 식별하므로, ingress 우회 경로가 있으면 헤더 spoofing 위험.
  • 이슈:
  • PR:

범위

포함 범위

  • P1A 컴포넌트 다이어그램 (텍스트 + Mermaid)
  • 토큰 교환 sequence 7단계
  • Ingress 선택(nginx vs Traefik)과 auth service 선택(oauth2-proxy vs 호환 OIDC agent)의 2축 비교
  • nginx auth_request 방식과 Traefik forwardAuth 방식의 차이
  • 신뢰 경계 정의 (ingress → proxy까지)
  • 장단점 / 운영 비용 / 보안 surface
  • 외부 공식 문서 raw 보존 (oauth2-proxy, Traefik, nginx)

제외 범위

  • Google IdP brokering (=P1B sub-branch에서 다룸)
  • 실제 K8s / docker-compose 환경 구축 (root branch P3A 한정)
  • BFF 패턴 (별도 결합 패턴, sub-branch에서 언급만)
  • mTLS / FAPI / DPoP 등 고급 보안 옵션
  • oauth2-proxy 비-Keycloak provider (GitHub, Google direct 등)

근거 (필수, 최소 1개+)

본 sub-branch의 P1A Edge ForwardAuth 패턴 채택 근거. 상세 대안 비교는 §외부 근거 / 대안 조사 참조.

Source 정당화하는 결정
raw/official-docs/oauth2-proxy-overview-config-official oauth2-proxy 공식 — 채택 컴포넌트 근거 (load-bearing: OAUTH2PROXY-C2/C3; C1needs-confirmation, 결정 미인용)
raw/official-docs/oauth2-proxy-keycloak-oidc-provider-official oauth2-proxy ↔ Keycloak OIDC 연동 — provider=keycloak-oidc 채택 근거
raw/official-docs/oauth2-proxy-nginx-integration-official nginx auth_request 통합 — Ingress-Nginx 결합 근거
raw/official-docs/nginx-auth-request-module-official nginx ngx_http_auth_request_module — subrequest 동작 근거
raw/official-docs/traefik-forwardauth-middleware-official Traefik ForwardAuth middleware — K8s 환경 대안 비교 근거

컴포넌트 다이어그램

텍스트

Browser → Ingress (Nginx / Traefik)
            │
            ├── (1) ForwardAuth subrequest → oauth2-proxy / compatible auth service
            │                                       │
            │                                       └── (2) OIDC handshake → Keycloak
            │                                                                  │
            │                                       ← (3) 세션 쿠키 + X-Auth-Request-* 헤더 ←┘
            │
            ↓ (4) 인증 통과 시 backend로 forward (헤더만 신뢰)
        Backend (인증 코드 0줄, 헤더 trust만)

Mermaid

flowchart LR
    B[Browser] -->|HTTPS| I[Ingress: Nginx or Traefik]
    I -. auth_request or forwardAuth .-> P[oauth2-proxy / auth service]
    P -. OIDC .-> K[Keycloak]
    P -- 202 + X-Auth-Request-* --> I
    I -->|trusted headers| BE[Backend API]

토큰 교환 sequence

"Browser, Ingress, oauth2-proxy, Keycloak, Backend" 5개 액터 기준.

  1. Browser → Ingress: unauthenticated request GET /api/orders (쿠키 없음).
  2. Ingress → oauth2-proxy /oauth2/auth: nginx의 auth_request 디렉티브 또는 Traefik의 forwardAuth 미들웨어가 subrequest 전송. 이 endpoint는 요청을 프록시하지 않고 202(Accepted) 또는 401(Unauthorized)만 반환.
  3. oauth2-proxy → Keycloak /protocol/openid-connect/auth: 쿠키 없으므로 401 → Ingress가 error_page로 받아 named location @oauth2_signin으로 302 redirect 발급. 사용자 브라우저가 Keycloak 로그인 페이지로 이동.
  4. Browser → Keycloak 로그인 UI → 사용자 인증 → callback: Authorization Code Flow + PKCE. Keycloak이 oauth2-proxy의 callback URL (/oauth2/callback)로 code 파라미터와 함께 redirect.
  5. oauth2-proxy → Keycloak /protocol/openid-connect/token: code + client_secretaccess_token + id_token + (옵션) refresh_token 교환. oauth2-proxy는 confidential client.
  6. oauth2-proxy → 세션 쿠키 발급: JavaScript가 raw token을 읽지 못하는 HttpOnly 세션 쿠키(_oauth2_proxy)를 발급한다. cookie-backed store면 encrypted cookie가 token material을 보유할 수 있고, Redis/server-side store면 cookie는 opaque session identifier만 보유한다. 이후 auth_request subrequest 통과 시 X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Groups 헤더를 Ingress에 응답한다(P1A baseline은 access-token upstream 전달 미사용).
  7. Ingress → Backend: Ingress가 응답 헤더에서 auth_request_set 으로 변수 추출 → proxy_set_header X-User $user; X-Email $email; 형식으로 backend에 헤더 주입. 백엔드는 JWT 검증을 하지 않고 헤더만 신뢰.

장점 / 단점

장점

  • 백엔드 인증 코드 0줄: Resource Server 보일러플레이트(spring-security-oauth2-resource-server, JWT decoder, JWKS cache 등) 불필요.
  • 다중 서비스 일관 인증: 같은 ingress 뒤의 모든 backend에 동일한 인증 정책 적용. 마이크로서비스 환경에서 인증 코드 분산을 방지.
  • raw token의 JavaScript 노출 없음: HttpOnly cookie라 SPA script가 access/refresh token bytes를 직접 읽지 못한다. 다만 cookie-backed session이면 브라우저가 encrypted token-bearing cookie를 보유하므로 server-side custody와 동일하다고 표현하지 않는다.
  • 운영 일원화: 인증 정책 변경(allowed-role, allowed-group 등) 시 oauth2-proxy config만 수정.

단점

  • 헤더 spoofing risk: 백엔드가 ingress-only traffic을 강제하지 못하면(예: backend가 직접 NodePort 노출), 공격자가 X-Auth-Request-User: admin 헤더를 위조해 우회 가능.
  • proxy SPOF: oauth2-proxy 다운 시 모든 backend 접근 불가. HA 구성 필수.
  • 세션 저장 방식별 위험: cookie-backed store가 access token까지 encrypted cookie에 담으면 nginx의 기본 4kb 헤더 한도를 넘어 split-cookie 처리가 필요하다. Redis/server-side store면 cookie는 opaque ID지만 외부 state store 운영 책임이 생긴다.
  • 백엔드가 토큰 claim 직접 접근 불가: scope / custom claim 기반 fine-grained 권한 체크가 필요하면 추가로 X-Auth-Request-Access-Token 헤더로 토큰 자체를 전달하거나, 결국 backend에서도 JWT 파싱해야 함.

신뢰 경계

[ Public Internet ]  ←→  [ Ingress + Forward-Auth Proxy ]  ←→  [ Backend ]
       untrusted              ← 인증 경계 (boundary)             trusted-by-header
  • 인증 boundary: ingress → proxy 까지. 이 구간에서 사용자 식별 확정.
  • 백엔드 전제: ingress 외 경로로는 도달 불가. 구체적 강제 수단:
    • K8s: NetworkPolicy 로 ingress namespace에서만 backend pod 접근 허용.
    • VM: backend listen address를 loopback / private subnet으로 한정. Security Group으로 ingress IP만 허용.
  • 이 전제가 깨지면 패턴 전체가 깨짐 → 외부 공격자가 backend에 직접 X-Auth-Request-User: anyuser 헤더로 요청 가능.

제외 범위 (재확인)

TODO

각 항목 옆에 증거 등급 표기: actually-implemented | locally-verified | prod-verified | documented-only | planned | needs-confirmation

  • P1A 컴포넌트 다이어그램 (텍스트 + Mermaid) — 등급: documented-only
  • 토큰 교환 sequence 7단계 — 등급: documented-only
  • Ingress(nginx/Traefik)와 auth service(oauth2-proxy/호환 agent) 선택축 분리 (D1) — 등급: documented-only
  • 신뢰 경계 정의 + header spoofing 방어(D4)를 자식 branch 로 위임 — 등급: documented-only
  • 실 구현(oauth2-proxy config + nginx auth_request block) — root branch P3A 한정 — 등급: planned
  • §Claims To Verify 5개 주장 실측 (nginx build flag / 4kb cookie / 헤더 전파 / ingress-only / Traefik 비-2XX) — 등급: planned (일부 needs-confirmation)

진행 중 메모

  • P1A 의 본질 한 줄: edge proxy 가 인증을 종결하고 backend 는 헤더만 신뢰 → "backend 인증 코드 0줄" 이 최대 이점이자 동시에 최대 약점(header spoofing). 이 한 문장이 §장점·§단점·D3·D4 를 관통한다.
  • subrequest mode endpoint 구분: oauth2-proxy 의 /oauth2/auth 는 요청을 프록시하지 않고 2xx/401 만 반환하는 subrequest 전용 endpoint(O2PN-C2)로, 정상 reverse-proxy mode(/oauth2/start,/oauth2/callback)와 경로가 다르다. nginx auth_request 는 이 endpoint 만 부른다 — 두 mode 를 혼동하면 302 루프가 난다.
  • 4kb cookie 함정: cookie-backed store가 access token을 encrypted cookie에 실으면 nginx 기본 헤더 한도(4kb)를 넘어 split cookie가 되고, nginx가 첫 Set-Cookie만 복사하는 문제(O2PN-C6)가 있다. Redis/server-side store에서는 이 크기 위험 대신 state-store 운영 위험을 검증한다.
  • 본 sub-branch 는 documented-only. wiki/projects/ 승급은 root 의 6-패턴 비교 매트릭스 시점에 일괄 처리(개별 승급 없음).

결정 사항 (decisions)

  • D1 2026-05-25: 선택을 두 축으로 분리한다.
    • Ingress 축: Ingress-Nginx면 auth_request, Traefik이면 forwardAuth middleware를 사용한다.
    • Auth service 축: oauth2-proxy를 baseline OIDC agent로 두며, 다른 호환 auth service를 쓰려면 동일한 allow/deny·header contract를 검증한다.
    • Traefik forwardAuth는 OIDC session provider 자체가 아니라 외부 auth service를 호출하는 middleware다. 따라서 Traefik + oauth2-proxy는 정상 조합이며 상호 배타적 대안이 아니다.
  • D2 2026-05-25: 헤더 이름은 nginx 측 X-Auth-Request-User 가 사실상 표준 (oauth2-proxy 응답 헤더). Traefik의 X-Forwarded-User는 oauth2-proxy 측 옵션 --pass-user-headers가 추가 발급하는 헤더로, 본 문서에서는 nginx 계열 명명 우선.
  • D3 2026-05-25: 백엔드 인증 코드를 제거하고 edge proxy 의 ForwardAuth subrequest 로 인증 위임 (Edge ForwardAuth 패턴 채택).
  • D4 2026-05-25: header spoofing 방어를 위해 ingress-only traffic 강제 (K8s NetworkPolicy 또는 VPC SG) — backend 가 ingress 외 경로로 도달 불가해야 함.

결정-근거 매핑

본 sub-branch 의 P1A Edge ForwardAuth 패턴 채택 결정과 raw source claim 매핑. claim 형식 raw/<category>/<slug>.md#<CLAIM-ID>.

Decision ID Decision Supporting Claims Evidence Strength Open Risk
D1 Ingress 축(nginx auth_request / Traefik forwardAuth)과 auth service 축(oauth2-proxy / compatible OIDC agent)을 분리. baseline은 두 ingress 모두 oauth2-proxy 호출 raw/official-docs/oauth2-proxy-overview-config-official.md#OAUTH2PROXY-C2, raw/official-docs/oauth2-proxy-overview-config-official.md#OAUTH2PROXY-C3, raw/official-docs/oauth2-proxy-keycloak-oidc-provider-official.md#O2PK-C1, raw/official-docs/oauth2-proxy-keycloak-oidc-provider-official.md#O2PK-C2, raw/official-docs/oauth2-proxy-nginx-integration-official.md#O2PN-C1, raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C1, raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C3, raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C4 official-vendor-doc (3 vendors: oauth2-proxy + Keycloak + Traefik) ingress별 비-2XX 처리 차이와 auth service 대체 호환성은 실측 필요
D2 헤더 명명은 nginx 계열 X-Auth-Request-User (oauth2-proxy 응답 헤더) 우선 raw/official-docs/oauth2-proxy-overview-config-official.md#OAUTH2PROXY-C3, raw/official-docs/oauth2-proxy-overview-config-official.md#OAUTH2PROXY-C4, raw/official-docs/oauth2-proxy-nginx-integration-official.md#O2PN-C3 official-vendor-doc X-Auth-Request-* (subrequest mode response headers) vs X-Forwarded-* (--pass-user-headers upstream forwarding) 의 정확한 default 활성화 여부는 OAUTH2PROXY-C4 의 "Does not prove" 에 명시 — 별도 config 확인 필요
D3 백엔드 인증 코드 제거 + edge proxy 의 ForwardAuth subrequest 로 인증 위임 (Edge ForwardAuth 패턴 채택) raw/official-docs/nginx-auth-request-module-official.md#NGAR-C1, raw/official-docs/nginx-auth-request-module-official.md#NGAR-C2, raw/official-docs/nginx-auth-request-module-official.md#NGAR-C4, raw/official-docs/nginx-auth-request-module-official.md#NGAR-C5, raw/official-docs/oauth2-proxy-nginx-integration-official.md#O2PN-C2, raw/official-docs/oauth2-proxy-nginx-integration-official.md#O2PN-C5, raw/official-docs/traefik-forwardauth-middleware-official.md#TFA-C1 official-standard (nginx) + official-vendor-doc (oauth2-proxy, Traefik) "다중 백엔드에 일관 인증" / "백엔드 코드 0줄" 의 운영상 이점은 본 raw claim 들이 직접 enumerate 하지 않음 — 운영 관행 추론
D4 header spoofing 방어 — ingress-only traffic 강제 (NetworkPolicy / VPC SG) UNSUPPORTED_DECISION (오current Sources 표 에는 NetworkPolicy / VPC SG enforcement 의 공식 raw 가 없음 — sub-sub-branch feature-keycloak-header-spoofing-defense 에서 별도 raw 보존 필요) internal-reasoning (보안 일반 원칙) NetworkPolicy default deny / VPC SG 정확한 구성 패턴이 본 sub-branch 의 Sources 표에 부재. 구현 단계 진입 전 K8s NetworkPolicy 공식 doc + AWS SG 공식 doc 을 raw 로 보존 필요

구현 가이드

본 sub-branch 는 documented-only — 산출물은 코드가 아니라 패턴 문서다. 아래는 root branch P3A 에서 실제 구현 시 이 branch 의 결정(D1~D4)이 강제하는 config 앵커의 사전 명세. 모든 항목 등급 planned(코드 미존재 — src/ grep 으로 확정 안 됨). NO_GROUND_TRUTH: 본 branch 는 keycloak-patterns 학습 프로젝트 소속으로 ca-tmpl skeleton 범위 밖 인프라 설정이다 — error-codes/env-keys/headers registry 등 ca-tmpl 계약 SSOT 대조 대상이 아니며, 근거는 vendor 공식 doc(oauth2-proxy / nginx / Traefik)이다.

1. oauth2-proxy config (K8s + Ingress-Nginx 경로)

Trace: D1(nginx ingress + oauth2-proxy baseline) + D2(헤더 명명 nginx 계열). Supporting: OAUTH2PROXY-C2, O2PK-C1, O2PK-C2, O2PN-C3.

  • UNSUPPORTED_IMPL_DECISION: 없음 — 아래 파라미터·값은 vendor doc 이 verbatim 명시.
설정 근거 claim
--provider keycloak-oidc O2PK-C1
--client-id / --client-secret / --oidc-issuer-url confidential client 3종 필수 파라미터 O2PK-C1
issuer URL 패턴 Keycloak 17+ https://<host>/realms/<realm> (17 미만 legacy /auth/realms/...) O2PK-C2
--set-xauthrequest 활성 — X-Auth-Request-User/-Email 응답 헤더 발급 (subrequest mode) O2PN-C3

2. nginx auth_request location block

Trace: D3(edge ForwardAuth 로 인증 위임). Supporting: NGAR-C1, NGAR-C2, NGAR-C4, NGAR-C5, O2PN-C2, O2PN-C5.

  • UNSUPPORTED_IMPL_DECISION: named location 이름(@oauth2_signin)은 관례적 명명 — 임의 선택 가능(vendor 예시 관용값). 강제되는 것은 이름이 아니라 "401 → 302 redirect" contract(O2PN-C5)뿐. trade-off: 관용값을 벗어나면 남의 예시 config 를 그대로 못 붙임.
디렉티브 역할 근거 claim
auth_request /oauth2/auth; 보호 location 에서 subrequest 발사 (URI = oauth2-proxy subrequest endpoint) NGAR-C4, O2PN-C2
subrequest 응답 contract 2xx=allow, 401/403=deny NGAR-C2, O2PN-C2
auth_request_set $user $upstream_http_x_auth_request_user; (+ $email) subrequest 응답 헤더 → main request 변수 NGAR-C5, O2PN-C3
proxy_set_header X-User $user; (+ X-Email $email;) backend 로 사용자 식별 헤더 주입 O2PN-C3
error_page 401 = @oauth2_signin;return 302 /oauth2/sign_in?rd=... 미인증 브라우저 302 redirect O2PN-C5
nginx build --with-http_auth_request_module 필수 (기본 빌드 미포함) NGAR-C1 · 검증 → §Claims 1 (NGAR-C7)

3. Traefik forwardAuth ingress variant (auth service는 별도)

Trace: D1(Traefik ingress 축). forwardAuth.address는 oauth2-proxy 또는 호환 auth service를 가리킨다. Supporting: TFA-C1, TFA-C3, TFA-C4.

  • UNSUPPORTED_IMPL_DECISION: nginx(401/403 만 deny)와 Traefik(모든 non-2XX 를 302 포함 client 에 그대로 전달)의 비-2XX 처리 contract 차이는 vendor doc 이 명시(TFA-C1)하나, 두 경로가 동일 로그인 UX 를 내는지는 미실측 → §Claims 5. trade-off: 두 경로를 "동등"으로 문서화하려면 이 실측이 선행.
미들웨어 옵션 역할 근거 claim
forwardAuth.address oauth2-proxy /oauth2/auth 로 위임, 2XX=allow + 원본 요청 진행 TFA-C1
authResponseHeaders 인증 서버 응답 헤더(X-Auth-Request-*)를 forwarded request 로 복사 (충돌 헤더 대체) TFA-C3
authRequestHeaders 인증 서버로 전달할 request 헤더 필터 (비우면 전부 전달 — sensitive 헤더 노출 주의) TFA-C4

4. ingress-only 강제 (header spoofing 방어) — 자식 branch 로 위임

Trace: D4(UNSUPPORTED_DECISION).

  • R3 OUT_OF_BRANCH_SCOPE: NetworkPolicy default-deny / VPC SG 의 구체 구성은 P1A 결정 범위 밖 — 자식 sub-sub-branch raw/branch-notes/feature-keycloak-header-spoofing-defense 가 owner. 본 branch 는 "ingress 외 경로로 backend 도달 불가를 강제해야 한다"는 원칙만 명시하고 enforcement detail 은 재진술하지 않는다(포인터만).

엣지·실패·의존

R4(깊이 게이트) 캡처. 정상 경로(§토큰 교환 sequence) 외 구현 중 부딪힐 실패·엣지 + 다른 계약 의존.

  • 실패·엣지 경로:
    • proxy SPOF: oauth2-proxy 다운 → 같은 ingress 뒤 모든 backend 접근 불가(§단점). 기대 동작: HA(replica ≥2) + readiness probe. 미구성 시 단일 장애점.
    • 4kb cookie 초과 / split cookie: access_token 을 cookie 에 실으면 nginx 헤더 한도 초과 → nginx 가 첫 Set-Cookie 만 복사(O2PN-C6). 기대 동작: cookie 분할 처리 또는 access_token 을 cookie 에 싣지 않음. → §Claims 2.
    • 미인증 XHR/API 요청: O2PN-C5 의 401→302 redirect 는 브라우저 전제. API client 는 302 를 따라가지 못함. 기대 동작: Accept: application/json 요청엔 401 유지(별도 처리 — O2PN-C5 "Does not prove" 참조).
    • nginx build 에 auth_request 모듈 부재: 기본 빌드 미포함(NGAR-C7) → auth_request directive 무효화. 기대 동작: 기동 시 config 오류로 조기 실패. → §Claims 1.
    • nginx vs Traefik 비-2XX contract 차이: oauth2-proxy 가 5xx 반환 시 nginx(401/403 만 deny, 그 외 error)와 Traefik(모든 non-2XX 를 client 에 전달)의 최종 응답이 갈림(TFA-C1). → §Claims 5.
  • 다른 계약 의존 (대상 브랜치 + 그 Decision ID 병기):

검증해야 할 주장

본 sub-branch 는 documented-only 단계. 구현 진입 시 검증해야 할 주장 enumerate.

Claim Why uncertain How to verify Status
nginx 빌드에 --with-http_auth_request_module 가 활성화되어 있음 NGAR-C7 명시 — 기본 빌드에 포함되지 않음 nginx -V 2>&1 | grep -o with-http_auth_request_module planned (구현 진입 시)
oauth2-proxy 가 큰 access_token (Keycloak refresh token 포함) 을 cookie 4kb 한도 내에서 처리 또는 split O2PN-C6 명시 — 분할 cookie 시 nginx 가 첫 Set-Cookie 만 복사 docker-compose 환경에서 큰 토큰 발급 후 브라우저 cookie 확인 + nginx access_log 의 Set-Cookie 헤더 검사 planned
--set-xauthrequest 활성화 시 nginx auth_request_set 이 backend 까지 X-User / X-Email 헤더 전파 O2PN-C3 가 contract 명시했으나 실제 nginx config 의 proxy_set_header 작성 필요 backend 에 echo endpoint 추가 후 curl 로 헤더 확인 planned
backend 가 ingress-only traffic 만 받음 (header spoofing 우회 차단) D4 의 UNSUPPORTED_DECISION 와 동일 — 정책 enforcement 가 실제로 강제되는지 별도 검증 필요 K8s: NetworkPolicy default-deny 적용 후 다른 namespace 에서 curl 시도 → 차단 확인. VM: backend listen address 가 loopback / private subnet 인지 ss -tln 확인 needs-confirmation
Traefik forwardAuth 의 비-2XX 응답 처리가 nginx auth_request 와 호환 가능 TFA-C1 가 "비 2XX 응답은 그대로 client 에 반환" 명시 — nginx 의 "401/403 만 deny, 그 외 error" 와 contract 차이 두 환경에서 oauth2-proxy 가 5xx 반환 시 client 가 받는 응답 비교 (curl -v) planned

마주친 문제

  • 아직 없음(문서 단계).

묶음 (자식 sub-sub-branches)

Sources / 근거 자료는 본 문서 하단 "외부 근거 / 대안 조사" 섹션 참조. Errors / Interview prep / Lectures 는 현재 없음 (Phase 3 P3A 실 구현 또는 외부 산출물 단계에 누적 예정).

관련 일일 노트

관련 sub-branch

외부 근거 / 대안 조사 (2026-05-25 — P1A Edge Forward Auth)

본 sub-branch의 Edge ForwardAuth 패턴 채택에 대한 외부 source 조사. 대안은 동일 목적(브라우저 인증 + 백엔드 신뢰)을 다른 방식으로 달성하는 패턴들과 비교.

  • 채택 결정 (nginx auth_request 또는 Traefik forwardAuth ingress + oauth2-proxy baseline + Keycloak):
  • 검토한 대안:
    • 대안 1: SPA Direct OIDC + Resource Server (P2A) — 클라이언트가 직접 Keycloak 호출, 백엔드는 JWT validator. 장: 백엔드 stateless / 단: SPA에 token 노출. 비교 sub-branch: raw/branch-notes/feature-keycloak-internal-spa-direct-no-google.
    • 대안 2: BFF (Backend-for-Frontend) — 백엔드 session cookie + 백엔드가 token holder. 장: XSS surface 축소 / 단: 백엔드 stateful. (Curity / Philippe De Ryck 권고).
    • 대안 3: API Gateway 인증 (Kong, AWS API Gateway + Cognito) — vendor lock-in + cloud 종속.
    • 대안 4: Service Mesh (Istio AuthorizationPolicy + JWT filter) — K8s mesh 인프라 전제.
    • 대안 5: 백엔드 직접 인증 (Spring Security oauth2Login) — 백엔드가 redirect/callback 처리. 단일 서비스에는 단순하나 다중 서비스 시 중복.
  • 비교 핵심: Edge ForwardAuth는 다중 백엔드 서비스가 동일 인증을 공유할 때 가장 단순. 백엔드 코드 0줄 인증. 단, header spoofing 방어 (ingress-only traffic 강제 — K8s NetworkPolicy 또는 VPC SG) 필수. SPA Direct는 mobile/IoT까지 같은 token으로 쓸 때 유리. BFF는 XSS 민감 환경(예: 금융). Service Mesh는 이미 mesh 도입된 환경.

완료 후 정리

본 sub-branch는 문서까지만. wiki 추출은 root branch의 비교 매트릭스 시점에 일괄 처리.

  • PR 링크:
  • 리뷰 메모:
  • 머지 결과 / 배포 환경: 해당 없음 (문서 단계)
  • wiki 추출 대상 (verified만, wiki/projects/로만 추출):
    • actually-implemented 항목: 없음
    • locally-verified 항목: 없음
    • prod-verified 항목: 없음
  • 추출하지 않을 항목 (planned / documented-only / abandoned):
    • 본 sub-branch 전체가 documented-only 등급. 추후 root branch의 6 패턴 비교 매트릭스에 인용되는 형태로만 활용. wiki/projects/ 직접 승급 없음.