Files
document-haness/.playwright-mcp/page-2026-08-26T11-29-17-928Z.yml

319 lines
25 KiB
YAML

- generic [ref=f5e3]:
- link "본문으로 건너뛰기" [ref=f5e4] [cursor=pointer]:
- /url: "#main-content"
- banner [ref=f5e5]:
- generic [ref=f5e6]:
- link "TechLog Studio" [ref=f5e7] [cursor=pointer]:
- /url: /studio
- text: TechLog
- generic [ref=f5e8]: Studio
- navigation "Studio 주 탐색" [ref=f5e10]:
- link "작업본" [ref=f5e11] [cursor=pointer]:
- /url: /studio/documents
- link "게시 기록" [ref=f5e12] [cursor=pointer]:
- /url: /studio/publications
- link "새 문서" [ref=f5e13] [cursor=pointer]:
- /url: /studio/documents/new
- link "주제·프로젝트" [ref=f5e14] [cursor=pointer]:
- /url: /studio/taxonomy
- link "릴리즈" [ref=f5e15] [cursor=pointer]:
- /url: /studio/releases
- link "공개 사이트 보기" [ref=f5e16] [cursor=pointer]:
- /url: /
- button "로그아웃" [ref=f5e17]
- main [ref=f5e18]:
- generic [ref=f5e19]:
- generic [ref=f5e20]:
- region [ref=f5e21]:
- generic [ref=f5e22]:
- paragraph [ref=f5e23]: PROJECT_DECISION · VERSION 12
- heading "문서 편집" [level=1] [ref=f5e24]
- paragraph [ref=f5e25]: 인증 구조를 보안 성숙도 단계로 취급하지 않는다
- region [ref=f5e26]:
- generic [ref=f5e27]:
- paragraph [ref=f5e28]: DOCUMENT
- heading "기본 정보" [level=2] [ref=f5e29]
- generic [ref=f5e30]:
- generic [ref=f5e31]:
- generic [ref=f5e32]: 제목
- textbox "제목" [ref=f5e33]: 인증 구조를 보안 성숙도 단계로 취급하지 않는다
- generic [ref=f5e34]:
- generic [ref=f5e35]: slug
- textbox "slug" [ref=f5e36]:
- /placeholder: 비우면 제목에서 만듭니다 (영문 소문자·숫자·하이픈)
- text: patterns-are-not-a-maturity-ladder
- generic [ref=f5e37]:
- generic [ref=f5e38]: 요약
- textbox "요약" [ref=f5e39]: SPA, Mediator, BFF, Forward-Auth는 credential을 처리하는 주체와 API 호출 경로가 서로 다르다. 번호나 브라우저 token 노출 여부를 보안 등급으로 사용하지 않고 각각 별도의 아키텍처 패턴으로 취급한다.
- generic [ref=f5e40]:
- generic [ref=f5e41]: Topic
- combobox "Topic" [ref=f5e42]:
- option "선택하지 않음"
- option "OAuth/OIDC 인증 경계" [selected]
- generic [ref=f5e43]:
- generic [ref=f5e44]: Project
- combobox "Project" [ref=f5e45]:
- option "미지정"
- option "Backend Clean Architecture"
- option "KeyCloak Patterns" [selected]
- option "Liner N + 1문제"
- group "근거 기록" [ref=f5e46]:
- generic [ref=f5e48]:
- generic [ref=f5e49]:
- generic [ref=f5e50]: 근거 1 대상
- combobox "근거 1 대상" [ref=f5e51]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준"
- option "BFF 인증 구조 설계 기준"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser에서 OAuth Token을 제거해야 하는 경우 BFF가 Token을 소유한다"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정" [disabled]
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [disabled]
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건"
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준" [disabled]
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [disabled]
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [selected]
- generic [ref=f5e52]:
- generic [ref=f5e53]: 근거 1 이유
- textbox "근거 1 이유" [ref=f5e54]: 브라우저가 code 교환, token 보관, API 호출을 직접 수행한다.
- generic [ref=f5e55]:
- button "위로" [disabled] [ref=f5e56]
- button "아래로" [ref=f5e57]
- button "삭제" [ref=f5e58]
- generic [ref=f5e59]:
- generic [ref=f5e60]:
- generic [ref=f5e61]: 근거 2 대상
- combobox "근거 2 대상" [ref=f5e62]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준"
- option "BFF 인증 구조 설계 기준"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser에서 OAuth Token을 제거해야 하는 경우 BFF가 Token을 소유한다"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정" [disabled]
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [disabled]
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건"
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준" [disabled]
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [selected]
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [disabled]
- generic [ref=f5e63]:
- generic [ref=f5e64]: 근거 2 이유
- textbox "근거 2 이유" [ref=f5e65]: mediator가 code 교환과 refresh token 보관을 담당하고 브라우저가 access token으로 API를 직접 호출한다.
- generic [ref=f5e66]:
- button "위로" [ref=f5e67]
- button "아래로" [ref=f5e68]
- button "삭제" [ref=f5e69]
- generic [ref=f5e70]:
- generic [ref=f5e71]:
- generic [ref=f5e72]: 근거 3 대상
- combobox "근거 3 대상" [ref=f5e73]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준"
- option "BFF 인증 구조 설계 기준"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser에서 OAuth Token을 제거해야 하는 경우 BFF가 Token을 소유한다"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정" [selected]
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [disabled]
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건"
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준" [disabled]
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [disabled]
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [disabled]
- generic [ref=f5e74]:
- generic [ref=f5e75]: 근거 3 이유
- textbox "근거 3 이유" [ref=f5e76]: BFF가 token과 session을 server-side에서 관리하고 Resource Server를 호출한다.
- generic [ref=f5e77]:
- button "위로" [ref=f5e78]
- button "아래로" [ref=f5e79]
- button "삭제" [ref=f5e80]
- generic [ref=f5e81]:
- generic [ref=f5e82]:
- generic [ref=f5e83]: 근거 4 대상
- combobox "근거 4 대상" [ref=f5e84]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준"
- option "BFF 인증 구조 설계 기준"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser에서 OAuth Token을 제거해야 하는 경우 BFF가 Token을 소유한다"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정" [disabled]
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [selected]
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건"
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준" [disabled]
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [disabled]
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [disabled]
- generic [ref=f5e85]:
- generic [ref=f5e86]: 근거 4 이유
- textbox "근거 4 이유" [ref=f5e87]: oauth2-proxy가 인증을 처리하고 upstream에는 identity header를 전달한다.
- generic [ref=f5e88]:
- button "위로" [ref=f5e89]
- button "아래로" [ref=f5e90]
- button "삭제" [ref=f5e91]
- generic [ref=f5e92]:
- generic [ref=f5e93]:
- generic [ref=f5e94]: 근거 5 대상
- combobox "근거 5 대상" [ref=f5e95]:
- option "대상 선택"
- option "인증 구조를 보안 성숙도 단계로 취급하지 않는다"
- option "서버 세션 기반 인증 구조는 다중 인스턴스에서 어떻게 운영할 것인가"
- option "Authorization Code Flow의 Endpoint와 Credential 이동 기준"
- option "BFF 인증 구조 설계 기준"
- option "BFF의 Session과 OAuth2AuthorizedClient를 어디에 저장할 것인가"
- option "Browser에서 OAuth Token을 제거해야 하는 경우 BFF가 Token을 소유한다"
- option "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정" [disabled]
- option "Forward-Auth 구조에서 Application Authorization을 어디까지 Edge에 둘 것인가"
- option "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [disabled]
- option "Forward-Auth에서 Identity Header를 신뢰하기 위한 조건"
- option "외부 IdP Federation을 별도의 인증 구조로 세지 않는다"
- option "외부 IdP Federation과 Application 인증 경계"
- option "OAuth/OIDC 인증 패턴 선택 기준" [selected]
- option "OAuth Token과 Application Session을 구분하는 기준"
- option "Public Client와 Confidential Client 구분 기준"
- option "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [disabled]
- option "Refresh Token Rotation과 다중 Replica 경쟁을 어떻게 처리할 것인가"
- option "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [disabled]
- generic [ref=f5e96]:
- generic [ref=f5e97]: 근거 5 이유
- textbox "근거 5 이유" [ref=f5e98]: 이 결정을 적용하는 선택 기준이다.
- generic [ref=f5e99]:
- button "위로" [ref=f5e100]
- button "아래로" [disabled] [ref=f5e101]
- button "삭제" [ref=f5e102]
- button "근거 추가" [ref=f5e103]
- region [ref=f5e104]:
- generic [ref=f5e105]:
- paragraph [ref=f5e106]: PROJECT DECISION
- heading "프로젝트 결정" [level=2] [ref=f5e107]
- generic [ref=f5e108]:
- generic [ref=f5e109]:
- generic [ref=f5e110]: 결정 상태
- combobox "결정 상태" [ref=f5e111]:
- option "아직 정하지 않음"
- option "PROPOSED"
- option "ADOPTED" [selected]
- generic [ref=f5e112]:
- generic [ref=f5e113]: 결정일
- textbox "결정일" [ref=f5e114]: 2026-08-24
- generic [ref=f5e115]:
- generic [ref=f5e116]: 결정문
- textbox "결정문" [ref=f5e117]: SPA에서 Mediator, BFF, OAuth2-Proxy로 가는 순서를 낮은 보안에서 높은 보안으로 가는 단계로 모델링하지 않는다. 네 구조는 credential과 인증 상태를 처리하는 주체가 서로 다른 별개의 아키텍처 패턴으로 취급한다.
- generic [ref=f5e118]:
- generic [ref=f5e119]: 판단 이유
- textbox "판단 이유" [ref=f5e120]: BFF는 브라우저 token을 없애지만 server session과 CSRF, 공유 저장소를 만든다. Forward-Auth는 애플리케이션의 token custody를 줄이지만 edge 헤더 신뢰와 network 경계를 만든다. 뒤 구조가 앞 구조의 문제를 없애는 것이 아니라 다른 곳에 다른 요구를 만든다. 네 구조의 차이는 code를 교환하는 주체, token 저장 방식, API 호출 주체, 보호 자원이 신뢰하는 credential에서 확인됐다. 이 차이를 보안 성숙도 순서로 환산하지 않는다. 성숙도 모델로 두면 「일단 제일 뒤 구조로 가자」는 판단이 나온다. backend 직접 경로를 닫을 수 없는 환경에서 edge에 인증을 맡기면 upstream이 헤더 하나로 사용자를 판단하는데 그 헤더를 누구나 만들어 보낼 수 있다. 그런 환경에서는 브라우저가 token을 직접 들고 서명을 검증받는 구조가 낫다.
- group "영향" [ref=f5e121]:
- generic [ref=f5e123]:
- generic [ref=f5e124]:
- generic [ref=f5e125]: 영향 1
- textbox "영향 1" [ref=f5e126]: 패턴을 비교할 때는 적용 조건과 운영해야 할 상태, 신뢰 경계, 장애 지점을 함께 적는다. 브라우저 token 노출 여부 하나만으로 순서를 매기지 않는다.
- generic [ref=f5e127]:
- button "위로" [disabled] [ref=f5e128]
- button "아래로" [ref=f5e129]
- button "삭제" [ref=f5e130]
- generic [ref=f5e131]:
- generic [ref=f5e132]:
- generic [ref=f5e133]: 영향 2
- textbox "영향 2" [ref=f5e134]: 구조를 고를 때 번호가 아니라 code 교환·token 보관·API 호출의 배치를 먼저 답한다. 뒤 구조에서 앞 구조로 되돌아가는 선택도 후퇴가 아니라 credential 계약의 변경으로 적는다.
- generic [ref=f5e135]:
- button "위로" [ref=f5e136]
- button "아래로" [ref=f5e137]
- button "삭제" [ref=f5e138]
- generic [ref=f5e139]:
- generic [ref=f5e140]:
- generic [ref=f5e141]: 영향 3
- textbox "영향 3" [ref=f5e142]: 구조 이름만으로 운영 속성을 추정하지 않는다. 공유 저장소와 장애 복구, secret 교체는 매번 따로 확인한다.
- generic [ref=f5e143]:
- button "위로" [ref=f5e144]
- button "아래로" [disabled] [ref=f5e145]
- button "삭제" [ref=f5e146]
- button "영향 추가" [ref=f5e147]
- region [ref=f5e148]:
- generic [ref=f5e149]:
- paragraph [ref=f5e150]: LIVE
- heading "즉시 미리보기" [level=2] [ref=f5e151]
- generic [ref=f5e154]:
- navigation "문서 경로" [ref=f5e155]:
- link "Project" [ref=f5e156] [cursor=pointer]:
- /url: /projects
- generic [ref=f5e157]: /
- link "KeyCloak Patterns" [ref=f5e158] [cursor=pointer]:
- /url: /projects/keycloak-patterns
- generic [ref=f5e159]: /
- link "Decision" [ref=f5e160] [cursor=pointer]:
- /url: /projects/keycloak-patterns/decisions
- list [ref=f5e161]:
- listitem [ref=f5e162]:
- article [ref=f5e163]:
- generic [ref=f5e164]:
- generic [ref=f5e165]:
- generic [ref=f5e166]: ADOPTED
- time [ref=f5e167]: 2026.08.24
- heading "인증 구조를 보안 성숙도 단계로 취급하지 않는다" [level=2] [ref=f5e168]
- paragraph [ref=f5e169]: SPA에서 Mediator, BFF, OAuth2-Proxy로 가는 순서를 낮은 보안에서 높은 보안으로 가는 단계로 모델링하지 않는다.네 구조는 credential과 인증 상태를 처리하는 주체가 서로 다른 별개의 아키텍처 패턴으로 취급한다.
- generic [ref=f5e170]:
- heading "판단 이유" [level=3] [ref=f5e171]
- paragraph [ref=f5e172]: BFF는 브라우저 token을 없애지만 server session과 CSRF, 공유 저장소를 만든다. Forward-Auth는 애플리케이션의 token custody를 줄이지만 edge 헤더 신뢰와 network 경계를 만든다. 뒤 구조가 앞 구조의 문제를 없애는 것이 아니라 다른 곳에 다른 요구를 만든다.네 구조의 차이는 code를 교환하는 주체, token 저장 방식, API 호출 주체, 보호 자원이 신뢰하는 credential에서 확인됐다. 이 차이를 보안 성숙도 순서로 환산하지 않는다.성숙도 모델로 두면 「일단 제일 뒤 구조로 가자」는 판단이 나온다. backend 직접 경로를 닫을 수 없는 환경에서 edge에 인증을 맡기면 upstream이 헤더 하나로 사용자를 판단하는데 그 헤더를 누구나 만들어 보낼 수 있다. 그런 환경에서는 브라우저가 token을 직접 들고 서명을 검증받는 구조가 낫다.
- generic [ref=f5e173]:
- heading "영향" [level=3] [ref=f5e174]
- list [ref=f5e175]:
- listitem [ref=f5e176]: 패턴을 비교할 때는 적용 조건과 운영해야 할 상태, 신뢰 경계, 장애 지점을 함께 적는다. 브라우저 token 노출 여부 하나만으로 순서를 매기지 않는다.
- listitem [ref=f5e177]: 구조를 고를 때 번호가 아니라 code 교환·token 보관·API 호출의 배치를 먼저 답한다. 뒤 구조에서 앞 구조로 되돌아가는 선택도 후퇴가 아니라 credential 계약의 변경으로 적는다.
- listitem [ref=f5e178]: 구조 이름만으로 운영 속성을 추정하지 않는다. 공유 저장소와 장애 복구, secret 교체는 매번 따로 확인한다.
- generic [ref=f5e179]:
- heading "근거 기록" [level=3] [ref=f5e180]
- list [ref=f5e181]:
- listitem [ref=f5e182]:
- link "SPA에서 토큰을 직접 관리하면서 드러난 Browser Credential 경계" [ref=f5e183] [cursor=pointer]:
- /url: /cases/spa-browser-credential-boundary
- listitem [ref=f5e184]:
- link "Refresh Token 관리만 서버로 이전, Access Token은 여전히 Browser에 노출" [ref=f5e185] [cursor=pointer]:
- /url: /cases/split-custody-access-token
- listitem [ref=f5e186]:
- link "Browser Token을 없애면서 BFF에 Session과 CSRF 책임이 생긴 과정" [ref=f5e187] [cursor=pointer]:
- /url: /cases/bff-session-csrf-responsibility
- listitem [ref=f5e188]:
- link "Forward-Auth에서 Client가 보낸 Identity Header를 신뢰하면 안 되는 이유" [ref=f5e189] [cursor=pointer]:
- /url: /cases/identity-header-trust
- complementary [ref=f5e190]:
- heading "작업 상태" [level=2] [ref=f5e191]
- status "편집 상태" [ref=f5e192]: 저장됨
- generic [ref=f5e193]:
- generic [ref=f5e194]:
- term [ref=f5e195]: 저장 버전
- definition [ref=f5e196]: "12"
- generic [ref=f5e197]:
- term [ref=f5e198]: 종류
- definition [ref=f5e199]: Decision
- paragraph [ref=f5e200]: 불완전한 초안도 저장할 수 있습니다. Ctrl+S 로도 저장합니다. 게시를 누르면 채워야 할 칸을 그 자리에 표시합니다.
- generic [ref=f5e201]:
- button "저장" [disabled] [ref=f5e202]
- button "게시" [ref=f5e203]
- paragraph [ref=f5e204]: 버전 12으로 저장했습니다.