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-google-claim-attribute-mapping (Google claim → Keycloak attribute mapping) | branch-note | raw | BR-KEYCLOAK-PATTERNS-OVERVIEW-017 | project-work-item | keycloak-patterns-overview | WI-KEYCLOAK-PATTERNS-OVERVIEW-017 |
|
|
1 | feature-keycloak-google-claim-attribute-mapping |
|
|
2026-05-25 | in-progress | f1610a6ccdece483c1cdbf85293c304f640dede279cd7bfe7bf4cdb64e1f6e52 |
branch: feature-keycloak-google-claim-attribute-mapping (Google claim → Keycloak attribute mapping)
Layer:
raw/branch-notes/— raw/project-notes/keycloak-patterns-overview의WI-KEYCLOAK-PATTERNS-OVERVIEW-017직접 branch. 학습 노트: P1B는documented-only(실 구현 안 함).status_label:in-progress
정합 노트 (2026-07-14 감사): 본 노트 = Google claim → Keycloak attribute-mapping owner (hub Branch 분해 Tier-2
feature-keycloak-google-claim-attribute-mapping). 형제 raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role 와 매핑 내용이 겹치는데, 그쪽은 role → 권한(RBAC) 부분만 남기고 §5 deferred 로 분리됨.정합 노트 (2026-07-16 /branch-spec): 근거 승격·delegate·구현 명세 채움 회차. §Decision Evidence Map 에
선택 조건(R2) 열 추가, D3 근거 official 승격, D5(hd→role) 형제로 delegate,## 구현 가이드·## 엣지·실패·의존신설. 자동조사 dispatch 0회(근거 이미 아카이브됨). 상세는 §Audit & Findings. coverage:governing_docs미지정 +related_projects: [keycloak-patterns]→ 면제(coverage-gate §7).
부모 (필수)
raw/project-notes/keycloak-patterns-overview
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
1 - 패킷 스키마:
contract_packet: 1 - 완료 조건: Google email·name claim이 Keycloak attribute로 매핑된다
상속한 프로젝트 결정
| Decision Ref | Project Summary | Branch Application | Source |
|---|---|---|---|
DEC-KEYCLOAK-PATTERNS-OVERVIEW-IDP-BROKERING-001@1 |
Google federation은 Keycloak IdP brokering과 hardened First Broker Login을 사용한다 | Google claim을 Keycloak user attribute로 매핑하는 정책에 적용한다 | 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 |
|---|
없음.
목표
Google ID token에는 sub, email, email_verified, name, given_name, family_name, picture, locale 등 표준 claim이 포함된다. 이를 Keycloak user의 속성(firstName, lastName, email, custom attribute) 또는 role로 매핑하려면 Identity Provider Mapper를 설정해야 한다.
본 노트는 mapper 종류, sync mode, primary key 선택 (sub vs email)의 함의를 정리한다.
핵심 통찰:
subclaim은 영구·불변 (Google이 사용자별로 발급한 고유 ID). email은 변경 가능 / 재사용 가능 (자세한 분석은 raw/branch-notes/feature-keycloak-account-linking-sub-vs-email).- Keycloak의 federated identity 테이블은 **
identity_provider+provider_user_id(= Googlesub)**를 primary key로 사용 → email이 바뀌어도 link 유지. - Mapper 모드 (
IMPORT,LEGACY,FORCE,INHERIT)에 따라 first login 시점에만 매핑 / 매 로그인마다 갱신 / IdP 설정 상속 등으로 동작이 달라짐.
범위
본 노트 = attribute-mapping owner (2026-07-14 감사). claim → role(RBAC) 은 형제 소유(아래 delegate).
포함 범위
- Google ID token 표준 claim → Keycloak user attribute 매핑 (Attribute Importer):
email/given_name/family_name/picture(D4) - federated identity primary key = Google
sub(built-in, mapper 불필요) (D1) - Username 생성 정책 (Username Template Importer):
${ALIAS}.${CLAIM.sub}(D2) - IdP-level Sync Mode 선택 (IMPORT vs FORCE) — attribute 최신성 정책 (D3)
- mapper 종류 카탈로그 정리 (D6,
needs-confirmation)
제외 범위
의도적으로 제외한 것. 대부분 다른 owner 브랜치로 delegate — §엣지·실패·의존 의 "다른 계약 의존" 참조.
- claim → role (RBAC 인가) 매핑 (
hd→role 포함) — owner raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role (D5 delegate) - account linking key 안전성 (sub vs email 계정탈취) — owner raw/branch-notes/feature-keycloak-account-linking-sub-vs-email
- First Broker Login Flow
email_verified게이트 / email auto-linking 방어 — owner raw/branch-notes/feature-keycloak-first-broker-login-flow - Client Scope Mapper (Keycloak user attribute → access token claim, 2단계 전파) — client-level (P2A 계열), 본 IdP-level 범위 밖
- 실제 코드/배포 — 본 P1B sub-sub-branch 전체
documented-only/planned
근거 (필수, 최소 1개+)
- raw/official-docs/keycloak-identity-provider-mappers — Keycloak IdP Mapper 종류 / sync mode 공식 (mapper 종류
KC-IDP-MAPPER-C4는 verbatim 부재 →needs-confirmation) - raw/official-docs/google-openid-connect-oidc — Google ID token 표준 claim (
GOIDC-C3sub영구·emailprimary key 금지 /GOIDC-C4emailscope) - raw/official-docs/google-oidc-discovery-spec — D5 (
hd) 와 D1 (sub) 보강:GOOGLE-OIDC-C7(hd= Google Workspace/Cloud org domain, verbatim) +GOOGLE-OIDC-C6(subunique among all Google Accounts and never reused) +GOOGLE-OIDC-C4(scope =openid+profile/email). 기존related_branches에 본 브랜치가 이미 포함돼 있었으나 Sources 표에 미등록이었음 → 2026-07-16 추가 - raw/official-docs/keycloak-identity-brokering-overview-official — federated identity 모델
- raw/official-docs/keycloak-identity-provider-sync-mode-official — D3의 IdP-level attribute Sync Mode 공식 근거(IMPORT/FORCE/LEGACY/INHERIT verbatim). 이전
keycloak-identity-provider-mappers.md#KC-IDP-MAPPER-C5의needs-confirmationgap 을 메움
TODO
각 항목 옆에 증거 등급. 본 P1B sub-sub-branch는 전체 documented-only / planned.
- Identity Provider Mapper 종류 정리 — 등급:
documented-only- Attribute Importer: Google claim → Keycloak user attribute (예:
pictureclaim →pictureuser attribute) - Username Template Importer: Google claim 조합으로 Keycloak username 생성 (예:
${CLAIM.email}또는${ALIAS}.${CLAIM.sub}) - Hardcoded Role: 본 IdP로 로그인한 모든 사용자에게 특정 role 부여 (예:
realm:user) - Hardcoded Attribute: 모든 broker 사용자에게 같은 속성값 부여
- Claim to Role: Google claim 값에 따라 조건부 role 매핑 (예:
hdclaim =mycompany.com→realm:employee) - Advanced Attribute to Role / Claim to Group: 복합 조건 매핑
- Attribute Importer: Google claim → Keycloak user attribute (예:
- 표준 Google claim 매핑 계획 — 등급:
plannedemail→ Keycloakemail(자동 매핑 가능)given_name→ KeycloakfirstNamefamily_name→ KeycloaklastNamepicture→ Keycloak custom attributepicturesub→ Keycloak federated identityprovider_user_id(자동, mapper 불필요)
- Sync Mode 비교 정리 — 등급:
documented-only- IMPORT: first login 시점에만 attribute 복사. 이후 Google 측 변경 무시.
- LEGACY: deprecated.
- FORCE: 매 로그인마다 Google claim으로 Keycloak attribute 덮어쓰기. Google 측 변경 자동 반영.
- INHERIT: IdP 설정의 default sync mode 상속.
- Username 생성 정책 결정 — 등급:
documented-only- 옵션 A:
email을 username으로 (가독성 ↑, email 변경 시 username 변경 문제) - 옵션 B:
${ALIAS}.${CLAIM.sub}(예:google.1234567890, 영구 안정 / 가독성 ↓) - 권장: B (불변성 우선)
- 옵션 A:
hd(hosted domain) claim 활용 검토 — 등급:documented-only— DELEGATED → 형제 raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role (role/RBAC owner, D5 참조). 본 노트는hd를 attribute 로 import 하는 경우만 §구현 가이드 §1 방식 재사용, role 매핑은 형제 소유.- Google Workspace 사용자의 경우
hd=mycompany.comclaim 제공 (사실 근거:GOOGLE-OIDC-C7) - "Claim to Role" mapper로 사내 도메인 사용자에게 자동 role 부여 가능 (→ 형제 D3)
- Google Workspace 사용자의 경우
진행 중 메모
- Keycloak 25.x 기준 Mapper 설정 UI는 IdP 상세 페이지의
Mappers탭. 새 mapper 추가는Add mapper버튼. Attribute Importer의Claim필드는 Google claim 이름 그대로 (예:email,given_name). 중첩 claim은 dot notation (예:address.locality).Username Template Importer는 first login 시점에만 실행 (이후 username 변경 없음) — 따라서 Sync Mode와 무관하게 IMPORT 동작.- email을 username으로 쓰면 사용자 friendly하지만, Google에서 email alias 변경 / 회사 이메일 재배정 시 충돌 발생 가능 → 본 프로젝트는 sub 기반 username 권장.
- federated identity 자체는
sub기반 — mapper와 별개로 Keycloak이 internal하게 관리.
결정 사항 (decisions)
본 sub-sub-branch는
documented-only— 실 환경 결정 없음. 만약 구현한다면 권장 기본값.
- 2026-05-25: federated identity primary key = Google
subclaim. email 변경에 robust. - 2026-05-25: Username 생성 =
${ALIAS}.${CLAIM.sub}(불변성 우선). 사용자에게 보이는 display name은 별도nameattribute로 분리. - 2026-05-25: Sync Mode = IMPORT (first login 시점 매핑만). 매 로그인마다 덮어쓰기는 사용자 직접 변경한 Keycloak attribute를 매번 되돌려 UX 저하.
- 2026-05-25:
email/given_name/family_name/picture4개 Attribute Importer 매핑 기본. - 2026-05-25:
hdclaim 기반 role 매핑은 Google Workspace 도입 시점에 추가 (현재는 보류). → 2026-07-16 정합: 이hd→role 결정은 role/RBAC owner 인 형제 raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role D3 소유로 delegate(본 노트는 attribute-mapping owner). Decision Evidence Map D5 참조.
결정-근거 매핑
본 sub-sub-branch 는
documented-only. cited raw:keycloak-identity-provider-mappers,google-openid-connect-oidc,google-oidc-discovery-spec,keycloak-identity-provider-sync-mode-official,keycloak-identity-brokering-overview-official. 2026-07-16 정합 (/branch-spec) — 상세는 §Audit & Findings: (1) D3 근거를KC-IDP-MAPPER-C5(needs-confirmation) →KC-SYNCMODE-C3/C4/C1(official-vendor-doc)로 승격 (Sync Mode verbatim 회수됨). (2) D5(hd→role)를 형제 raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role D3 으로 delegate — 본 노트는 attribute-mapping owner, role/RBAC 는 형제 소유.hd사실 근거는GOOGLE-OIDC-C7(verbatim)로 확보. (3) mapper 종류(KC-IDP-MAPPER-C4)는 여전히needs-confirmation— Admin UI 캡처 대상.
| Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|---|
| D1 | federated identity primary key = Google sub claim — email 변경에 robust |
N/A — sub 는 불변·재사용 없음이라 항상 primary key. email 은 어떤 조건에서도 primary key 부적합("shouldn't use email … Always use the sub") |
raw/official-docs/google-openid-connect-oidc.md#GOIDC-C3 ("Always use the sub field as it is unique to a Google Account even if the user changes their email address") + raw/official-docs/google-oidc-discovery-spec.md#GOOGLE-OIDC-C6 (sub unique among all Google Accounts and never reused) |
official-vendor-doc |
Keycloak 의 provider_user_id 가 정확히 sub 로 매핑된다는 verbatim 은 cited raw 에 부재 — Server Admin Guide "Federated Identity" 섹션 raw 추가 필요 (→ Claims To Verify) |
| D2 | Username 생성 = ${ALIAS}.${CLAIM.sub} (불변성 우선); display name 은 별도 name attribute 로 분리 |
username 안정성(불변) 우선 시 → sub 기반. 가독성 우선 + email 재배정/충돌 없음 보장 시 → ${CLAIM.email} (대안). 학습 노트는 불변성 우선 |
raw/official-docs/google-openid-connect-oidc.md#GOIDC-C3 (email 변경 가능, sub 불변) — 배경 정당화. Username Template Importer 의 ${ALIAS}.${CLAIM.sub} syntax 자체는 raw/official-docs/keycloak-identity-provider-mappers.md#KC-IDP-MAPPER-C4 가 needs-confirmation (verbatim 부재) |
official-vendor-doc (sub 불변) + needs-confirmation (mapper syntax) |
Username Template Importer syntax verbatim 확보 필요 (Keycloak 소스 또는 admin UI 캡처) |
| D3 | IdP-level default Sync Mode = IMPORT (profile attribute는 first login 시점 매핑) |
사용자가 Keycloak 에서 직접 편집한 attribute 를 보존해야 하면 → IMPORT. Google 측 name/picture 변경을 매 로그인 자동 반영해야 하면 → IdP-level FORCE (대안) | raw/official-docs/keycloak-identity-provider-sync-mode-official.md#KC-SYNCMODE-C3 (import = first login 시점 데이터 import, verbatim) + #KC-SYNCMODE-C4 (force = update user data at each user login) + #KC-SYNCMODE-C1 (IdP-level Sync Mode = 모든 mapper default) |
official-vendor-doc |
Keycloak 25.x Admin UI 드롭다운 라벨과 실제 attribute 반영 시점은 realm export/UI 실측 전까지 needs-confirmation |
| D4 | email / given_name / family_name / picture 4개 Attribute Importer 매핑 |
N/A — 표준 프로필 claim 을 Keycloak user model 로 옮기는 기본 매핑(선택 분기 없음). scope 는 openid profile email 필요 |
raw/official-docs/keycloak-identity-provider-mappers.md#KC-IDP-MAPPER-C1 (incoming token → user/session attribute) + #KC-IDP-MAPPER-C3 (external credential → user model) + raw/official-docs/google-oidc-discovery-spec.md#GOOGLE-OIDC-C4 (scope 는 openid + profile/email) |
official-vendor-doc (general mapper + scope) + needs-confirmation (Attribute Importer 화면값) |
Attribute Importer 설정 화면값 verbatim 부재. given_name/family_name/picture 개별 claim 의 Google verbatim 부재 (C4 는 scope 규칙만) |
| D5 | hd (hosted domain) claim 기반 role 매핑 — DELEGATED (본 노트 결정 범위 밖) |
본 노트(attribute-mapping owner) 범위 밖 — claim → role(RBAC) 결정은 형제가 소유. hd→role 은 형제 D3 이 결정(Workspace 도입 시 Advanced Claim to Role 추가, 현재 보류) |
delegation → raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role D3. hd 사실 근거 = raw/official-docs/google-oidc-discovery-spec.md#GOOGLE-OIDC-C7 ("The domain associated with the Google Workspace or Cloud organization of the user.") |
delegated (hd 사실근거 official-vendor-doc) |
personal Gmail 의 hd 부재 시 mapper 동작(null/skip) — GOOGLE-OIDC-C7 "does not prove", 형제 노트에서 검증 |
| D6 | mapper 종류 5+ 존재 (Attribute Importer, Username Template Importer, Hardcoded Role, Hardcoded Attribute, Claim to Role, Advanced Claim to Role) | N/A — 사실(존재) 진술, 선택 분기 아님 | raw/official-docs/keycloak-identity-provider-mappers.md#KC-IDP-MAPPER-C4 (구체적 mapper 종류 목록 — strength: needs-confirmation, verbatim 부재) |
needs-confirmation |
Keycloak Admin UI 캡처 + Server Admin Guide sub-page 직접 발췌로 mapper 종류 verbatim 확보 |
- raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role D1 — role mapper freshness policy. Role freshness는 본 D3의 IdP-level attribute sync policy와 분리된 별도 owner가 결정한다.
Audit & Findings (2026-07-16 /branch-spec)
/branch-spec채움 회차의 정합·이관 기록. 결정 본문 아님(추적용). 자동조사 dispatch 0회 — 필요한 근거가 이미 repo 에 아카이브돼 있었음.
- SYNC_MODE_VERBATIM_RECOVERED (D3): 근거를
KC-IDP-MAPPER-C5(needs-confirmation) →KC-SYNCMODE-C3/C4/C1(official-vendor-doc)로 승격. Sync Mode verbatim 을 raw/official-docs/keycloak-identity-provider-sync-mode-official 이 회수(2026-07-15). 원 소스keycloak-identity-provider-mappers.md#KC-IDP-MAPPER-C5파일 자체의 strength 승격은 별도 migrate 대상(본 task 밖). - HD_CLAIM_EVIDENCE_FOUND (D5):
hd사실 근거가 citedgoogle-openid-connect-oidc엔 없었으나, 이미 repo 에 있던 raw/official-docs/google-oidc-discovery-spec#GOOGLE-OIDC-C7(Workspace domain, verbatim)이 커버 → Sources 표에 추가(그 raw 의related_branches엔 이미 본 브랜치 포함돼 있었음). D5 는UNSUPPORTED_DECISION이 아니라 형제로 delegate. - RESTATED_FOREIGN_DECISION (D5):
hd→role 은 형제 raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role D3 소유(2026-07-14 감사의 attribute/role owner 분리). 본 노트에서 결정으로 재진술하지 않고 delegate 포인터로 전환. - SYNC_MODE_OWNERSHIP_OVERLAP (2026-07-18 해소): 본 노트 D3는 IdP-level attribute sync policy만 소유한다. Role freshness 정책은 Decision Evidence Map 아래의 direct-owner pointer로 위임했고, 본 노트에서는 값·메커니즘을 재서술하지 않는다.
- BACKREF_IMPACT (비차단): 본 결정 표 수정으로 raw/branch-notes/feature-keycloak-account-linking-sub-vs-email · raw/branch-notes/feature-keycloak-account-linking-spa-ux 의 D1/D3/D4/D5 참조가 영향받을 수 있음. D1/D3/D4 는 의미 불변(evidence 보강만) → 참조 유효. D5 는 의미 변경(deferred → delegated) → 참조처 요약 대조 필요(§Claims To Verify 아래 처리 /
/sync).
구현 가이드
본 branch 는
documented-only— 실 Keycloak 등록 전 사전 명세. IdP-level Mapper(Identity Provider → Mappers 탭)만 다룬다. user attribute → access token claim 전파(Client Scope Mapper)는 client-level 이라 본 범위 밖(§범위 Out of scope). Keycloak 25.x 기준.
1. Attribute Importer mapper 카탈로그 (D4)
Trace: D4 —
KC-IDP-MAPPER-C1(incoming token → user attribute) +KC-IDP-MAPPER-C3(external credential → user model) +GOOGLE-OIDC-C4(scope =openid profile email). Sync Mode 계층은 §3(D3).
- UNSUPPORTED_IMPL_DECISION: (a) mapper instance 명(
google-*)은 임의 명명 — 근거 raw 에 명명 규칙 없음. trade-off:google-<claim>prefix 로 provider 출처+대상 claim 을 한눈에. (b) Attribute Importer 의 정확한 UI 필드명(Claim/User Attribute Name)과 built-in vs custom attribute 구분은KC-IDP-MAPPER-C4needs-confirmation— Admin UI 캡처로 확정.
| mapper instance (임의명) | mapper type | Google Claim | Keycloak target attribute | 비고 |
|---|---|---|---|---|
google-email |
Attribute Importer | email |
email (built-in user field) |
scope email 필요(GOOGLE-OIDC-C4). email 은 primary key 아님(D1) |
google-given-name |
Attribute Importer | given_name |
firstName (built-in) |
scope profile |
google-family-name |
Attribute Importer | family_name |
lastName (built-in) |
scope profile |
google-picture |
Attribute Importer | picture |
picture (custom attribute) |
URL 만료 가능(§엣지) |
2. Username Template Importer (D2)
Trace: D2 —
GOIDC-C3(sub 불변)이 sub 기반 username 을 정당화. syntax 자체는KC-IDP-MAPPER-C4needs-confirmation.
- UNSUPPORTED_IMPL_DECISION: template 문자열
${ALIAS}.${CLAIM.sub}의 정확한 placeholder 문법·구분자는 verbatim 미확보 — Admin UI/소스 확인 필요. trade-off:${ALIAS}prefix 로 다중 IdP username 충돌 방지 +sub로 불변성.
- Username Template:
${ALIAS}.${CLAIM.sub}→ 예google.1234567890 - 실행 시점: first login 만 (username 은 이후 불변) — Sync Mode 와 무관하게 IMPORT 동작(진행 중 메모).
3. IdP-level attribute Sync Mode (D3)
Trace: D3 —
KC-SYNCMODE-C1(IdP-levelSync Mode= 모든 mapper default) +KC-SYNCMODE-C3(import= first login) +KC-SYNCMODE-C4(force= each login). official-vendor-doc — UNSUPPORTED 아님.
- IdP-level
Sync Mode=IMPORT— §1 의 profile Attribute Importer default 로 상속. - profile attribute를 매 로그인 갱신해야 하는 환경에서는 IdP-level
FORCE를 대안으로 선택한다(D3).
4. federated identity (D1) — built-in, mapper 불필요
Trace: D1 —
GOIDC-C3+GOOGLE-OIDC-C6. Keycloak 이(identity_provider, provider_user_id=sub)로 internal 관리 → 별도 mapper 없음.
- UNSUPPORTED_IMPL_DECISION:
provider_user_id == sub매핑은 Keycloak 내부 동작으로 추정 — verbatim 미확보(Claims To Verify). trade-off: mapper 로 강제하지 않고 built-in 신뢰(공식 문서가 별도 mapper 를 요구하지 않음).
엣지·실패·의존
R4(깊이 게이트) 캡처용. 정상 매핑 경로 외 실패/엣지 + 다른 계약 의존.
- 실패·엣지 경로:
email_verified=falseGoogle 계정: attribute import 자체는 수행되나 계정 신뢰/링크 안전성은 별개 관심사 — First Broker Login Flow 게이트에 의존(아래). 게이트 없으면 email auto-linking 계정탈취 위험.- personal Gmail (
hd부재):hdclaim 이 없어hd기반 mapper 는 매칭 안 됨(null/skip 추정).GOOGLE-OIDC-C7"does not prove" — 실동작 검증은 형제(D5 delegate). pictureURL 만료: Google profile picture URL 은 OAuth scope 만료/변경 시 깨질 수 있음 → 장기 저장 시 stale. 표시용으로만 쓰고 캐싱/재조회 정책 별도(needs-confirmation).- Sync Mode IMPORT 부작용(의도됨): Google 측 name/picture 변경이 Keycloak 에 반영 안 됨 → 최신성 필요 시 FORCE 로 전환(D3 대안).
- 중첩 claim: dot notation(
address.locality) — 진행 중 메모 기준, verbatim 부재(needs-confirmation).
- 다른 계약 의존:
- raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D1(linking key =
sub) 에 의존 — 본 노트 D1(primary key = sub)이 그 결정을 consume. linking key 가 email 로 바뀌면 본 노트 primary-key 전제 붕괴. - raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role D3(
hd→role) 에 본 노트 D5 를 delegate — role/RBAC owner. - raw/branch-notes/feature-keycloak-idp-brokering-google-client D4(scope =
openid profile email) 에 의존 — 본 노트 §구현 가이드 §1 의 Attribute Importer 는 그 브랜치가 IdP client 에openid profile emailscope 를 등록해야만email/given_name/family_name/pictureclaim 이 채워짐(GOOGLE-OIDC-C4). scope 가 축소되면 해당 attribute 가 빈 값. - raw/branch-notes/feature-keycloak-first-broker-login-flow —
email_verified게이트 + email auto-linking 방어 owner (해당 브랜치 결정 번호화 시 그 Decision ID 로 상향 링크). - Client Scope Mapper(user attribute → access token claim, 2단계 전파) — client-level(P2A 계열) owner, 본 IdP-level 범위 밖.
- raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D1(linking key =
검증해야 할 주장
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
Keycloak 의 federated_identity 테이블이 (identity_provider, provider_user_id) 를 primary key 로 사용하고 provider_user_id 가 Google sub 와 동일 |
Keycloak 내부 스키마의 verbatim 인용 없음 | Keycloak Server Admin Guide "Federated Identity" 섹션 raw 추가 + docker 컨테이너의 H2/Postgres 스키마 직접 확인 | needs-confirmation |
Username Template Importer mapper 의 ${ALIAS}.${CLAIM.sub} syntax 가 실제 동작 |
mapper 의 verbatim 인용이 cited raw 에 부재 | Keycloak 25.x docker 실행 후 mapper 등록 + 실제 Google 로그인 → username 생성 결과 확인 | planned |
| Sync Mode IMPORT 가 first login 시점에만 attribute 매핑, FORCE 는 매 로그인마다 덮어쓰기 | verbatim 은 회수됨(KC-SYNCMODE-C3/C4, official) — 남은 불확실성은 (a) Keycloak 25.x Admin UI 드롭다운 라벨이 AsciiDoc 원문과 일치하는지 (b) 실제 런타임 반영 시점(token refresh vs full re-login) |
Keycloak 25.x 에서 IMPORT vs FORCE 토글 + 2회 로그인 + Google 측 name 변경 시 Keycloak DB 반영 차이 캡처 | planned |
Google hd claim 이 Workspace 사용자에게만 제공되며 hosted domain 값을 담음 |
hd = Workspace/Cloud org domain 의 verbatim 은 회수됨(GOOGLE-OIDC-C7, official) — 남은 불확실성은 personal Gmail 의 hd 부재 시 mapper 동작(null/skip/거부). C7 "does not prove" 명시. (본 항목은 D5 delegate 대상 — 형제 raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role 에서 검증) |
Workspace 계정 + 개인 Gmail 각각 로그인하여 ID Token 의 hd 유무 + Keycloak mapper 반영 차이 확인 |
needs-confirmation |
Google given_name / family_name / picture claim 이 profile scope 요청 시 제공 |
cited GOIDC-C4 는 email claim 만 다룸 |
Google OIDC claims table 의 profile scope 섹션 verbatim 발췌 추가 |
needs-confirmation |
picture URL 의 만료/CDN 캐싱 정책 — 장기 저장 시 깨질 수 있음 |
Google 측 정책의 verbatim 인용 없음 | Google People API / OIDC picture claim 공식 문서 raw 추가 |
needs-confirmation |
마주친 문제
- 아직 없음(문서 단계).
묶음
- raw/official-docs/google-oidc-discovery-spec
- raw/official-docs/google-openid-connect-oidc
- raw/official-docs/keycloak-google-idp-setup
- raw/official-docs/keycloak-identity-provider-mappers
- raw/official-docs/keycloak-identity-provider-sync-mode-official
본 sub-sub-branch 는 leaf — 자식 자료 없음. Phase 3 P3A 실 구현 또는 외부 산출물 단계에서 errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.
오류 기록 (이 sub-sub-branch 작업 중 발생)
- (없음 — 현재 documented-only 단계)
면접 준비 (이 작업에서 나올 수 있는 면접 질문)
- (없음 — Phase 3 실 구현 단계에 누적)
관련 일일 노트
완료 후 정리
- PR 링크: (없음, 문서까지만)
- 머지 결과 / 배포 환경: 없음 (
documented-only) - wiki 추출 대상: 없음. P1B sub-sub-branch는 root 정책상 wiki/projects/ 승급 안 함.
- 추출하지 않을 항목: 본 sub-sub-branch 전체 (
documented-only/planned).