LabHub

블로그

Keycloak로 SSO 구축하기 — Realm·Client·플로우부터 2026 신기능까지

한국어English日本語中文

들어가며 — 로그인은 왜 직접 만들면 안 되는가

사내 앱이 20개라고 합시다. 각각에 회원가입·비밀번호 재설정·2FA·소셜 로그인·세션 관리를 따로 구현하면, 보안 구멍이 20배가 됩니다. SSO(Single Sign-On)의 아이디어는 단순합니다 — 로그인이라는 일을 전담하는 서버를 하나 두고, 모든 앱이 그 서버에 "이 사람 누구야?"를 위임하는 것입니다. 사용자는 한 번 로그인하면 20개 앱을 다 쓰고, 앱들은 비밀번호를 아예 만지지 않습니다.

Keycloak은 이 아이덴티티 서버의 오픈소스 표준입니다(현재 CNCF 인큐베이팅 프로젝트, Red Hat build of Keycloak의 업스트림). OIDC와 SAML을 모두 말하고, 소셜 로그인 브로커링·LDAP 연동·2FA·WebAuthn을 기본 제공합니다. 이 글은 Keycloak을 4개의 핵심 개념으로 이해하고, 로그인 흐름을 한 단계씩 따라간 뒤, 배포의 함정과 2026년 신기능까지 정리합니다. 인증 흐름 자체가 낯설다면 인증 플로우 시각화 도구를 먼저 만져 보면 이 글이 훨씬 쉬워집니다.

1부 — 4개의 핵심 개념으로 보는 Keycloak

Keycloak의 관리 콘솔은 메뉴가 수십 개지만, 뼈대는 네 개입니다.

개념                역할                                    비유
─────────────────  ──────────────────────────────────────  ──────────────────
Realm              완전히 격리된 테넌트 (자체 유저·설정)    하나의 "왕국"
Client             인증을 위임받는 애플리케이션             왕국의 "출입증 발급 대상"
Role / Group       권한과 사용자 묶음                       "직책"과 "부서"
Identity Provider  외부 로그인 소스 (구글·상위 OIDC/SAML)   "다른 왕국의 여권 인정"

2부 — OIDC 로그인 흐름 한 단계씩

가장 많이 쓰는 흐름은 Authorization Code + PKCE입니다. SPA가 Keycloak에 로그인을 위임하는 과정을 따라가 봅시다.

① 사용자가 앱의 "로그인" 클릭
   → 앱이 브라우저를 Keycloak authorize 엔드포인트로 리다이렉트
     (client_id, redirect_uri, scope=openid, code_challenge 포함)

② Keycloak이 로그인 화면 표시 → 사용자가 인증 (비밀번호 + OTP 등)
   ※ 이미 Keycloak 세션이 있으면 이 화면을 건너뜀 = SSO의 핵심

③ Keycloak이 redirect_uri로 되돌려보냄 + 일회용 authorization code

④ 앱 백엔드(또는 SPA)가 code + code_verifier를 token 엔드포인트로 교환
   → access_token(JWT) + id_token + refresh_token 수령

⑤ 앱은 access_token을 API 호출 Authorization 헤더에 실어 보냄
   API는 Keycloak의 공개키(JWKS)로 서명만 검증 — 매 요청 Keycloak에 안 물어봄

여기서 세 가지가 핵심입니다. 첫째, PKCE(code_challenge/code_verifier)는 탈취된 authorization code를 무력화합니다 — public 클라이언트라면 필수입니다. 둘째, ②의 "세션이 있으면 건너뜀"이 바로 SSO입니다. 두 번째 앱이 로그인을 위임하면 Keycloak은 이미 브라우저 쿠키로 사용자를 알아보고 로그인 화면 없이 즉시 code를 발급합니다. 셋째, ⑤에서 API는 매 요청 Keycloak을 호출하지 않습니다 — access_token은 서명된 JWT이므로 공개키로 로컬 검증만 하면 됩니다. 이 무상태성이 SSO가 확장되는 이유입니다.

토큰 세 종류의 역할도 헷갈리지 마세요:

id_token       "누가 로그인했는가" — 사용자 정보. 앱(클라이언트)이 소비
access_token   "무엇을 할 수 있는가" — 권한. API(리소스 서버)가 검증
refresh_token  "다시 발급받을 권리" — access_token 만료 시 갱신용, 안전하게 보관

