Files
keycloak-pattern/docs/guides/experiments/README.md
T
DongHyeonkaandClaude Opus 5 6f6ab86345 docs(guides): reproduction guides for all 26 experiments
Written by subagents running under the writing-practitioner-guides skill,
one guide per experiment, 22,566 lines. Each walks a reader from baseline
capture through injection, injection verification, observation and recovery.

Section 3 carries the weight in most of them. Injection failed silently nine
times in this lab, and a failed injection looks exactly like no effect — so
the guides verify the target is actually in the intended state before
reading any result. A-4 makes virsh list the only proof because the node
reads Ready for 40 seconds after the machine is off; A-5 makes the packet
counter the sole go/no-go because a rule on the wrong node produces an empty
result that reads like a finding; A-6 quotes the run where 적용완료 was
printed between four Cannot find device "eth0" lines.

The traps the guides are built around are ones that invert a conclusion
rather than merely annoy:

  A-0   emptying the session table without a restart leaves cache entries
        that get counted as replication arriving
  A-2   dropping -o /dev/null fuses body and status into one string
  A-3   presence of "ready to accept connections" instead of its timestamp
  B-2   row count alone reads an UPDATE as nothing having happened
  B-4   tr ',' '\n' splits ["admin","editor"] so only admin is seen
  B-7   no login screen means the cookie died and SSO re-authenticated
  C-1   counting sessions without joining realm counts your own kcadm one
  D-1   kubectl exec without -i restores nothing and still exits 0
  D-4a  "ran with error output" is what success looks like

Every quoted block is copied from docs/evidence/ and marked 실측; reshaped
commands are marked 미검증 rather than passed off as measured. Where a source
document carries a ★ correction the guides follow the corrected claim — A-7's
REVOKED_TOKEN hypothesis, C-1's session count, B-2's schema attribution.

Two hazards are stated rather than smoothed over: B-6 deletes a key that
cannot be recreated, and D-1/D-4 need host sudo, which asks for a password,
so those steps say a person must type them.

Audit over all 26: 672 interpretation pairs, 486 evidence citations, 117
undo sections, and zero occurrences of the patterns the skill forbids —
no python data processing, no deprecated kubectl get endpoints, no
placeholders, no bare kcadm.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 18:29:00 +09:00

5.7 KiB

실험 재현 가이드 26편

각 편은 직접 쳐서 재현하는 문서다. 무엇을 발견했는지는 docs/experiment-*.md 가 적고, 여기는 그것을 다시 만들려면 무엇을 어떤 순서로 치는가를 적는다.

전제

기반 7단계가 끝나 있어야 한다. 특히 05 까지는 모든 실험의 공통 전제이고, 지표를 보는 실험은 06 도 필요하다.

각 편의 구조

이 가이드가 끝나면 · 전제 · 주의 · 표시 규약
0  왜 이 실험인가
1  기준선          ← 주입 전에 평시를 잡는다
2  주입
3  주입 검증        ← 여기가 대부분의 편에서 가장 중요하다
4  관찰
5  복구
막히면 · 다음

3번이 핵심인 편이 많다. 이 실험대에서 주입은 아홉 번 조용히 실패했고, 실패한 주입은 「아무 일도 없었다」로 보여 「영향이 없다」와 구별되지 않는다. 그래서 결과를 읽기 전에 대상이 실제로 그 상태인지를 따로 확인한다.

표시 규약

표시
실측 증거 파일에 있는 출력 원문. 그대로 나온다
형태 모양만 같고 값은 환경마다 다르다
미검증 손으로 치기 좋게 고쳐 쓴 형태. 원래 실행에서 그대로 쓰이지는 않았다

A층 — Keycloak 자체가 깨질 때

