Files
llm-wiki/raw/branch-notes/feature-keycloak-patterns.md
T

310 lines
19 KiB
Markdown

---
title: branch / feature-keycloak-patterns (root, 작업 인덱스)
source_type: branch-note
status: raw
id: BR-KEYCLOAK-PATTERNS-OVERVIEW-020
kind: project-work-item
project: keycloak-patterns-overview
work_item: WI-KEYCLOAK-PATTERNS-OVERVIEW-020
inherits: [DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1]
refines: []
overrides: []
depends_on: []
contract_packet: 1
branch: feature-keycloak-patterns
parent_branch:
related_projects: [keycloak-patterns]
tags: [branch, keycloak-patterns, oauth2, oidc, auth]
created: 2026-05-25
target_merge:
status_label: in-progress
contract_packet_sha256: 6855baa10b305d5b251f64bfec1f707854488bd72d631b0f9968cfcaaf1f8981
---
# branch: feature-keycloak-patterns (root)
> Layer: `raw/branch-notes/` — **작업 진행 인덱스**. 프로젝트 정의·6 패턴 분류·공통 컴포넌트는 [[raw/project-notes/keycloak-patterns-overview]] 참조.
> 본 root는 sub-branch 진행 상태와 일정만 추적.
> `status_label`: `in-progress`
<!-- section-id: branch-parent -->
## 부모 (필수)
[[raw/project-notes/keycloak-patterns-overview]]
<!-- GENERATED: branch-contract:start -->
<!-- section-id: branch-contract-packet -->
## 브랜치 계약 패킷
- **생성 시 프로젝트 개정**: `1`
- **패킷 스키마**: `contract_packet: 1`
- **완료 조건**: project governance hub가 AP1~AP4 taxonomy와 child progress index를 유지한다
<!-- section-id: inherited-project-decisions -->
### 상속한 프로젝트 결정
| Decision Ref | Project Summary | Branch Application | Source |
|---|---|---|---|
| `DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1` | canonical 분류축은 AP1~AP4 인증 통합 아키텍처와 cross-cutting 변형이다 | AP1~AP4 taxonomy와 child progress index를 유지하는 governance hub에 적용한다 | [[raw/project-notes/keycloak-patterns-overview]] |
<!-- section-id: branch-local-decisions -->
### 브랜치 지역 결정
> 기존 branch-local 결정은 아래 `## Decision Evidence Map`의 D-row가 소유하며 이 packet에서 복제하지 않는다.
| Decision ID | Decision | Relation | Supporting Claims | Status |
|---|---|---|---|---|
<!-- section-id: declared-overrides -->
### 선언한 예외
| Override ID | Overrides | Reason | Approval | Status |
|---|---|---|---|---|
없음.
<!-- GENERATED: branch-contract:end -->
## 프로젝트 SSOT
- **canonical SSOT**: [[raw/project-notes/keycloak-patterns-overview]] — 프로젝트 정의 / 6 패턴 분류 / 공통 컴포넌트 / 인프라 / 본인 작업 / 트러블슈팅 / 자신 없는 부분 / 진행 단계.
- **사용자 본인 인프라 개요**: [[raw/project-notes/project-infra-overview]] (sister project note)
<!-- section-id: branch-goal -->
## 목표
본 root branch는 keycloak-patterns 프로젝트의 **작업 진행 인덱스** 역할. 면접에서 "왜 이 배치를 택했나" / "Google 로그인이 붙으면 흐름이 어떻게 바뀌나" / "BFF vs SPA Direct OIDC trade-off는?"에 자신 있게 답할 수 있는 수준의 6 패턴 이해 + P3A 한정 실 구현이 최종 목표 (canonical SSOT 참조).
본 root 자체의 책무:
- 6 sub-branch + 27 sub-sub-branch 진행 상태 추적
- 외부 근거 raw 보존 인덱스
- 머지 후 wiki 추출 시 비교 매트릭스 산출
- 이슈:
- PR:
<!-- section-id: branch-scope -->
## 범위
### 포함 범위
- (본문 해당 섹션에서 다룬 항목 참조)
### 제외 범위
- (명시 필요)
## 근거 (root는 hub 역할이라 자체 인용은 적고, 개별 결정 근거는 각 sub-branch의 Sources 표 참조)
개별 패턴별 근거는 sub-branch (feature-keycloak-edge-forwardauth-no-google ~ -6) 의 Sources 표에 위임.
## 6 sub-branch + 27 sub-sub-branch 진행 인덱스
> **⚠️ 갱신 (2026-07-14)**: 아래 6패턴 인덱스는 **Phase 0 legacy(배치×federation 축)**. 현 실행계획 SSOT 는 [[raw/project-notes/keycloak-patterns-overview]] 의 **§Branch 분해 / 실행계획(R4)** — 인증 아키텍처 4패턴(AP1~AP4) + 19 Tier-2. 신규 작업은 hub 분해표를 따르며, 아래 슬러그는 hub §2.3 매핑대로 AP 로 re-map 대상. D2(`-{N}-{M}` numbered 명명)는 CLAUDE.md §11 위반으로 폐기(각 sub-sub 는 이미 content-descriptive 슬러그라 실제 영향은 프레이밍뿐).
총 34 branch-notes (root 1 + sub 6 + sub-sub 27). 모두 `documented-only` / `planned` (P3A만 실 구현 대상).
### P1A — Edge Forward Auth (no Google) — [[raw/branch-notes/feature-keycloak-edge-forwardauth-no-google]]
- 외부 근거 raw 5개 / sub-sub 4개
- [[raw/branch-notes/feature-keycloak-oauth2-proxy-oidc-flow]] — oauth2-proxy 구성과 OIDC 흐름
- [[raw/branch-notes/feature-keycloak-nginx-auth-request-integration]] — nginx auth_request 통합 (4kb cookie 함정)
- [[raw/branch-notes/feature-keycloak-header-spoofing-defense]] — 헤더 spoofing 방어 (NetworkPolicy / SG / mTLS)
- [[raw/branch-notes/feature-keycloak-traefik-forwardauth-alternative]] — Traefik ForwardAuth 대안 비교
### P1B — Edge + Google IdP Brokering — [[raw/branch-notes/feature-keycloak-edge-forwardauth-google-federation]]
- 외부 근거 raw 5개 / sub-sub 4개
- [[raw/branch-notes/feature-keycloak-idp-brokering-google-client]] — Keycloak IdP brokering 구성 (Google client 등록)
- [[raw/branch-notes/feature-keycloak-first-broker-login-flow]] — First Broker Login Flow (Confirm Link Existing Account)
- [[raw/branch-notes/feature-keycloak-google-claim-attribute-mapping]] — Google claim → Keycloak attribute mapping
- [[raw/branch-notes/feature-keycloak-account-linking-sub-vs-email]] — Account Linking 보안 (`sub` vs `email`)
### P2A — Internal SPA + Resource Server (no Google) — [[raw/branch-notes/feature-keycloak-internal-spa-direct-no-google]]
- 외부 근거 raw 6개 / sub-sub 5개
- [[raw/branch-notes/feature-keycloak-pkce-flow-stages]] — PKCE 4단계 (verifier/challenge/auth/exchange)
- [[raw/branch-notes/feature-keycloak-spring-rs-audience-validator]] — Spring Security Resource Server + audience validator
- [[raw/branch-notes/feature-keycloak-spa-token-storage-tradeoff]] — Token 저장 위치 trade-off (localStorage/cookie/memory)
- [[raw/branch-notes/feature-keycloak-bff-vs-spa-direct]] — BFF 대안 비교
- [[raw/branch-notes/feature-keycloak-refresh-token-rotation]] — Refresh token rotation + revocation
### P2B — Internal + Google federation — [[raw/branch-notes/feature-keycloak-internal-spa-direct-google-federation]]
- 외부 근거 raw 4개 / sub-sub 4개
- [[raw/branch-notes/feature-keycloak-federation-spa-zero-change]] — SPA 코드 변경 없음 검증 (P2A → P2B 전환)
- [[raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role]] — IdP Mappers (Google claim → Keycloak role)
- [[raw/branch-notes/feature-keycloak-three-leg-trust-chain]] — 3-leg trust chain 검증
- [[raw/branch-notes/feature-keycloak-account-linking-spa-ux]] — Account Linking SPA 컨텍스트
### **P3A — Single EC2 (실 구현 대상)** — [[raw/branch-notes/feature-keycloak-single-ec2-no-google]]
- 외부 근거 raw 4개 / sub-sub 6개 (각 sub-sub는 실 구현 plan 포함)
- [[raw/branch-notes/feature-keycloak-docker-compose-stack]] — docker-compose 환경 구성
- [[raw/branch-notes/feature-keycloak-realm-client-export]] — Keycloak realm/client 설정 + JSON export
- [[raw/branch-notes/feature-keycloak-spring-rs-role-mapping]] — Spring Boot Resource Server + audience validator
- [[raw/branch-notes/feature-keycloak-vanilla-js-spa-pkce]] — vanilla JS SPA (Authorization Code + PKCE)
- [[raw/branch-notes/feature-keycloak-iss-claim-hostname-mismatch]] — iss claim mismatch 함정 + KC_HOSTNAME 해결
- [[raw/branch-notes/feature-keycloak-refresh-rotation-and-logout]] — refresh token rotation + 로그아웃 흐름
### P3B — Single EC2 + Google federation — [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]]
- 외부 근거 raw 4개 / sub-sub 4개
- [[raw/branch-notes/feature-keycloak-public-domain-tunneling]] — public 도메인 확보 (ngrok / Cloudflare Tunnel)
- [[raw/branch-notes/feature-keycloak-reverse-proxy-headers]] — Keycloak reverse proxy 설정 (KC_PROXY_HEADERS + KC_HOSTNAME)
- [[raw/branch-notes/feature-keycloak-google-redirect-uri-policy]] — Google OAuth client 등록 + redirect_uri 갱신
- [[raw/branch-notes/feature-keycloak-https-termination-caddy-nginx]] — HTTPS termination (Caddy vs nginx+certbot vs Cloudflare Tunnel)
## TODO
- [x] 6 sub-branch 1차 작성 (목표 / 다이어그램 / 토큰 sequence / 장단점) — 등급: `documented-only`
- [x] 28 외부 근거 raw 보존 — 등급: `documented-only`
- [x] [[raw/project-notes/keycloak-patterns-overview]] 신설 (메인 SSOT, 2026-05-25) — 등급: `documented-only`
- [ ] 6 sub-branch 외부 근거 섹션 강화 (채택 결정 / 검토 대안 / 비교 핵심 구조) — 등급: `planned`
- [ ] 각 sub-branch 별 sub-sub-branch (세부 학습/구현 단계) 추가 — 등급: `planned`
- [ ] P3A 실 구현 (`/home/donghyeon/workspace/keycloak-patterns/`) — 등급: `planned`
- [ ] 6 패턴 trade-off 매트릭스 통합 문서 (Phase 4) — 등급: `planned`
## 진행 중 메모
- root branch-note 슬림화: 프로젝트 정의는 [[raw/project-notes/keycloak-patterns-overview]]로 이전 (2026-05-25). root는 작업 인덱스만 유지.
- 외부 근거 구조 강화 후속 작업: ca-tmpl branch-notes와 동일하게 "채택 결정 / 검토 대안 / 비교 핵심" 3단 구조로 재작성.
- **역사 기록(폐기됨)**: 초기에는 `feature-keycloak-patterns-{N}-{M}` numbered hierarchy를 제안했으나 현 규칙과 충돌해 사용하지 않는다. 현재 규약은 구현 내용을 드러내는 4~8단어 영문 kebab-case slug이며 계층은 `parent_branch``## Parent`로만 표현한다.
## 결정 사항 (decisions)
- **D1** 2026-05-25: 프로젝트 정의는 `raw/project-notes/`에, 작업 진행은 `raw/branch-notes/`에. ca-tmpl과 동일 위계.
- **D2 (Historical / superseded — DO NOT USE)** 2026-05-25: sub-sub-branch를 `-{N}-{M}` dash-숫자로 명명하자는 초기 결정. 현 `CLAUDE.md` §11과 `rules/naming-conventions.md`에 의해 폐기되었으며, 구현 내용을 드러내는 4~8단어 영문 kebab-case slug가 현행 결정이다.
## 결정-근거 매핑
> 본 root branch 는 hub 역할 — 자체 결정은 **운영 / 조직 규약** 만 다루고, 패턴 채택 결정은 sub-branch 로 위임됨. 따라서 본 hub 의 결정은 외부 raw source 가 아닌 **프로젝트 내부 규약 (CLAUDE.md / rules/) + ca-tmpl 선례** 에 근거함 → 외부 raw claim 측면에서는 모두 UNSUPPORTED_DECISION.
| Decision ID | Decision | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|
| D1 | 프로젝트 정의는 `raw/project-notes/`, 작업 진행은 `raw/branch-notes/` 분리 (ca-tmpl 과 동일 위계) | UNSUPPORTED_DECISION (외부 raw source 없음 — 내부 규약 `rules/linking-rules.md` §12 named hub 패턴 + `CLAUDE.md` §2 디렉터리 역할 + ca-tmpl 선례에 근거) | `internal-convention` | 외부 표준 근거 없음 — 다른 wiki / KMS 패턴과 비교 평가 미수행. 단 본 프로젝트 단일 vault 내 일관성은 충분 |
| D2 | **RETIRED / superseded**`-{N}-{M}` numbered hierarchy는 사용하지 않는다. 현행 규약은 구현 내용을 드러내는 4~8단어 영문 kebab-case slug이고 계층은 `parent_branch` + `## Parent`로만 표현한다. | `CLAUDE.md` §11 + `rules/naming-conventions.md` §2.1.2~§2.1.6 | `internal-convention` | 기존 파일·링크에 남은 numbered slug는 별도 migration 계획으로 정리하되 신규 문서에서는 생성 금지 |
## 구현 가이드
> **Trace**: D1(프로젝트 정의와 진행 노트 분리)과 D2(내용 기반 slug + frontmatter 계층)를 따른다.
>
> - **UNSUPPORTED_IMPL_DECISION**: hub의 수기 인덱스 갱신 방식은 외부 raw source가 정하지 않는 vault 운영 선택이다. 본 hub에는 class/config/API 명세를 두지 않고, child owner의 진행 상태와 링크만 유지한다.
- [[raw/branch-notes/feature-keycloak-edge-forwardauth-no-google]] — P1A 작업 묶음 owner; 구현·설정 세부는 child에서만 유지한다.
- [[raw/branch-notes/feature-keycloak-edge-forwardauth-google-federation]] — P1B 작업 묶음 owner; 구현·설정 세부는 child에서만 유지한다.
- [[raw/branch-notes/feature-keycloak-internal-spa-direct-no-google]] — P2A 작업 묶음 owner; 구현·설정 세부는 child에서만 유지한다.
- [[raw/branch-notes/feature-keycloak-internal-spa-direct-google-federation]] — P2B 작업 묶음 owner; 구현·설정 세부는 child에서만 유지한다.
- [[raw/branch-notes/feature-keycloak-single-ec2-no-google]] — P3A 구현 owner; hub는 증거 등급과 완료 상태만 반영한다.
- [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] — P3B 문서 작업 owner; hub는 증거 등급과 완료 상태만 반영한다.
## 엣지·실패·의존
- **실패·엣지 경로**: 수기 인덱스가 실제 파일·`parent_branch`와 어긋나면 진행률과 owner 탐색이 stale해진다. 아래 Claims To Verify의 파일·frontmatter 대조를 통과한 뒤에만 개수를 갱신한다.
- **다른 계약 의존**: [[raw/project-notes/keycloak-patterns-overview]]가 실행계획과 패턴 분류를 소유한다. 본 hub는 그 내용을 재진술하지 않고 위 child owner 링크와 상태만 소비한다.
## 검증해야 할 주장
> root branch 는 hub 인덱스이므로 자체 verification 보다는 sub-branch 의 결정 / 구현이 정확한지에 대한 메타 검증 항목 위주.
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
| 6 sub-branch + 27 sub-sub-branch 진행 인덱스가 실제 파일과 일치 | 본 root 의 인덱스는 수기 유지, drift 가능 | `ls raw/branch-notes/feature-keycloak-*` + `grep parent_branch:` 와 본 §6 sub-branch 인덱스 cross-check | `needs-confirmation` |
| 폐기된 numbered slug가 기존 파일·링크에 남아 있는지 | D2는 폐기됐지만 역사적으로 생성된 경로가 있을 수 있어 일괄 rename 시 링크 파손 위험이 있음 | `rules/naming-conventions.md` 기준으로 기존 slug를 inventory하고, 역링크를 포함한 별도 migration plan에서 단계적으로 정리 | `planned` |
| P3A 한정 실 구현 → wiki/projects/ 승급 가능한 verified 항목이 실제로 생성됨 | 현재 모두 `documented-only` / `planned` | Phase 3 완료 후 [[raw/branch-notes/feature-keycloak-single-ec2-no-google]] 의 TODO 항목별 `actually-implemented` / `locally-verified` 등급 부여 + 측정 evidence 첨부 | `planned` |
| 패턴별 외부 근거 raw 자료가 모두 `## Claims Extracted` + `## Usage Boundaries` 구조를 갖춤 | claim traceability 정책이 2026-05-27 도입 — 기존 raw 는 migration 대상 | `grep -L "## Claims Extracted" raw/official-docs/keycloak*` + `raw/company-tech-blogs/keycloak*` | `needs-confirmation` |
## 마주친 문제
- 아직 없음(문서 단계).
## 묶음
<!-- GENERATED: sources:start -->
- [[raw/company-tech-blogs/curity-bff-pattern-spa]]
- [[raw/company-tech-blogs/keycloak-google-login-codemancers]]
- [[raw/official-docs/cloudflare-tunnel-routing-official]]
- [[raw/official-docs/google-oauth2-redirect-uri-validation-official]]
- [[raw/official-docs/google-openid-connect-oidc]]
- [[raw/official-docs/keycloak-first-broker-login-flow]]
- [[raw/official-docs/keycloak-first-login-flow]]
- [[raw/official-docs/keycloak-getting-started-docker]]
- [[raw/official-docs/keycloak-google-idp-setup]]
- [[raw/official-docs/keycloak-hostname-configuration]]
- [[raw/official-docs/keycloak-identity-brokering-overview-official]]
- [[raw/official-docs/keycloak-reverseproxy-official]]
- [[raw/official-docs/keycloak-securing-apps-overview-official]]
- [[raw/official-docs/keycloak-server-containers-docker]]
- [[raw/official-docs/nginx-auth-request-module-official]]
- [[raw/official-docs/ngrok-http-tunnel-official]]
- [[raw/official-docs/oauth-v2-1-draft-ietf]]
- [[raw/official-docs/oauth2-pkce-rfc-7636]]
- [[raw/official-docs/oauth2-proxy-keycloak-oidc-provider-official]]
- [[raw/official-docs/oauth2-proxy-nginx-integration-official]]
- [[raw/official-docs/oauth2-proxy-overview-config-official]]
- [[raw/official-docs/oidc-client-ts-library]]
- [[raw/official-docs/owasp-html5-storage-xss-spa]]
- [[raw/official-docs/spring-security-resource-server-jwt]]
- [[raw/official-docs/traefik-forwardauth-middleware-official]]
<!-- GENERATED: sources:end -->
<!-- GENERATED: branches:start -->
- [[raw/branch-notes/feature-keycloak-account-linking-spa-ux]]
- [[raw/branch-notes/feature-keycloak-bff-vs-spa-direct]]
- [[raw/branch-notes/feature-keycloak-edge-forwardauth-google-federation]]
- [[raw/branch-notes/feature-keycloak-edge-forwardauth-no-google]]
- [[raw/branch-notes/feature-keycloak-federation-spa-zero-change]]
- [[raw/branch-notes/feature-keycloak-https-termination-caddy-nginx]]
- [[raw/branch-notes/feature-keycloak-internal-spa-direct-google-federation]]
- [[raw/branch-notes/feature-keycloak-internal-spa-direct-no-google]]
- [[raw/branch-notes/feature-keycloak-pkce-flow-stages]]
- [[raw/branch-notes/feature-keycloak-public-domain-tunneling]]
- [[raw/branch-notes/feature-keycloak-reverse-proxy-headers]]
- [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]]
- [[raw/branch-notes/feature-keycloak-single-ec2-no-google]]
<!-- GENERATED: branches:end -->
> 본 root는 6 sub-branch hub. 위 "6 sub-branch + 27 sub-sub-branch 진행 인덱스" 섹션과 중복 정보이나, `templates/linking-rules.md` §4 양방향 작성 패턴에 따라 카테고리별 명시.
### Sub-branches (6 패턴별 hub)
- [[raw/branch-notes/feature-keycloak-edge-forwardauth-no-google]] — P1A Edge / Ingress (no Google)
- [[raw/branch-notes/feature-keycloak-edge-forwardauth-google-federation]] — P1B Edge / Ingress + Google federation
- [[raw/branch-notes/feature-keycloak-internal-spa-direct-no-google]] — P2A Cluster-internal SPA-direct (no Google)
- [[raw/branch-notes/feature-keycloak-internal-spa-direct-google-federation]] — P2B Cluster-internal + Google federation
- [[raw/branch-notes/feature-keycloak-single-ec2-no-google]] — P3A Single EC2 (no Google) **— vanilla JS 실 구현 대상**
- [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] — P3B Single EC2 + Google federation
### 근거 자료
- (패턴별 official-docs / company-tech-blogs 는 sub-branch 의 Sources 표에서 cited)
### 오류 기록
- (없음 — Phase 3 P3A 실 구현 진입 시 발생 예상)
### 면접 준비
- (없음 — 패턴별 면접 후보는 sub-branch Cluster의 Interview prep 항목 참조)
### 강의
- (없음)
### Blog drafts / job-posting tie-ins
- (없음)
## 관련 일일 노트
## 완료 후 정리
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경: P3A 한정 로컬 검증 예정
- **wiki 추출 대상** (verified만, `wiki/projects/`로만 추출):
- `actually-implemented` 항목: (Phase 3 완료 후 채움)
- `locally-verified` 항목: (Phase 3 완료 후 채움)
- `prod-verified` 항목: (없음, prod 배포 out of scope)
- **추출하지 않을 항목** (planned / documented-only / abandoned): P1A/P1B/P2A/P2B/P3B 5개 패턴은 문서까지만.