213 lines
6.1 KiB
JSON
213 lines
6.1 KiB
JSON
{
|
|
"version": "1.1",
|
|
"id": "ap4-edge-forward-auth-flow",
|
|
"title": "AP4 proxy session에서 trusted identity JSON까지",
|
|
"question": "AP4에서 AP4_SESSION은 어떤 순서로 검증되고 allowlisted identity header와 internal token을 거쳐 JSON이 되는가?",
|
|
"type": "sequence",
|
|
"direction": "LR",
|
|
"audience": [
|
|
"forward-auth와 upstream header trust를 검토하는 플랫폼 개발자"
|
|
],
|
|
"summary": "Nginx가 oauth2-proxy에 internal auth subrequest를 보내 session을 확인하고, 인증 결과로 client identity header를 덮어쓴 뒤 internal token과 함께 Spring upstream을 호출한다.",
|
|
"alt": "브라우저, Nginx, oauth2-proxy, Spring upstream 사이에서 AP4_SESSION 검증, identity header 덮어쓰기, internal token 검증과 JSON 응답이 이어지는 순서도.",
|
|
"long_description": "브라우저가 AP4_SESSION cookie로 Nginx의 /api/edge를 호출한다. Nginx는 oauth2-proxy의 internal auth endpoint에 subrequest를 보내고 인증된 user와 email 결과를 받는다. 이어서 client가 보낸 동명 header를 사용하지 않고 oauth2-proxy 결과와 Nginx 환경의 internal token으로 /edge/me 요청을 새로 조립한다. Spring controller가 user header와 internal token을 함께 확인해 identity JSON을 만들고 Nginx가 브라우저에 전달한다.",
|
|
"source_context": {
|
|
"document": "document.md",
|
|
"document_sha256": "df4d1a604c74e756672b5b40510abfedb8c67b39af280a5f51985ea9972f5371",
|
|
"anchor": {
|
|
"kind": "marker",
|
|
"value": "ap4-edge-forward-auth-flow",
|
|
"line": 1108
|
|
}
|
|
},
|
|
"composition": {
|
|
"profile": "sequence",
|
|
"diagram_only": true,
|
|
"reference_ids": [
|
|
"payment-approval-sequence"
|
|
],
|
|
"rationale": "외부 요청, auth subrequest, auth 결과, upstream rewrite와 JSON 응답이 엄격한 순서로 이어지므로 sequence 문법이 신뢰 경계의 변환 시점을 가장 잘 보여 준다.",
|
|
"focus_node": "nginx"
|
|
},
|
|
"groups": [],
|
|
"nodes": [
|
|
{
|
|
"id": "browser",
|
|
"label": "브라우저",
|
|
"kind": "participant",
|
|
"role": "participant",
|
|
"description": "AP4_SESSION cookie와 함께 edge endpoint를 호출하는 외부 client.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 992,
|
|
"end_line": 1007
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "nginx",
|
|
"label": "Nginx edge",
|
|
"kind": "participant",
|
|
"role": "participant",
|
|
"emphasis": "primary",
|
|
"description": "Internal auth subrequest를 만들고 인증 결과를 allowlisted upstream header와 internal token으로 재조립한다.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 914,
|
|
"end_line": 939
|
|
},
|
|
{
|
|
"start_line": 1009,
|
|
"end_line": 1028
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "oauth2-proxy",
|
|
"label": "oauth2-proxy",
|
|
"kind": "participant",
|
|
"role": "participant",
|
|
"description": "AP4_SESSION을 검증하고 인증된 user, email과 필요 시 갱신 cookie를 auth response로 돌려준다.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 980,
|
|
"end_line": 990
|
|
},
|
|
{
|
|
"start_line": 1009,
|
|
"end_line": 1015
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "spring-upstream",
|
|
"label": "Spring upstream",
|
|
"kind": "participant",
|
|
"role": "participant",
|
|
"description": "Identity header와 internal token을 함께 검증해 allowlisted identity JSON을 반환한다.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 1017,
|
|
"end_line": 1026
|
|
},
|
|
{
|
|
"start_line": 1030,
|
|
"end_line": 1063
|
|
}
|
|
],
|
|
"assumption": false
|
|
}
|
|
],
|
|
"edges": [
|
|
{
|
|
"id": "edge-request",
|
|
"from": "browser",
|
|
"to": "nginx",
|
|
"label": "GET /api/edge + AP4_SESSION",
|
|
"kind": "request",
|
|
"order": 1,
|
|
"evidence": [
|
|
{
|
|
"start_line": 992,
|
|
"end_line": 999
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "auth-subrequest",
|
|
"from": "nginx",
|
|
"to": "oauth2-proxy",
|
|
"label": "internal /oauth2/auth subrequest",
|
|
"kind": "request",
|
|
"order": 2,
|
|
"evidence": [
|
|
{
|
|
"start_line": 922,
|
|
"end_line": 939
|
|
},
|
|
{
|
|
"start_line": 1009,
|
|
"end_line": 1009
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "auth-result",
|
|
"from": "oauth2-proxy",
|
|
"to": "nginx",
|
|
"label": "authenticated user + email",
|
|
"kind": "response",
|
|
"style": "dashed",
|
|
"order": 3,
|
|
"evidence": [
|
|
{
|
|
"start_line": 1009,
|
|
"end_line": 1015
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "upstream-request",
|
|
"from": "nginx",
|
|
"to": "spring-upstream",
|
|
"label": "GET /edge/me · trusted headers + internal token",
|
|
"kind": "request",
|
|
"emphasis": "primary",
|
|
"order": 4,
|
|
"evidence": [
|
|
{
|
|
"start_line": 1017,
|
|
"end_line": 1026
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "identity-map",
|
|
"from": "spring-upstream",
|
|
"to": "nginx",
|
|
"label": "trusted identity JSON",
|
|
"kind": "response",
|
|
"style": "dashed",
|
|
"order": 5,
|
|
"evidence": [
|
|
{
|
|
"start_line": 1030,
|
|
"end_line": 1048
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "browser-response",
|
|
"from": "nginx",
|
|
"to": "browser",
|
|
"label": "pattern + user + email + identityHeader",
|
|
"kind": "response",
|
|
"style": "dashed",
|
|
"order": 6,
|
|
"evidence": [
|
|
{
|
|
"start_line": 1039,
|
|
"end_line": 1048
|
|
},
|
|
{
|
|
"start_line": 1065,
|
|
"end_line": 1076
|
|
}
|
|
],
|
|
"assumption": false
|
|
}
|
|
],
|
|
"legend": [],
|
|
"metadata": {
|
|
"rationale": "로그인 redirect는 이미 앞 단계에서 설명되므로 authenticated /api/edge 요청의 trust transformation만 표현했다."
|
|
}
|
|
}
|