33 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-redirect-uri-policy (P3B Google OAuth client 등록 — redirect_uri 정책 + URL 변경 시 갱신) | branch-note | raw | BR-KEYCLOAK-CHILD-9019B40A | branch-child | keycloak-patterns-overview | WI-KEYCLOAK-PATTERNS-OVERVIEW-017 |
|
|
1 | feature-keycloak-google-redirect-uri-policy | feature-keycloak-google-claim-attribute-mapping |
|
|
2026-05-25 | in-progress | 2f73e474940f2931d53b3b512bda9bf501dd0801196d19e86bede25c36ba5656 |
branch: feature-keycloak-google-redirect-uri-policy (P3B Google OAuth client 등록 — redirect_uri 정책 + URL 변경 시 갱신)
Layer:
raw/branch-notes/— raw/branch-notes/feature-keycloak-google-claim-attribute-mapping의 child branch. Google Cloud Console에 OAuth 2.0 client 생성하고 redirect_uri 등록하는 절차, 그리고 ngrok 무료 plan URL이 변경될 때마다 Console을 갱신해야 하는 운영 burden 학습. 본 sub-sub-branch는 문서까지만 — 실 Google Cloud project 생성 / OAuth client 등록 / Keycloak Admin IdP 등록은 진행하지 않음. 등급documented-only.status_label:in-progress
부모 (필수)
raw/branch-notes/feature-keycloak-google-claim-attribute-mapping
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
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 OAuth redirect URI가 Keycloak broker endpoint와 일치하도록 하는 정책에 적용한다 | 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 |
|---|
없음.
목표
P3B의 brokering 흐름이 동작하려면 다음 3개 좌표가 글자 단위로 일치해야 한다:
- **Google Cloud Console "Authorized redirect URIs"**에 등록된 URL
- Keycloak Admin → Identity Providers → Google에서 발급하는 callback URL
- 실제 사용자 브라우저가 Google → Keycloak으로 redirect 받을 때의 URL
이 3개가 어긋나면 Google이 redirect_uri_mismatch 에러로 인증 차단. 그래서 ngrok 무료 plan(URL 매 세션 변경)을 쓰면 매번 Google Console에 들어가 redirect_uri를 새 URL로 갱신해야 한다 — 이 운영 burden이 sub-sub-branch -6-1에서 Cloudflare Tunnel 정적 도메인 선택의 결정 근거.
면접에서 답해야 할 질문:
- Keycloak callback URL의 정확한 포맷은? →
https://<keycloak-domain><relative-path>/realms/<realm>/broker/<idp-alias>/endpoint - Google OAuth client의 "Authorized JavaScript origins"는 왜 필요한가? → 본 시나리오에서는 불필요(server-to-server brokering). SPA가 Google과 직접 통신하면 필요.
- Verification screen이 무엇이고 언제 필요한가? → basic identity scope(
openid email profile)만 쓰는 학습 앱은 test-user allowlist·100명 상한·7일 만료 예외다. sensitive/restricted scope를 추가할 때 별도 verification 조건을 검토한다.
- 이슈:
- PR:
범위
포함 범위
- Google Cloud Console OAuth 2.0 Client ID 생성 절차 (web application 타입)
- Authorized JavaScript origins / Authorized redirect URIs 정책
client_id+client_secret발급 후 Keycloak Admin Console 입력 위치- Verification screen (consent screen) 설정 — test users / scopes / app domain
- ngrok URL 변경 시 Google Console 갱신 흐름 (수동 작업 순서)
- Cloudflare Tunnel 정적 도메인이 운영 burden 감소시키는 결정 근거 정리
제외 범위
- Google Workspace SAML federation (OIDC만)
- Google Sign-In JS SDK 직접 사용 (Keycloak 우회 시나리오)
- Google API Scopes 확장 (Gmail / Drive 등) — 본 학습은
openid email profile만 - 다른 OIDC Provider(GitHub / Auth0) 등록 비교
근거 (필수, 최소 1개+)
- raw/official-docs/google-oauth2-redirect-uri-validation-official — Google redirect_uri 검증 규칙 공식 (D1~D4, D8 근거)
- raw/official-docs/keycloak-google-idp-setup — Keycloak Google IdP 설정 가이드 (D1, D5 근거)
- raw/official-docs/keycloak-first-login-flow — First Broker Login "Confirm Link Existing Account" + 자동 link 보안 경고 공식 (D7 근거 —
/branch-spec보강, 2026-07-16) - raw/official-docs/google-oauth-app-verification-state-overview-official — Google App Verification "OAuth app state overview": Testing/External 앱은 basic identity scope(
openid/email/profile)만 요청하면 allowlist 없이 임의 사용자 접근 가능, verification(Published-Verified)은 sensitive/restricted scope 요청 앱에 required — D5의 "sensitive scope 회피 → verification 불필요" 부분 developer-doc 측 근거 보강 (2026-07-16) - raw/official-docs/google-oauth2-client-application-types-official — Google OAuth client Application-type 분류(Web application vs Native[Android/iOS/Desktop/UWP] vs TV & Limited-Input) + Private/Public Client 정의 공식 (D6 근거 —
wiki-source-summarizer보강, 2026-07-16) - raw/official-docs/google-oauth-manage-app-audience-official — Google OAuth publishing status(Testing/In production) + basic identity scope(name/email/profile) 예외 공식 (D5 verification-policy 부분 근거 —
wiki-source-summarizer보강, 2026-07-16) - raw/official-docs/google-oauth2-web-server-flow-official — Google "Using OAuth 2.0 for Web Server Applications" 공식 문서. confidential/server-to-server flow 정의, "Web application" application type 선택 지침, redirect URIs 요구사항 근거 (D6 근거 보강 —
wiki-source-summarizer, 2026-07-16). 단 JavaScript origins 미언급 — D6 의 "JS origins 비움" 부분은 여전히UNSUPPORTED_DECISION
관련 sub-branch
- raw/branch-notes/feature-keycloak-single-ec2-google-federation (부모, P3B Single EC2 + Google federation)
- raw/branch-notes/feature-keycloak-public-domain-tunneling — 학습 환경 public 도메인 확보 (ngrok / Cloudflare Tunnel) ← Cloudflare Tunnel 결정 근거 cross-reference
- raw/branch-notes/feature-keycloak-reverse-proxy-headers — Keycloak reverse proxy 설정
- raw/branch-notes/feature-keycloak-https-termination-caddy-nginx — HTTPS termination
TODO
각 항목 옆에 증거 등급 표기.
- Google Cloud project 생성 —
console.cloud.google.com→ New project → project name 설정 — 등급:planned - OAuth consent screen 설정 — External user type / app name / support email / app logo (선택) / scopes(
openid,email,profile). 이 basic scope 조합은 test-user 등록 불필요 — 등급:planned - OAuth 2.0 Client ID 생성 — APIs & Services → Credentials → Create Credentials → OAuth client ID → Application type: Web application — 등급:
planned - Authorized JavaScript origins 입력 — 본 시나리오에서는 불필요 (Keycloak server-to-server brokering). 명시만 — 등급:
documented-only - Authorized redirect URIs 입력 —
https://<keycloak-domain>/keycloak/realms/<realm>/broker/google/endpoint(Keycloak Admin에서 자동 생성한 callback URL 그대로 복사) — 등급:planned client_id+client_secret발급 + Keycloak Admin 입력 — Keycloak Admin Console → Identity Providers → Add provider → Google → Client ID / Client Secret 필드 — 등급:planned- Verification screen 정책 정리 — 학습용
openid email profile은 basic identity scope 예외라 test-user allowlist·100명 상한·7일 만료·unverified 경고가 적용되지 않는다. sensitive/restricted scope 추가 시 별도 verification 정책으로 분기 — 등급:documented-only - ngrok URL 변경 시 갱신 흐름 — (a) 새 ngrok 세션 시작 → (b) 새 URL 확인 → (c) Google Console → Edit OAuth client → Authorized redirect URIs 갱신 → (d) Keycloak
KC_HOSTNAME환경변수 + redeploy → (e) Keycloak Admin Google IdP의 redirect URL 확인 — 등급:planned - Cloudflare Tunnel 정적 도메인이 burden 제거하는 이유 정리 — 1회 등록 후 영구. 6-1과 cross-reference — 등급:
planned
진행 중 메모
- Keycloak Admin Console에서 IdP alias를
google로 설정하면 callback URL이.../broker/google/endpoint형식으로 발급. alias를 다르게 바꾸면 그에 맞춰 URL도 변경. - Google
client_secret은 Keycloak DB에 plaintext 저장(또는 vault credentials store) → secret rotation 정책 필요. 학습용은 무시. - Google OAuth 2.0 Client 생성 시 "Authorized JavaScript origins"는 implicit/PKCE flow의 SPA가 직접 Google과 통신할 때만 필요. 본 시나리오는 Keycloak이 server-to-server로 Google
/token호출 → JavaScript origins 비워둬도 동작. - Verification screen: External user type +
openid email profile만 사용하면 basic identity scope 예외로 test-user allowlist 등록 없이 접근할 수 있다. sensitive/restricted scope를 추가할 때만 해당 verification·quota를 별도 검토한다.
ngrok URL 변경 시 갱신 절차 (운영 burden 데모)
| 단계 | 작업 | 소요 |
|---|---|---|
| 1 | ngrok http 80 재시작 → 새 URL 확인 |
즉시 |
| 2 | Google Cloud Console → APIs & Services → Credentials → OAuth client 편집 | 1분 |
| 3 | Authorized redirect URIs 갱신: https://<new-ngrok>.ngrok-free.app/keycloak/realms/<realm>/broker/google/endpoint |
1분 |
| 4 | Save → 변경 propagation 대기 (Google docs: 최대 수시간, 보통 즉시) | 0~수시간 |
| 5 | Keycloak KC_HOSTNAME=https://<new-ngrok>.ngrok-free.app 갱신 후 컨테이너 재시작 |
1분 |
| 6 | Keycloak Admin → Identity Providers → Google → callback URL 확인 (자동 갱신) | 즉시 |
| 7 | SPA redirect_uri가 새 도메인을 가리키는지 확인 (vanilla JS에서는 build/run config 갱신) |
1분 |
→ 매 세션 5~10분 + propagation 대기. 학습 친화적 X.
Cloudflare Tunnel 정적 도메인 대안
| 단계 | 작업 | 소요 |
|---|---|---|
| 1 | cloudflared tunnel run <name> 시작 → 정적 도메인 사용 |
즉시 |
| 2 | Google Console redirect_uri 1회 등록 | 1분 (최초만) |
| 3 | 이후 세션 변경에도 redirect_uri 갱신 불필요 | 0 |
결정 사항 (decisions)
- 2026-05-25: Google IdP scope는
openid email profile만 사용. 이유: sensitive scope 회피 → Google verification 심사 불필요 → 학습 환경에서 unverified test users로 즉시 동작. - 2026-05-25: Google OAuth client Application type은 Web application 채택. 이유: Keycloak이 server-to-server로
/token호출, confidential client (client_secret 사용). SPA에서 직접 Google 호출 안 함 → JavaScript origin 비워둠. - 2026-05-25 (historical, superseded):
First Broker Login Flow는 부모 P3B "마주친 문제 4번"에 따라email_verified=truehard-reject까지 본 등록 노트에서 정한다. - 2026-07-18: First Broker Login 정책은 raw/branch-notes/feature-keycloak-first-broker-login-flow D1/D4만 consume한다 — AutoLink를 추가하지 않아 silent auto-link를 차단한다.
email_verified=false전체 hard-reject는 구현된 custom SPI가 있는 별도 variant로 유보한다. - 2026-05-25: ngrok 운영 burden을 정량적으로 (
매 세션 5~10분 + propagation 대기) 기록. 이 데이터가 sub-sub-branch-6-1의 Cloudflare Tunnel 우선 결정의 근거가 됨. - 2026-05-25: 본 sub-sub-branch 전체 등급
documented-only. 실 Google Cloud project 생성 / OAuth client 등록은 P3A 완료 후 선택적 확장 시점에 재검토.
결정-근거 매핑
본 sub-sub-branch 는
documented-only. cited raw sources:google-oauth2-redirect-uri-validation-official,keycloak-google-idp-setup,keycloak-first-login-flow(D7),google-oauth2-client-application-types-official+google-oauth2-web-server-flow-official(D6),google-oauth-manage-app-audience-official+google-oauth-app-verification-state-overview-official(D5). D5·D6·D7 은/branch-spec자동조사(2026-07-16)로UNSUPPORTED_DECISION→official-vendor-doc승급(단 D6 JS-origins 비움은 구조적 추론, D7 email_verified 강제·D8 정량 수치는 잔여 UNSUPPORTED).
| Decision ID | Decision | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|
| D1 | Authorized redirect URIs 에 https://<keycloak-domain>/keycloak/realms/<realm>/broker/google/endpoint 1개만 정확히 등록 — exact match 요구 |
raw/official-docs/google-oauth2-redirect-uri-validation-official.md#GOOGLE-REDIR-C3 ("The value must exactly match one of the authorized redirect URIs ... If this value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch' error") + raw/official-docs/keycloak-google-idp-setup.md#KC-GIDP-C3 ("you'll need from this page is the Redirect URI. You'll have to provide that to Google when you register Keycloak as a client there") + raw/official-docs/keycloak-google-idp-setup.md#KC-GIDP-C4 ("copy and paste the Redirect URI ... into the Authorized redirect URIs field") |
official-vendor-doc |
"exactly match" 의 byte-level 정의 (trailing slash / case / query string) 는 vendor verbatim 부재 — 실험 검증 필요 |
| D2 | redirect URI 는 HTTPS scheme 필수 (학습 환경의 localhost 예외 제외) | raw/official-docs/google-oauth2-redirect-uri-validation-official.md#GOOGLE-REDIR-C1 ("Redirect URIs must use the HTTPS scheme, not plain HTTP. Localhost URIs (including localhost IP address URIs) are exempt from this rule") |
official-vendor-doc |
localhost 예외가 production 시나리오 에서 허용된다는 뜻은 아님 — 학습 단계 한정 |
| D3 | redirect URI host 는 raw IP 금지 — public domain 필요 → ngrok/Cloudflare Tunnel 같은 tunneling 도구 채택 정당화 | raw/official-docs/google-oauth2-redirect-uri-validation-official.md#GOOGLE-REDIR-C2 ("Hosts cannot be raw IP addresses. Localhost IP addresses are exempted from this rule") |
official-vendor-doc |
Cloudflare Tunnel 의 <UUID>.cfargotunnel.com 같은 generic subdomain 이 "raw IP 가 아니므로" 항상 허용되는지 vendor 정책 verbatim 부재 |
| D4 | redirect URI 에 wildcard / fragment 사용 불가 → 다중 환경 (dev/staging/prod) 각각 별도 등록 | raw/official-docs/google-oauth2-redirect-uri-validation-official.md#GOOGLE-REDIR-C4 ("Redirect URIs cannot contain the fragment component") + raw/official-docs/google-oauth2-redirect-uri-validation-official.md#GOOGLE-REDIR-C5 ("Redirect URIs cannot contain certain characters including: Wildcard characters ('*')") |
official-vendor-doc |
환경 분리 best practice 자체는 cited raw 에 verbatim 없음 — wildcard 금지 결과로 유도된 운영 결정 |
| D5 | Google IdP scope 는 openid email profile 만 사용 — sensitive scope 회피 → verification 심사 불필요, 그리고 이 basic identity scope 조합은 test-user allowlist 등록·100명 상한·7일 만료·unverified 경고가 모두 면제됨 (기존 본문의 "100명 test users까지" 표현은 부정확 → §마주친 문제 정합 권고 참조) |
raw/official-docs/keycloak-google-idp-setup.md#KC-GIDP-C5 ("By default, Keycloak uses the following scopes: openid profile email") + raw/official-docs/google-oauth-manage-app-audience-official.md#GOOGLE-APPAUD-C4 ("The only exception ... userinfo.email, userinfo.profile, openid ... your users do not need to be in the trusted user list, they will not see a warning message, and their authorizations will not expire after 7 days") + raw/official-docs/google-oauth-app-verification-state-overview-official.md#GOOGLE-VERIFY-STATE-C2 ("Exception: If the app only requests basic identity scopes (openid, email, profile), any user can access without being on the allowlist") + #GOOGLE-VERIFY-STATE-C4 (verification 은 sensitive/restricted scope public 앱에만 "Required for") |
official-vendor-doc |
Published(In production) 전환 시에도 이 예외가 유지되는지(brand verification 별도 요구 여부)는 미확인 — documented-only/Testing 고정이라 당장 무영향. Testing 100-user cap(GOOGLE-APPAUD-C1)과 unverified-app-screen 신규 100-user cap 은 서로 다른 quota — 혼동 금지 |
| D6 | Google OAuth client Application type = Web application (confidential/server-side client); Keycloak 이 server-to-server /token 호출 → JavaScript origins 비워둠 |
Application type: raw/official-docs/google-oauth2-web-server-flow-official.md#GOOGLE-WEBSERVER-C2 ("Select the Web application application type") + confidential flow: #GOOGLE-WEBSERVER-C1 ("designed for applications that can store confidential information and maintain state") + raw/official-docs/google-oauth2-client-application-types-official.md#GOOGLE-CLIENTTYPE-C1 ("Private Clients ... can securely store the client secret because they run on servers you control") + #GOOGLE-CLIENTTYPE-C3 (web application 정의). JS origins 비움: #GOOGLE-CLIENTTYPE-C5 ("Applications that use client-side JavaScript ... must specify authorized JavaScript origins") 의 조건부 트리거 + web-server-flow 문서가 redirect URIs(GOOGLE-WEBSERVER-C3)만 언급하고 JS origins 미언급 → 구조적 추론 (명시적 "비워도 됨" 문장은 vendor 부재) |
official-vendor-doc (Application type/confidential 확정) + official-vendor-doc 구조적 추론 (JS origins 비움 — 명시 아님) |
Google 어떤 공식 문서도 "JavaScript origins 를 비워도 된다"를 명시적으로 선언 안 함 — 조건부 스코핑(C5)+web-server 문서 침묵의 추론. verified 승급은 실제 Console 등록 실험 후에만(§Claims To Verify). Service-account/native-app 흐름은 본 D6 범위 밖 |
| D7 | DELEGATED — raw/branch-notes/feature-keycloak-first-broker-login-flow D1/D4 — AutoLink를 추가하지 않고 소유 증명 없는 silent auto-link를 차단 | raw/official-docs/keycloak-first-login-flow.md#KC-FLF-C2, #KC-FLF-C3 |
delegated + official-vendor-doc |
email_verified=false 전체 hard-reject는 현재 provider/SPI artifact가 없으므로 본 branch가 보장하지 않는다. 필요한 경우 별도 custom SPI variant에서 구현·검증 후 owner를 연결한다. |
| D8 | ngrok 운영 burden (매 세션 5~10분 갱신) → sub-sub-branch -6-1 의 Cloudflare Tunnel 정적 도메인 채택 정당화 |
raw/official-docs/google-oauth2-redirect-uri-validation-official.md#GOOGLE-REDIR-C3 (exact match 요구로 인해 URL 변경 시 매번 갱신 필요) — 간접 근거. "5~10분" 정량 수치 는 작성자 운영 추정 (UNSUPPORTED_DECISION — verbatim 외부 출처 없음) |
official-vendor-doc (exact match 배경) + UNSUPPORTED_DECISION (정량 수치) |
"5~10분" 수치를 실제 측정으로 대체 (P3B 구현 시점) 또는 작성자 추정임을 명시 유지 |
구현 가이드
본 sub-sub-branch 는
documented-only— 여기서 "구현"은 코드가 아니라 Google Cloud Console + Keycloak Admin 등록 절차의 사전 명세다. 실 등록을 수행할 미래 작업자가 되묻지 않고 필드를 채울 수 있는 수준이 목표. 3-rule: R1 각 row 는 Decision ID + Claim ID reference · R2 근거 없는 detail 은UNSUPPORTED_IMPL_DECISION+ trade-off 한 줄 · R3 본 branch 결정 범위 밖(부모 proxy/hostname 설정 · sibling flow authenticator · tunnel 설정)은 §엣지·실패·의존 으로 위임(여기 재진술 안 함).
1. Google Cloud Console — OAuth 2.0 Client ID 등록 필드 명세
Trace: D1·D2·D3·D4 (
GOOGLE-REDIR-C1~C5) redirect URI 정책 · D5 (KC-GIDP-C5+GOOGLE-APPAUD-C4+GOOGLE-VERIFY-STATE-C2) scope+verification · D6 (GOOGLE-WEBSERVER-C1/C2+GOOGLE-CLIENTTYPE-C1/C3/C5) client type/JS origins.
- UNSUPPORTED_IMPL_DECISION: (a)
Name표시값 = 임의(동작 무관, trade-off: 학습 단계 무영향). (b)·(c) 는/branch-spec자동조사(2026-07-16)로 해소 — JS origins 비움은GOOGLE-CLIENTTYPE-C5조건부 트리거의 구조적 추론(명시적 "비워도 됨" vendor 부재 → D6 Open Risk 유지), test-user 정책은GOOGLE-APPAUD-C4예외로 정정(basic scope 조합엔 100명 한도 부적용).
| 필드 | 입력 값 | Trace | Note |
|---|---|---|---|
| Application type | Web application | D6 (GOOGLE-WEBSERVER-C2, GOOGLE-CLIENTTYPE-C1/C3) |
confidential(server-to-server) client — client_secret 서버 보관 |
| Name | 임의 (예: keycloak-broker-learning) |
— | UNSUPPORTED_IMPL_DECISION — 표시 이름, 동작 무관 |
| Authorized redirect URIs | https://<keycloak-domain>/keycloak/realms/<realm>/broker/google/endpoint |
D1 (GOOGLE-REDIR-C3) + KC-GIDP-C4 |
실제 SSOT = Keycloak Admin "Redirect URI" 표시값(KC-GIDP-C3). /keycloak=부모 D4, <realm>/google alias=프로젝트 값(§엣지·실패·의존 위임) |
| — scheme | HTTPS 필수 | D2 (GOOGLE-REDIR-C1) |
localhost 만 예외 → 학습도 tunnel HTTPS 사용 |
| — host | raw IP 금지 → tunnel 도메인 | D3 (GOOGLE-REDIR-C2) |
cfargotunnel.com 통과 여부 = Claims To Verify |
| — 제약 | wildcard(*)·fragment(#) 불가 |
D4 (GOOGLE-REDIR-C4,C5) |
dev/staging/prod 각각 별도 등록 |
| Authorized JavaScript origins | (비움) | D6 (GOOGLE-CLIENTTYPE-C5) |
client-side JS 미사용 → 구조적 추론상 불필요(명시적 vendor 문장 부재 → D6 Open Risk). verified 는 Console 실험 후(§Claims To Verify) |
| Consent screen — User type | External | D5 | |
| Consent screen — Scopes | openid email profile |
D5 (KC-GIDP-C5, GOOGLE-VERIFY-STATE-C4) |
non-sensitive → verification 회피(공식 근거 확보) |
| Consent screen — Test users | (등록 불필요) | D5 (GOOGLE-APPAUD-C4) |
⚠️ 정정: basic scope 조합은 test-user allowlist·100명 상한·7일 만료·경고 모두 면제 — "100명 한도까지 동작" 표현은 부정확 |
2. Keycloak Admin Console — Google IdP 입력 매핑
Trace: D1 +
KC-GIDP-C1~C5. 양방향 등록(Keycloak Redirect URI → Google, Google client_id/secret → Keycloak).
| 단계 | 위치 | 입력/취득 | Trace |
|---|---|---|---|
| IdP 추가 | Identity Providers → Add provider → Google | alias=google |
KC-GIDP-C1 |
| Redirect URI 취득 | Add Identity Provider 페이지 Redirect URI 표시값 |
§1 Authorized redirect URIs 의 SSOT — 이 값을 Google 에 복사 | KC-GIDP-C3,C4 |
| Client ID/Secret 입력 | 같은 페이지 Client ID / Client Secret 필드 |
Google 발급값 | KC-GIDP-C2 |
| Default Scopes | Advanced → Default Scopes | openid profile email(기본값 유지) |
KC-GIDP-C5 |
3. URL 변경 시 redirect_uri 갱신 절차
Trace: D8 (
GOOGLE-REDIR-C3exact match → URL 변경 시 재등록 필수). 절차 표는 §진행 중 메모 "ngrok URL 변경 시 갱신 절차" + "Cloudflare Tunnel 정적 도메인 대안" 이 owner — Single-Owner 원칙상 여기서 재진술하지 않는다. tunnel 도구 채택 결정 자체는 sibling raw/branch-notes/feature-keycloak-public-domain-tunneling D1/D2 소유(§엣지·실패·의존 위임).
엣지·실패·의존
R4 캡처용. 정상 등록 경로 외의 실패/엣지 + 본 branch 가 consume 하는 다른 계약. 실 적용 전이므로 "예상" 경로.
실패·엣지 경로:
- redirect_uri exact match 위반 (D1): trailing slash 유무 / scheme 누락(http) / relative path 오타(
/keycloak누락) / alias 불일치 → Googleredirect_uri_mismatch→ 인증 차단. byte-level 정의(trailing slash·case·query)는 미확정 → Claims To Verify. - propagation lag (D1·D8): Google Console redirect_uri 변경 후 즉시~수분 지연 → 학습 시 디버깅 noise. 기대 동작: 재시도/대기.
- generic subdomain 거부 가능성 (D3):
<UUID>.cfargotunnel.com이 "no raw IP" 정책은 통과하나 Google 이 별도 사유로 거부할 여지 → 미검증(Claims To Verify; sibling tunneling D1 의 "Does not prove" 단서와 동일 미해소). - email auto-link 보안 위험 (D7): OOTB 기본은 Confirm Link이며 AutoLink는 별도 opt-in이다. 기대 동작: raw/branch-notes/feature-keycloak-first-broker-login-flow D1/D4에 따라 AutoLink를 추가하지 않아 silent link를 차단한다.
- client_secret 노출 (진행 중 메모): Keycloak DB plaintext 저장 + docker-compose env 노출 → git 커밋 누출 위험. 기대 동작: vault/secret 관리(학습은 무시) → Claims To Verify.
- scope 확장으로 verification 조건 진입 (D5): basic identity scope에는 test-user 한도가 적용되지 않는다. sensitive/restricted scope를 추가하면 별도 verification·quota 조건으로 진입할 수 있으므로 학습 흐름은
openid email profile로 고정한다.
다른 계약 의존 (consume):
- raw/branch-notes/feature-keycloak-single-ec2-google-federation
D6— broker endpoint URL 포맷(.../broker/google/endpoint)을 consume. 이 URL 이 곧 §구현가이드 §1 Authorized redirect URIs 값. 부모 계약 변경 시 본 branch 재등록 필요. - raw/branch-notes/feature-keycloak-single-ec2-google-federation
D4—KC_HOSTNAME+KC_HTTP_RELATIVE_PATH=/keycloak를 consume. redirect_uri 의 host·path 가 여기서 결정됨. proxy/hostname 설정은 부모 owner — 본 branch 는 결과 URL 만 사용. - raw/branch-notes/feature-keycloak-first-broker-login-flow D1/D4 — AutoLink 미사용과 silent auto-link 차단을 consume한다. hard-reject는 본 branch 범위가 아니다.
- raw/branch-notes/feature-keycloak-public-domain-tunneling D1/D2 — public 도메인 확보 수단을 consume한다. D8의 갱신 burden 비교가 이 tunnel 채택 결정에 종속하며 설정 detail은 sibling owner다.
검증해야 할 주장
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
Keycloak callback URL 의 정확한 path 형식 <keycloak-domain><relative-path>/realms/<realm>/broker/<idp-alias>/endpoint 이 모든 Keycloak 버전에서 동일 |
path 형식의 vendor verbatim 부재; KC_HTTP_RELATIVE_PATH 조합 시 정확한 결과의 verbatim 없음 |
Keycloak 25.x docker 실행 + admin UI 의 IdP "Redirect URI" 자동 표시값 캡처 + Server Admin Guide raw 발췌 | needs-confirmation |
| "exactly match" 의 byte-level 정의 (trailing slash / case sensitivity / query string) | cited GOOGLE-REDIR-C3 에 디테일 명시 없음 — "일반 OAuth 관례" 추정 | trailing slash 유무로 등록 후 실제 redirect 시 Google 응답 차이 실험 | needs-confirmation |
Cloudflare Tunnel <UUID>.cfargotunnel.com generic subdomain 이 Google "no raw IP" 정책 통과 |
cited GOOGLE-REDIR-C2 의 "raw IP 금지" 가 generic subdomain 도 cover 하는지 verbatim 부재 | Cloudflare Tunnel 정적 도메인 등록 + Google Console 등록 시도 → propagation 결과 확인 | planned |
| ngrok URL 변경 시 Google Console propagation 시간 (vendor docs "최대 수시간") | cited raw 에 verbatim 없음 | Google Cloud Console "OAuth 2.0 settings propagation" 공식 페이지 raw 추가 | needs-confirmation |
unverified(Testing) app + openid email profile (non-sensitive scope) 만 사용 시 test-user 등록 없이 임의 Google 계정 정상 동작 (100명 한도 개념 부적용) |
공식 근거 확보(GOOGLE-APPAUD-C4 + GOOGLE-VERIFY-STATE-C2 — test-user allowlist·100명·7일·경고 모두 면제). 잔여 불확실 = Published(In production) 전환 시 brand verification 별도 요구 여부만 |
실제 Testing app 으로 등록 후 임의 Google 계정 로그인 동작 실측 (문서 근거는 완료) | needs-confirmation (문서 근거 확보, 실측 미실시) |
Keycloak client_secret plaintext 저장 (또는 vault credentials store) 동작 — git 커밋 누출 위험 |
cited raw 에 verbatim 없음 | Keycloak Server Admin Guide "Vault" 섹션 raw 추가 + Keycloak DB 의 client_secret 컬럼 확인 |
needs-confirmation |
Authorized JavaScript origins 가 server-to-server brokering 시나리오에서 정말 비워둘 수 있음 |
구조적 근거 확보(GOOGLE-CLIENTTYPE-C5 조건부 트리거 "client-side JS 사용 시에만 필수" + GOOGLE-WEBSERVER 문서의 JS origins 미언급) — 단 "비워도 됨" 명시 문장은 vendor 부재(추론) |
origins 비운 상태로 Keycloak ↔ Google /token 호출 정상 동작 실측 (구조적 근거는 완료) |
needs-confirmation (구조적 근거 확보, 실측 미실시) |
마주친 문제
- 아직 없음 (문서 단계). 실 적용 시 예상되는 함정:
- redirect_uri exact match 위반: trailing slash 유무 / scheme 누락 / relative path 오타. Google docs는 "must match exactly".
- propagation lag: Google 측 redirect_uri 변경 후 즉시 반영되지만 캐시 영향으로 수분 지연 사례 보고됨. 학습 시 디버깅 noise.
- First Broker Login email match AutoLink: OOTB 기본이 아니라 별도 opt-in이며, 활성화하면 보안 위험이 생긴다. 현재 정책은 raw/branch-notes/feature-keycloak-first-broker-login-flow D1에 따라 추가하지 않는다.
client_secret노출: Keycloak DB에 plaintext 저장. Git 커밋 / docker-compose env file 노출 위험.
정합 권고 (
/branch-spec자동조사 2026-07-16 — 사용자 본문 verbatim 미변경, 정정만 surface): 정합 반영 완료 (2026-07-18):목표/WHY·TODO·진행 중 메모의 옛 "100명 test users까지" 문구를 basic identity scope 예외로 갱신했다.openid/profile만 요청하면 test-user allowlist·100명 상한·7일 만료·unverified 경고가 면제된다(GOOGLE-APPAUD-C4,GOOGLE-VERIFY-STATE-C2). sensitive/restricted scope의 quota는 별도 조건이다.
묶음
- raw/official-docs/google-oauth-app-verification-state-overview-official
- raw/official-docs/google-oauth-manage-app-audience-official
- raw/official-docs/google-oauth2-client-application-types-official
- raw/official-docs/google-oauth2-redirect-uri-validation-official
- raw/official-docs/google-oauth2-web-server-flow-official
- raw/official-docs/keycloak-google-idp-setup
- raw/official-docs/keycloak-identity-brokering-overview-official
- raw/official-docs/oauth-v2-1-draft-ietf
본 branch 는 leaf — 자식 자료 없음. errors / interview prep / lectures 가 누적되면 본 섹션에서 그룹화.
근거 자료
전체 목록·정당화 결정 매핑은 상단 "## Sources / 근거" 섹션이 owner (Single-Owner, 중복 재진술 안 함). 최근 추가: raw/official-docs/google-oauth-app-verification-state-overview-official — D5 verification-policy 부분 developer-doc 근거 보강 (2026-07-16).
오류 기록
- (없음)
면접 준비
- (없음)
관련 일일 노트
완료 후 정리
본 sub-sub-branch는 문서까지만. 실 Google Cloud project / OAuth client 등록은 P3A 완료 후 선택적 확장.
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경: 해당 없음 (문서 단계, P3B 전체
documented-only) - wiki 추출 대상 (verified만,
wiki/projects/로만 추출):actually-implemented항목: 없음locally-verified항목: 없음prod-verified항목: 없음
- 추출하지 않을 항목 (planned / documented-only / abandoned):
- 본 sub-sub-branch 전체가
documented-only. 추후wiki/concepts/keycloak-deployment-patterns.md합성 시 "Google IdP 등록 + redirect_uri exact match" 섹션으로 인용 후보.
- 본 sub-sub-branch 전체가