세션·토큰 수명 튜닝은 Realm 설정의 핵심 레버입니다. access_token은 짧게(수 분), refresh_token은 길게(SSO 세션 수명까지) 잡는 것이 표준이며, 짧은 access_token + 로컬 서명 검증의 조합이 "탈취돼도 곧 만료"와 "빠른 검증"을 동시에 줍니다.

3부 — 배포: Quarkus 2단계 모델과 프로덕션 함정

Keycloak 17부터 배포판은 Quarkus 기반입니다(옛 WildFly/JBoss 배포는 제거됨). 여기서 처음 만지는 사람이 가장 많이 걸리는 함정이 build/start 2단계 모델입니다.

# ① 빌드 단계(augmentation): DB 벤더·활성 기능을 "구워 넣는다"
#    — 이 단계는 느리지만 자주 하지 않음
bin/kc.sh build --db=postgres --features=organizations,token-exchange

# ② 실행 단계: 런타임 설정(호스트명·DB 접속·TLS)만 넘김
bin/kc.sh start --optimized \
  --hostname=https://auth.example.com \
  --db-url=jdbc:postgresql://db/keycloak \
  --db-username=keycloak --db-password="$KC_DB_PASSWORD"

# 로컬 개발용은 두 단계를 합쳐 주는 편의 명령
bin/kc.sh start-dev

--optimized 플래그는 "이미 build 했으니 start에서 재빌드하지 마"라는 뜻입니다. 컨테이너 이미지에서는 빌드 단계를 Dockerfile에 넣어 이미지에 구워 두고, 런타임에는 start --optimized만 도는 것이 정석입니다.

프로덕션에서 밟는 대표적인 지뢰 세 가지:

쿠버네티스라면 Keycloak OperatorKeycloak·KeycloakRealmImport CRD로 이 모든 것을 선언형으로 감싸 줍니다. 쿠버네티스 감각이 필요하면 쿠버네티스 놀이터에서 CRD·오퍼레이터 패턴을 먼저 익혀 두면 좋습니다.

4부 — 2026년의 Keycloak: 26.x 신기능

이 글 기준 최신은 26.6.3입니다(내부 Quarkus 3.33.2). 26 계열에서 정식 기능이 된 것들 중 실무 임팩트가 큰 넷:

토큰 교환(token exchange)에는 아직 경계가 있습니다 — 현재 OIDC/OAuth 교환만 지원하고 SAML 기반 클라이언트·IdP 교환은 향후 과제입니다. 그래서 외부 신뢰 수립은 위의 JWT Authorization Grant가 더 표준적인 답입니다.

5부 — 언제 쓰고, 언제 다시 생각할까

Keycloak이 빛나는 곳: 온프레미스·하이브리드에서 데이터 주권이 필요할 때, 프로토콜(OIDC+SAML) 커버리지가 넓어야 할 때, 라이선스 비용 없이 대규모로 확장할 때. 관리형 SaaS(Auth0·Okta·Entra ID)와의 갈림길은 대개 "운영 부담을 질 것인가, 비용·종속을 질 것인가"입니다 — Keycloak은 DB·업그레이드·가용성을 직접 책임지는 대신, 데이터와 커스터마이징의 완전한 통제를 줍니다.

다시 생각할 지점: 아이덴티티 서버는 단일 장애점입니다. 죽으면 20개 앱이 동시에 로그인 불가가 됩니다. 그래서 다중 인스턴스 + 외부 세션 저장(Infinispan/DB) + 무중단 패치가 선택이 아니라 필수입니다. 그리고 토큰·세션 수명, redirect URI 화이트리스트, PKCE 강제 같은 보안 기본기를 놓치면 SSO는 오히려 공격면을 한곳에 모아 주는 꼴이 됩니다. 이 감각은 인증·보안 실습 랩에서 OAuth·OIDC·JWT를 직접 손으로 돌려 보며 다지는 것을 권합니다.

마치며

Keycloak은 결국 "로그인을 한 곳으로 모으는" 인프라입니다. Realm(격리)·Client(앱)·Role/Group(권한)·IdP(외부 연동) 네 개념으로 뼈대를 세우고, Authorization Code + PKCE로 흐름을 이해하고, build/start 2단계 + hostname v2로 배포 함정을 피하고, Organizations로 멀티테넌시를 풀면 — 20개 앱의 로그인이 하나의 잘 지켜지는 문으로 수렴합니다. 오픈소스이면서 표준을 정직하게 따른다는 점이, 10년 넘게 이 프로젝트가 사랑받는 이유입니다.

참고 자료

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다