Files
llm-wiki/raw/branch-notes/feature-keycloak-edge-forwardauth-google-federation.md

33 KiB
Raw Permalink Blame History

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-edge-forwardauth-google-federation (P1B Edge Forward Auth + Google federation) branch-note raw BR-KEYCLOAK-CHILD-8F3B8B4E branch-child keycloak-patterns-overview WI-KEYCLOAK-PATTERNS-OVERVIEW-020
DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1
1 feature-keycloak-edge-forwardauth-google-federation feature-keycloak-patterns
keycloak-patterns
branch
keycloak-patterns
auth
oauth2
oidc
2026-05-25 in-progress 0d0cfce93fa2e7290518d60b46e5559d479877936fb26cc8dacbf2232cb0d8d3

branch: feature-keycloak-edge-forwardauth-google-federation (P1B Edge Forward Auth + Google federation)

Layer: raw/branch-notes/ — root raw/branch-notes/feature-keycloak-patterns의 sub-branch. 패턴 ID: P1B — Edge ForwardAuth (oauth2-proxy / Traefik) + Keycloak에 Google을 외부 IdP로 brokering. 비교 대상: raw/branch-notes/feature-keycloak-edge-forwardauth-no-google (P1A: 같은 배치, Google 없음). status_label: in-progress

부모 (필수)

브랜치 계약 패킷

  • 생성 시 프로젝트 개정: 1
  • 패킷 스키마: contract_packet: 1
  • 완료 조건: project governance hub가 AP1~AP4 taxonomy와 child progress index를 유지한다

상속한 프로젝트 결정

Decision Ref Project Summary Branch Application Source
DEC-KEYCLOAK-PATTERNS-OVERVIEW-AUTH-TAXONOMY-001@1 canonical 분류축은 AP1~AP4 인증 통합 아키텍처와 cross-cutting 변형이다 Edge ForwardAuth에 Google federation을 결합한 cross-cutting 변형으로 분류한다 raw/project-notes/keycloak-patterns-overview

브랜치 지역 결정

Decision ID Decision Relation Supporting Claims Status
D1 First Login Review Profile을 기본 off로 둔다 local raw/project-notes/keycloak-patterns-overview proposed
D2 automatic email linking 대신 manual confirm을 사용한다 local raw/project-notes/keycloak-patterns-overview proposed
D3 environment별 Google OAuth client를 분리한다 local raw/project-notes/keycloak-patterns-overview proposed
D4 Google scope를 openid profile email로 제한한다 local raw/project-notes/keycloak-patterns-overview proposed
D5 persistent federation key policy는 child owner를 소비한다 local raw/project-notes/keycloak-patterns-overview proposed

선언한 예외

Override ID Overrides Reason Approval Status

없음.

묶음 (자식 sub-sub-branches)

Sources는 하단 "외부 근거" 섹션. Errors/Interview/Lectures/Blog 는 현재 없음.

목표

P1A에 외부 IdP(Google)가 붙으면 토큰 흐름이 어떻게 확장되는지를 명확히 한다.

핵심 통찰: edge proxy 입장에서는 변화가 없다. oauth2-proxy는 여전히 Keycloak 한 곳에만 redirect 하고, Keycloak이 발급한 Keycloak access token만 받는다. Google federation은 Keycloak 내부에서 일어나는 외부 IdP brokering 흐름이며, edge / backend 입장에서는 투명(transparent)하다.

면접 / 설계 시 자주 헷갈리는 지점:

  • "Google 로그인을 붙이면 backend가 Google ID token을 검증해야 하나?" → 아니다. P1B backend trust는 raw/branch-notes/feature-keycloak-edge-forwardauth-no-google D3 — P1A와 같은 header-only 계약이며 Google token과 Keycloak token을 backend로 전달하지 않는다.
  • "edge proxy가 Google client secret을 알아야 하나?" → 아니다. Google credential은 Keycloak이 보관·사용.
  • "추가되는 trust hop은 어디인가?" → Google → Keycloak. P1A 대비 추가된 신뢰 경계는 이 한 hop.

범위

