Keycloak Subject User Mapping

email이 아니라 OIDC subject로 서비스 사용자를 식별하는 방식

Keycloak 기반 로그인에서 email과 username은 변경 가능한 사용자 속성이고, 안정적인 인증 주체 식별자는 OIDC token의 subject다. 각 서비스는 검증된 token의 issuer와 subject를 기준으로 내부 User를 매핑해야 한다.

SSO

개념

Keycloak을 인증 서버로 쓰는 시스템에서 사용자를 식별할 때 기준은 email이 아니라 OIDC token의 sub다. sub는 subject의 약자이고, Keycloak realm 안에서 특정 User 레코드를 가리키는 안정적인 식별자다.

로그인 정책상 username을 email로 강제하더라도 email은 식별자가 아니다. email, username, first name, last name, group, role은 바뀔 수 있는 사용자 속성이다. 반면 같은 Keycloak User 레코드가 유지되는 동안 다시 로그인해도 sub는 유지된다.

정확한 표준 키는 issuer + subject 조합이다.

issuer  = token.iss
subject = token.sub

단일 Keycloak realm만 운영하는 시스템에서는 실무적으로 sub만으로도 동작할 수 있다. 그러나 realm 분리, 인증 서버 이전, issuer 변경 가능성을 고려하면 데이터 모델은 issuer + sub를 기준으로 잡는 편이 맞다.

왜 필요한가

email을 사용자 식별자로 쓰면 운영 중 변경에 취약하다.

  • 사용자가 email을 변경할 수 있다.
  • username=email 정책이 나중에 바뀔 수 있다.
  • 같은 email로 계정을 삭제 후 재생성하면 다른 사용자일 수 있다.
  • 서비스마다 email 동기화 시점이 다르면 사용자 매핑이 어긋난다.
  • 외부 IdP나 realm 확장이 들어오면 email 충돌 가능성이 커진다.

인증 시스템에서 "이 사람이 같은 인증 주체인가"를 판단하는 기준은 표시용 속성이 아니라 인증 서버가 발급한 subject여야 한다. Keycloak 환경에서는 token의 sub가 그 역할을 한다.

속성과 식별자

사용자 데이터는 식별자와 속성을 분리해서 봐야 한다.

성격 식별자로 사용
sub Keycloak User의 subject 가능
iss + sub issuer 범위를 포함한 subject 권장
email 연락처/로그인 입력값 부적절
preferred_username 표시/로그인 이름 부적절
firstName, lastName 프로필 속성 부적절
groups, roles 권한/소속 속성 부적절

sub도 물리적으로 절대 불변은 아니다. Keycloak User를 삭제 후 재생성하거나, realm을 새로 만들거나, 마이그레이션에서 user id를 보존하지 않으면 달라질 수 있다. 그래서 더 정확한 표현은 "절대 안 바뀐다"가 아니라 "같은 issuer 안에서 같은 User 레코드가 유지되는 동안 안정적이다"이다.

서비스 간 사용자 판독

여러 서비스가 하나의 Keycloak을 신뢰한다면 서비스 간 사용자 판독 기준도 sub로 통일하는 것이 자연스럽다.

Keycloak
  ↓ token.iss + token.sub
API Gateway
  ↓ token exchange
Frappe / HR / Drive / 기타 서비스
  ↓
각 서비스 내부 User/Profile/Permission 매핑

각 서비스는 자체 DB의 내부 사용자 ID를 계속 가질 수 있다. 다만 외부 인증 주체와 내부 사용자를 연결하는 키는 email이 아니라 issuer + sub여야 한다.

서비스 내부 사용자 FK = 각 서비스의 내부 user id
서비스 간 사용자 매핑 키 = Keycloak issuer + sub
표시/연락 속성 = email, name, username

API Gateway와 Token Exchange

API Gateway가 Keycloak 로그인을 처리하고 token exchange까지 수행하는 구조에서는 보통 다음 흐름이 된다.

1. 사용자가 Keycloak에서 로그인
2. Keycloak이 JWT 발급
3. Gateway가 JWT 서명, iss, aud, exp를 검증
4. Gateway가 token.sub를 세션의 사용자 principal로 저장
5. Gateway가 대상 서비스 audience로 token exchange 수행
6. Gateway가 서비스에 Authorization: Bearer <exchanged_token> 전달
7. 서비스가 exchanged token을 검증하고 iss + sub로 내부 User 조회

