Files
document-haness/.playwright-mcp/page-2026-08-26T11-30-51-300Z.yml
T

428 lines
31 KiB
YAML

- generic [ref=f7e3]:
- link "본문으로 건너뛰기" [ref=f7e4] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f7e5]:
- generic [ref=f7e6]:
- link "TechLog Studio" [ref=f7e7] [cursor=pointer]:
- /url: /studio
- text: TechLog
- generic [ref=f7e8]: Studio
- navigation "Studio 주 탐색" [ref=f7e10]:
- link "작업본" [ref=f7e11] [cursor=pointer]:
- /url: /studio/documents
- link "게시 기록" [ref=f7e12] [cursor=pointer]:
- /url: /studio/publications
- link "새 문서" [ref=f7e13] [cursor=pointer]:
- /url: /studio/documents/new
- link "주제·프로젝트" [ref=f7e14] [cursor=pointer]:
- /url: /studio/taxonomy
- link "릴리즈" [ref=f7e15] [cursor=pointer]:
- /url: /studio/releases
- link "공개 사이트 보기" [ref=f7e16] [cursor=pointer]:
- /url: /
- button "로그아웃" [ref=f7e17]
- main [ref=f7e18]:
- generic [ref=f7e19]:
- generic [ref=f7e20]:
- region [ref=f7e21]:
- generic [ref=f7e22]:
- paragraph [ref=f7e23]: QUESTION · VERSION 10
- heading "문서 편집" [level=1] [ref=f7e24]
- paragraph [ref=f7e25]: Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가
- region [ref=f7e26]:
- generic [ref=f7e27]:
- paragraph [ref=f7e28]: DOCUMENT
- heading "기본 정보" [level=2] [ref=f7e29]
- generic [ref=f7e30]:
- generic [ref=f7e31]:
- generic [ref=f7e32]: 제목
- textbox "제목" [ref=f7e33]: Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가
- generic [ref=f7e34]:
- generic [ref=f7e35]: slug
- textbox "slug" [ref=f7e36]:
- /placeholder: 비우면 제목에서 만듭니다 (영문 소문자·숫자·하이픈)
- text: edge-authorization-scope
- generic [ref=f7e37]:
- generic [ref=f7e38]: 요약
- textbox "요약" [ref=f7e39]: 지금 edge는 user와 email만 전달하고 upstream은 role 판단을 하지 않는다. 다음 요구가 들어왔을 때 role까지 헤더로 보낼지, 아니면 인가를 애플리케이션으로 되돌릴지 정하지 않았다.
- generic [ref=f7e40]:
- generic [ref=f7e41]: Topic
- combobox "Topic" [ref=f7e42]:
- option "선택하지 않음"
- option "OAuth/OIDC 인증 경계" [selected]
- generic [ref=f7e43]:
- generic [ref=f7e44]: Project
- combobox "Project" [ref=f7e45]:
- option "미지정"
- option "Backend Clean Architecture"
- option "KeyCloak Patterns" [selected]
- option "Liner N + 1문제"
- group "관계" [ref=f7e46]:
- generic [ref=f7e48]:
- generic [ref=f7e49]:
- generic [ref=f7e50]: 관계 1 대상
- combobox "관계 1 대상" [ref=f7e51]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준"
- option "BFF 인증 구조 설계 기준" [disabled]
- option "BFF가 OAuth Token을 관리하는 조건"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정"
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [selected]
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건" [disabled]
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준"
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출"
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계"
- generic [ref=f7e52]:
- generic [ref=f7e53]: 관계 1 이유
- textbox "관계 1 이유" [ref=f7e54]: edge가 user와 email만 전달한다는 사실의 출처다.
- generic [ref=f7e55]:
- button "위로" [disabled] [ref=f7e56]
- button "아래로" [ref=f7e57]
- button "삭제" [ref=f7e58]
- generic [ref=f7e59]:
- generic [ref=f7e60]:
- generic [ref=f7e61]: 관계 2 대상
- combobox "관계 2 대상" [ref=f7e62]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준"
- option "BFF 인증 구조 설계 기준" [disabled]
- option "BFF가 OAuth Token을 관리하는 조건"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정"
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [disabled]
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건" [selected]
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준"
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출"
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계"
- generic [ref=f7e63]:
- generic [ref=f7e64]: 관계 2 이유
- textbox "관계 2 이유" [ref=f7e65]: 헤더 allowlist와 검증 조건이 이 기준에 있다.
- generic [ref=f7e66]:
- button "위로" [ref=f7e67]
- button "아래로" [ref=f7e68]
- button "삭제" [ref=f7e69]
- generic [ref=f7e70]:
- generic [ref=f7e71]:
- generic [ref=f7e72]: 관계 3 대상
- combobox "관계 3 대상" [ref=f7e73]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준"
- option "BFF 인증 구조 설계 기준" [selected]
- option "BFF가 OAuth Token을 관리하는 조건"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정"
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [disabled]
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건" [disabled]
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준"
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출"
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계"
- generic [ref=f7e74]:
- generic [ref=f7e75]: 관계 3 이유
- textbox "관계 3 이유" [ref=f7e76]: 되돌리는 선택지의 기준이 이 문서다.
- generic [ref=f7e77]:
- button "위로" [ref=f7e78]
- button "아래로" [disabled] [ref=f7e79]
- button "삭제" [ref=f7e80]
- button "관계 추가" [ref=f7e81]
- region [ref=f7e82]:
- generic [ref=f7e83]:
- paragraph [ref=f7e84]: QUESTION
- heading "판단과 다음 검증" [level=2] [ref=f7e85]
- generic [ref=f7e86]:
- generic [ref=f7e87]: 질문 상태
- combobox "질문 상태" [ref=f7e88]:
- option "아직 정하지 않음"
- option "OPEN" [selected]
- option "RESOLVED"
- group "사실" [ref=f7e89]:
- generic [ref=f7e91]:
- generic [ref=f7e92]:
- generic [ref=f7e93]: 사실 1
- textbox "사실 1" [ref=f7e94]: 지금 edge 응답은 user와 email만 전달한다. role과 groups, tenant, 인증 방식, token 만료는 전달하지 않는다.
- generic [ref=f7e95]:
- button "위로" [disabled] [ref=f7e96]
- button "아래로" [ref=f7e97]
- button "삭제" [ref=f7e98]
- generic [ref=f7e99]:
- generic [ref=f7e100]:
- generic [ref=f7e101]: 사실 2
- textbox "사실 2" [ref=f7e102]: upstream의 identity endpoint는 role 판단을 하지 않고 누가 왔는지만 응답에 담는다.
- generic [ref=f7e103]:
- button "위로" [ref=f7e104]
- button "아래로" [ref=f7e105]
- button "삭제" [ref=f7e106]
- generic [ref=f7e107]:
- generic [ref=f7e108]:
- generic [ref=f7e109]: 사실 3
- textbox "사실 3" [ref=f7e110]: internal token 검사가 controller 한 곳에 있고 security 설정은 그 경로 전체를 permitAll로 둔다. 새 endpoint에는 보호가 따라오지 않는다.
- generic [ref=f7e111]:
- button "위로" [ref=f7e112]
- button "아래로" [ref=f7e113]
- button "삭제" [ref=f7e114]
- generic [ref=f7e115]:
- generic [ref=f7e116]:
- generic [ref=f7e117]: 사실 4
- textbox "사실 4" [ref=f7e118]: Nginx는 client가 보낸 동명 헤더를 merge하지 않고 덮어쓴다. 늘리는 헤더도 같은 처리를 받아야 한다.
- generic [ref=f7e119]:
- button "위로" [ref=f7e120]
- button "아래로" [ref=f7e121]
- button "삭제" [ref=f7e122]
- generic [ref=f7e123]:
- generic [ref=f7e124]:
- generic [ref=f7e125]: 사실 5
- textbox "사실 5" [ref=f7e126]: upstream은 JWT를 입력으로 받지 않아서 헤더로 온 값을 스스로 검증할 수단이 없다.
- generic [ref=f7e127]:
- button "위로" [ref=f7e128]
- button "아래로" [disabled] [ref=f7e129]
- button "삭제" [ref=f7e130]
- button "사실 추가" [ref=f7e131]
- group "가정" [ref=f7e132]:
- generic [ref=f7e134]:
- generic [ref=f7e135]:
- generic [ref=f7e136]: 가정 1
- textbox "가정 1" [ref=f7e137]: 헤더 종류가 늘어나면 정해야 할 계약도 함께 늘어난다.
- generic [ref=f7e138]:
- button "위로" [disabled] [ref=f7e139]
- button "아래로" [ref=f7e140]
- button "삭제" [ref=f7e141]
- generic [ref=f7e142]:
- generic [ref=f7e143]:
- generic [ref=f7e144]: 가정 2
- textbox "가정 2" [ref=f7e145]: role이 바뀌는 시점과 요청이 오는 시점이 달라서 그 사이에 들어온 요청은 옛 값을 본다.
- generic [ref=f7e146]:
- button "위로" [ref=f7e147]
- button "아래로" [disabled] [ref=f7e148]
- button "삭제" [ref=f7e149]
- button "가정 추가" [ref=f7e150]
- group "미지수" [ref=f7e151]:
- generic [ref=f7e153]:
- generic [ref=f7e154]:
- generic [ref=f7e155]: 미지수 1
- textbox "미지수 1" [ref=f7e156]: 다중 값 role을 어떤 구분자와 escaping으로 보낼지. 값 안에 그 구분자가 들어오면 어떻게 되는지.
- generic [ref=f7e157]:
- button "위로" [disabled] [ref=f7e158]
- button "아래로" [ref=f7e159]
- button "삭제" [ref=f7e160]
- generic [ref=f7e161]:
- generic [ref=f7e162]:
- generic [ref=f7e163]: 미지수 2
- textbox "미지수 2" [ref=f7e164]: 헤더 크기 상한을 넘으면 무엇이 먼저 깨지는지. proxy가 자르는지 요청 자체가 거부되는지.
- generic [ref=f7e165]:
- button "위로" [ref=f7e166]
- button "아래로" [ref=f7e167]
- button "삭제" [ref=f7e168]
- generic [ref=f7e169]:
- generic [ref=f7e170]:
- generic [ref=f7e171]: 미지수 3
- textbox "미지수 3" [ref=f7e172]: role이 바뀌었을 때 proxy session과 downstream 인가가 언제 따라가는지. 권한 회수가 몇 분 뒤에 반영되는지.
- generic [ref=f7e173]:
- button "위로" [ref=f7e174]
- button "아래로" [ref=f7e175]
- button "삭제" [ref=f7e176]
- generic [ref=f7e177]:
- generic [ref=f7e178]:
- generic [ref=f7e179]: 미지수 4
- textbox "미지수 4" [ref=f7e180]: upstream이 헤더 존재만 볼지 값과 service identity까지 볼지.
- generic [ref=f7e181]:
- button "위로" [ref=f7e182]
- button "아래로" [disabled] [ref=f7e183]
- button "삭제" [ref=f7e184]
- button "미지수 추가" [ref=f7e185]
- group "제약" [ref=f7e186]:
- generic [ref=f7e188]:
- generic [ref=f7e189]:
- generic [ref=f7e190]: 제약 1
- textbox "제약 1" [ref=f7e191]: 전달할 헤더는 allowlist로 고정해야 하고 client가 보낸 동명 헤더는 언제나 덮어써야 한다.
- generic [ref=f7e192]:
- button "위로" [disabled] [ref=f7e193]
- button "아래로" [ref=f7e194]
- button "삭제" [ref=f7e195]
- generic [ref=f7e196]:
- generic [ref=f7e197]:
- generic [ref=f7e198]: 제약 2
- textbox "제약 2" [ref=f7e199]: internal token 검사가 controller 한 곳에만 있다. 헤더를 늘리기 전에 이 검사를 공통 경계로 옮기는 것이 먼저다.
- generic [ref=f7e200]:
- button "위로" [ref=f7e201]
- button "아래로" [ref=f7e202]
- button "삭제" [ref=f7e203]
- generic [ref=f7e204]:
- generic [ref=f7e205]:
- generic [ref=f7e206]: 제약 3
- textbox "제약 3" [ref=f7e207]: upstream을 고칠 수 없어서 이 구조를 골랐다면 BFF로 되돌리는 선택지는 없다.
- generic [ref=f7e208]:
- button "위로" [ref=f7e209]
- button "아래로" [disabled] [ref=f7e210]
- button "삭제" [ref=f7e211]
- button "제약 추가" [ref=f7e212]
- group "선택지" [ref=f7e213]:
- generic [ref=f7e215]:
- generic [ref=f7e216]:
- generic [ref=f7e217]: 선택지 1 제목
- textbox "선택지 1 제목" [ref=f7e218]: 현재 — 인증만 edge에 둔다
- generic [ref=f7e219]:
- generic [ref=f7e220]: 선택지 1 설명
- textbox "선택지 1 설명" [ref=f7e221]: 헤더가 user와 email 둘로 고정돼 있어서 계약이 가장 작고 크기 상한 문제도 생기지 않는다. 인가는 upstream이 자기 저장소로 해결한다. 서비스마다 권한 조회를 따로 붙여야 한다.
- generic [ref=f7e222]:
- button "위로" [disabled] [ref=f7e223]
- button "아래로" [ref=f7e224]
- button "삭제" [ref=f7e225]
- generic [ref=f7e226]:
- generic [ref=f7e227]:
- generic [ref=f7e228]: 선택지 2 제목
- textbox "선택지 2 제목" [ref=f7e229]: 다음 후보 — role 전달까지 edge에 둔다
- generic [ref=f7e230]:
- generic [ref=f7e231]: 선택지 2 설명
- textbox "선택지 2 설명" [ref=f7e232]: 공통 role을 한 곳에서 주면 서비스마다 권한을 조회하지 않아도 된다. 이 선택을 하면 다중 값 직렬화와 크기 상한, 갱신 시점 계약을 먼저 정해야 한다. upstream은 그 값을 검증할 수단이 없어서 edge가 틀리면 그대로 틀린다.
- generic [ref=f7e233]:
- button "위로" [ref=f7e234]
- button "아래로" [ref=f7e235]
- button "삭제" [ref=f7e236]
- generic [ref=f7e237]:
- generic [ref=f7e238]:
- generic [ref=f7e239]: 선택지 3 제목
- textbox "선택지 3 제목" [ref=f7e240]: 보류 — tenant와 인가 판단까지 edge에 둔다
- generic [ref=f7e241]:
- generic [ref=f7e242]: 선택지 3 설명
- textbox "선택지 3 설명" [ref=f7e243]: tenant는 잘못 들어간 값 하나가 다른 조직의 데이터를 그대로 열어 준다. 이 값만은 upstream이 다시 확인할 수단을 함께 설계해야 해서 지금 구성으로는 감당할 수 없다. 인가 판단까지 옮기면 edge가 애플리케이션 도메인을 알아야 하고 정책이 바뀔 때마다 edge를 배포하게 된다.
- generic [ref=f7e244]:
- button "위로" [ref=f7e245]
- button "아래로" [ref=f7e246]
- button "삭제" [ref=f7e247]
- generic [ref=f7e248]:
- generic [ref=f7e249]:
- generic [ref=f7e250]: 선택지 4 제목
- textbox "선택지 4 제목" [ref=f7e251]: 경계가 커지면 — BFF로 되돌린다
- generic [ref=f7e252]:
- generic [ref=f7e253]: 선택지 4 설명
- textbox "선택지 4 설명" [ref=f7e254]: role·tenant 정보를 edge header로 계속 확장하지 않고 BFF가 필요한 정보를 조회해 인가와 API 조합을 처리하는 선택지도 있다. 이 경우 BFF session, CSRF 검증, shared store 운영이 다시 필요하다.
- generic [ref=f7e255]:
- button "위로" [ref=f7e256]
- button "아래로" [disabled] [ref=f7e257]
- button "삭제" [ref=f7e258]
- button "선택지 추가" [ref=f7e259]
- generic [ref=f7e260]:
- generic [ref=f7e261]: 다음 검증
- textbox "다음 검증" [ref=f7e262]: upstream이 실제로 요구하는 claim을 먼저 적는다. 그 목록을 놓고 아래를 본다. 1. 전달하려는 claim이 계속 늘어나는가. 2. role이나 tenant 변경이 즉시 반영돼야 하는가. 3. 정책이 애플리케이션 도메인을 알아야 하는가. 4. 헤더 값이 인가 판단의 근거가 되는가. 5. 서비스별 정책 차이가 커지는가. 2번부터 5번 중 하나라도 그렇다면 헤더를 늘리는 방향이 아니라 되돌리는 방향을 본다. role을 헤더로 실은 구성을 먼저 만들어 다중 값과 크기 상한을 넣고 무엇이 먼저 깨지는지 확인한다. role을 바꾼 뒤 몇 번째 요청부터 반영되는지도 잰다.
- region [ref=f7e263]:
- generic [ref=f7e264]:
- paragraph [ref=f7e265]: LIVE
- heading "즉시 미리보기" [level=2] [ref=f7e266]
- generic [ref=f7e269]:
- generic [ref=f7e270]:
- navigation "문서 경로" [ref=f7e271]:
- link "Open Question" [ref=f7e272] [cursor=pointer]:
- /url: /explore/questions
- generic [ref=f7e273]: /
- generic [ref=f7e274]: OAuth/OIDC 인증 경계
- generic [ref=f7e275]: /
- link "KeyCloak Patterns" [ref=f7e276] [cursor=pointer]:
- /url: /projects/keycloak-patterns
- heading "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가" [level=1] [ref=f7e277]
- paragraph [ref=f7e278]: 지금 edge는 user와 email만 전달하고 upstream은 role 판단을 하지 않는다. 다음 요구가 들어왔을 때 role까지 헤더로 보낼지, 아니면 인가를 애플리케이션으로 되돌릴지 정하지 않았다.
- generic [ref=f7e279]:
- generic [ref=f7e280]:
- term [ref=f7e281]: 유형
- definition [ref=f7e282]: Open Question
- generic [ref=f7e283]:
- term [ref=f7e284]: 프로젝트
- definition [ref=f7e285]: KeyCloak Patterns
- generic [ref=f7e286]:
- term [ref=f7e287]: 게시
- definition [ref=f7e288]: 게시 전
- paragraph [ref=f7e289]: OPEN
- article [ref=f7e290]:
- region [ref=f7e291]:
- heading "확인한 사실" [level=2] [ref=f7e292]
- list [ref=f7e293]:
- listitem [ref=f7e294]: 지금 edge 응답은 user와 email만 전달한다. role과 groups, tenant, 인증 방식, token 만료는 전달하지 않는다.
- listitem [ref=f7e295]: upstream의 identity endpoint는 role 판단을 하지 않고 누가 왔는지만 응답에 담는다.
- listitem [ref=f7e296]: internal token 검사가 controller 한 곳에 있고 security 설정은 그 경로 전체를 permitAll로 둔다. 새 endpoint에는 보호가 따라오지 않는다.
- listitem [ref=f7e297]: Nginx는 client가 보낸 동명 헤더를 merge하지 않고 덮어쓴다. 늘리는 헤더도 같은 처리를 받아야 한다.
- listitem [ref=f7e298]: upstream은 JWT를 입력으로 받지 않아서 헤더로 온 값을 스스로 검증할 수단이 없다.
- region [ref=f7e299]:
- heading "가정" [level=2] [ref=f7e300]
- list [ref=f7e301]:
- listitem [ref=f7e302]: 헤더 종류가 늘어나면 정해야 할 계약도 함께 늘어난다.
- listitem [ref=f7e303]: role이 바뀌는 시점과 요청이 오는 시점이 달라서 그 사이에 들어온 요청은 옛 값을 본다.
- region [ref=f7e304]:
- heading "남은 미지수" [level=2] [ref=f7e305]
- list [ref=f7e306]:
- listitem [ref=f7e307]: 다중 값 role을 어떤 구분자와 escaping으로 보낼지. 값 안에 그 구분자가 들어오면 어떻게 되는지.
- listitem [ref=f7e308]: 헤더 크기 상한을 넘으면 무엇이 먼저 깨지는지. proxy가 자르는지 요청 자체가 거부되는지.
- listitem [ref=f7e309]: role이 바뀌었을 때 proxy session과 downstream 인가가 언제 따라가는지. 권한 회수가 몇 분 뒤에 반영되는지.
- listitem [ref=f7e310]: upstream이 헤더 존재만 볼지 값과 service identity까지 볼지.
- region [ref=f7e311]:
- heading "제약" [level=2] [ref=f7e312]
- list [ref=f7e313]:
- listitem [ref=f7e314]: 전달할 헤더는 allowlist로 고정해야 하고 client가 보낸 동명 헤더는 언제나 덮어써야 한다.
- listitem [ref=f7e315]: internal token 검사가 controller 한 곳에만 있다. 헤더를 늘리기 전에 이 검사를 공통 경계로 옮기는 것이 먼저다.
- listitem [ref=f7e316]: upstream을 고칠 수 없어서 이 구조를 골랐다면 BFF로 되돌리는 선택지는 없다.
- region [ref=f7e317]:
- heading "검토한 선택지" [level=2] [ref=f7e318]
- list [ref=f7e319]:
- listitem [ref=f7e320]:
- heading "현재 — 인증만 edge에 둔다" [level=3] [ref=f7e321]
- paragraph [ref=f7e322]: 헤더가 user와 email 둘로 고정돼 있어서 계약이 가장 작고 크기 상한 문제도 생기지 않는다. 인가는 upstream이 자기 저장소로 해결한다. 서비스마다 권한 조회를 따로 붙여야 한다.
- listitem [ref=f7e323]:
- heading "다음 후보 — role 전달까지 edge에 둔다" [level=3] [ref=f7e324]
- paragraph [ref=f7e325]: 공통 role을 한 곳에서 주면 서비스마다 권한을 조회하지 않아도 된다. 이 선택을 하면 다중 값 직렬화와 크기 상한, 갱신 시점 계약을 먼저 정해야 한다. upstream은 그 값을 검증할 수단이 없어서 edge가 틀리면 그대로 틀린다.
- listitem [ref=f7e326]:
- heading "보류 — tenant와 인가 판단까지 edge에 둔다" [level=3] [ref=f7e327]
- paragraph [ref=f7e328]: tenant는 잘못 들어간 값 하나가 다른 조직의 데이터를 그대로 열어 준다. 이 값만은 upstream이 다시 확인할 수단을 함께 설계해야 해서 지금 구성으로는 감당할 수 없다. 인가 판단까지 옮기면 edge가 애플리케이션 도메인을 알아야 하고 정책이 바뀔 때마다 edge를 배포하게 된다.
- listitem [ref=f7e329]:
- heading "경계가 커지면 — BFF로 되돌린다" [level=3] [ref=f7e330]
- paragraph [ref=f7e331]: role·tenant 정보를 edge header로 계속 확장하지 않고 BFF가 필요한 정보를 조회해 인가와 API 조합을 처리하는 선택지도 있다. 이 경우 BFF session, CSRF 검증, shared store 운영이 다시 필요하다.
- region [ref=f7e332]:
- paragraph [ref=f7e333]: Next
- heading "다음 검증" [level=2] [ref=f7e334]
- paragraph [ref=f7e335]: upstream이 실제로 요구하는 claim을 먼저 적는다. 그 목록을 놓고 아래를 본다.1. 전달하려는 claim이 계속 늘어나는가.2. role이나 tenant 변경이 즉시 반영돼야 하는가.3. 정책이 애플리케이션 도메인을 알아야 하는가.4. 헤더 값이 인가 판단의 근거가 되는가.5. 서비스별 정책 차이가 커지는가.2번부터 5번 중 하나라도 그렇다면 헤더를 늘리는 방향이 아니라 되돌리는 방향을 본다.role을 헤더로 실은 구성을 먼저 만들어 다중 값과 크기 상한을 넣고 무엇이 먼저 깨지는지 확인한다. role을 바꾼 뒤 몇 번째 요청부터 반영되는지도 잰다.
- region [ref=f7e336]:
- paragraph [ref=f7e337]: Relations
- heading "이 기록과 연결된 맥락" [level=2] [ref=f7e338]
- list [ref=f7e339]:
- listitem [ref=f7e340]:
- link "edge가 user와 email만 전달한다는 사실의 출처다. Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [ref=f7e341] [cursor=pointer]:
- /url: /cases/identity-header-trust
- generic [ref=f7e342]: edge가 user와 email만 전달한다는 사실의 출처다.
- strong [ref=f7e343]: Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유
- generic [ref=f7e344]:
- complementary [ref=f7e345]:
- heading "작업 상태" [level=2] [ref=f7e346]
- status "편집 상태" [ref=f7e347]: 저장됨
- generic [ref=f7e348]:
- generic [ref=f7e349]:
- term [ref=f7e350]: 저장 버전
- definition [ref=f7e351]: "10"
- generic [ref=f7e352]:
- term [ref=f7e353]: 종류
- definition [ref=f7e354]: QUESTION
- paragraph [ref=f7e355]: 불완전한 초안도 저장할 수 있습니다. Ctrl+S 로도 저장합니다. 게시를 누르면 채워야 할 칸을 그 자리에 표시합니다.
- generic [ref=f7e356]:
- button "저장" [disabled] [ref=f7e357]
- button "게시" [ref=f7e358]
- paragraph [ref=f7e359]: 버전 10으로 저장했습니다.