Files
llm-wiki/raw/diagrams/keycloak-patterns/archived/architecture-p3a-single-ec2-no-google-2026-05-26-v1.drawio
T

114 lines
10 KiB
Plaintext

<mxfile host="Claude Code" agent="ca-superpowers" version="24.0.0" type="device">
<diagram name="P3A-Single-EC2-no-Google" id="p3a-overall">
<mxGraphModel dx="1422" dy="800" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1400" pageHeight="900" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<!-- TITLE -->
<mxCell id="title" value="P3A — Single EC2 (no Google)&#10;vanilla JS SPA + Spring Boot Resource Server + Keycloak (localhost)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;fontStyle=1;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" vertex="1" parent="1">
<mxGeometry x="40" y="20" width="900" height="50" as="geometry" />
</mxCell>
<!-- EXTERNAL: User -->
<mxCell id="grp-external" value="클러스터 외부 (Internet)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#F6F8FA;strokeColor=#D0D7DE;strokeWidth=1;dashed=1;fontSize=12;fontStyle=1;fontFamily=Pretendard,Helvetica;fontColor=#57606A;align=left;verticalAlign=top;spacingLeft=12;spacingTop=8;" vertex="1" parent="1">
<mxGeometry x="40" y="90" width="240" height="700" as="geometry" />
</mxCell>
<mxCell id="user" value="User&#10;Browser&#10;(SPA 호출 + OIDC redirect)" style="ellipse;whiteSpace=wrap;html=1;fillColor=#FFFFFF;strokeColor=#57606A;strokeWidth=1;fontSize=12;fontStyle=0;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="80" y="380" width="160" height="100" as="geometry" />
</mxCell>
<!-- TRUST BOUNDARY: Single EC2 -->
<mxCell id="grp-ec2" value="Trust Boundary: Single EC2 (localhost containers)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FBFCFD;strokeColor=#1F6FEB;strokeWidth=2;dashed=0;fontSize=13;fontStyle=1;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;align=left;verticalAlign=top;spacingLeft=12;spacingTop=8;" vertex="1" parent="1">
<mxGeometry x="320" y="90" width="1000" height="700" as="geometry" />
</mxCell>
<!-- nginx -->
<mxCell id="nginx" value="&lt;b&gt;nginx&lt;/b&gt;&#10;static SPA serving&#10;+ reverse proxy&#10;&#10;:443 (or :80)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFF7ED;strokeColor=#FB923C;strokeWidth=1;fontSize=11;fontStyle=0;fontFamily=Pretendard,Helvetica;fontColor=#C2410C;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="380" y="140" width="220" height="100" as="geometry" />
</mxCell>
<!-- Backend -->
<mxCell id="backend" value="&lt;b&gt;Spring Boot&lt;/b&gt;&#10;Resource Server&#10;Spring Security 6.x&#10;JWT validator (iss, aud, exp)&#10;&#10;localhost:8080" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#D4EDDA;strokeColor=#155724;strokeWidth=1;fontSize=11;fontStyle=0;fontFamily=Pretendard,Helvetica;fontColor=#155724;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="850" y="140" width="240" height="120" as="geometry" />
</mxCell>
<!-- Keycloak -->
<mxCell id="keycloak" value="&lt;b&gt;Keycloak 25.x&lt;/b&gt;&#10;Authorization Server&#10;KC_HOSTNAME=&amp;lt;public-host&amp;gt;&#10;&#10;localhost:8180" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#CFE2FF;strokeColor=#0D6EFD;strokeWidth=1;fontSize=11;fontStyle=0;fontFamily=Pretendard,Helvetica;fontColor=#0D6EFD;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="380" y="400" width="260" height="120" as="geometry" />
</mxCell>
<!-- PostgreSQL -->
<mxCell id="postgres" value="&lt;b&gt;PostgreSQL 16&lt;/b&gt;&#10;Keycloak 백엔드 DB&#10;&#10;localhost:5432" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#F8D7DA;strokeColor=#842029;strokeWidth=1;fontSize=11;fontStyle=0;fontFamily=Pretendard,Helvetica;fontColor=#842029;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="900" y="420" width="180" height="100" as="geometry" />
</mxCell>
<!-- EDGES -->
<!-- User <-> nginx (HTTPS) -->
<mxCell id="e-user-nginx" value="HTTPS :443&#10;GET / + GET /api/v1/*&#10;Bearer access_token" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.3;exitDx=0;exitDy=0;entryX=0;entryY=0.4;entryDx=0;entryDy=0;strokeColor=#0969DA;strokeWidth=2;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#0969DA;" edge="1" parent="1" source="user" target="nginx">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-nginx-user" value="static SPA&#10;(HTML/JS/CSS)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.7;exitDx=0;exitDy=0;entryX=1;entryY=0.6;entryDx=0;entryDy=0;strokeColor=#57606A;strokeWidth=1;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#57606A;dashed=1;" edge="1" parent="1" source="nginx" target="user">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- User <-> Keycloak (OIDC browser redirect) -->
<mxCell id="e-user-kc" value="OIDC Authorization Code + PKCE&#10;(browser redirect)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.7;exitDx=0;exitDy=0;entryX=0;entryY=0.3;entryDx=0;entryDy=0;strokeColor=#0D6EFD;strokeWidth=2;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#0D6EFD;" edge="1" parent="1" source="user" target="keycloak">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e-kc-user" value="{access_token, refresh_token, id_token}" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.7;exitDx=0;exitDy=0;entryX=1;entryY=0.85;entryDx=0;entryDy=0;strokeColor=#57606A;strokeWidth=1;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#57606A;dashed=1;" edge="1" parent="1" source="keycloak" target="user">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- nginx -> Backend (reverse proxy) -->
<mxCell id="e-nginx-backend" value="reverse proxy&#10;localhost:8080" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#155724;strokeWidth=2;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#155724;" edge="1" parent="1" source="nginx" target="backend">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Backend -> Keycloak (JWKS) -->
<mxCell id="e-backend-kc" value="JWKS&#10;(localhost:8180/realms/.../certs)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.3;exitY=1;exitDx=0;exitDy=0;entryX=0.7;entryY=0;entryDx=0;entryDy=0;strokeColor=#155724;strokeWidth=1;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#155724;dashed=1;" edge="1" parent="1" source="backend" target="keycloak">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Keycloak -> PostgreSQL (JDBC) -->
<mxCell id="e-kc-pg" value="JDBC&#10;(localhost:5432)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#842029;strokeWidth=2;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#842029;" edge="1" parent="1" source="keycloak" target="postgres">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- LEGEND -->
<mxCell id="grp-legend" value="Legend / 범례" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFFF;strokeColor=#D0D7DE;strokeWidth=1;dashed=0;fontSize=11;fontStyle=1;fontFamily=Pretendard,Helvetica;fontColor=#24292F;align=left;verticalAlign=top;spacingLeft=10;spacingTop=6;" vertex="1" parent="1">
<mxGeometry x="900" y="620" width="400" height="160" as="geometry" />
</mxCell>
<mxCell id="legend-ext" value="외부 (Internet) — 점선 테두리" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#F6F8FA;strokeColor=#D0D7DE;dashed=1;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#57606A;" vertex="1" parent="1">
<mxGeometry x="920" y="650" width="180" height="22" as="geometry" />
</mxCell>
<mxCell id="legend-tb" value="Trust Boundary — 파란 실선" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FBFCFD;strokeColor=#1F6FEB;strokeWidth=2;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#1F6FEB;" vertex="1" parent="1">
<mxGeometry x="920" y="680" width="180" height="22" as="geometry" />
</mxCell>
<mxCell id="legend-proxy" value="Edge proxy (nginx) — 주황" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFF7ED;strokeColor=#FB923C;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#C2410C;" vertex="1" parent="1">
<mxGeometry x="920" y="710" width="180" height="22" as="geometry" />
</mxCell>
<mxCell id="legend-backend" value="Backend (Spring Boot) — 초록" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#D4EDDA;strokeColor=#155724;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#155724;" vertex="1" parent="1">
<mxGeometry x="1110" y="650" width="180" height="22" as="geometry" />
</mxCell>
<mxCell id="legend-kc" value="Auth Server (Keycloak) — 파랑" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#CFE2FF;strokeColor=#0D6EFD;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#0D6EFD;" vertex="1" parent="1">
<mxGeometry x="1110" y="680" width="180" height="22" as="geometry" />
</mxCell>
<mxCell id="legend-db" value="DB (PostgreSQL) — 빨강" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#F8D7DA;strokeColor=#842029;fontSize=10;fontFamily=Pretendard,Helvetica;fontColor=#842029;" vertex="1" parent="1">
<mxGeometry x="1110" y="710" width="180" height="22" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>