Files
llm-wiki/raw/branch-notes/feature-keycloak-realm-client-export.md
T

27 KiB

title, source_type, status, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, branch, parent_branch, related_projects, tags, created, target_merge, status_label, contract_packet_sha256
title source_type status id kind project work_item inherits refines overrides depends_on contract_packet branch parent_branch related_projects tags created target_merge status_label contract_packet_sha256
branch / feature-keycloak-realm-client-export (Keycloak realm/client 설정 + realm JSON export) branch-note raw BR-KEYCLOAK-PATTERNS-OVERVIEW-002 project-work-item keycloak-patterns-overview WI-KEYCLOAK-PATTERNS-OVERVIEW-002
DEC-KEYCLOAK-PATTERNS-OVERVIEW-REALM-CLIENT-001@1
DEC-KEYCLOAK-PATTERNS-OVERVIEW-SECRET-BOUNDARY-001@1
WI-KEYCLOAK-PATTERNS-OVERVIEW-001
1 feature-keycloak-realm-client-export
keycloak-patterns
branch
keycloak-patterns
p3a
implementation
keycloak-realm
pkce
oidc-client
2026-05-25 in-progress f751af30be9944511f5759f72096e406a9d6e191e075904df611b11f5797c5df

branch: feature-keycloak-realm-client-export (Keycloak realm/client 설정 + JSON export)

Layer: raw/branch-notes/raw/project-notes/keycloak-patterns-overview Work Item의 직접 자식 branch. P3A는 실 구현 대상. 본 sub-sub는 학습 + 작업 plan 기록 — 실 구현은 /home/donghyeon/workspace/keycloak-patterns/.

부모 (필수)

raw/project-notes/keycloak-patterns-overview

브랜치 계약 패킷

  • 생성 시 프로젝트 개정: 1
  • 패킷 스키마: contract_packet: 1
  • 완료 조건: realm import와 client 4개 등록 후 unauthenticated protected endpoint가 401이고 export가 재현된다

상속한 프로젝트 결정

Decision Ref Project Summary Branch Application Source
DEC-KEYCLOAK-PATTERNS-OVERVIEW-REALM-CLIENT-001@1 단일 realm keycloak-patterns에서 인증 패턴별 client를 분리한다 realm import와 인증 패턴별 client export 구성에 적용한다 raw/project-notes/keycloak-patterns-overview
DEC-KEYCLOAK-PATTERNS-OVERVIEW-SECRET-BOUNDARY-001@1 confidential client secret은 env var로 주입하고 commit·realm export 평문을 금지한다 realm export artifact의 secret redaction과 주입 경계에 적용한다 raw/project-notes/keycloak-patterns-overview

브랜치 지역 결정

기존 branch-local 결정은 아래 ## Decision Evidence Map의 D-row가 소유하며 이 packet에서 복제하지 않는다.

Decision ID Decision Relation Supporting Claims Status

선언한 예외

Override ID Overrides Reason Approval Status

없음.

목표

keycloak-patterns realm + spa-client (public, PKCE S256 강제) + 테스트 user 2명 + role 2개를 설정하고 realm JSON export를 commit한다. import 배선은 raw/branch-notes/feature-keycloak-docker-compose-stack D4가 소유하며, 본 문서는 그 consumer가 사용할 JSON artifact의 내용·검증 계약만 소유한다.

면접 질문: "Keycloak에서 public client에 PKCE 강제는 어떻게 거나요?" → "대상 Keycloak Client의 Capability config에서 PKCE method = S256을 지정합니다. 실제 export의 client attribute와 verifier 없는 요청의 거부 응답은 배포 버전에서 확인합니다. RFC 7636 관점에서 client_secret을 안전하게 보관할 수 없는 public SPA의 code interception 위험을 PKCE로 완화합니다."

  • 이슈:
  • PR: (별도 keycloak-patterns repo)

범위

