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>
4.8 KiB
kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, assets, evidence, source, module, priority
| kind | slug | title | topic | project | status | sourceRevision | rootTreeNode | evidenceCapturedOn | assets | evidence | source | module | priority | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CASE | grpc-advanced-diagnostics-f01 | 마스킹이 IPv4 만 알고, 그 결과 "마스킹되지 않은 주소" 검사가 나머지 형태를 전부 통과시킨다 | security-policy-enforcement | clean-architecture-backend-template | 게시 전 | 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 | case:grpc-advanced-diagnostics-f01 | 2026-09-01 |
|
|
|
grpc-advanced-diagnostics | P2 |
마스킹이 IPv4 만 알고, 그 결과 "마스킹되지 않은 주소" 검사가 나머지 형태를 전부 통과시킨다
IPv4 가 아닌 주소는 패턴에 맞지 않아 입력 그대로 반환된다. 그리고 스냅숏 생성자의 검사는 이렇게 되어 있다.
문제
IPv4 가 아닌 주소는 패턴에 맞지 않아 입력 그대로 반환된다.
그리고 스냅숏 생성자의 검사는 이렇게 되어 있다.
결론
마스킹 결과가 입력과 같으면 이미 마스킹된 것으로 판정한다.
그러므로 IPv4 가 아닌 주소는 전부 이 검사를 통과한다.
세 번째와 네 번째가 문제다.
이 플랫폼이 겨냥하는 배포 형태가 쿠버네티스이고(grpc-discovery 전체가 그 주제다), 헤드리스 레코드의 엔드포인트는 파드 DNS 이름이며 이중 스택 클러스터에서는 IPv6 주소다.
편집기가 막으려 한 것이 정확히 그것이다 — "a diagnostics endpoint that publishes peer addresses publishes every tenant's connection." unix 소켓 경로도 통과한다.
그것은 호스트 파일 시스템 경로다.
테스트의 주소 리터럴이 전부 IPv4 다 — 10.4.13.201:9090 · 10.9.13.201 · 10.4.x.x · 10.5.x.x.
IPv6 도 호스트 이름도 없다.
검증 환경
OpenJDK : 21.0.12 java -version 으로 확인 Gradle : 9.0.0 src/gradle/wrapper/gradle-wrapper.properties 의 distributionUrl 로 확인 확인 방식 : 마스킹 정규식이 받는 주소 형태와 스냅숏 생성자의 판정 조건 대조 소스 수정 : x
재현 조건
원문은 analysis/grpc/grpc-advanced-diagnostics.md#L167 에 있다.
본문
IPv4 가 아닌 주소는 패턴에 맞지 않아 입력 그대로 반환된다. 그리고 스냅숏 생성자의 검사는 마스킹 결과가 입력과 같으면 이미 마스킹된 것으로 판정한다.
마스킹이 아는 형태
:::evidence key="grpc-advanced-diagnostics-f01-diagram" alt="IPv4 점 십진만 마스킹 대상 안에 놓이고 IPv6 주소와 호스트 이름 및 unix 경로가 바깥에 빗금으로 놓인다" caption="마스킹이 아는 형태" zoom="false" :::
그러므로 IPv4 가 아닌 주소는 전부 이 검사를 통과한다.
마스킹되지 않은 입력이 통과하는 이유
:::evidence key="grpc-advanced-diagnostics-f01" alt="분석 문서 analysis/grpc/grpc-advanced-diagnostics.md 에서 이 기록의 근거 절을 그대로 잘라낸 15줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="analysis/grpc/grpc-advanced-diagnostics.md 발췌 — 15줄" zoom="true" :::
셋째와 넷째가 문제다
이 플랫폼이 겨냥하는 배포 형태가 쿠버네티스이고(grpc-discovery 전체가 그 주제다), 헤드리스 레코드의 엔드포인트는 파드 DNS 이름이며 이중 스택 클러스터에서는 IPv6 주소다. 편집기가 막으려 한 것이 정확히 그것이다 — "a diagnostics endpoint that publishes peer addresses publishes every tenant's connection." unix 소켓 경로도 통과하는데, 그것은 호스트 파일 시스템 경로다.
테스트의 주소 리터럴이 전부 IPv4 다
10.4.13.201:9090 · 10.9.13.201 · 10.4.x.x · 10.5.x.x. IPv6 도 호스트 이름도 없다.
수정
마스킹을 형태별로 나눈다 — IPv6 는 앞 두 그룹만 남기고 나머지를 :x:x 로, 호스트 이름은 최상위 라벨 몇 개만 남기고, 그 밖의 형태는 unknown 으로 접는다. 그리고 검사를 "결과가 입력과 같으면 통과" 가 아니라 "알려진 마스킹 형태와 일치해야 통과" 로 뒤집는다. 지금 형태는 마스킹이 모르는 입력을 전부 안전하다고 판정한다.
확인하지 못한 것
IPv6 주소로 스냅숏을 만들어 실행으로 재현하지 않았다. 정규식과 생성자 검사로 판정했다. 실제 Channelz 서비스를 띄우지 않았다.