가이드 무엇을 직접 보게 되나
A-0 세션 공유 경로 세션을 나르는 것이 Infinispan 이 아니라 PostgreSQL 이라는 것
A-1 7800 차단 세션 공유는 안 깨지고 로그아웃 전파만 깨진다
A-2 DB 정지 503 이 나는 동안에도 up 이 1 이다
A-3 DB 크래시 200 을 받은 로그인 153건 중 4건이 DB 에 없다
A-4 노드 상실 죽은 노드가 40초 동안 Ready 로 읽힌다
A-5 비대칭 분단 한 방향만 막으면 열린 쪽으로 재연결한다
A-6 지연 주입 200밀리초가 두 단계를 지나 22.2초가 된다
A-7 volatile 비교 설정 하나로 A층 결론 셋이 뒤집힌다
A-7a volatile 원인 확정 같은 설정이 캐시 온도만으로 400·500·200 세 답을 낸다
A-8 롤링 재시작 세션은 남고 캐시만 사라진다

B층 — 애플리케이션 쪽 저장소

가이드 무엇을 직접 보게 되나
B-0 자동구성 확인 아무것도 안 주면 Spring 이 무엇을 고르는가
B-1 Redis 세션 저장소 세션은 옮겨지는데 토큰은 안 따라온다
B-2 다중 인스턴스 저장소를 옮겨도 안 고쳐지는 것 — 원인은 기본키다
B-3 refresh 경쟁 이긴 요청의 토큰조차 못 쓴다
B-4 Edge 인가 범위 위조 헤더가 그대로 도착한다
B-5 Redis 상실·영속화 볼륨 없는 영속화 설정은 장식이다
B-6 키 회전 JWKS 캐시에 유예 구간이 없다
B-7 cookie secret 회전 겹침 구간을 만들 수 없고 서버 세션이 고아로 남는다
B-7a 고아 세션 정리 TTL 로 생성 시각을 역산해 골라낸다

C층 — SSO 와 로그아웃

가이드 무엇을 직접 보게 되나
C-1 다중 앱 SSO SSO 는 되는데 로그아웃이 안 퍼진다
C-2 백채널 로그아웃 양쪽 다 없었다 — 한쪽만 고치면 여전히 안 된다

D층 — 운영

가이드 무엇을 직접 보게 되나
D-1 백업·복구 백업이 진짜 백업인지 스키마를 지워서 확인한다
D-2 버전 업그레이드 롤백이 되는 조건은 스키마가 안 움직였을 때다
D-3 비밀 관리 base64 는 인코딩이지 암호화가 아니다
D-4 인증서 갱신 갱신은 성공했는데 38분 25초 동안 옛 인증서가 나갔다
D-4a deploy 훅 훅 하나로 그 공백이 1~2초가 된다

순서

A-0 을 먼저 한다. 나머지 A층 결론이 전부 거기서 확인한 「세션이 어디 있는가」 위에 서 있다.

A-0 ─┬─ A-1 ─┬─ A-5
     │        └─ A-6
     ├─ A-2 ── A-3 ── D-1 ── D-2
     ├─ A-4
     ├─ A-8
     └─ A-7 ── A-7a          ← A층을 다 한 뒤 설정 하나만 바꿔 재실행한다

B-0 ── B-1 ─┬─ B-2 · B-3 · B-4 · B-5 · B-6
            └─ B-7 ── B-7a

C-1 ── C-2                    D-3 · D-4 ── D-4a  (언제든 독립적으로)

A-7 을 A층 마지막에 두는 이유 — 앞의 실험을 다 마친 뒤 설정 하나만 바꿔 재실행하면 같은 주입에 대한 정반대 결과를 한 벌로 얻는다.

안전

각 편의 2번(주입)부터 상태가 바뀐다. 모든 편이 되돌리는 명령을 주입보다 먼저 보여 주고, 5번에서 원상복구를 확인한다.

호스트(test-server)에서 하는 일은 sudo 비밀번호가 필요해 사람이 직접 쳐야 한다. D-1 과 D-4 가 여기 해당하며, 각 편이 어느 단계가 그런지 적는다.