The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
67 lines
3.9 KiB
Plaintext
67 lines
3.9 KiB
Plaintext
# B-4 ③ — IdP 의 클레임 변경은 언제 upstream 에 반영되는가
|
|
#
|
|
# 이 파일은 재수집본이다. 첫 수집본은 "이제 요청을 반복해 본다" 에서 끝났고,
|
|
# 그 뒤의 12회 결과는 브라우저 콘솔에서만 보고 파일로 남기지 않았다.
|
|
# 서브에이전트 감사가 "증거 없이 서 있는 결론" 으로 지적했고, 다시 측정했다.
|
|
#
|
|
# 수집 방법:
|
|
# - 요청부: Playwright 로 연 브라우저에서 fetch('/api/echo') 를 반복.
|
|
# oauth2-proxy 세션 쿠키가 HttpOnly 라 curl 로는 재현할 수 없어 브라우저를 썼다.
|
|
# 아래 출력은 브라우저 콘솔이 돌려준 문자열 그대로다.
|
|
# - 변경부·저장소 확인부: test-server 의 kubectl 출력 그대로.
|
|
|
|
=== [1] 기준선 — 변경 전 (브라우저 fetch) ===
|
|
2026-09-04T07:51:23.862Z req#1 HTTP 200 x-forwarded-email=labuser@example.com x-forwarded-preferred-username=labuser
|
|
2026-09-04T07:51:24.304Z req#2 HTTP 200 x-forwarded-email=labuser@example.com x-forwarded-preferred-username=labuser
|
|
2026-09-04T07:51:24.722Z req#3 HTTP 200 x-forwarded-email=labuser@example.com x-forwarded-preferred-username=labuser
|
|
|
|
=== [2] IdP 에서 email 을 바꾼다 (kubectl 출력) ===
|
|
변경 시각(UTC): 2026-09-04T07:53:32.000Z
|
|
IdP 의 값:
|
|
[ {
|
|
"email" : "changed-labuser@example.com"
|
|
} ]
|
|
oauth2-proxy 세션: 1 개 (그대로 살아 있다)
|
|
|
|
=== [시계 보정] 두 시계가 다르다 — 해석에 필요하다 ===
|
|
개발 머신(브라우저 fetch 의 타임스탬프): 2026-09-04T07:52:20Z
|
|
test-server (kubectl 출력의 타임스탬프): 2026-09-04T07:54:07Z
|
|
→ test-server 가 약 107초 앞선다.
|
|
브라우저 07:51:56 = 서버 07:53:43 이므로, 아래 12회는 변경(07:53:32) 11초 뒤다.
|
|
|
|
=== [3] 변경 후 12회 반복 (브라우저 fetch) ===
|
|
2026-09-04T07:51:56.300Z req#1 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:51:56.864Z req#2 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:51:57.489Z req#3 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:51:58.018Z req#4 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:51:58.602Z req#5 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:51:59.217Z req#6 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:51:59.743Z req#7 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:52:00.342Z req#8 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:52:00.964Z req#9 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:52:01.574Z req#10 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:52:02.187Z req#11 HTTP 200 x-forwarded-email=labuser@example.com
|
|
2026-09-04T07:52:02.719Z req#12 HTTP 200 x-forwarded-email=labuser@example.com
|
|
|
|
→ 12회 · 약 6.4초 동안 전부 옛 값. 요청 횟수로는 반영되지 않는다.
|
|
|
|
=== [4] IdP 값은 이미 바뀌어 있었다 (대조) ===
|
|
IdP: "email" : "changed-labuser@example.com"
|
|
|
|
=== [5] 세션을 지워 재인증을 강제한다 ===
|
|
남은 oauth2-proxy 세션: 0 개
|
|
(Keycloak SSO 는 살아 있으므로 조용히 재인증된다)
|
|
|
|
=== [6] 재인증 후 (브라우저 fetch) ===
|
|
2026-09-04T07:53:01.121Z req#1 HTTP 200 x-forwarded-email=changed-labuser@example.com
|
|
2026-09-04T07:53:01.456Z req#2 HTTP 200 x-forwarded-email=changed-labuser@example.com
|
|
2026-09-04T07:53:01.785Z req#3 HTTP 200 x-forwarded-email=changed-labuser@example.com
|
|
|
|
=== 결론 ===
|
|
변경 후 12회 요청(6.4초) → labuser@example.com (옛 값)
|
|
세션 삭제 후 재인증 → changed-labuser@example.com (새 값)
|
|
|
|
→ 반영 시점은 요청 횟수가 아니라 세션이 새로 만들어지는가로 정해진다.
|
|
--cookie-refresh 가 설정되어 있지 않으므로, 실제 운영에서는
|
|
쿠키 만료(1시간) 또는 재인증까지 옛 값이 간다.
|