포함 범위

  • P1B 컴포넌트 다이어그램 (P1A 대비 추가 컴포넌트 표시)
  • P1A 대비 추가되는 토큰 교환 단계 (4–8) 명시
  • Google federation 시 추가되는 신뢰 경계와 보안 surface
  • First Login Flow 정책 결정 지점 (Review Profile / Account Linking)
  • P1A 대비 장단점 / 운영 비용 비교

제외 범위

  • 실제 구현 (P1B는 문서까지만 — root의 implementation 대상은 P3A)
  • Google 외 IdP (GitHub / Facebook / Apple). Google만.
  • Keycloak Authentication Flow custom code (Java SPI). 설정 옵션 수준까지.
  • prod 환경 Google API rate limit / quota 분석.

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

본 sub-branch의 P1B (Edge + Google federation) 채택 근거. 상세 대안 비교는 §외부 근거 / 대안 조사 참조.

Source 정당화하는 결정
raw/official-docs/keycloak-identity-brokering-overview-official Keycloak Identity Broker 공식 — Google IdP brokering 패턴 채택 근거
raw/official-docs/keycloak-google-idp-setup Keycloak Google IdP setup 절차 — 구성 단계 근거
raw/official-docs/google-openid-connect-oidc Google OIDC 표준 (issuer, scopes, claims) — Google IdP 표준 동작 근거
raw/official-docs/keycloak-first-login-flow First Broker Login Flow — Account Linking 정책 근거
raw/company-tech-blogs/keycloak-google-login-codemancers Keycloak + Google 통합 실무 사례 (참고)

컴포넌트 다이어그램

Browser
   │
   ▼
Ingress (nginx / Traefik)
   │
   ▼
ForwardAuth (oauth2-proxy)  ────► Keycloak  (realm: app)
                                     │  (사용자가 "Sign in with Google" 클릭)
                                     ▼
                                  Google OIDC
                                  (authorize / token / userinfo)
                                     │  (Google ID token + access token)
                                     ▼
                                  Keycloak
                                  (First Login Flow:
                                     Google sub/email → Keycloak user
                                     매핑 또는 신규 생성)
                                     │  (Keycloak access token 발급)
                                     ▼
                                  oauth2-proxy
                                     │  (proxy 세션 cookie 셋팅 + 헤더 주입)
                                     ▼
                                  Ingress
                                     │
                                     ▼
                                  Backend
                                  - edge가 주입한 trusted header만 신뢰
                                  - JWT/Google token은 보지 않음

핵심 표시:

토큰 교환 sequence (P1A 대비 추가 단계 포함)

