Files
llm-wiki/raw/branch-notes/feature-keycloak-google-redirect-uri-policy.md

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
DEC-KEYCLOAK-PATTERNS-OVERVIEW-IDP-BROKERING-001@1
WI-KEYCLOAK-PATTERNS-OVERVIEW-015
1 feature-keycloak-google-redirect-uri-policy feature-keycloak-google-claim-attribute-mapping
keycloak-patterns
branch
keycloak-patterns
p3b
google-oauth
idp-brokering
redirect-uri
consent-screen
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개 좌표가 글자 단위로 일치해야 한다:

  1. **Google Cloud Console "Authorized redirect URIs"**에 등록된 URL
  2. Keycloak Admin → Identity Providers → Google에서 발급하는 callback URL
  3. 실제 사용자 브라우저가 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 정적 도메인 선택의 결정 근거.

면접에서 답해야 할 질문:

  1. Keycloak callback URL의 정확한 포맷은? → https://<keycloak-domain><relative-path>/realms/<realm>/broker/<idp-alias>/endpoint
  2. Google OAuth client의 "Authorized JavaScript origins"는 왜 필요한가? → 본 시나리오에서는 불필요(server-to-server brokering). SPA가 Google과 직접 통신하면 필요.
  3. 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개+)

관련 sub-branch

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=true hard-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_DECISIONofficial-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 DELEGATEDraw/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-C3 exact 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 불일치 → Google redirect_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):

검증해야 할 주장

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/email/profile만 요청하면 test-user allowlist·100명 상한·7일 만료·unverified 경고가 면제된다(GOOGLE-APPAUD-C4, GOOGLE-VERIFY-STATE-C2). sensitive/restricted scope의 quota는 별도 조건이다.

묶음

본 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" 섹션으로 인용 후보.