26 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-account-linking-spa-ux (Account Linking 정책 — SPA 컨텍스트의 사용자 노출) | branch-note | raw | BR-KEYCLOAK-CHILD-1666E2E0 | branch-child | keycloak-patterns-overview | WI-KEYCLOAK-PATTERNS-OVERVIEW-020 |
|
1 | feature-keycloak-account-linking-spa-ux | feature-keycloak-patterns |
|
|
2026-05-25 | in-progress | 90ab9a8505129356c2a13f017db9741ca882313952664fa7262177c192b79286 |
branch: feature-keycloak-account-linking-spa-ux (Account Linking 정책 — SPA 컨텍스트)
Layer:
raw/branch-notes/— raw/branch-notes/feature-keycloak-patterns의 branch-child. 학습 노트. P2B는documented-only단계.
부모 (필수)
raw/branch-notes/feature-keycloak-patterns
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
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 변형이다 | account-linking SPA UX를 IdP-brokering cross-cutting 학습 자료로 분류한다 | raw/project-notes/keycloak-patterns-overview |
브랜치 지역 결정
| Decision ID | Decision | Relation | Supporting Claims | Status |
|---|---|---|---|---|
| D1 | automatic email linking 대신 confirm flow를 사용한다 | local |
raw/project-notes/keycloak-patterns-overview | proposed |
| D2 | SPA UX는 linking trust policy owner의 결론을 소비한다 | local |
raw/project-notes/keycloak-patterns-overview | proposed |
| D3 | link 상태 표시는 Account REST API 검증 대상으로 둔다 | local |
raw/project-notes/keycloak-patterns-overview | proposed |
| D4 | unlink UX는 Account Console을 기본 진입점으로 둔다 | local |
raw/project-notes/keycloak-patterns-overview | proposed |
| D5 | link trigger는 Client Initiated Account Linking을 사용한다 | local |
raw/project-notes/keycloak-patterns-overview | proposed |
선언한 예외
| Override ID | Overrides | Reason | Approval | Status |
|---|
없음.
목표
P1B의 Account Linking 보안 정책(sub primary key + Confirm Link Existing Account)을 SPA 컨텍스트에서 어떻게 사용자에게 노출할지 정리. P1B는 oauth2-proxy가 cookie session을 다루지만, P2B는 SPA가 직접 token을 다루므로 UX 노출 지점이 다름.
면접 질문: "기존 Keycloak 사용자가 나중에 Google 로그인을 추가하려면 어떤 흐름인가요?" → "Keycloak의 Account Console에서 'Linked Accounts' 메뉴를 통해 Google 계정을 link합니다. 또는 로그인 화면에서 Google로 처음 로그인했을 때 같은 email의 기존 계정이 있으면 'Confirm Link Existing Account' 뒤에 owner flow가 선택한 Email verification 또는 password re-authentication이 실행됩니다. SPA는 이 흐름에 직접 관여하지 않고, Keycloak이 redirect로 처리합니다. SPA는 link 완료 후 access token을 받고, 자체 UI로 'Google 계정 연결됨'을 표시할 수 있습니다 (token claim 또는 별도 API 호출)."
- 이슈:
- PR:
범위
포함 범위
- 3가지 사용자 시나리오:
- 신규 Google 사용자 (Keycloak에 같은 email 없음) → First Broker Login Flow가 자동 user 생성
- 기존 Keycloak local 사용자가 Google 로그인 시도 (같은 email) → Confirm Link Existing Account → owner flow의 verification profile(Email 또는 password re-authentication) 통과 후 link
- 이미 link된 사용자 → 평상 로그인
- Account 관리 진입점 비교 (SPA 관점):
- Keycloak Account Console (
/realms/{r}/account/) — Keycloak이 제공하는 user-facing UI - SPA 자체 UI + Keycloak Admin REST API
- Keycloak Account REST API (사용자 자신의 데이터 조작)
- Keycloak Account Console (
- SPA가 "Account linked"를 표시하는 방법
- access token claim에
federated_identities포함 불가 (기본). Account REST API 호출 또는 별도 backend endpoint.
- access token claim에
- unlink 흐름 — Keycloak Account Console의 "Linked Accounts" 메뉴
제외 범위
- 코드 변경 없음 검증 — raw/branch-notes/feature-keycloak-federation-spa-zero-change
- claim mapping — raw/branch-notes/feature-keycloak-idp-mappers-claim-to-role
- JWT signature 검증 — raw/branch-notes/feature-keycloak-three-leg-trust-chain
- P1B와의 흐름 동일성은 raw/branch-notes/feature-keycloak-edge-forwardauth-google-federation (Edge proxy 컨텍스트) 참고
근거 (필수, 최소 1개+)
- raw/official-docs/keycloak-first-login-flow — D1 근거: email 자동 link 는 security hole 공식 경고 + Confirm Link info page 동작
- raw/official-docs/keycloak-client-initiated-account-linking — D5 근거: SPA/client 가 계정 링크를 트리거하는 공식 메커니즘("Client Initiated Account Linking" — 서명된 redirect URL fabrication +
account.manage-account/account.manage-account-linksrole) +keycloak.login({action:'link'})built-in 가정 미확인(does-not-prove) - raw/official-docs/google-oidc-discovery-spec — D2 위임 컨텍스트: Google
sub은 unique/never-reused(GOOGLE-OIDC-C6) → email 아닌sub기반 매칭 근거. raw/branch-notes/feature-keycloak-first-broker-login-flow D4 — linking trust policy를 consume한다.
TODO
- First Broker Login Flow의 default authenticator 흐름 정리 — 등급:
documented-only - Auto-Link 보안 위험 — default
Automatically Set Existing User사용 시 hijack 가능. 본 패턴은 사용 금지 — 등급:documented-only - Confirm Link Existing Account authenticator 채택 — 후속 verification 방식은 raw/branch-notes/feature-keycloak-first-broker-login-flow D2 — owner profile을 consume — 등급:
documented-only - 신규 Google 사용자 first-time 경험: review profile (옵션) → 자동 user 생성 → SPA로 redirect — 등급:
documented-only - 기존 사용자 link 시점 — login 화면에서 자동 트리거 vs Account Console에서 명시적 link — 등급:
documented-only - SPA가 "현재 link된 IdP 목록" 표시하려면 — Keycloak Account REST API (
GET /realms/{r}/account/linked-accounts) 호출 필요 — 등급:needs-confirmation - unlink 흐름 — Account Console "Linked Accounts" → Remove. unlink 후 해당 IdP로 로그인 시 다시 first broker login 흐름 — 등급:
documented-only - 로컬 비밀번호 없는 사용자가 마지막 federated identity를 unlink하면 Keycloak 엔진이 거부 — raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D3 — source-grounded, 배포 release tag 재확인 필요 — 등급:
documented-only - SPA에서 link/unlink 트리거 시 redirect 흐름 —
keycloak.login({ action: 'link', idpHint: 'google' })가능 여부 — 등급:needs-confirmation→ 조사 반영(2026-07-15): 공식 메커니즘은 built-in login action 이 아니라 서명 redirect URL fabrication(D5, raw/official-docs/keycloak-client-initiated-account-linking). adapter helper 존재 여부만 잔여 확인.
진행 중 메모
- P1B와의 핵심 차이: P1B는 oauth2-proxy가 cookie session으로 사용자 상태를 가짐. SPA가 없으므로 "Account linked" UI는 별도 페이지(예:
/account/)로 redirect. P2B는 SPA가 SPA 안에서 "내 계정" 화면을 그리고, link 상태는 API 호출로 가져옴. - 하지만 brokering 흐름 자체는 동일 — Keycloak이 First Broker Login Flow를 실행하고, SPA / proxy는 결과만 받음.
- Auto-Link의 위험 (재확인):
- 시나리오: 공격자가
victim@example.com로 Google 가입 (Google은email_verified=true표시) → 그 Google 계정으로 Keycloak 로그인 → 만약 Auto-Link면victim@example.comKeycloak local 계정으로 자동 link → 계정 탈취. - 방어:
email_verified검증만으로는 부족하다. Confirm Link Existing Account 뒤 소유 증명이 본질이며, 구체 수단은 raw/branch-notes/feature-keycloak-first-broker-login-flow D2의 조건부 profile(Email 기본 또는 password 재인증 관철/폴백)을 따른다.
- 시나리오: 공격자가
- SPA가 link 상태를 표시하는 방법:
- Keycloak Account REST API
/realms/{r}/account/linked-accounts호출 (SPA가 자기 access token 사용 —accountaudience 필요) - 또는 backend가 Keycloak Admin API를 통해
GET /admin/realms/{r}/users/{id}/federated-identity호출 후 SPA에 노출 (backend는 service account 사용)
- Keycloak Account REST API
- unlink 후 재로그인: link 해제하면 Federated Identity record가 삭제됨. 다시 Google로 로그인하면 First Broker Login Flow가 다시 실행 → Confirm Link Existing Account가 다시 트리거됨.
- orphan account 방지: raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D3 — Keycloak 엔진의 마지막 federated identity 제거 guard를 consume한다. 본 branch는 HTTP 400 UX 처리만 소유하며, 배포 release tag 동일성은
needs-confirmation이다. - 조사 반영(2026-07-15,
/branch-spec):- Claim #4 정정 — keycloak-js 에
keycloak.login({action:'link'})같은 built-in link action 은 KC-CIAL 로 확인 안 됨. 공식 경로는 앱이broker/{provider}/linkredirect URL 을 hash 서명과 함께 직접 fabricate(D5). keycloak-js/securing-apps 문서 모두 built-in link 메서드를 다루지 않음. - D2 재framing —
email_verified는 Keycloak 의 linking gate 가 아니라 Trust Email(외부 IdP 계정 생성 시 verified 표시) 설정(Keycloak admin 문서, WebSearch 비아카이브). raw/branch-notes/feature-keycloak-first-broker-login-flow D4 — linking trust policy를 정본으로 참조하며, 이 branch는 메커니즘을 복제하지 않는다. - CVE 참고 — first-broker-login 의 cross-session email verification proof 가 upstream identity 에 bound 되지 않는 취약점(CVE-2026-9087, keycloak/keycloak#49175, 비아카이브)이 존재 → 실 구현 단계에서 Keycloak 버전 patch 확인 대상.
- Claim #4 정정 — keycloak-js 에
결정 사항
추후 면접/회고에서 "왜 이렇게 했나" 답할 근거. 대안과 함께 기록.
- 2026-05-25: Auto-Link 금지 / Confirm Link Existing Account 채택 — 이유: 같은 email의 기존 계정 hijack 방지. (P1B와 동일 정책)
- 2026-05-25 (Historical / superseded):
email_verified=true만 link 허용한다는 초기 판단. Active policy는 raw/branch-notes/feature-keycloak-first-broker-login-flow D4 — linking trust policy를 참조한다. - 2026-05-25: SPA의 link 상태 표시 = Keycloak Account REST API 호출 — backend 거치지 않고 SPA가 직접. 이유: backend 코드 추가 0 (P2A와 동일하게 유지). Account API audience(
account)가 SPA token에 자동 포함되는지 확인 필요 (needs-confirmation). - 2026-05-25: unlink 흐름 = Keycloak Account Console 사용 — SPA 자체 UI는 학습 단계에선 미구현. 운영 시 SPA 안에 카드형 UI 추가 검토.
- 2026-07-15 (
/branch-spec조사): D5 추가 — SPA 가 link 를 트리거하는 공식 메커니즘 = Client Initiated Account Linking (서명된 redirect URL fabrication) — keycloak-js built-in login action 이 아님. 검토한 대안: (a)keycloak.login({action:'link'})built-in — 공식 근거 없음, (b) 앱이broker/{provider}/link?...&hash=URL 직접 구성 — 공식(KC-CIAL). 근거: raw/official-docs/keycloak-client-initiated-account-linking. - 2026-07-15 (
/branch-spec재framing): D2 는 이 브랜치가 소유하지 않고 위임(consume) — raw/branch-notes/feature-keycloak-first-broker-login-flow D4 — linking trust policy. 이 브랜치는 SPA 컨텍스트에서 동일 게이트를 재진술하지 않고 참조만 한다(consistency-contract Single-Owner).
결정-근거 매핑
각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시한다.
Decision ID는 이 branch-note 안에서 안정적으로 유지한다.Supporting Claims는raw/<category>/<slug>.md#<CLAIM-ID>형식.
| Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|---|
| D1 | Auto-Link 금지 / Confirm Link Existing Account 채택 (같은 email 의 기존 계정 hijack 방지) | 외부 IdP email 을 항상 신뢰 못할 때(=일반 케이스) → Confirm Link. 폐쇄망에서 IdP 를 완전 신뢰하면 Trust Email + auto-link 도 가능하나 본 패턴 미채택 | raw/official-docs/keycloak-first-login-flow.md#KC-FLF-C2, raw/official-docs/keycloak-first-login-flow.md#KC-FLF-C3 — flow 구성(정확한 authenticator step)은 owner raw/branch-notes/feature-keycloak-first-broker-login-flow D1(auto-link DISABLED)·D2(Confirm Link + Verify Existing Account — SMTP 시 Email 기본 / Re-auth 는 email authenticator DISABLE 시)에 위임 |
official-vendor-doc (공식 경고 + Confirm Link info page 동작) |
"Confirm Link Existing Account" 가 default flow 에 포함되는지 vs 별도 추가 필요한지 Keycloak version 별 확인 필요 (owner 브랜치 D2 에서 추적) |
| D2 | SPA UX는 linking trust policy를 새로 정하지 않고 owner 결론을 consume | 정책을 바꾸려면 owner에서 변경. 이 branch는 사용자 노출과 상태 표시만 다룸(Reference-Only) | raw/branch-notes/feature-keycloak-first-broker-login-flow D4 — linking trust policy | delegated |
Trust Email은 linking gate가 아니다. custom SPI artifact가 확인되지 않은 상태에서 이 branch가 별도 hard-reject를 주장하지 않음 |
| D3 | SPA 의 link 상태 표시 = Keycloak Account REST API (GET /realms/{r}/account/linked-accounts) 직접 호출 |
backend 없이 SPA 가 상태 표시해야 → Account REST API 시도(미문서화, needs-confirmation). backend 가 이미 있으면 → Admin API federated-identity(문서화, service account)가 안전 |
UNSUPPORTED_DECISION | — | KC-CIAL(신규 Source)이 이 linked-accounts read endpoint 를 다루지 않음을 명시 확인(does-not-prove) + 커뮤니티상 undocumented(WebSearch). account audience 자동 포함 여부는 Claims To Verify 로 이관 |
| D4 | unlink UX 진입점 = Keycloak Account Console (SPA 자체 UI 미구현) — UX 진입점 선택만 소유 | 학습 단계 → 기본 Account Console UI(코드 0). 운영에서 in-SPA unlink UX 필요 → SPA 자체 카드 UI(별도 구현) | UNSUPPORTED_DECISION (UX 진입점 선택); raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D3 — unlink 안전정책 owner | — | 엔진 guard는 source-grounded이나 인용 기준이 Keycloak main이므로 배포 release tag 재확인 필요. 본 branch는 400 UX만 결정 |
| D5 | SPA 가 link 를 트리거하는 방법 = Client Initiated Account Linking (앱이 서명된 redirect URL 을 fabricate), keycloak-js built-in login action 아님 | 로그인된 사용자에게 "지금 Google 연결" 버튼 제공 → client-initiated linking URL fabricate(D5). 최초 로그인 시 자동 link 은 First Broker Login(D1) 경로 — 트리거 시점이 다름 | raw/official-docs/keycloak-client-initiated-account-linking.md#KC-CIAL-C1, raw/official-docs/keycloak-client-initiated-account-linking.md#KC-CIAL-C2, raw/official-docs/keycloak-client-initiated-account-linking.md#KC-CIAL-C3, raw/official-docs/keycloak-client-initiated-account-linking.md#KC-CIAL-C4 |
official-vendor-doc |
SPA(브라우저)가 hash 재료(token.getSessionState()/token.getIssuedFor())를 keycloak-js tokenParsed 에서 얻는지 코드 미확인(planned). KC-CIAL-C4 does-not-prove: 문서가 "CSRF 를 완전히 막지는 못한다" 경고 → SPA state 별도 방어 필요 |
구현 가이드
결정(Decisions) 이 "무엇" 이라면 본 §는 "어디에 어떻게" 의 사전 명세. 본 브랜치는
documented-only학습 노트이므로, 구현 detail 은 공식 문서가 규정하는 프로토콜·값을 anchor 로 하고 코드 미확인 항목은planned/UNSUPPORTED_IMPL_DECISION로 명시한다.
1. 계정 링크 트리거 — Client Initiated Account Linking (SPA → Keycloak)
Trace: D5 +
KC-CIAL-C1/C2/C3/C4. 이미 로그인된 SPA 사용자가 "Google 연결" 버튼을 눌렀을 때의 사전 명세.
- UNSUPPORTED_IMPL_DECISION: (a) SPA(브라우저)가 hash 재료
token.getSessionState()·token.getIssuedFor()를 keycloak-jstokenParsed.session_state·tokenParsed.azp로 얻는 매핑 — KC-CIAL 예시는 Java Servlet 전용(KC-CIAL-C3does-not-prove), JS 매핑은 미확인. trade-off: 학습 단계엔 이 매핑을planned로 남기고 실 구현 시 keycloak-jstokenParsed필드로 검증. (b) 브라우저에서 SHA-256 계산은crypto.subtle.digest('SHA-256', ...)+ Base64URL 인코딩으로 수행 — 표준 Web Crypto 이나 KC-CIAL 이 JS 구현을 규정하지 않으므로UNSUPPORTED_IMPL_DECISION.
| 항목 | 값 / 명세 | 근거 |
|---|---|---|
| redirect URL 템플릿 | {auth-server-root}/auth/realms/{realm}/broker/{provider}/link?client_id={id}&redirect_uri={uri}&nonce={nonce}&hash={hash} |
KC-CIAL-C3 |
provider |
google (Keycloak IdP alias) |
D5, KC-CIAL-C3 (provider 파라미터) |
hash 계산 |
Base64URL( SHA_256( nonce + token.getSessionState() + token.getIssuedFor() + provider ) ) |
KC-CIAL-C4 |
| 전제조건 | 사용자에 account.manage-account 또는 account.manage-account-links role + 그 role 의 scope 가 access token 에 부여 + 앱이 자기 access token 접근 |
KC-CIAL-C2 |
| 목적(왜 hash) | auth server 가 client 가 요청을 시작했음을 보장(rogue app 임의 link 방지) — 단 CSRF 완전 방지는 아님 | KC-CIAL-C4 |
2. 최초 로그인 링크 경로 — First Broker Login (Google 로그인 화면 → Keycloak)
Trace: D1 +
KC-FLF-C2/C3/C4. §1 과 다른 트리거 시점(로그인 시 email collision).
- OUT_OF_BRANCH_SCOPE: raw/branch-notes/feature-keycloak-first-broker-login-flow D2 — Confirm Link 이후 verification profile의 정본. 이 브랜치는 owner 결과에 따른 UX만 기술한다.
| 시나리오 | 동작 | 근거 |
|---|---|---|
| 신규 Google 사용자(같은 email 없음) | 자동 user 생성. Review Profile mode 에 따라 확인 페이지(On/missing/Off) |
KC-FLF-C4 |
| 같은 email 기존 사용자 | Confirm Link Existing Account info page → (A) profile 재검토 후 다른 email/username, (B) 기존 계정 link 확인 | KC-FLF-C3 |
| 금지 | Automatically Set Existing User(auto-link) — email 자동 link 는 security hole |
KC-FLF-C2 |
3. 링크 상태 표시 (Read path)
Trace: D3 (UNSUPPORTED_DECISION). SPA 가 "현재 연결된 IdP" 를 그리는 방법.
- UNSUPPORTED_IMPL_DECISION: 옵션 A 의
/account/linked-accountsendpoint 는 KC-CIAL 가 다루지 않고 커뮤니티상 undocumented. trade-off: backend-zero(옵션 A, 미검증) vs 문서화된 안정성(옵션 B, backend 코드 추가). 학습 단계엔 옵션 A 를planned로 시도하되 실패 시 옵션 B fallback.
| 옵션 | 호출 | 인증 | 상태 |
|---|---|---|---|
| A | SPA → GET /realms/{r}/account/linked-accounts |
SPA access token (account audience 필요) |
needs-confirmation (undocumented) |
| B | backend → GET /admin/realms/{r}/users/{id}/federated-identity |
service account | documented-only (Admin API) |
4. Unlink
Trace: D4 (UNSUPPORTED_DECISION, UX 진입점). raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D3 — 안전정책 owner.
- UNSUPPORTED_IMPL_DECISION: Account Console UI를 재사용할지 SPA 자체 unlink 카드를 만들지는 project UX 선택이다. orphan 거부 자체는 owner D3의 엔진 guard를 consume하며, 이 branch는 HTTP 400 안내를 처리한다.
엣지·실패·의존
R4 캡처용. 정상 경로 외 실패/엣지/의존.
- 실패·엣지 경로:
- hash 누락/불일치 (§1):
broker/{provider}/link에hash가 없거나 틀리면 auth server 가 link 요청을 client-initiated 로 인정하지 않음(KC-CIAL-C4). 단 문서가 "CSRF 를 완전히 막지 못함" 경고 → SPA 는 별도state로 CSRF 방어 필요. - Auto-Link hijack (§2): 공격자가
victim@example.com로 Google 가입 후 그 IdP 로 로그인 → auto-link 면 계정 탈취. 방어 = D1 Confirm Link + raw/branch-notes/feature-keycloak-first-broker-login-flow D2의 owner-selected verification profile(Email 기본 또는 password 재인증 관철/폴백);email_verified만으로는 불충분(KC-FLF-C2). - orphan account (§4): raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D3 — 마지막 federated identity 제거 guard를 consume. 배포 release tag가 owner 근거와 같은지는
needs-confirmation. - unlink 후 재로그인 (§4): Federated Identity record 삭제 → 다시 Google 로그인 시 First Broker Login 재실행 → Confirm Link 재트리거(D1 경로).
accountaudience 부재 (§3): SPA access token 의aud에account미포함 시 옵션 A 는 401/403 → 옵션 B fallback 필요.- CVE-2026-9087 (§2): first-broker-login 의 cross-session email verification proof 가 upstream identity 에 bound 안 됨(keycloak/keycloak#49175, 비아카이브). 실 구현 시 Keycloak 버전 patch 상태 확인.
- hash 누락/불일치 (§1):
- 다른 계약 의존:
- raw/branch-notes/feature-keycloak-first-broker-login-flow D1 — silent auto-link 방지 owner. raw/branch-notes/feature-keycloak-first-broker-login-flow D2 — verification profile owner.
- raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D1 — persistent federation key owner. raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D3 — unlink guard owner.
- raw/branch-notes/feature-keycloak-first-broker-login-flow D4 — linking trust policy; 본 branch는 UX만 consume.
- raw/branch-notes/feature-keycloak-google-claim-attribute-mapping D4 — Google claim→user attribute mapping owner.
검증해야 할 주장
공식 문서 근거가 있어도 내 프로젝트에서의 동작을 자동으로 보장하지 않는다.
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
| "Confirm Link Existing Account" authenticator 가 P2B 의 default first-broker-login flow 에 자동 포함된다 | KC-FLF-C3 는 authenticator 의 동작만 정의하며, default flow inclusion 여부는 Keycloak version (26.x) 별 admin UI 에서 확인 필요 | Keycloak admin console > Authentication > Flows > First Broker Login 의 step list 캡처 | needs-confirmation |
SPA access token 의 aud claim 에 account audience 가 자동 포함되어 Account REST API 호출 가능 |
본 branch 의 Sources 에 audience mapping 동작 문서 없음. Keycloak default client 설정 의존 | dev 환경에서 SPA access token decode 후 aud 필드 확인 + GET /realms/{r}/account/linked-accounts 호출 결과 200 확인 |
needs-confirmation |
Keycloak Account REST API 에 linked-accounts read endpoint 가 실제로 존재하고 SPA 로 호출 가능하다 |
KC-CIAL 은 이 endpoint 를 다루지 않음(does-not-prove); 커뮤니티상 undocumented(WebSearch) | dev 환경에서 실 호출 + 응답 schema 확인, 또는 옵션 B(Admin API federated-identity)로 대체 |
needs-confirmation |
| 인용한 Keycloak 엔진 unlink guard가 배포 release tag에서도 동일하게 동작한다 | raw/branch-notes/feature-keycloak-account-linking-sub-vs-email D3의 근거는 Keycloak main source이며 배포 image tag와 동일성은 아직 확인하지 않음 |
배포 tag의 LinkedAccountsResource guard 대조 + Google-only 사용자로 마지막 link 제거 시 HTTP 400 확인 |
needs-confirmation (owner decision은 source-grounded) |
SPA 에서 link 트리거는 built-in keycloak.login({action:'link'}) 가 아니라 broker/{provider}/link 서명 URL fabrication 이다 |
KC-CIAL(KC-CIAL-C1/C3)은 앱이 URL 을 직접 fabricate 함을 규정하나 adapter API 표면은 다루지 않음 — keycloak-js 가 helper 를 제공하는지는 미확인 |
keycloak-js 공식 adapter 레퍼런스에서 login() action 지원 목록 확인 + dev 환경에서 서명 URL 수동 구성 테스트 |
needs-confirmation |
마주친 문제
- (학습 단계, 미실행)
- 잠재적 함정: SPA가 Account REST API를 호출할 때 access token의
aud에account가 포함되어야 함. Keycloak 기본 client 설정에서accountaudience가 자동 포함되는지 확인 필요.
묶음
- raw/official-docs/keycloak-client-initiated-account-linking
- raw/official-docs/keycloak-first-broker-login-flow
- raw/official-docs/keycloak-first-login-flow
본 sub-sub-branch 는 leaf — 자식 자료 없음. Phase 3 P3A 실 구현 또는 외부 산출물 단계에서 errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.
오류 기록 (이 sub-sub-branch 작업 중 발생)
- (없음 — 현재 documented-only 단계)
면접 준비 (이 작업에서 나올 수 있는 면접 질문)
- (없음 — Phase 3 실 구현 단계에 누적)
관련 일일 노트
완료 후 정리
학습 노트. P2B는
documented-only유지.
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경: 학습 노트 (
documented-only) - wiki 추출 대상:
actually-implemented항목: (없음)locally-verified항목: (없음)prod-verified항목: (없음)
- 추출하지 않을 항목: 전 항목 (
documented-only/needs-confirmation)