P1A 단계와 일치하는 부분은 그대로, Google federation 분기만 새 번호로 표기.

  1. (P1A 1과 동일) 사용자 브라우저가 보호 리소스 GET → Ingress → oauth2-proxy.
  2. (P1A 2와 동일) oauth2-proxy: 세션 없음 → Keycloak authorize redirect.
  3. (P1A 3과 동일) Keycloak 로그인 페이지 표시.
  4. (추가) Keycloak 로그인 UI에 "Sign in with Google" 버튼 노출 (Identity Provider로 Google 등록 시 자동).
  5. (추가) 사용자 버튼 클릭 → Keycloak → Google authorize endpoint redirect (https://accounts.google.com/o/oauth2/v2/auth, scope=openid profile email).
  6. (추가) 사용자 Google 로그인 → Google → Keycloak broker callback (/realms/<realm>/broker/google/endpoint, code 전달).
  7. (추가) Keycloak → Google /token (https://oauth2.googleapis.com/token), Google ID token + access token 수신.
  8. (추가) Keycloak: Google ID token의 sub(영구 식별자) / email claim → First Login Flow 진입.
    • 기존 federated user 있음 → 그대로 매핑된 Keycloak user 사용.
    • 없고 email match로 기존 local user 있음 → Handle Existing Account 서브플로우 (자동 링크 / 수동 confirm).
    • 둘 다 없음 → 신규 Keycloak user 생성 (Review Profile 옵션에 따라 확인 페이지).
  9. (P1A 5와 동일) Keycloak → oauth2-proxy callback (/oauth2/callback, code 전달). oauth2-proxy → Keycloak /token. Keycloak access token + refresh token + ID token 발급.
  10. (P1A 67과 동일) oauth2-proxy: 세션 cookie 셋팅 + 헤더(X-Auth-Request-Email 등) 주입 후 backend로 forward. P1B 기본 계약은 bearer token을 전달하지 않고 backend가 edge header만 신뢰한다.

신뢰 경계 (P1A 대비 변화)

경계 P1A P1B
Browser ↔ oauth2-proxy TLS, 세션 cookie 동일
oauth2-proxy ↔ Keycloak TLS, client secret 동일
Keycloak ↔ Google 신규. TLS, Google OAuth client secret (Keycloak이 보관)
oauth2-proxy ↔ Backend trusted identity header (bearer token 미전달) 동일
Backend의 token 검증 없음 — edge에서 인증 종결, header-only 동일 — Google federation만 추가

신규 trust hop = Google → Keycloak 한 개. Google ID token signature는 Keycloak이 검증하고 oauth2-proxy는 Keycloak 세션을 만든다. 그 이후 backend trust는 P1A와 같은 header-only 경계다.

장점 / 단점 vs P1A

장점

  • 사용자가 Google 계정으로 로그인 가능 → 별도 비밀번호 관리 불필요. UX 개선.
  • 조직이 Google Workspace 사용 중이면 사실상의 SSO 통합 (사내 Google 계정 그대로 사용).
  • Keycloak이 brokering 하므로 edge/backend 코드 변화 0 — P1A에서 Identity Provider만 추가 설정.
  • 다른 외부 IdP(Microsoft / GitHub) 추가 시에도 동일 패턴으로 확장 가능 (broker만 추가 등록).

단점

  • 외부 의존: Google OIDC downtime / rate limit 시 신규 로그인 불가 (이미 발급된 Keycloak 세션은 영향 없음).
  • 사용자 매핑 정책 운영 부담: First Login Flow / Account Linking 정책 결정 필요. 잘못 설정 시 보안 이슈 (자동 email match linking → account takeover 위험).
  • 보안 surface 확장:
    • Google OAuth client secret이 Keycloak DB(또는 vault)에 저장됨.
    • Google Cloud Console의 redirect URI 등록 관리 (환경별 OAuth client 분리 필요).
    • Google 측 권한 변경(예: scope 변경, OAuth verification 요구) 시 영향 받음.
  • 개인정보 / 동의 흐름 추가: Google scope 동의 화면, GDPR 등 데이터 처리 정책 영향.
  • 디버깅 복잡도: 로그인 실패 시 oauth2-proxy / Keycloak / Google 3-leg 중 어디서 실패했는지 추적 필요 (로그 corr id 설계 중요).

결정 사항 (decisions)

본 sub-branch는 문서까지만 (documented-only)이므로 실제 환경 결정은 없음. 만약 구현한다면 권장 기본값:

  • D1 — First Login Flow / Review Profile: OFF (Google이 email/profile 제공하므로 불필요). 단, 신규 사용자 동의 페이지가 필요한 비즈니스 요건이면 ON.
  • D2 — Account Linking: 수동 confirm. 공식 문서가 "automatic linking by email = potential security hole" 명시. email match 시 사용자가 명시적으로 link 확인하도록.
  • D3 — Google OAuth client 분리: dev / staging / prod 환경별 별도 OAuth client. redirect URI 충돌 방지.
  • D4 — scope: openid profile email만. (추정 — 추가 scope 요청 시 Google OAuth verification 이 트리거될 수 있으나 인용 raw 가 enumerate 안 함, 별도 raw 확보 전까지 근거 미보증.)
  • D5 — persistent federation key requirement: raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D1 — concrete key policy owner. 본 parent는 안정적인 외부 subject를 사용한다는 P1B invariant만 consume한다.

needs-confirmation:

  • Keycloak 세션 만료 시 Google refresh token으로 자동 갱신 가능 여부 (Keycloak이 Google refresh token을 보관하나? 정책상 사용자 재로그인이 일반적).
  • Google account 삭제 / suspend 시 Keycloak local user 자동 비활성화 여부.

결정-근거 매핑

P1B 권장 기본값 결정과 raw source claim 매핑. company-tech-blog (codemancers) claim 은 보조 근거 — 공식 best practice 로 격상 금지 (CLAUDE.md §5).

선택 조건 열(R2): 각 결정이 "어떤 조건일 때 이 값, 다른 조건이면 어떤 대안" 인지. 상세 근거는 §결정 사항 prose.

Decision ID Decision 선택 조건 (언제 이 결정 / 언제 대안) Supporting Claims Evidence Strength Open Risk
D1 First Login Flow / Review Profile = OFF (Google이 email/profile 제공하므로 불필요) Google 이 email+profile 을 제공 → Off. 신규 사용자 동의/추가 attribute 수집이 비즈니스 요건이면 On, mandatory attr 부재 대비 fallback 만이면 missing (KC-FLF-C4 의 3-mode) raw/official-docs/keycloak-first-login-flow.md#KC-FLF-C4, raw/official-docs/keycloak-google-idp-setup.md#KC-GIDP-C5, raw/official-docs/google-openid-connect-oidc.md#GOIDC-C4 official-vendor-doc (Keycloak) + official-standard (Google OIDC) KC-FLF-C4 의 "mandatory information" 정확한 목록 (locale 포함 여부 등) 미확정 — Off mode 에서도 누락 시 자동 fallback 동작 확인 필요
D2 Account Linking = 수동 confirm (자동 email link 금지) 외부 IdP email 을 항상 신뢰할 수 없음이 기본(KC-FLF-C2 공식 경고) → 항상 Confirm Link. 자동 email link 는 통제된 신뢰 환경에서도 공식 경고 대상이라 채택 안 함 (대안 없음) raw/official-docs/keycloak-first-login-flow.md#KC-FLF-C2, raw/official-docs/keycloak-first-login-flow.md#KC-FLF-C3 official-vendor-doc (Keycloak 공식 security warning 명시) "Confirm Link Existing Account" 가 Keycloak version 별 default flow 에 포함되는지 vs 별도 추가인지 — KC-FLF-C3 의 "Does not prove" 에 명시 — version 별 확인 필요
D3 dev / staging / prod 환경별 별도 Google OAuth client 환경별 redirect URI/도메인이 다름 → 환경당 별도 OAuth client. 단일 도메인·단일 환경이면 client 1개 + 다중 redirect URI 로도 가능 raw/official-docs/keycloak-google-idp-setup.md#KC-GIDP-C3, raw/official-docs/keycloak-google-idp-setup.md#KC-GIDP-C4, raw/company-tech-blogs/keycloak-google-login-codemancers.md#CM-KC-GG-C4 (보조 — company case study, 공식 best practice 아님) official-vendor-doc (Keycloak) + company-case-study (codemancers, 보조) "환경별 분리가 redirect URI 충돌 방지에 필수" 는 일반 운영 원칙으로 raw claim 들이 직접 명시하지 않음 — KC-GIDP-C4 의 wildcard / 부분 매칭 허용 여부가 raw 범위 밖
D4 scope = openid profile email email/profile 매핑만 필요 → Keycloak default 3 scope 유지. hd(도메인 제한)·groups 등 추가 사용자 데이터가 필요할 때만 scope 추가 raw/official-docs/keycloak-google-idp-setup.md#KC-GIDP-C5, raw/official-docs/google-openid-connect-oidc.md#GOIDC-C4 official-vendor-doc (Keycloak default) + official-standard (Google OIDC scope contract) "추가 scope 요청 시 Google OAuth verification 트리거" 는 본 raw 들이 직접 enumerate 하지 않음 — Google OAuth verification 정책 별도 raw 보존 필요
D5 P1B는 stable external subject를 요구하며 concrete persistent federation key policy를 직접 소유하지 않음 key 선택·변경은 child owner에서만 수행. parent는 그 결과를 P1B topology invariant로 consume raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D1 — persistent Google federation key owner delegated Keycloak 저장 메커니즘과 initial collision locator의 차이는 child에서 추적; parent에 복제하지 않음

구현 가이드

본 브랜치는 documented-only 설계 hub — P1B topology와 pattern-level 요구만 소유하고 Google brokering의 mutable 설정은 자식 브랜치(§Cluster 4개)에 위임한다. 아래 parent D-row는 자식 owner의 값을 복제하지 않고 pointer로 consume한다. 모든 항목 등급 planned — 구현 repo(keycloak-patterns/)가 아직 없어 코드로 확정된 것은 0개(NO_GROUND_TRUTH, ground truth = 공식 raw 문서). 코드 확인 후 등급 승격.

3-rule 준수: 각 sub-section 은 Decision ID + Supporting Claim ID 를 Trace. 근거 raw 가 원칙 만 주고 detail 은 안 주는 cell 은 UNSUPPORTED_IMPL_DECISION + trade-off 한 줄. 본 브랜치 결정 범위 밖 detail(Java SPI custom code 등)은 §범위 out-of-scope 로 이미 배제.

1. Google IdP 등록 (realm config) — D3 · D4 + delegated D5

Trace: D3(환경별 client)·D4(scope). raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D1 — persistent federation key owner. IdP client 설정 owner는 raw/branch-notes/feature-keycloak-idp-brokering-google-client.

  • UNSUPPORTED_IMPL_DECISION: (a) redirect URI 정확한 path 형식 — raw 가 명시 안 함(KC-GIDP-C3 "does not prove"), Admin Console 자동표시값을 복사(Claim To Verify #6 가 추적). trade-off: path 를 하드코딩하면 KC_HTTP_RELATIVE_PATH/host 조합 변화에 취약 → UI 표시값 복사가 안전. (b) discovery endpoint cache/retry 동작 — GOIDC-C5 는 URL 만 줌(Claim To Verify #1). (c) 환경별 client 분리 — official 미보증 운영 추론(KC-GIDP-C3/C4 는 양방향 등록까지만). trade-off: 단일 client 다중 redirect URI 도 가능하나 환경 간 실수 유출 위험 → 환경별 분리가 안전측.
설정 항목 값 / 경로 Trace 등급
IdP 등록 진입 Admin Console → Identity ProvidersAdd providerGoogle KC-GIDP-C1 planned
Client 자격 Google 발급 Client ID + Client Secret 을 Keycloak Google IdP 에 입력 (Keycloak DB/vault 보관) KC-GIDP-C2, D3 planned
환경 분리 dev/staging/prod 각 환경별 Google OAuth client 별도 발급 (redirect URI 충돌 방지). UNSUPPORTED_IMPL_DECISION — official 미보증 운영 추론 D3(운영 추론, KC-GIDP-C3/C4 는 양방향 등록까지만 L1 증명) · CM-KC-GG-C4(보조) planned
Redirect URI Keycloak Add Identity Provider 페이지 표시값 → Google Cloud Console Authorized redirect URIs 에 복사. 예상 형식 https://<keycloak-host>/realms/<realm>/broker/google/endpoint (UNSUPPORTED_IMPL_DECISION — 형식은 raw 인용 밖, UI 표시값 신뢰) KC-GIDP-C3, KC-GIDP-C4 planned
Scope Default Scopes = openid profile email 유지, 추가 scope 금지(D4 조건) KC-GIDP-C5, D4 planned
Discovery "Import from URL" = https://accounts.google.com/.well-known/openid-configuration GOIDC-C5 planned (Claim To Verify #1)

2. First Broker Login Flow hardening — D1 · D2

Trace: D1(Review Profile)·D2(Confirm Link) / Claims KC-FLF-C2, KC-FLF-C3, KC-FLF-C4. Owner 자식: raw/branch-notes/feature-keycloak-first-broker-login-flow.

Flow 설정 Trace 등급
Flow 편집 전 복제 built-in "first broker login" flow 를 복제 후 수정 (원본 훼손 시 외부 IdP 전체 차단 위험) KC-FLF 운영맥락(L90) planned
Review Profile authenticator Off (Google 이 email+profile 제공). 동의 페이지 필요 시만 On, mandatory 부재 대비만이면 missing KC-FLF-C4, D1 planned
Confirm Link Existing Account required — 자동 email link 금지, 사용자 명시 confirm 강제 (info page: 다른 email 사용 vs link 확인) KC-FLF-C2, KC-FLF-C3, D2 planned
linking trust policy raw/branch-notes/feature-keycloak-first-broker-login-flow D4 — silent auto-link 방지 core를 consume. email_verified=false 전체 hard-reject는 custom SPI가 별도 채택될 때만 추가 delegated documented-only; SPI variant는 out-of-scope

3. Account matching identifier (IdP mapper) — D5

Trace: D5. raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D1 — persistent federation key owner. raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D4 — claim→attribute mapper owner.

  • UNSUPPORTED_IMPL_DECISION: sub 를 federated identity primary key 로 매핑하는 정확한 Keycloak IdP mapper 타입/옵션 — 참조 raw 미포함(D5 Open Risk 가 keycloak-identity-provider-mappers.md 필요 명시). trade-off: mapper 타입 임의 선택 시 재로그인 매칭 실패 가능 → mapper raw 확보 후 자식 브랜치에서 확정.
  • Persistent federation key와 mapper 타입/옵션은 위 두 owner D-row를 참조한다. 본 parent는 stable external subject requirement만 유지한다.

엣지·실패·의존

R4 캡처용. 본 브랜치는 documented-only 지만, Google leg 추가로 P1A 대비 새 실패 경로가 생기고, 자식·형제 브랜치와 계약 의존이 있다.

검증해야 할 주장

본 sub-branch 는 documented-only. 만약 구현한다면 검증해야 할 주장 enumerate.

Claim Why uncertain How to verify Status
Keycloak 의 Google IdP "Use discovery endpoint" 옵션이 https://accounts.google.com/.well-known/openid-configuration 으로 정상 OIDC discovery 수행 GOIDC-C5 가 URL 명시했으나, Keycloak 의 discovery 호출 실제 동작 (cache TTL, retry 정책 등) 별도 검증 Keycloak Admin Console > Identity Provider > Google > "Import from URL" 클릭 후 endpoint 자동 채워지는지 확인 + keycloak debug log 에서 GET 요청 확인 planned
Keycloak 세션 만료 시 Google refresh token 으로 자동 갱신 가능 여부 본 sub-branch §결정 사항 needs-confirmation 명시 — Keycloak 이 Google refresh token 을 보관하는지 정책 불명 Keycloak Admin Console > Identity Provider > Google > "Store Tokens" 옵션 활성화 후 세션 만료 후 동작 관찰 + Keycloak DB federated_identity 테이블 검사 needs-confirmation
Google account 삭제 / suspend 시 Keycloak local user 자동 비활성화 여부 본 sub-branch §결정 사항 needs-confirmation 명시 — Keycloak 에 webhook / polling 메커니즘 없음 (일반적) Google Cloud Console 에서 test account suspend 후 Keycloak login 시도 → 거부 여부 관찰 (예상: Keycloak 은 모름, login 시점에 Google 측 401 로만 차단) needs-confirmation
First Broker Login Flow 의 "Confirm Link Existing Account" authenticator 가 Keycloak 26.x default flow 에 포함됨 KC-FLF-C3 가 authenticator 존재 명시했으나 version 별 default flow 포함 여부 별도 확인 필요 Keycloak Admin Console > Authentication > Flows > "first broker login" flow 확인 + "Confirm Link Existing Account" step 존재 여부 planned
P1B가 P1A의 header-only backend trust를 유지하고 Google/Keycloak bearer token을 backend로 전달하지 않음 raw/branch-notes/feature-keycloak-edge-forwardauth-no-google D3을 consume하지만 실제 proxy config는 아직 없음 Google 로그인 후 oauth2-proxy/ingress config와 backend request capture에서 trusted headers 존재, Authorization 부재, direct spoof 요청 차단을 확인 planned
Google OAuth client 의 redirect URI 가 /realms/<realm>/broker/google/endpoint 형식과 정확히 일치 KC-IDP-BROKER-C2 가 verbatim 부재 명시 — Admin UI 표시값을 신뢰 Keycloak Admin Console > Identity Provider > Google 페이지의 "Redirect URI" 필드 값을 복사 → Google Cloud Console 의 Authorized redirect URIs 와 byte-level 일치 확인 planned
(Deferred SPI variant) email_verified=false를 flow 진입 즉시 hard-reject하는 custom authenticator를 별도 구현할 필요가 있는가 현재 corpus에 provider JAR/SPI artifact가 없고 core silent-link 방지는 raw/branch-notes/feature-keycloak-first-broker-login-flow D4로 성립 별도 제품 요구가 생길 때 SPI branch를 만들고 provider JAR, flow export, false-email negative E2E를 함께 검증 planned (현재 acceptance 아님)

외부 근거 / 대안 조사 (2026-05-25 — P1B Edge + Google IdP Brokering)

본 sub-branch의 Edge ForwardAuth + Google IdP Brokering 채택에 대한 외부 source. P1A에 외부 IdP federation을 추가하는 방식의 대안 비교.

  • 채택 결정 (Keycloak IdP Brokering — Google을 외부 IdP로 등록):
  • 검토한 대안:
    • 대안 1: SAML federation (Keycloak ↔ Google Workspace SAML) — 엔터프라이즈 단일 사인온 표준. 그러나 Google OIDC가 더 단순.
    • 대안 2: Google OIDC 직접 (Keycloak 우회) — 백엔드가 Google ID token 직접 검증. 장: Keycloak 운영 부담 0 / 단: 다중 IdP 통합 어려움, role mapping 직접 작성.
    • 대안 3: Auth0 / Okta (managed multi-IdP SaaS) — 운영 완전 위임. 단: vendor lock-in, 비용.
    • 대안 4: oauth2-proxy --provider=google 직접 — Keycloak 없이 oauth2-proxy가 Google과 직접 통신. 장: Keycloak 제거 / 단: realm/role 관리 불가, 멀티 IdP 통합 불가.
    • 대안 5: AWS Cognito + Google federation — AWS 종속, 동일 패턴.
  • 비교 핵심: IdP Brokering의 본질적 가치는 "코드 변경 없이 IdP 추가". SPA/백엔드는 Keycloak만 알면 되고, Google/SAML/LDAP 추가는 Keycloak admin 설정만. AutoLink는 별도 opt-in 위험 기능이며, 본 패턴은 raw/branch-notes/feature-keycloak-first-broker-login-flow D1/D4의 silent-link 방지 core를 따른다.

TODO

각 항목 옆에 증거 등급.

  • P1B 다이어그램을 Mermaid sequence로 재작성 — 등급: planned
  • P1A vs P1B diff matrix (sequence 단계 / trust boundary / 운영 비용) — 등급: planned
  • First Login Flow 정책 분기 트리 도식화 — 등급: documented-only (구현 안 함)
  • Keycloak refresh / Google session 만료 상호작용 확인 — 등급: needs-confirmation

진행 중 메모

  • Google ID token은 Keycloak이 검증한 뒤 backend로 전달하지 않는다. oauth2-proxy가 Keycloak token으로 session을 만들고, P1B backend는 raw/branch-notes/feature-keycloak-edge-forwardauth-no-google D3과 같은 edge-injected header-only 계약만 소비한다. 따라서 backend로 Google/Keycloak bearer token이 흐른다고 표현하지 않는다.
  • "Google 로그인 = backend가 Google과 통신"으로 오해하기 쉬움. 다이어그램에서 Google ↔ Keycloak leg를 별도 색/박스로 강조해야 함.
  • 본 sub-branch는 documented-only 한정 — wiki/projects/로 승급 안 함 (root TODO 참조).

마주친 문제

  • 없음 (구현 안 함).

관련 sub-branch

관련 일일 노트

완료 후 정리

  • PR 링크: (없음, 문서까지만)
  • 머지 결과 / 배포 환경: 없음 (documented-only)
  • wiki 추출 대상: 없음. P1B는 root 정책상 wiki/projects/ 승급 안 함.
  • 추출하지 않을 항목: 본 sub-branch 전체 (documented-only / planned).