포함 범위

  • realm keycloak-patterns 생성
  • Client spa-client (public, Standard Flow + PKCE S256 강제)
  • Valid Redirect URIs (http://localhost/*, http://127.0.0.1/*)
  • Web Origins (+ — Valid Redirect URI에서 자동 도출)
  • User 2명 (admin-user / regular-user) + 초기 password
  • Role 2개 (admin-role / user-role) + user에 매핑
  • Refresh Token Rotation 설정 필드와 target-version 실험 후보값 기록(현재 후보: ON / Max Reuse: 0; 의미는 owner 실험 전 확정하지 않음)
  • Realm JSON export 파일 commit (./realm-export.json)
  • import consumer가 사용할 realm JSON artifact의 파일명·내용·redaction 검증 계약

제외 범위

근거 (필수, 최소 1개+)

노트 최초 작성(2026-05-25) 당시 근거 raw 가 부재해 D1/D2/D5 가 UNSUPPORTED_DECISION 이었으나, 이후 corpus 성장으로 아래 raw 들이 추가되어 official 근거로 승격했다(재조사 없이 기존 raw 재매핑). 상세는 §Audit & Findings EVIDENCE_UPGRADE.

Source 정당화하는 결정
raw/official-docs/oauth2-pkce-rfc-7636 D1 — public client 의 code interception 취약성 + S256 공식 + token endpoint 의 verifier 불일치 거부 (PKCE-RFC7636-C1/C3/C4)
raw/official-docs/keycloak-client-pkce-method-enforcement-official D1 — Keycloak client 단위 PKCE 강제 옵션의 정식 명칭("PKCE method")과 S256 값 동작 (KC-PKCE-C1/C3)
raw/official-docs/oauth2-browser-based-apps-ietf-draft D1 — 브라우저 앱 = public client(client credentials 없음) 표준 정의 (OAUTH-BBA-C3)
raw/official-docs/oauth-v2-1-draft-ietf D1 — 모든 client PKCE MUST + AS enforce MUST (OA21-C1); D2 — redirect URI exact-match MUST (OA21-C5); D3 — refresh token scope/RS bound + code flow 발급 경로 (OA21-C3/C6)
raw/official-docs/keycloak-getting-started-docker D2 — quickstart 자체가 redirect URI 를 .../* wildcard + Web origins 정확값으로 설정 (KC-GSD-C4); realm=tenant, client 등록 절차 (KC-GSD-C3)
raw/official-docs/keycloak-import-export-realms D5 — --import-realm startup import + 컨테이너 import dir(/opt/keycloak/data/import) + 기존 realm skip(멱등) + offline --override 차이 (KC-IMPORT-C1..C4)
raw/official-docs/keycloak-server-containers-docker D5 — 컨테이너 실행/env context; 정확한 env 이름·기본 포트는 KC-CONTAINER-C5needs-confirmation

TODO

  • Keycloak admin console 접속 (http://localhost:8080, admin 계정) — 등급: planned
  • realm keycloak-patterns 생성 — 등급: planned
  • Client spa-client 생성: Access Type public, Standard Flow Enabled, Direct Access Grants Disabled — 등급: planned
  • Client Capability config: PKCE method = S256; 생성된 realm export의 내부 key도 함께 확인 — 등급: planned
  • Client Valid Redirect URIs: http://localhost/*, http://127.0.0.1/* 양쪽 등록 — 등급: planned
  • Client Web Origins: + (Redirect URIs에서 자동 도출) — 등급: planned
  • Role 생성: realm role admin-role, user-role — 등급: planned
  • User 생성: admin-user (password 초기화, admin-role 부여) — 등급: planned
  • User 생성: regular-user (password 초기화, user-role 부여) — 등급: planned
  • Realm Settings → Tokens: owner 실험 profile에 따라 Revoke Refresh TokenRefresh Token Max Reuse 값을 설정하고 export에 기록(0/1의 의미는 사전 단정 금지) — 등급: planned
  • Realm Settings → Tokens: Access Token Lifespan 5분 (학습용 짧게) — 등급: planned
  • Realm export: admin console → Export 또는 kc.sh export --realm keycloak-patterns --file /opt/keycloak/data/import/realm-export.json — 등급: planned
  • export JSON에서 secret/password 제거(또는 placeholder 치환) 후 git commit — 등급: planned
  • raw/branch-notes/feature-keycloak-docker-compose-stack D4가 본 artifact를 소비하는지 acceptance 검증(경로·파일명·realm/client 존재 확인); mount/command 저작은 하지 않음 — 등급: planned
  • 환경 reset 후 consumer import acceptance 검증 (docker compose down -v && up → admin 로그인 → realm/client 존재 확인) — 등급: planned

진행 중 메모

  • PKCE는 Keycloak public client 기본 권장. S256만 허용(plain 거부)이 보안 표준.
  • Valid Redirect URIslocalhost127.0.0.1 둘 다 등록하는 이유: 브라우저가 어느 호스트로 SPA를 로드하느냐에 따라 redirect URI도 달라짐. 두 URI는 Keycloak이 다른 것으로 본다.
  • Web Origins +는 Redirect URIs 도메인을 자동으로 CORS allow에 추가. wildcard *는 학습에서도 비권장.
  • Realm export의 credential 포함 여부·표현 형식은 Keycloak 버전과 export mode에 따라 달라질 수 있으며 현재 근거로 확정할 수 없다. target image의 kc.sh export --help, 실제 JSON, re-import 후 로그인까지 확인하기 전에는 password 포함/미포함을 모두 가정하지 않는다. 기본 절차는 credential을 별도 bootstrap/reset하고 commit 전 민감 필드를 redact하는 것이다.
  • --import-realm은 Keycloak 19+ 부터 지원 (자동 import). 구버전은 kc.sh import 별도 실행.

결정 사항 (decisions)

  • 2026-05-25: public client + PKCE S256 강제. 이유: vanilla JS SPA는 client_secret 보관 불가 (RFC 7636), public client + PKCE가 표준.
  • 2026-05-25: Redirect URI에 wildcard /* 사용. 이유: 학습 환경 한정 (localhost callback 경로 자유로움). prod에서는 정확한 경로 하나만.
  • 2026-05-25 (Historical / superseded rationale): Refresh Token Rotation ON + Max Reuse 0을 곧바로 보안 정책으로 확정했으나, Max Reuse 의미와 reuse 후 family 동작은 target-version 실험 전 단정할 수 없다. 현 결정은 raw/branch-notes/feature-keycloak-refresh-token-rotation D1/D2의 정책·검증 계약을 소비해 확정된 값을 export에 기록하는 것이다.
  • 2026-05-25: Access Token Lifespan 5분. 이유: rotation/revoke 시연 시 access token이 즉시 invalidate 안 됨을 짧게 검증.
  • 2026-05-25: Realm JSON export commit. 이유: 환경 reset 1줄 정책 (docker compose down -v && up 후 실 import).

결정-근거 매핑

각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시. Decision ID 는 본 branch-note 안에서 안정적으로 유지. 선택 조건 열: "이 조건일 때 이 결정, 다른 조건이면 어떤 대안". 분기 없으면 N/A. D3/D4/D5 는 sibling owner 브랜치에 rationale/wiring 을 위임(delegate) 한다 — Single-Owner(consistency-contract) 준수, 재진술(RESTATED_FOREIGN_DECISION) 금지. 상세는 §Audit & Findings.

Decision ID Decision 선택 조건 (언제 이 결정 / 언제 대안) Supporting Claims Evidence Strength Open Risk
D1 public client + PKCE S256 강제 (vanilla JS SPA 는 client_secret 보관 불가) SPA 가 client_secret 을 안전 보관 못할 때 이 결정 (OAUTH-BBA-C3, PKCE-RFC7636-C1). backend 를 둘 수 있으면 → 대안 BFF confidential client (OA21-C4) raw/official-docs/oauth2-pkce-rfc-7636.md#PKCE-RFC7636-C1, raw/official-docs/oauth2-pkce-rfc-7636.md#PKCE-RFC7636-C3, raw/official-docs/oauth2-pkce-rfc-7636.md#PKCE-RFC7636-C4, raw/official-docs/keycloak-client-pkce-method-enforcement-official.md#KC-PKCE-C1, raw/official-docs/keycloak-client-pkce-method-enforcement-official.md#KC-PKCE-C3, raw/official-docs/oauth-v2-1-draft-ietf.md#OA21-C1 official-standard + official-vendor-doc code_challenge_method=plain/verifier 없는 요청의 4xx 거부KC-PKCE-C3 가 증명 안 함(강제 적용 암시만) → §Claims To Verify 로 실측. Admin UI 라벨은 "PKCE method"(§Audit NAMING_DRIFT)
D2 Redirect URI 에 wildcard /* 사용 (localhost 학습 한정) localhost/학습이면 /* (callback 경로 자유·quickstart 도 /* 사용 KC-GSD-C4). prod 진입 시 → 대안 exact-match 단일 경로 (표준 OA21-C5: AS MUST reject non-exact redirect URI) raw/official-docs/keycloak-getting-started-docker.md#KC-GSD-C4, raw/official-docs/oauth-v2-1-draft-ietf.md#OA21-C5 official-vendor-doc + official-standard prod 에서 /*OA21-C5 exact-match MUST 위반 — out of scope(Out of scope 는 아니나 prod 미대상). KC-GSD-C4/* 예시만 보증, wildcard 의 보안 영향은 미증명
D3 realm export에 rotation 실험 후보값을 기록하되 의미를 재정의하지 않음 값·정책의 owner인 raw/branch-notes/feature-keycloak-refresh-token-rotation D1/D2가 확정한 target-version profile을 소비한다. runtime 동작은 raw/branch-notes/feature-keycloak-refresh-rotation-and-logout D1/D5에서 관찰한다. raw/official-docs/oauth-v2-1-draft-ietf.md#OA21-C3, raw/official-docs/oauth-v2-1-draft-ietf.md#OA21-C6 + delegated official-standard (baseline) + delegated Max Reuse=0의 의미와 refresh-token family invalidation은 배포 버전 실험 전 확정하지 않는다. 본 branch는 export에 최종 선택값만 반영한다.
D4 Access Token Lifespan 실험값을 realm export에 기록 TTL 정책은 raw/branch-notes/feature-keycloak-refresh-token-rotation D2를 소비하고, 5분이라는 실행 편의값과 관찰은 raw/branch-notes/feature-keycloak-refresh-rotation-and-logout D2에서 검증한다. prod TTL은 별도 결정이다. UNSUPPORTED_DECISION + delegated UNSUPPORTED_DECISION + delegated target-version export의 내부 key와 실제 만료 시간이 일치하는지 runtime acceptance 필요
D5 realm-export.json 저작 + commit (realm/client/role/user/token 설정을 담고 민감 필드를 검토·redact) 환경 reset 반복 + realm 즉시 복원이 목표면 export artifact를 commit. 1회성 수동 설정이면 Admin UI 수동 생성. 기존 realm 강제 덮어쓰기는 offline import --override(KC-IMPORT-C4) 검토 raw/official-docs/keycloak-import-export-realms.md#KC-IMPORT-C2, raw/official-docs/keycloak-import-export-realms.md#KC-IMPORT-C3, raw/official-docs/keycloak-import-export-realms.md#KC-IMPORT-C4 + import 배선 delegate raw/branch-notes/feature-keycloak-docker-compose-stack D4 official-vendor-doc + delegated (wiring) secret/password/credential 포함 여부와 형식은 모두 needs-confirmation. import wiring은 compose sibling D4 owner이며 본 문서는 artifact만 소유한다.

구현 가이드

본 branch 는 실 구현 repo(/home/donghyeon/workspace/keycloak-patterns/)가 아직 부재(§Audit NO_GROUND_TRUTH) → 모든 항목 planned. code grep 으로 actually-implemented 확정 불가. 3-rule(CLAUDE.md §15.5): R1 Reference 필수 · R2 UNSUPPORTED_IMPL_DECISION 명시 · R3 OUT_OF_BRANCH_SCOPE 정제.

1. realm-export.json 저작 명세 (client

Trace: D1(PKCE-RFC7636-C1/C3/C4, KC-PKCE-C1/C3, OA21-C1) · D2(KC-GSD-C4, OA21-C5) · D3(raw/branch-notes/feature-keycloak-refresh-token-rotation D1/D2 + runtime raw/branch-notes/feature-keycloak-refresh-rotation-and-logout D1/D5) · D4(raw/branch-notes/feature-keycloak-refresh-token-rotation D2 + runtime raw/branch-notes/feature-keycloak-refresh-rotation-and-logout D2)

  • UNSUPPORTED_IMPL_DECISION:
    • client 내부 JSON 속성 key pkce.code.challenge.methodKC-PKCE-C1 "Does not prove" 가 이 내부 속성명이 page 에 명시 안 됨을 명시. Admin UI 라벨("PKCE method")만 증명됨. trade-off: export-first 접근(Admin UI 에서 설정 → kc.sh export 로 정확한 key 자동 생성) 채택, hand-author JSON key 는 금지. needs-confirmation.
    • realm token 설정 JSON key(revokeRefreshToken/refreshTokenMaxReuse/accessTokenLifespan) — cited raw 에 verbatim 부재. trade-off: 마찬가지로 export-first 로 확정. needs-confirmation.
    • user credential의 export 포함 여부와 JSON 표현(users[].credentials[] 등) — cited raw 미증명. target kc.sh export --help, 실제 export JSON, re-import login을 확인하기 전에는 포함/미포함을 가정하지 않는다. trade-off: 별도 bootstrap/reset을 default로 두고 hand-authored credential block은 피한다. needs-confirmation.
JSON path (planned, export-first 로 확정) 근거 상태
realm keycloak-patterns D5 / 범위 planned
clients[].clientId spa-client 범위 planned
clients[].publicClient true D1 PKCE-RFC7636-C1 (SPA=public), OAUTH-BBA-C3 planned
clients[].standardFlowEnabled true 범위 (Standard Flow = Authorization Code) planned
clients[].directAccessGrantsEnabled false 범위 (ROPC 비활성) planned
clients[].attributes."pkce.code.challenge.method" S256 D1 KC-PKCE-C3(UI "PKCE method"=S256). 내부 key = UNSUPPORTED_IMPL needs-confirmation
clients[].redirectUris ["http://localhost/*","http://127.0.0.1/*"] D2 KC-GSD-C4 (redirect URI 형식) planned
clients[].webOrigins ["+"] 범위 (Redirect URI 에서 CORS 자동 도출) planned
roles.realm[].name admin-role, user-role 범위 planned
users[].username (+ realmRoles) admin-user(admin-role), regular-user(user-role) 범위 planned
users[].credentials[] (초기 password) 포함 여부·형식 미확정. 별도 bootstrap/reset을 default로 두고 hand-author 금지 범위("초기 password") + §엣지 + Claims To Verify #4 needs-confirmation
realm token: revokeRefreshToken owner가 확정한 target-version 실험값(현재 candidate true) D3 → raw/branch-notes/feature-keycloak-refresh-token-rotation D1/D2. key = UNSUPPORTED_IMPL needs-confirmation
realm token: refreshTokenMaxReuse owner가 0/1 실험 후 확정한 값(현재 candidate 0) D3 → concept owner + runtime observation. key = UNSUPPORTED_IMPL needs-confirmation
realm token: accessTokenLifespan 300 (5분, 실행 편의 candidate) D4 → concept owner + runtime raw/branch-notes/feature-keycloak-refresh-rotation-and-logout D2. key = UNSUPPORTED_IMPL needs-confirmation

2. export 절차 + secret/password redaction

Trace: D5(KC-IMPORT-C4 offline export 경로, KC-CONTAINER context)

  • UNSUPPORTED_IMPL_DECISION: kc.sh export 의 정확한 flag(--dir vs --file, --users 옵션)와 client secret 이 export 에 평문 포함되는지 = cited raw 미증명 → §Claims To Verify. trade-off: 실 export 1회 수행 후 JSON 을 grep 으로 확인하는 절차로 대체.
  1. Admin console 에서 realm/client/role/user/token 설정 (§1 표대로).
  2. export: kc.sh export --realm keycloak-patterns --file /opt/keycloak/data/import/realm-export.json (또는 --dir). --users 처리 정책은 §엣지 참조.
  3. commit 전 redact: grep -n 'secret\|password\|credential' realm-export.json → 평문 노출 필드는 placeholder 치환 또는 .gitignore.
  4. ./realm-export.json 로 repo 에 commit.

3. import 배선 (OUT_OF_BRANCH_SCOPE — delegate)

Trace / R3: volume mount + Keycloak 부트 command --import-realm는 sibling raw/branch-notes/feature-keycloak-docker-compose-stack D4가 owner (KC-IMPORT-C1/C2/C3/C4 인용). 본 branch는 realm-export.json 저작과 consumer acceptance만 담당하며 배선을 재진술하지 않는다. 배선 계약이 바뀌면 본 export 파일 배치에 영향(§엣지·의존).

엣지·실패·의존

R4 캡처: 정상 경로 외 실패/엣지 + 다른 계약 의존(대상 브랜치 + Decision ID).

  • 실패·엣지 경로:
    • export JSON 에 client secret 평문 포함 가능 — public client 는 secret 없지만 confidential 전환 시 위험. 기대 동작: commit 전 secret grep + redact(§구현 가이드 2-3). (§Claims To Verify #3)
    • credential 포함 여부 미확정 — export mode·version에 따라 password/credential 포함 여부와 형식이 다를 수 있다. 기대 동작: 별도 bootstrap/reset을 기본으로 하고 commit 전 secret|password|credential 검색, 실제 re-import login으로 검증. (§Claims To Verify #4)
    • 기존 realm 존재 시 auto-import skipKC-IMPORT-C3(멱등). docker compose down -v 로 postgres volume 을 삭제해야 재import 됨(볼륨 잔존 시 옛 realm 유지, 새 export 반영 안 됨).
    • import dir 파일명/확장자 오류KC-IMPORT-C2: .json regular file 만 읽고 sub-dir 무시. 경로/확장자 오타 시 silent skip → 부트는 성공하나 realm 없음.
  • 다른 계약 의존:

검증해야 할 주장

공식 문서나 사례는 근거지만, 내 프로젝트에서의 동작을 자동으로 보장하지 않는다.

Claim Why uncertain How to verify Status
대상 Keycloak Client Capability config의 PKCE method = S256 설정이 token endpoint에서 code_verifier 없는 요청을 거부하는지 KC-PKCE-C1/C3은 UI 라벨과 S256 선택을 다루지만 exact HTTP status와 version별 내부 key는 증명하지 않음 target UI 설정 후 realm export의 내부 key를 확인하고 PKCE 없는 token request의 응답을 기록 needs-confirmation
--import-realm 옵션의 정확한 명령 형식 (docker run ... start-dev --import-realm 또는 kc.sh start --import-realm) KC-CONTAINER-C5 가 명시적으로 needs-confirmation — env/option verbatim 부재 Keycloak all-config / import 공식 페이지 발췌 후 raw/official-docs/ 에 추가하여 verbatim 인용 확보 needs-confirmation
Realm export JSON 에 client secret 이 평문으로 포함될 수 있음 → gitignore / redact 필요 본 branch 진행 중 메모 — 1차 raw 미수집 실 export 수행 후 JSON 파싱 → secret 필드 검색 + 평문 노출 여부 확인 needs-confirmation
target Keycloak의 export mode가 user credential을 어떤 조건·형식으로 포함하는지 usersExport=true와 password 포함을 연결하는 1차 근거가 없고 버전별 CLI 옵션 차이 가능 target image에서 kc.sh export --help 확인 → 실제 JSON의 credential 필드 검사 → re-import 후 로그인 검증 needs-confirmation
환경 reset (docker compose down -v && up) 후 realm/client/user 자동 import 동작 위 D5 가 needs-confirmation — 실제 동작 검증 미수행 docker-compose 구동 → admin 로그인 → realm keycloak-patterns 존재 + spa-client 존재 확인 planned
realm-export.json 의 client PKCE 내부 속성 key 가 pkce.code.challenge.method 인지 KC-PKCE-C1 "Does not prove" — page 에 내부 속성명 미명시 Admin UI 에서 "PKCE method=S256" 설정 후 kc.sh export → 생성된 JSON 의 clients[].attributes key 확인 needs-confirmation

Audit & Findings

/branch-spec 채움 중 발견한 정합/근거 이슈. 사용자 작성 결정 영역은 자동 rewrite 하지 않고 정합 권고만 기록(CLAUDE.md §11, consistency-contract).

  • EVIDENCE_UPGRADE — 노트 최초 작성(2026-05-25) 당시 D1/D2/D5 는 근거 raw 부재로 전부 UNSUPPORTED_DECISION 이었다. 이후 corpus 성장으로 oauth2-pkce-rfc-7636, keycloak-client-pkce-method-enforcement-official, oauth2-browser-based-apps-ietf-draft, oauth-v2-1-draft-ietf, keycloak-getting-started-docker, keycloak-import-export-realms 가 추가되어 official 근거로 승격. 재조사(researcher dispatch) 없이 기존 raw 재매핑으로 해결 — 모든 결정이 근거 보유 또는 정당한 UNSUPPORTED trade-off(D4).
  • NAMING_DRIFT (해소 2026-07-18) — §목표·§TODO·§Claims를 대상 UI의 PKCE method(Capability config)로 통일했다. 다른 Keycloak 버전의 라벨·내부 key 차이는 생성된 realm export와 대조하며, exact 거부 응답은 needs-confirmation으로 유지한다.
  • OWNERSHIP_NARROWED (D5) — 원 D5는 "export commit + --import-realm 자동 import"를 함께 기술했으나, --import-realm + volume mount 배선은 sibling raw/branch-notes/feature-keycloak-docker-compose-stack D4가 owner다. 본 D5는 realm-export.json 저작·commit과 consumer acceptance로 좁혔다.
  • DELEGATED_RATIONALE (D3/D4) — rotation 값·정책은 raw/branch-notes/feature-keycloak-refresh-token-rotation D1/D2, 실행·관찰은 raw/branch-notes/feature-keycloak-refresh-rotation-and-logout D1/D5가 owner다. 본 branch는 target-version 결과로 확정된 값을 realm-export.json에 기록할 뿐 Max Reuse나 family invalidation 의미를 재진술하지 않는다.
  • NO_GROUND_TRUTH (code) — 실 구현 repo /home/donghyeon/workspace/keycloak-patterns/ 부재 확인. 코드 grep 으로 actually-implemented 확정 불가 → 모든 항목 planned/documented-only 유지. (ca-tmpl ground truth 는 본 keycloak-patterns 프로젝트에 비적용 — 별개 트리)

마주친 문제

  • (구현 시작 후 추가) realm export JSON 안에 client secret이 평문으로 들어가는 경우 — gitignore 또는 redact 필요.
  • (구현 시작 후 추가) user password 재설정 자동화 어려움 — 초기 password 정책 / temporary password flag 활용 검토.

묶음

본 sub-sub-branch 는 leaf — 자식 자료 없음. Phase 3 P3A 실 구현 또는 외부 산출물 단계에서 errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.

오류 기록 (이 sub-sub-branch 작업 중 발생)

  • (없음 — 현재 documented-only 단계)

면접 준비 (이 작업에서 나올 수 있는 면접 질문)

  • (없음 — Phase 3 실 구현 단계에 누적)

관련 일일 노트

완료 후 정리

실 구현 후 realm import 자동화 검증 시 plannedactually-implemented/locally-verified 승급.

  • PR 링크: (별도 keycloak-patterns repo)
  • 리뷰 메모:
  • 머지 결과 / 배포 환경: 로컬 docker-compose / 단일 EC2 시뮬레이션
  • wiki 추출 대상:
    • actually-implemented 항목: (구현 후 채움)
    • locally-verified 항목: (구현 후 채움)
    • prod-verified 항목: (없음)
  • 추출하지 않을 항목: 현재 전부 planned.