Gateway가 X-Forwarded-Sub 같은 헤더를 보조로 전달할 수도 있다. 하지만 서비스가 그 헤더만 신뢰하면 안 된다. 외부에서 서비스에 직접 접근할 수 있거나 헤더 위조가 가능하면 인증이 깨진다.

보안적으로 더 명확한 방식은 각 서비스가 Authorization: Bearer로 받은 exchanged token을 직접 검증하고, 검증된 claim의 isssub를 쓰는 것이다.

헤더 기반 principal 전달은 아래 조건이 만족될 때만 허용 가능하다.

  • 서비스는 Gateway를 우회해서 외부에서 접근할 수 없다.
  • Gateway가 외부 요청의 인증 관련 헤더를 제거하거나 덮어쓴다.
  • Gateway와 서비스 사이 통신이 신뢰 가능한 네트워크, mTLS, 서비스 인증 등으로 보호된다.
  • 이 신뢰 경계가 문서와 배포 설정에 명시되어 있다.

Frappe User 매핑

Frappe 같은 애플리케이션 서비스는 인증 계정의 source of truth가 아니다. 인증 계정은 Keycloak이 관리하고, Frappe는 서비스 회원과 도메인 상태를 관리한다.

권장 모델은 다음과 같다.

User
- name 또는 내부 user id
- email
- keycloak_issuer
- keycloak_sub
- onboarding_status

권장 unique constraint는 다음이다.

unique(keycloak_issuer, keycloak_sub)

로그인 후 Frappe는 email로 User를 찾지 않는다. 검증된 token에서 isssub를 얻고, keycloak_issuer + keycloak_sub로 User를 조회한다.

좋은 흐름:
  token 검증 → iss/sub 추출 → User.keycloak_issuer/keycloak_sub 조회

나쁜 흐름:
  token 검증 → email 추출 → User.email 또는 User.name 조회

email은 User 프로필의 연락처나 표시 속성으로 동기화할 수 있다. 하지만 User 매핑의 기준으로 쓰면 안 된다.

Source of Truth

Keycloak과 애플리케이션 서비스의 책임은 분리해야 한다.

Keycloak

  • 인증 계정
  • password credential
  • login session
  • token 발급
  • OIDC subject

API Gateway

  • 로그인 흐름 처리
  • JWT 검증
  • 세션 관리
  • token exchange
  • downstream 서비스로 인증 컨텍스트 전달

Frappe 같은 애플리케이션 서비스

  • 서비스 회원
  • onboarding 상태
  • 프로필
  • 회사/조직 소속
  • 도메인 권한

따라서 "Keycloak에 사용자가 생겼다"는 말은 인증 계정이 생겼다는 뜻이다. 그것만으로 서비스 회원가입이나 onboarding이 완료됐다고 보면 안 된다.

언제 쓰나

이 패턴은 다음 상황에서 필요하다.

  • Keycloak을 중앙 인증 서버로 쓰는 경우
  • 여러 서비스가 같은 사용자를 판독해야 하는 경우
  • API Gateway가 BFF 또는 인증 경계 역할을 하는 경우
  • email 변경을 허용하거나 앞으로 허용할 수 있는 경우
  • token exchange로 서비스별 JWT를 발급하는 경우

반대로 단일 애플리케이션이 자체 email/password 로그인만 처리하고 외부 인증 서버가 없다면, 별도의 Keycloak subject 매핑은 필요 없다. 그 경우에도 email을 primary key로 쓰는 설계는 변경 비용과 계정 복구 리스크를 고려해야 한다.

더 보기

  • OAuth-OIDC-SAML — OIDC와 ID token의 역할
  • Token-Exchange — Gateway가 서비스별 토큰을 발급받는 방식
  • API-Gateway — 인증 경계를 중앙화하는 구조
  • BFF — 브라우저에 토큰을 노출하지 않는 로그인 구조
  • RBAC — subject 이후의 권한 모델
sunshinemoon · 2026