{ "version": "1.1", "id": "ap4-edge-trust-architecture", "title": "AP4는 공개 edge에서 session을 정제된 upstream identity로 바꾼다", "question": "AP4에서 외부 session 요청은 어떤 공개·비공개 경계를 지나 trusted identity header와 internal token이 되는가?", "type": "network", "direction": "LR", "audience": [ "Forward-auth edge와 upstream 신뢰 경계를 설계하는 개발자" ], "summary": "외부 브라우저 요청은 host-published Nginx에서 internal oauth2-proxy auth subrequest로 검증되고, Nginx가 덮어쓴 identity header와 internal token만 host 비공개 Spring upstream으로 전달된다.", "alt": "외부 브라우저 zone과 Nginx, oauth2-proxy, Spring upstream이 있는 AP4 deployment path를 나눈 edge trust 아키텍처.", "long_description": "왼쪽 외부 브라우저가 AP4_SESSION과 함께 AP4 deployment path의 공개 Nginx entry point를 호출한다. 같은 deployment path에서 Nginx는 host 비공개 oauth2-proxy의 internal /oauth2/auth endpoint에 subrequest를 보내 session을 검증하고 user와 email 결과를 받는다. 이어서 client가 보낸 동명 header를 덮어쓰고 Nginx-owned identity header와 internal token을 host 비공개 Spring upstream의 /edge/me로 전달한다. Upstream은 user header와 internal token을 함께 확인하며 JWT를 직접 입력으로 받지 않는다.", "source_context": { "document": "document.md", "document_sha256": "df4d1a604c74e756672b5b40510abfedb8c67b39af280a5f51985ea9972f5371", "anchor": { "kind": "marker", "value": "ap4-edge-trust-architecture", "line": 182 } }, "composition": { "profile": "two-zone-pipeline", "diagram_only": true, "reference_ids": [ "localization-pipeline" ], "rationale": "외부 browser와 AP4 deployment path의 경계 crossing, 그리고 deployment 내부 Nginx·auth service·upstream 관계가 중심이므로 zone containment와 crossing label을 드러내는 구성이 적합하다.", "focus_node": "nginx" }, "groups": [ { "id": "external-client-zone", "label": "External browser", "kind": "system", "role": "zone", "description": "AP4_SESSION을 애플리케이션의 공개 entry point로 보내는 외부 client 경계.", "evidence": [ { "start_line": 914, "end_line": 919 }, { "start_line": 980, "end_line": 999 } ], "assumption": false }, { "id": "ap4-deployment-zone", "label": "AP4 deployment path", "kind": "system", "role": "zone", "description": "Host-published Nginx와 host 비공개 oauth2-proxy 및 Spring app이 연결되는 deployment 경계.", "evidence": [ { "start_line": 914, "end_line": 914 }, { "start_line": 1093, "end_line": 1093 } ], "assumption": false } ], "nodes": [ { "id": "browser", "label": "Browser", "kind": "actor", "role": "source", "group": "external-client-zone", "shape": "actor", "description": "Opaque AP4_SESSION을 자동 첨부해 공개 edge endpoint를 호출한다.", "details": [ "HttpOnly AP4_SESSION" ], "evidence": [ { "start_line": 980, "end_line": 999 } ], "assumption": false }, { "id": "nginx", "label": "Nginx edge", "kind": "service", "role": "service", "group": "ap4-deployment-zone", "emphasis": "primary", "description": "Internal auth subrequest를 만들고 검증 결과를 allowlisted upstream header로 다시 조립하는 공개 gateway.", "details": [ "auth_request", "client header overwrite" ], "evidence": [ { "start_line": 914, "end_line": 928 }, { "start_line": 1009, "end_line": 1028 } ], "assumption": false }, { "id": "spring-upstream", "label": "Spring upstream", "kind": "service", "role": "sink", "group": "ap4-deployment-zone", "description": "정제된 user header와 Nginx-owned internal token을 함께 검증하는 /edge/me upstream.", "details": [ "X-Auth-Request-User", "X-Auth-Request-Email", "X-Internal-Auth-Token", "/edge/me controller check" ], "evidence": [ { "start_line": 1017, "end_line": 1037 }, { "start_line": 1065, "end_line": 1078 } ], "assumption": false }, { "id": "oauth2-proxy", "label": "oauth2-proxy", "kind": "service", "role": "service", "group": "ap4-deployment-zone", "description": "Confidential edge-proxy client이자 AP4_SESSION의 유효성을 판단하는 host 비공개 auth service.", "details": [ "edge-proxy client", "minimal cookie session", "returns user · email" ], "evidence": [ { "start_line": 940, "end_line": 990 }, { "start_line": 1009, "end_line": 1014 } ], "assumption": false } ], "edges": [ { "id": "browser-to-nginx", "from": "browser", "to": "nginx", "label": "GET /api/edge · AP4_SESSION", "kind": "request", "evidence": [ { "start_line": 994, "end_line": 999 } ], "assumption": false }, { "id": "nginx-to-oauth2-proxy", "from": "nginx", "to": "oauth2-proxy", "label": "internal /oauth2/auth subrequest", "kind": "request", "evidence": [ { "start_line": 922, "end_line": 928 }, { "start_line": 1009, "end_line": 1009 } ], "assumption": false }, { "id": "nginx-to-upstream", "from": "nginx", "to": "spring-upstream", "label": "allowlisted identity + internal token", "kind": "data", "emphasis": "primary", "evidence": [ { "start_line": 1017, "end_line": 1026 }, { "start_line": 1065, "end_line": 1078 } ], "assumption": false } ], "legend": [], "metadata": { "rationale": "Auth subrequest와 upstream forwarding을 한 직선 sequence가 아니라 공개 edge에서 갈라지는 trust topology로 표현했다." } }