17 KiB
title, source_type, url, archive_url, status, confidence, tags, related_projects, related_branches, created, last_reviewed
| title | source_type | url | archive_url | status | confidence | tags | related_projects | related_branches | created | last_reviewed | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| OAuth2 Proxy — Nginx Integration (Official Docs) | official-doc | https://oauth2-proxy.github.io/oauth2-proxy/configuration/integrations/nginx/ | raw | high |
|
|
|
2026-05-25 | 2026-07-17 |
OAuth2 Proxy — Nginx Integration (Official Docs)
Layer:
raw/official-docs/— oauth2-proxy 공식 문서 중 nginxauth_request결합 가이드. P1A 패턴 토큰 sequence 2단계(/oauth2/auth엔드포인트)와 7단계(헤더 주입)의 1차 근거.
Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| raw/branch-notes/feature-keycloak-patterns | keycloak-patterns root — edge 패턴에서 nginx auth_request + oauth2-proxy 결합이 정식 통합 방식이라는 사실 |
| raw/branch-notes/feature-keycloak-edge-forwardauth-no-google | P1A — /oauth2/auth 가 요청을 프록시하지 않고 202/401 만 반환하는 subrequest 패턴 채택 근거 |
| raw/branch-notes/feature-keycloak-nginx-auth-request-integration | nginx auth_request_set + X-Auth-Request-User/Email/Access-Token 변수 매핑 + error_page 401 = @oauth2_signin; 패턴의 공식 근거 |
| raw/branch-notes/feature-keycloak-oauth2-proxy-oidc-flow | OIDC code flow 의 edge subrequest 단계 + access token forwarding (--pass-access-token) 결정 근거 |
컨텍스트 / 왜 저장했는지
P1A의 핵심 메커니즘인 "ingress에서 ForwardAuth subrequest → 202 또는 401 응답 → 사용자 헤더를 backend에 forward" 의 공식 패턴이 어떻게 표현되는지 raw로 보존.
출처 / Source
- 원본 URL: https://oauth2-proxy.github.io/oauth2-proxy/configuration/integrations/nginx/
- 아카이브 URL: (미수집)
- 저자 / 조직: oauth2-proxy maintainers
- 발행일: rolling docs
- 마지막 확인일: 2026-07-17
핵심 인용 / Key quotes (verbatim)
[§Nginx auth_request directive] "The Nginx
auth_requestdirective allows Nginx to authenticate requests via the oauth2-proxy's/authendpoint"
[§Endpoint behavior] "only returns a 202 Accepted response or a 401 Unauthorized response without proxying the request through" — endpoint expects: "2xx: Request is authenticated, allow access" and "401 or 403: Request is not authenticated, deny access"
[§Headers] "pass information via X-User and X-Email headers to backend, requires running with --set-xauthrequest flag" — example: "auth_request_set $user $upstream_http_x_auth_request_user; auth_request_set $email $upstream_http_x_auth_request_email"
[§Access token] "if you enabled --pass-access-token, this will pass the token to the backend: auth_request_set $token $upstream_http_x_auth_request_access_token"
[§Sign-in redirect] "When a 401 is returned, nginx triggers the
error_pagedirective...returns a proper 302 redirect" — named location returns302 /oauth2/sign_in?rd=$scheme://$host$request_uri
[§Large cookies] "some provider's cookies can exceed the 4kb limit and so the OAuth2 Proxy splits these into multiple parts. Nginx normally only copies the first
Set-Cookieheader from the auth_request to the response"
[§Configuring for use with the Nginx
auth_requestdirective — 전체 nginx.conf 예제,location /oauth2/와location = /oauth2/auth두 block 분리] (2026-07-17 추가, 출처:docs/versioned_docs/version-7.15.x/configuration/integrations/nginx.mdraw markdown, master branch)location /oauth2/ { proxy_pass http://127.0.0.1:4180; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Auth-Request-Redirect $request_uri; # or, if you are handling multiple domains: # proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; } location = /oauth2/auth { proxy_pass http://127.0.0.1:4180; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Uri $request_uri; # nginx auth_request includes headers but not body proxy_set_header Content-Length ""; proxy_pass_request_body off; }(verbatim, elide 미적용 — controller 지정에 따라 코드 블록 완전성 보존을 위해 200자 elide 규칙의 예외로 전체 보존함)
[§Browser vs API Routes] (2026-07-17 추가) "Redirecting authentication failures (302 to
/oauth2/sign_in) should only be used for browser-facing routes. API or machine clients should receive a plain 401/403 response without redirect."
[§API / Machine routes (no redirect)] (2026-07-17 추가, verbatim code block)
location /api/ { auth_request /oauth2/auth; error_page 401 =401; # Pass through the 401 status proxy_pass http://backend/; }
Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| O2PN-C1 | nginx 의 auth_request 디렉티브를 통해 oauth2-proxy 의 /auth 엔드포인트로 인증을 위임할 수 있다 |
[§Nginx auth_request directive] "The Nginx auth_request directive allows Nginx to authenticate requests via the oauth2-proxy's /auth endpoint" |
official-vendor-doc |
nginx + oauth2-proxy 통합 | 모든 nginx 빌드에 auth_request 가 컴파일되어 있다는 뜻은 아님 (별도 module — nginx-auth-request-module-official.md 참조) |
| O2PN-C2 | /oauth2/auth 엔드포인트는 요청을 upstream 으로 프록시하지 않고 오직 2xx (인증됨) 또는 401/403 (거부) 만 반환 |
[§Endpoint behavior] "only returns a 202 Accepted response or a 401 Unauthorized response without proxying the request through" — "2xx: Request is authenticated, allow access" / "401 or 403: Request is not authenticated, deny access" | official-vendor-doc |
oauth2-proxy subrequest mode | 정상 reverse-proxy mode (/oauth2/start, /oauth2/callback) 의 동작에 적용된다는 뜻 아님 — subrequest 전용 |
| O2PN-C3 | backend 로 X-User/X-Email 헤더 전달은 oauth2-proxy 가 --set-xauthrequest 플래그로 실행되어 응답 헤더 X-Auth-Request-User/X-Auth-Request-Email 을 내보낼 때 가능 |
[§Headers] "pass information via X-User and X-Email headers to backend, requires running with --set-xauthrequest flag" — "auth_request_set $user $upstream_http_x_auth_request_user; auth_request_set $email $upstream_http_x_auth_request_email" | official-vendor-doc |
nginx → backend 사용자 신원 전달 | nginx 가 backend 가 X-User 헤더를 신뢰해도 안전하다는 뜻 아님 — 헤더 spoofing 방지는 별도 (header-stripping 결정 필요) |
| O2PN-C4 | --pass-access-token 활성화 시 access token 은 X-Auth-Request-Access-Token 응답 헤더로 노출되며 nginx auth_request_set 으로 backend 로 전달 가능 |
[§Access token] "if you enabled --pass-access-token, this will pass the token to the backend: auth_request_set $token $upstream_http_x_auth_request_access_token" | official-vendor-doc |
edge 에서 backend 로 access token forwarding | access token forwarding 이 RS audience validation 을 대체한다는 뜻은 아님 (별도 RS 측 검증) |
| O2PN-C5 | 401 응답 시 nginx 가 error_page 디렉티브로 named location 트리거 → 브라우저에 302 redirect (/oauth2/sign_in?rd=...) 반환 |
[§Sign-in redirect] "When a 401 is returned, nginx triggers the error_page directive...returns a proper 302 redirect" — return 302 /oauth2/sign_in?rd=$scheme://$host$request_uri |
official-vendor-doc |
미인증 브라우저 요청 처리 | XHR/API 요청에 302 redirect 반환이 적절하다는 뜻 아님 — API client 별도 처리 권장 |
| O2PN-C6 | 일부 provider 의 cookie 는 4KB 한도를 초과해 oauth2-proxy 가 여러 part 로 분리하며, nginx 는 기본적으로 auth_request 응답에서 첫 번째 Set-Cookie 헤더만 복사한다 |
[§Large cookies] "some provider's cookies can exceed the 4kb limit and so the OAuth2 Proxy splits these into multiple parts. Nginx normally only copies the first Set-Cookie header from the auth_request to the response" |
official-vendor-doc |
큰 토큰 (Keycloak refresh token 포함 세션 등) 처리 | multi-part cookie 처리 nginx 코드의 정확한 lua/scripting 방식은 본 인용 범위 밖 |
| O2PN-C7 | 공식 nginx.conf 예제는 oauth2-proxy 자체 endpoint(/oauth2/callback, /oauth2/start, /oauth2/sign_out 등)를 위한 prefix location block (location /oauth2/ { ... }, X-Auth-Request-Redirect 헤더 포함)과 auth_request 대상인 /oauth2/auth 를 위한 exact-match location block (location = /oauth2/auth { ... })을 별도의 두 block으로 분리해서 정의한다 |
[§전체 nginx.conf 예제] 위 "핵심 인용" §Configuring for use with the Nginx auth_request directive 의 verbatim 코드 블록 (location /oauth2/ { ... } + location = /oauth2/auth { ... } 두 block, line 26-42 of fetched raw markdown) |
official-vendor-doc |
D7 — oauth2-proxy 자체 endpoint 라우팅을 location /oauth2/ prefix block 으로, auth_request 대상을 location = /oauth2/auth exact block 으로 분리하는 결정 |
Negative finding: 공식 예제는 location = /oauth2/auth block 에 internal; directive 를 붙이지 않는다 (fetched 원문 전체에 internal 문자열 자체가 존재하지 않음 — grep 으로 확인). 즉 공식 예제만으로는 "이 location 을 외부에서 직접 호출 불가하게 격리해야 한다"는 하드닝을 증명하지 않는다 — 이는 사용자가 예제를 넘어 추가하는 보안 결정. 또한 이 예제는 standalone nginx 설정이며, ingress-nginx annotation 방식(K8s)에 그대로 적용된다는 뜻은 아니다 |
| O2PN-C8 | 공식 nginx.conf 예제의 location = /oauth2/auth block 은 # nginx auth_request includes headers but not body 라는 인라인 주석과 함께 proxy_set_header Content-Length ""; 및 proxy_pass_request_body off; 두 directive 를 포함한다 |
[§전체 nginx.conf 예제] "# nginx auth_request includes headers but not body" / "proxy_set_header Content-Length "";" / "proxy_pass_request_body off;" (line 39-41 of fetched raw markdown) | official-vendor-doc |
D6 — proxy_pass_request_body off + Content-Length "" 로 auth_request subrequest 의 body 전달을 차단하는 결정 |
원문은 "nginx 의 auth_request 메커니즘 자체가 subrequest 에 헤더는 포함하되 body 는 포함하지 않는다"는 사실만 명시한다. 원문은 "body 를 전달하면 POST endpoint 가 의도치 않게 오발동하거나 oauth2-proxy 의 CPU 사용량이 증가한다"는 인과관계를 말하지 않는다 — 이는 branch-note D6 의 Open Risk 컬럼에 있는 사용자 추론이며 이 quote 로 증명되지 않는다. 이 두 directive 를 생략해도 nginx auth_request 자체 동작(2xx/401 판정)에 문제가 생긴다고 원문이 말하는 것도 아니다 — 원문은 단지 공식 예제가 이 설정을 포함한다는 사실만 보여준다 |
| O2PN-C9 | 공식 문서는 인증 실패 시 302 redirect (/oauth2/sign_in)를 browser-facing route 에만 사용해야 하며, API/machine client 는 redirect 없는 plain 401/403 응답을 받아야 한다고 명시한다. 이를 위한 별도 예시로 location /api/ { auth_request /oauth2/auth; error_page 401 =401; proxy_pass http://backend/; } 패턴(302 redirect 없이 401 status 를 그대로 pass-through)을 제공한다 |
[§Browser vs API Routes] "Redirecting authentication failures (302 to /oauth2/sign_in) should only be used for browser-facing routes. API or machine clients should receive a plain 401/403 response without redirect." + [§API / Machine routes (no redirect)] verbatim 코드 블록 (error_page 401 =401; # Pass through the 401 status) |
official-vendor-doc |
D9 — 인증 실패 응답의 route 별 분기(1차 근거) / D7 부가 참고. (2026-07-17: 본 claim 을 근거로 feature-keycloak-nginx-auth-request-integration 에 D9 가 신설됨 — 최초 작성 시점엔 D9 가 없어 "D7 부가" 로만 라벨돼 있었다) |
이 섹션은 backend API route (예: /api/) 의 인증 실패 응답 정책을 다루는 것이지, oauth2-proxy 자체 endpoint 라우팅(location /oauth2/ prefix block 을 쓸지, callback/start/sign_out 을 internal 로 격리할지)의 근거는 아니다 — D7 의 핵심 근거는 O2PN-C7 이며, O2PN-C9 는 부가 참고 자료로만 D7 에 연결된다. 또한 이 자료 하나만으로 "모든 API 는 반드시 401 을 그대로 반환해야 한다"는 강제 규범이 존재한다는 뜻도 아니다 — 공식 문서는 권고(should)로 표현했을 뿐 |
Usage Boundaries / 적용 경계
- 이 자료가 직접 증명하는 것:
O2PN-C1~C6: nginxauth_request+ oauth2-proxy/oauth2/auth의 공식 통합 패턴, 응답 코드 의미, 헤더 매핑 변수명, 401 redirect 패턴, large cookie 한계O2PN-C7: 공식 예제가 oauth2-proxy 자체 endpoint(/oauth2/prefix)와 auth_request 대상(/oauth2/authexact)을 별도 location block 으로 분리한다는 사실 — D7 의 라우팅 분리 결정의 1차 근거O2PN-C8: 공식 예제가location = /oauth2/authblock 에proxy_set_header Content-Length ""+proxy_pass_request_body off를 포함한다는 사실 (인과관계·이유는 증명 안 함) — D6 의 1차 근거O2PN-C9: 공식 문서가 302 redirect 를 browser-facing route 에만 권고하고 API/machine client 는 plain 401/403 을 받아야 한다고 명시하는 사실 — D7 부가 참고
- 이 자료가 증명하지 않는 것:
- nginx
auth_request모듈이 모든 distribution 의 nginx 패키지에 컴파일되어 있는지 (별도nginx-auth-request-module-official.md) - backend 가
X-User헤더를 신뢰해도 안전한 보안 전제 (header-spoofing 방어는 별도 P1A 결정) --pass-access-token가 활성화된 환경에서 access token 의 audience 가 backend RS 와 일치할 것임 (audience validator 별도 RS 책임)location = /oauth2/auth를internal;로 격리해야 한다는 것 (공식 예제에internal자체가 없음 —O2PN-C7negative finding)proxy_pass_request_body off를 생략하면 POST 오발동이나 CPU 증가가 발생한다는 인과관계 (O2PN-C8does-not-prove — 원문은 설정 사실만 보여줌)- "모든 API 는 반드시 401 을 그대로 반환해야 한다"는 강제 규범 (
O2PN-C9는 권고(should) 표현일 뿐)
- nginx
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
- 사용하는 nginx 빌드에
auth_request모듈 포함 여부 (nginx -V 2>&1 | grep auth_request) - P1A 의 Keycloak realm 에서 access token 크기가 4KB 를 넘는지 (refresh token 포함 cookie split 필요 여부)
- edge 에서 forward 되는
X-User/X-Email의 spoofing 방지를 위해 backend 가 edge 외부 traffic 을 차단하는지 location = /oauth2/auth를 외부에서 직접 호출 불가하게 만들려면internal;등 별도 하드닝을 사용자가 직접 추가해야 함 (공식 예제 범위 밖)
- 사용하는 nginx 빌드에
메모 / Notes (내 프로젝트 해석)
본 섹션은 자료 직접 인용 아님. P1A 결정 컨텍스트 해석.
/oauth2/auth가 요청을 프록시하지 않음 이 핵심. 일반 reverse-proxy 모드(/oauth2/start,/oauth2/callback)와 구분.- 401 처리는
error_page 401 = @oauth2_signin;named location 패턴 사용 → 사용자 브라우저에 302 redirect 응답. auth_request_set의$upstream_http_x_auth_request_user변수명은 oauth2-proxy 응답 헤더X-Auth-Request-User의 nginx 변수 표현.- (2026-07-17)
O2PN-C7C6 인용의 backtick·markdown-link 표기 스타일과 일치하기 때문).C9추가 시 렌더링된 HTML 페이지(curl)와 GitHub raw markdown(docs/versioned_docs/version-7.15.x/configuration/integrations/nginx.md, master branch, edit-URL 로 경로 확인) 두 fetch 를 대조. 둘 다 "Browser vs API Routes" 섹션을 포함 — 선행 조사에서 제기된 "렌더링된 HTML 에는 없음" 불일치는 이번 재확인(2026-07-17 시점)에서는 재현되지 않음. raw markdown 을 self-grep 의 canonical 텍스트로 채택(기존 C1 O2PN-C7/C8의 nginx.conf 코드 블록은 200자 elide 규칙의 예외로 전체 verbatim 보존 — controller 지정 사항이며, 코드 config 블록을 elide 하면 기술적 완전성이 깨지기 때문.
Related / 관련
- 같은 주제 다른 official-doc:
- 인용하는 branch:
- 인용하는 wiki: (미작성)