12 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-idp-mappers-claim-to-role (IdP Mappers — Google claim → Keycloak role) | branch-note | raw | BR-KEYCLOAK-CHILD-321B472C | branch-child | keycloak-patterns-overview | WI-KEYCLOAK-PATTERNS-OVERVIEW-015 |
|
|
1 | feature-keycloak-idp-mappers-claim-to-role | feature-keycloak-idp-brokering-google-client |
|
|
2026-05-25 | in-progress | 6c7b7381db7953e7ba85ecf9dfc998cce5e018e0f146a3caa4a34e978c45324a |
branch: feature-keycloak-idp-mappers-claim-to-role (IdP Mappers — Google claim → Keycloak role)
Layer:
raw/branch-notes/— raw/branch-notes/feature-keycloak-idp-brokering-google-client의 WI015 child branch. 학습 노트. P2B는documented-only단계.
정합 노트 (2026-07-14 감사): 본 노트의 attribute-mapping 내용(Attribute Importer / Sync Mode /
hd/email_verified)은 형제 raw/branch-notes/feature-keycloak-google-claim-attribute-mapping 와 ~70% 겹친다 — 그쪽이 attribute-mapping owner. 본 노트의 고유 책임 = claim → role (RBAC 인가) 이며 §5 deferred authZ 트랙. /ingest 시 attribute 부분은 owner 를 인용하고 본 노트는 role 부분만 남긴다.
부모 (필수)
raw/branch-notes/feature-keycloak-idp-brokering-google-client
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
1 - 패킷 스키마:
contract_packet: 1 - 완료 조건: Google login·Keycloak user mapping 200과 application diff 0줄이 검증된다
상속한 프로젝트 결정
| 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-to-role mapper를 IdP brokering 구성의 하위 계약으로 적용한다 | 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 |
|---|
없음.
묶음
본 sub-sub-branch 는 leaf — 자식 자료 없음. Phase 3 P3A 실 구현 또는 외부 산출물 단계에서 errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.
오류 기록 (이 sub-sub-branch 작업 중 발생)
- (없음 — 현재 documented-only 단계)
면접 준비 (이 작업에서 나올 수 있는 면접 질문)
- (없음 — Phase 3 실 구현 단계에 누적)
목표
Google ID token claim을 Keycloak role로 매핑해서, SPA / backend가 Google 출신 사용자를 Keycloak local 사용자와 동일 RBAC 모델에서 다룰 수 있게 한다. Profile attribute 매핑은 raw/branch-notes/feature-keycloak-google-claim-attribute-mapping이 정본이다.
면접 질문: "Google에서 받은 사용자 정보를 backend가 어떻게 보나요?"
→ "Keycloak의 IdP role mapper로 Google claim(예: hd)을 role로 변환합니다. Profile attribute는 별도 owner가 매핑하고, backend는 최종 Keycloak access token의 role만 소비합니다."
- 이슈:
- PR:
범위
포함 범위
- Hardcoded Role / Claim to Role / Advanced Claim to Role: Google claim 값에 따른 role 부여.
- Google
hdclaim 기반 role 분기와 개인 Gmail(hd부재) 처리 정책. - role mapper instance-level
Sync Mode Override = FORCE: IdP-level default를 바꾸지 않고 role freshness만 갱신(D1).
제외 범위
- Google profile claim → user attribute, Username Template, picture 전파, IdP-level default Sync Mode → raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D2/D3/D4.
email_verified=falselink 정책 → raw/branch-notes/feature-keycloak-first-broker-login-flow D4. 현재 범위는 silent auto-link 차단이며 hard-reject SPI는 별도 variant다.- 코드 변경 없음 검증 — raw/branch-notes/feature-keycloak-federation-spa-zero-change
- JWT signature 검증 메커니즘 — raw/branch-notes/feature-keycloak-three-leg-trust-chain
- Account Linking 흐름 — raw/branch-notes/feature-keycloak-account-linking-spa-ux
TODO
- Role mapper 종류표 작성 — Hardcoded Role / Claim to Role / Advanced Claim to Role — 등급:
documented-only - Google
hdclaim → Advanced Claim to Role mapper 설정 (예:hd=example.com이면internal-userrole 부여) — 등급:documented-only - IdP-level default
IMPORT를 유지하면서 role mapper instance에만Sync Mode Override=FORCE설정 — 등급:planned hd미존재 시 (개인 Gmail 계정) 처리 정책 — 등급:planned
진행 중 메모
- Profile attribute와 token claim 전파는 raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D4 — 본 노트는 그 값을 재명세하지 않는다.
hdclaim은 Google Workspace 계정에만 존재. 개인 Gmail 계정은hd없음. 따라서 "hd 없으면 거부"는 사내 SaaS 용도 (학습 노트에선 미적용).- IdP-level default는 raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D3의
IMPORT다. 본 노트의FORCE는 role mapper instance-level override로만 적용한다.
결정 사항 (decisions)
- 2026-07-18: role mapper instance-level
Sync Mode Override = FORCE— role freshness만 갱신한다. IdP-level default는 raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D3의IMPORT를 유지한다. - 2026-07-18:
email_verified=false정책은 raw/branch-notes/feature-keycloak-first-broker-login-flow D4를 consume한다. 현재 custom SPI artifact가 없으므로 전체 hard-reject를 이 branch에서 주장하지 않는다. - 2026-05-25:
hdclaim 미적용 — 학습 단계는 개인 Gmail도 허용. 운영 SaaS 도입 시 Advanced Claim to Role로hd=example.com → internal-user매핑 추가. - 2026-05-25 (delegated):
picture전파는 raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D4가 소유한다.
마주친 문제
- (학습 단계, 미실행)
관련 일일 노트
근거 (필수, 최소 1개+)
- raw/official-docs/keycloak-identity-provider-mappers
- raw/official-docs/keycloak-identity-provider-sync-mode-official
- raw/official-docs/google-oidc-discovery-spec
결정-근거 매핑
각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시.
Decision ID는 본 branch-note 안에서 안정적으로 유지.
| Decision ID | Decision | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|
| D1 | role mapper instance-level Sync Mode Override = FORCE — IdP-level default IMPORT와 적용 계층을 분리 |
raw/official-docs/keycloak-identity-provider-sync-mode-official.md#KC-SYNCMODE-C4 (force = each login update), #KC-SYNCMODE-C5 (mapper-level override) + raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D3 — IdP-level default IMPORT |
official-vendor-doc + delegated |
role mapper에서 override가 노출되고 IdP default보다 우선하는지는 realm export/Admin UI 실측 전까지 needs-confirmation |
| D2 | DELEGATED — raw/branch-notes/feature-keycloak-first-broker-login-flow D4 — 현재 정책은 silent auto-link 차단 | owner D4 | delegated |
email_verified=false 전체 hard-reject는 구현된 custom SPI가 있는 별도 variant에서만 가능하며 현재 artifact 없음 |
| D3 | hd claim 미적용 (학습 단계 — 개인 Gmail 허용, 운영 SaaS 전환 시 Advanced Claim to Role 매핑 추가) |
raw/official-docs/google-oidc-discovery-spec.md#GOOGLE-OIDC-C7 (hd 는 Workspace/Cloud organization 도메인 — personal Google account 의 hd 부재는 인용에 명시 없음 단서) |
official-vendor-doc |
personal Gmail 의 hd claim 부재 시 Keycloak mapper 동작 (null / 없음 / 거부) 의 정확한 검증은 별도 필요 — GOOGLE-OIDC-C7 "Does not prove" 단서 |
| D4 | DELEGATED — raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D4 — profile attribute 매핑 owner | owner D4 | delegated |
본 role branch에서 attribute/token 전파 값을 재명세하지 않음 |
구현 가이드
| 단계 | 이 branch의 설정 | 완료 조건 |
|---|---|---|
| 1 | IdP-level default는 raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D3의 IMPORT를 그대로 사용 |
realm export에서 IdP 기본값이 IMPORT임을 확인 |
| 2 | Google IdP 아래 role mapper instance에만 Sync Mode Override=FORCE를 적용 |
realm export에서 해당 mapper의 override만 FORCE임을 확인 |
| 3 | 운영 SaaS variant에서만 hd=example.com 조건의 Advanced Claim to Role mapper를 추가 |
Workspace 계정과 개인 계정의 최종 Keycloak role 차이를 token으로 검증 |
현재는 documented-only다. Admin UI 캡처, realm export, 로그인 2회 후 role 갱신 증거가 모이기 전에는 구현 완료로 승격하지 않는다.
엣지·실패·의존
| 구분 | 조건 | 처리 / owner |
|---|---|---|
| Edge | 개인 Google 계정에 hd가 없을 수 있음 |
학습 variant에서는 로그인 자체를 거부하지 않고 도메인 기반 role만 부여하지 않는 정책을 검증한다 |
| Failure | FORCE를 IdP-level default로 잘못 적용 |
profile attribute까지 매 로그인 갱신되는 범위 확장을 피하고, role mapper instance override로 되돌린다 |
| Dependency | profile attribute와 IdP default Sync Mode | raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D3/D4 |
| Dependency | email_verified=false 연결 정책 |
raw/branch-notes/feature-keycloak-first-broker-login-flow D4 |
검증해야 할 주장
공식 문서나 사례는 근거지만, 내 프로젝트에서의 동작을 자동으로 보장하지 않는다.
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
role mapper instance-level Sync Mode Override=FORCE가 IdP default IMPORT보다 우선하는지 |
적용 계층은 공식 근거가 있으나 배포 버전 realm export/UI 실측 없음 | role mapper만 FORCE로 설정하고 2회 로그인 후 role 갱신과 profile attribute 보존을 함께 확인 | needs-confirmation |
Advanced Claim to Role mapper 가 hd=example.com 일 때만 internal-user role 부여 (운영 SaaS 시) |
KC-IDP-MAPPER-C4 가 명시적으로 needs-confirmation — mapper 종류 verbatim 부재 |
Keycloak Admin UI 의 IdP → Mappers → Add mapper → Advanced Claim to Role 캡쳐 + 실제 등록 후 hd 별 token 발급 → role 차이 확인 |
planned |
email_verified=false 전체 hard-reject variant |
현재 custom SPI provider/JAR/flow export가 없음 | 별도 SPI branch를 만들 때 provider artifact + realm flow export + negative E2E로 검증 | deferred |
완료 후 정리
학습 노트. P2B는
documented-only유지.
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경: 학습 노트 (
documented-only) - wiki 추출 대상:
actually-implemented항목: (없음)locally-verified항목: (없음)prod-verified항목: (없음)
- 추출하지 않을 항목: 전 항목 (
documented-only)