refactor: 문서 개선 중
This commit is contained in:
@@ -10,14 +10,14 @@ SPA, Keycloak, 브라우저 JavaScript memory, Resource Server가 왼쪽에서
|
||||
|
||||
## Elements and evidence
|
||||
|
||||
- **Public SPA** (service): Authorization Code와 PKCE를 직접 다루고 access JWT로 Resource Server를 호출하는 public OAuth client. Evidence: L144–L148.
|
||||
- **Browser JS memory** (database): Access, refresh, ID token을 실행 중 보관하며 reload 뒤에는 복구하지 않는 browser-side custody. Evidence: L148–L150.
|
||||
- **Keycloak** (service): SPA의 code 교환 상대이며 API가 검증하는 JWT 서명의 출처. Evidence: L144–L146.
|
||||
- **Resource Server** (service): Access JWT의 issuer, 시간 제약과 audience를 검증하는 API. Evidence: L144–L150.
|
||||
- **Public SPA** (service): Authorization Code와 PKCE를 직접 다루고 access JWT로 Resource Server를 호출하는 public OAuth client. Evidence: L168–L172.
|
||||
- **Browser JS memory** (database): Access, refresh, ID token을 실행 중 보관하며 reload 뒤에는 복구하지 않는 browser-side custody. Evidence: L172–L174.
|
||||
- **Keycloak** (service): SPA의 code 교환 상대이며 API가 검증하는 JWT 서명의 출처. Evidence: L168–L170.
|
||||
- **Resource Server** (service): Access JWT의 issuer, 시간 제약과 audience를 검증하는 API. Evidence: L168–L174.
|
||||
|
||||
## Relationships
|
||||
|
||||
- **Keycloak → Public SPA:** access · refresh · ID token. Evidence: L144–L148.
|
||||
- **Public SPA → Keycloak:** Authorization Code + PKCE S256. Evidence: L144–L146.
|
||||
- **Public SPA → Browser JS memory:** token set 보관. Evidence: L148–L150.
|
||||
- **Public SPA → Resource Server:** memory-held access JWT · Bearer. Evidence: L144–L150.
|
||||
- **Keycloak → Public SPA:** access · refresh · ID token. Evidence: L168–L172.
|
||||
- **Public SPA → Keycloak:** Authorization Code + PKCE S256. Evidence: L168–L170.
|
||||
- **Public SPA → Browser JS memory:** token set 보관. Evidence: L172–L174.
|
||||
- **Public SPA → Resource Server:** memory-held access JWT · Bearer. Evidence: L168–L174.
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="n_browser-spa" value="Public SPA<br/>spa-public<br/>PKCE S256" tooltip="Authorization Code와 PKCE를 직접 다루고 access JWT로 Resource Server를 호출하는 public OAuth client. | Evidence: L144-L148" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxCell id="n_browser-spa" value="Public SPA<br/>spa-public<br/>PKCE S256" tooltip="Authorization Code와 PKCE를 직접 다루고 access JWT로 Resource Server를 호출하는 public OAuth client. | Evidence: L168-L172" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
|
||||
<mxGeometry x="70.0" y="208.0" width="150.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_api-resource-server" value="Resource Server<br/>issuer · time<br/>keycloak-pattern-api audience" tooltip="Access JWT의 issuer, 시간 제약과 audience를 검증하는 API. | Evidence: L144-L150" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_api-resource-server" value="Resource Server<br/>issuer · time<br/>keycloak-pattern-api audience" tooltip="Access JWT의 issuer, 시간 제약과 audience를 검증하는 API. | Evidence: L168-L174" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="380.0" y="60.0" width="237.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_browser-token-memory" value="Browser JS memory<br/>access · refresh · ID token<br/>persistent Web Storage 없음" tooltip="Access, refresh, ID token을 실행 중 보관하며 reload 뒤에는 복구하지 않는 browser-side custody. | Evidence: L148-L150" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_browser-token-memory" value="Browser JS memory<br/>access · refresh · ID token<br/>persistent Web Storage 없음" tooltip="Access, refresh, ID token을 실행 중 보관하며 reload 뒤에는 복구하지 않는 browser-side custody. | Evidence: L172-L174" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="387.0" y="220.0" width="223.0" height="88.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="n_keycloak" value="Keycloak" tooltip="SPA의 code 교환 상대이며 API가 검증하는 JWT 서명의 출처. | Evidence: L144-L146" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxCell id="n_keycloak" value="Keycloak" tooltip="SPA의 code 교환 상대이며 API가 검증하는 JWT 서명의 출처. | Evidence: L168-L170" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
|
||||
<mxGeometry x="423.5" y="380.0" width="150.0" height="64.0" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="e_keycloak-to-spa" value="access · refresh · ID token" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_keycloak" target="n_browser-spa">
|
||||
|
||||
+4
-4
@@ -2,22 +2,22 @@
|
||||
"harness_version": "0.2.0",
|
||||
"spec_id": "ap1-direct-architecture",
|
||||
"spec_version": "1.1",
|
||||
"spec_sha256": "ea8f3f861258a68eabe2e902fb8a5b85ce250a68ef5893eefa8701f1b8eb3627",
|
||||
"spec_sha256": "b4cf9b9f65e7caca89b4efea39dbab413c71228f327acb8168e3f053e8bfe9c9",
|
||||
"source_context": {
|
||||
"document": "document.md",
|
||||
"document_sha256": "df4d1a604c74e756672b5b40510abfedb8c67b39af280a5f51985ea9972f5371",
|
||||
"document_sha256": "ea10df24b892e2c57123a37a4b4f0d821e4f394353e6746f50df6a48342353e9",
|
||||
"anchor": {
|
||||
"kind": "marker",
|
||||
"value": "ap1-direct-architecture",
|
||||
"line": 152
|
||||
"line": 176
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
"ap1-direct-architecture.svg",
|
||||
"ap1-direct-architecture.drawio",
|
||||
"ap1-direct-architecture.mmd",
|
||||
"ap1-direct-architecture.d2",
|
||||
"ap1-direct-architecture.dot",
|
||||
"ap1-direct-architecture.drawio",
|
||||
"ap1-direct-architecture.excalidraw",
|
||||
"ap1-direct-architecture.alt.md"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="535" viewBox="0 0 680 535" role="img" aria-labelledby="diagram-title diagram-description">
|
||||
<title id="diagram-title">AP1은 OAuth client와 token custody를 브라우저에 둔다</title>
|
||||
<desc id="diagram-description">왼쪽의 public SPA가 Keycloak과 Authorization Code 및 PKCE S256 계약을 수행한다. Keycloak token 응답의 access, refresh, ID token은 브라우저 JavaScript memory에 놓이며, 그중 access JWT가 오른쪽 Resource Server의 검증 입력이 된다. Resource Server는 issuer, 시간 제약과 keycloak-pattern-api audience를 검증한다.</desc>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"ap1-direct-architecture","profile":"component-flow"},"source_context":{"document":"document.md","document_sha256":"df4d1a604c74e756672b5b40510abfedb8c67b39af280a5f51985ea9972f5371","anchor":{"kind":"marker","value":"ap1-direct-architecture","line":152}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<metadata>{"techviz":{"spec_version":"1.1","id":"ap1-direct-architecture","profile":"component-flow"},"source_context":{"document":"document.md","document_sha256":"ea10df24b892e2c57123a37a4b4f0d821e4f394353e6746f50df6a48342353e9","anchor":{"kind":"marker","value":"ap1-direct-architecture","line":176}},"evidence_policy":"Each factual element cites source lines or is marked assumption.","diagram_only":true}</metadata>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" />
|
||||
@@ -50,41 +50,41 @@
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="canvas" width="680" height="535" />
|
||||
<polyline class="edge kind-response style-dashed emphasis-normal semantic-dashed" points="498.5,444.0 498.5,490.0 145.0,490.0 145.0,296.0" data-evidence="144-148" />
|
||||
<polyline class="edge kind-response style-dashed emphasis-normal semantic-dashed" points="498.5,444.0 498.5,490.0 145.0,490.0 145.0,296.0" data-evidence="168-172" />
|
||||
<rect class="edge-label-bg" x="148.3" y="448.0" width="198.9" height="22" rx="3" />
|
||||
<text class="edge-label" x="247.8" y="463.0">access · refresh · ID token</text>
|
||||
<polyline class="edge kind-request style-solid emphasis-normal" points="220.0,279.0 331.8,279.0 331.8,421.0 423.5,421.0" data-evidence="144-146" />
|
||||
<polyline class="edge kind-request style-solid emphasis-normal" points="220.0,279.0 331.8,279.0 331.8,421.0 423.5,421.0" data-evidence="168-170" />
|
||||
<rect class="edge-label-bg" x="198.2" y="326.0" width="219.0" height="22" rx="3" />
|
||||
<text class="edge-label" x="307.8" y="341.0">Authorization Code + PKCE S256</text>
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="220.0,243.0 303.5,243.0 303.5,264.0 387.0,264.0" data-evidence="148-150" />
|
||||
<polyline class="edge kind-data style-solid emphasis-normal" points="220.0,243.0 303.5,243.0 303.5,264.0 387.0,264.0" data-evidence="172-174" />
|
||||
<rect class="edge-label-bg" x="278.3" y="239.5" width="98.4" height="22" rx="3" />
|
||||
<text class="edge-label" x="327.5" y="254.5">token set 보관</text>
|
||||
<polyline class="edge kind-request style-solid emphasis-primary" points="220.0,225.0 300.0,225.0 300.0,104.0 380.0,104.0" data-evidence="144-150" />
|
||||
<polyline class="edge kind-request style-solid emphasis-primary" points="220.0,225.0 300.0,225.0 300.0,104.0 380.0,104.0" data-evidence="168-174" />
|
||||
<rect class="edge-label-bg" x="211.1" y="150.5" width="225.7" height="22" rx="3" />
|
||||
<text class="edge-label" x="324.0" y="165.5">memory-held access JWT · Bearer</text>
|
||||
<g id="node-browser-spa">
|
||||
<rect class="node-shape kind-service emphasis-primary role-source" data-evidence="144-148" x="70.0" y="208.0" width="150.0" height="88.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-primary role-source" data-evidence="168-172" x="70.0" y="208.0" width="150.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="145.0" y="235.0">Public SPA</text>
|
||||
<line class="node-detail-divider" x1="84.0" y1="256.0" x2="206.0" y2="256.0" />
|
||||
<text class="node-detail" x="86.0" y="273.0">spa-public</text>
|
||||
<text class="node-detail" x="86.0" y="289.0">PKCE S256</text>
|
||||
</g>
|
||||
<g id="node-api-resource-server">
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="144-150" x="380.0" y="60.0" width="237.0" height="88.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-sink" data-evidence="168-174" x="380.0" y="60.0" width="237.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="498.5" y="87.0">Resource Server</text>
|
||||
<line class="node-detail-divider" x1="394.0" y1="108.0" x2="603.0" y2="108.0" />
|
||||
<text class="node-detail" x="396.0" y="125.0">issuer · time</text>
|
||||
<text class="node-detail" x="396.0" y="141.0">keycloak-pattern-api audience</text>
|
||||
</g>
|
||||
<g id="node-browser-token-memory">
|
||||
<rect class="node-shape kind-database emphasis-normal role-store" data-evidence="148-150" x="387.0" y="220.0" width="223.0" height="88.0" rx="7" />
|
||||
<rect class="node-shape kind-database emphasis-normal role-store" data-evidence="172-174" x="387.0" y="220.0" width="223.0" height="88.0" rx="7" />
|
||||
<text class="node-label" x="498.5" y="247.0">Browser JS memory</text>
|
||||
<line class="node-detail-divider" x1="401.0" y1="268.0" x2="596.0" y2="268.0" />
|
||||
<text class="node-detail" x="403.0" y="285.0">access · refresh · ID token</text>
|
||||
<text class="node-detail" x="403.0" y="301.0">persistent Web Storage 없음</text>
|
||||
</g>
|
||||
<g id="node-keycloak">
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="144-146" x="423.5" y="380.0" width="150.0" height="64.0" rx="7" />
|
||||
<rect class="node-shape kind-service emphasis-normal role-service" data-evidence="168-170" x="423.5" y="380.0" width="150.0" height="64.0" rx="7" />
|
||||
<text class="node-label" x="498.5" y="410.0">Keycloak</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Reference in New Issue
Block a user