{ "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": "e2cc061f683294c937f089ad874cbf7a617f7313c07a92c2148fb11287a0da37", "anchor": { "kind": "heading", "value": "AP4: OAuth를 모르는 upstream 앞에서 신뢰 경로를 만든다", "line": 202 } }, "composition": { "profile": "component-flow", "diagram_only": true, "reference_ids": [ "payment-event-flow" ], "rationale": "경계는 group 으로 남기고 방향이 있는 경로로 그린다 — two-zone-pipeline 은 지역 안쪽 엣지 라벨을 캔버스 위쪽에 고정해 group 테두리를 덮는다.", "focus_node": "nginx" }, "groups": [ { "id": "external-client-zone", "label": "External browser", "kind": "system", "role": "zone", "description": "AP4_SESSION을 애플리케이션의 공개 entry point로 보내는 외부 client 경계.", "evidence": [ { "start_line": 952, "end_line": 957 }, { "start_line": 1018, "end_line": 1039 } ], "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": 952, "end_line": 952 }, { "start_line": 1133, "end_line": 1133 } ], "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": 1018, "end_line": 1039 } ], "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": [ "/api/edge", "auth_request", "client header overwrite" ], "evidence": [ { "start_line": 952, "end_line": 966 }, { "start_line": 1049, "end_line": 1068 } ], "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": 1057, "end_line": 1077 }, { "start_line": 1105, "end_line": 1118 } ], "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": 978, "end_line": 1028 }, { "start_line": 1049, "end_line": 1054 } ], "assumption": false } ], "edges": [ { "id": "browser-to-nginx", "from": "browser", "to": "nginx", "label": "AP4_SESSION", "kind": "request", "evidence": [ { "start_line": 1034, "end_line": 1039 } ], "assumption": false }, { "id": "nginx-to-oauth2-proxy", "from": "nginx", "to": "oauth2-proxy", "label": "auth subrequest", "kind": "request", "evidence": [ { "start_line": 960, "end_line": 966 }, { "start_line": 1049, "end_line": 1049 } ], "assumption": false }, { "id": "nginx-to-upstream", "from": "nginx", "to": "spring-upstream", "label": "identity", "kind": "data", "emphasis": "primary", "evidence": [ { "start_line": 1057, "end_line": 1066 }, { "start_line": 1105, "end_line": 1118 } ], "assumption": false } ], "legend": [], "metadata": { "rationale": "Auth subrequest와 upstream forwarding을 한 직선 sequence가 아니라 공개 edge에서 갈라지는 trust topology로 표현했다." } }