feat: 가상화 문서들 추가

This commit is contained in:
DongHyeonka
2026-09-10 08:54:05 +09:00
parent e9f6a93327
commit 43e1aadef0
695 changed files with 153404 additions and 12754 deletions
+23 -45
View File
@@ -82,22 +82,15 @@ AP3와 AP4를 처음 보았을 때는 JavaScript가 OAuth token을 받지 않으
그래서 이 글에서 “브라우저에 없다”는 표현은 애플리케이션이 사용하는 OAuth token에만 쓰기로 했습니다. IdP의 SSO 상태까지 없다는 뜻은 아닙니다. 반대로 AP1이 Web Storage에 token을 쓰지 않는다고 JavaScript에서 token이 사라지는 것도 아니었습니다. Access·refresh·ID token은 실행 중 memory에 있었습니다. 악성 script는 같은 화면에서 fetch를 가로채거나 사용자를 대신해 API를 부를 수 있었습니다. Memory-only로 줄어드는 것은 새로고침 뒤에도 남는 복사본이지 실행 중 XSS의 권한은 아니었습니다.
<!-- techviz:begin id=credential-custody-map context-sha256=df4d1a604c74e756672b5b40510abfedb8c67b39af280a5f51985ea9972f5371 -->
| 패턴 | OAuth credential 은 어디로 가나? | 브라우저에 남는 것은? | 보관 모델은? | 지금 입증된 운영 범위는? |
|---|---|---|---|---|
| AP1 | token 3종이 JavaScript 로 | 실행 중 JS 가 읽음 | runtime memory | 영속 Web Storage 없음 |
| AP2 | refresh 가 mediator 로 | session cookie | server-side state | shared store 미입증 |
| AP3 | refresh 가 BFF 로 | HttpOnly session | session + readable XSRF | shared store 미입증 |
| AP4 | JavaScript 가 받지 않음 | proxy session | minimal client-side | secret 공유·회전 미검증 |
<!-- techviz:generate id=credential-custody-map -->
![AP1부터 AP4까지 OAuth credential 소유자, 브라우저 credential, 보관 모델과 현재 입증된 운영 범위를 같은 네 축으로 정렬한 비교 다이어그램.](assets/credential-custody-map/credential-custody-map.svg)
<details>
<summary>Diagram description</summary>
왼쪽부터 AP1, AP2, AP3, AP4를 읽습니다. 각 항목은 OAuth credential 소유자, 브라우저에 남는 애플리케이션 credential, 보관 모델, shared durability나 replica 운영에 관한 현재 근거를 같은 순서로 제시합니다. AP1의 access·refresh·ID token은 실행 중 JavaScript memory에 있고 persistent Web Storage 복사본만 줄입니다. AP2는 refresh token을 mediator가 소유하고 server session 식별 cookie를 사용하지만 shared durable store는 입증되지 않았습니다. AP3는 refresh token을 BFF가 소유하며 브라우저에는 HttpOnly session과 readable XSRF token이 남습니다. AP4는 minimal client-side proxy session을 사용하고 replica cookie secret 공유와 rotation은 검증되지 않았습니다.
</details>
[Editable source](assets/credential-custody-map/credential-custody-map.drawio) · [Grounded VizSpec](.techviz/credential-custody-map/spec.json)
<!-- techviz:end id=credential-custody-map -->
Credential 은 사라지지 않고 owner 와 형태가 바뀝니다. AP1 의 세 token 은 실행 중 JavaScript memory 에
있고 persistent Web Storage 복사본만 줄입니다.
### 현재 구현은 운영 참조 아키텍처가 아니라 관찰 가능한 학습 환경이다
@@ -145,22 +138,15 @@ AP2의 PKCE 칸은 다른 패턴과 똑같이 채우지 않았습니다. “Auth
| AP3 | `AP3_SESSION`; POST에는 `X-XSRF-TOKEN` 추가 | BFF가 authorized client에서 access token을 읽고 downstream Bearer header 생성 | BFF가 보낸 Bearer JWT | BFF가 중계한 JSON |
| AP4 | `AP4_SESSION` | Nginx auth subrequest, oauth2-proxy의 user·email 결과, 배포 secret | 정제된 identity header + internal token | `/edge/me`가 만든 identity JSON |
<!-- techviz:begin id=four-pattern-request-boundaries context-sha256=df4d1a604c74e756672b5b40510abfedb8c67b39af280a5f51985ea9972f5371 -->
| 패턴 | 브라우저가 보내는 입력은? | 중간에서 무엇이 바뀌나? | 보호 자원이 받는 것은? | 브라우저가 받는 출력은? |
|---|---|---|---|---|
| AP1 · SPA direct | Bearer access token | 없음 | 동일 Bearer JWT | `/api/me` JSON |
| AP2 · token mediator | session 뒤 Bearer | access JSON 반환 | browser-created JWT | token JSON + `/api/me` |
| AP3 · BFF | `AP3_SESSION` | BFF 가 Bearer 생성 | BFF Bearer JWT | 중계된 JSON |
| AP4 · edge forward-auth | `AP4_SESSION` | auth 결과 투영 | identity header + internal token | `/edge/me` JSON |
<!-- techviz:generate id=four-pattern-request-boundaries -->
![AP1, AP2, AP3, AP4의 브라우저 입력, 중간 변환, 보호 자원 credential과 브라우저 출력을 같은 네 축으로 비교한 다이어그램.](assets/four-pattern-request-boundaries/four-pattern-request-boundaries.svg)
<details>
<summary>Diagram description</summary>
왼쪽부터 AP1 SPA direct, AP2 token mediator, AP3 BFF, AP4 edge forward-auth를 읽습니다. 각 항목은 브라우저가 보내는 입력, 중간 계층의 변환, 보호 자원이 실제로 받는 credential, 브라우저가 받는 출력을 같은 순서로 보여 줍니다. AP1과 AP2는 브라우저가 Bearer JWT로 API를 직접 호출하고, AP3는 BFF가 Bearer JWT를 조립하며, AP4는 Nginx가 인증 결과를 identity header와 internal token으로 바꿉니다.
</details>
[Editable source](assets/four-pattern-request-boundaries/four-pattern-request-boundaries.drawio) · [Grounded VizSpec](.techviz/four-pattern-request-boundaries/spec.json)
<!-- techviz:end id=four-pattern-request-boundaries -->
AP1 과 AP2 는 브라우저가 Bearer JWT 로 API 를 직접 호출하고, AP3 는 BFF 가 Bearer JWT 를 조립하며,
AP4 는 Nginx 가 인증 결과를 identity header 와 internal token 으로 바꿉니다.
### AP1에서 막히는 지점: protocol 투명성과 browser credential
@@ -1496,22 +1482,14 @@ AP3에서 AP4로 옮기는 일은 한 단계 업그레이드가 아니었습니
반대로 AP4의 upstream이 더 많은 claim과 애플리케이션 흐름을 요구하기 시작하면 BFF로 돌아갈 수 있었습니다. Header 종류를 계속 늘리는 것보다 API 조합 책임을 애플리케이션에 돌려주는 편이 명확할 수 있었습니다. 저는 어느 쪽으로 옮길지를 번호로 판단하지 않았습니다. 새로 일을 맡는 곳이 state와 검증을 감당할 수 있는지를 보았습니다.
<!-- techviz:begin id=credential-contract-migration context-sha256=df4d1a604c74e756672b5b40510abfedb8c67b39af280a5f51985ea9972f5371 -->
| 이동 | 호출 계약은? | 책임 소유자는? | 브라우저는? | 운영에서 더 할 일은? | 성격은? |
|---|---|---|---|---|---|
| AP1 → AP2 | Bearer API 유지 | callback 이 mediator 로 | access API + session | CORS 를 AP2 UI 로 | callback 재배치 |
| AP2 → AP3 | direct API 가 `/bff/**` 로 | UI API 가 BFF 로 | `/token/access` 제거 | error mapping + CSRF | direct path 제거 |
| AP3 → AP4 | API 조합이 identity 로 | app session 이 edge 로 | identity projection | 인가를 upstream·policy 로 | upgrade 아님 |
| AP4 → AP3 | header 가 BFF workflow 로 | claims·workflow 가 BFF 로 | app workflow | state + verification | 역방향 가능 |
<!-- techviz:generate id=credential-contract-migration -->
![AP1에서 AP2, AP2에서 AP3, AP3에서 AP4, AP4에서 AP3로 이동할 때 호출 계약, 소유권, 브라우저 계약, 운영 책임과 전환 성격을 같은 다섯 축으로 비교한 네 항목.](assets/credential-contract-migration/credential-contract-migration.svg)
<details>
<summary>Diagram description</summary>
네 항목을 호출 계약, 소유권, 브라우저 계약, 운영 책임, 전환 성격의 다섯 축으로 비교합니다. AP1에서 AP2는 Resource Server의 Bearer 계약을 유지하면서 OAuth callback을 mediator로 옮깁니다. AP2에서 AP3는 browser의 access endpoint와 direct API 호출을 없애고 UI API를 BFF 계약으로 바꿉니다. AP3에서 AP4는 application-owned session과 orchestration을 edge-owned session과 identity projection으로 전환합니다. AP4에서 AP3로 되돌아가는 선택도 별도 항목으로 두어 번호 순서나 성숙도 상승을 암시하지 않습니다.
</details>
[Editable source](assets/credential-contract-migration/credential-contract-migration.drawio) · [Grounded VizSpec](.techviz/credential-contract-migration/spec.json)
<!-- techviz:end id=credential-contract-migration -->
패턴 이동은 기능 추가가 아니라 credential contract 의 소유권 전환입니다.
## 결국 지키려던 것은 무엇이었나