콘텐츠로 이동
Study NoteKeycloak

인증 생태계의 큰 그림

결론부터
인증은 사용자가 누구인지 확인하고 인가는 그 사용자의 행동을 허용할지 판단하며, 관련 기술은 신원 원본부터 앱의 결정까지 계층별로 놓아야 관계가 보인다.

사용자가 관리 화면의 삭제 버튼을 눌렀다고 하자. 시스템은 먼저 요청자가 누구인지 확인하고, 그다음 그 사용자가 이 작업을 해도 되는지 판단해야 한다. 앞이 인증(authentication), 뒤가 인가(authorization)다. 인증만 있으면 로그인한 모든 사용자가 같은 일을 할 수 있고, 인가만 있으면 정책을 누구에게 적용할지 알 수 없다.

사내 앱마다 이 두 판단을 모두 직접 구현하면 비밀번호 처리와 로그인 정책이 중복되고, 권한 규칙과 감사 지점도 흩어진다. 그래서 로그인은 Identity Provider(IdP)로 모으고, 앱과 API는 IdP가 전달한 신원·권한 정보를 자기 정책과 결합해 최종 접근을 결정한다.

이 장에서 처음 나오는 말3개
authentication인증
비밀번호·OTP 같은 자격 증명이나 기존 세션을 확인해 요청자의 신원을 확립하는 과정.
authorization인가
확인된 신원이 특정 자원에 특정 행동을 해도 되는지 정책으로 판단하는 과정.
IdPIdentity Provider
사용자를 인증하고 앱이 검증할 수 있는 인증 결과를 제공하는 주체. Keycloak과 AD FS가 이 역할을 할 수 있다.

먼저 각 층의 제목을 위에서 아래로 읽는다. 신원을 얻는 곳 → 로그인을 맡는 곳 → 통신 규칙 → 주고받는 값 → 값을 사용하는 곳 순서다. 각 상자는 그 자리에서 만날 용어와 짧은 뜻을 묶었다. 실제 요청 순서나 모든 시스템에 필수인 구성요소를 뜻하지는 않는다.

Keycloak 개념 지도: 외부 신원 연결, Keycloak 내부 관리, OAuth·OIDC·SAML 통신 규칙, token·claim, 앱·API의 판단과 운영 기반

이 지도에서 특히 세 가지 관계를 찾으면 된다.

  • Keycloak은 로그인 담당 서버, OIDC는 앱과 대화하는 규칙, token은 주고받는 값이다. 그래서 셋은 함께 쓰인다. 파란 영역의 용어는 Keycloak 내부의 관리 개념이다.
  • 노란 영역의 OAuth → OIDC는 권한 위임에 사용자 인증을 더하는 관계다. Authorization Code는 그때 쓸 수 있는 교환 흐름이고 PKCE는 그 흐름을 보호한다. 왜 각각 필요한지는 별도 예제로 이어진다.
  • SSO는 규칙이나 token의 이름이 아니라 로그인 경험이다. 앱마다 자기 세션을 만들면서도 Keycloak의 기존 세션을 재사용해 비밀번호를 다시 묻지 않을 수 있다.

Service Account는 사용자 대신 앱 자체의 신원을 쓰는 경우, oauth2-proxy는 앱 앞에서 로그인을 맡는 경우, Kubernetes OIDC는 Kubernetes API가 신원 정보를 소비하는 경우다. 새로운 프로토콜 계층이 생기기보다 위 지도의 담당 주체나 소비자가 달라진다.

  • 인증과 인가는 왜 둘 다 필요하고, 각각 누가 결정하는가?
  • AD·LDAP·IdP·OIDC·SAML은 어느 계층에 있으며, 같은 층의 대안은 무엇인가?
  • Authorization Code와 PKCE는 OIDC 로그인 안에서 어떻게 이어지는가?
  • Keycloak이 AD를 직접 읽는 경로와 AD FS에 인증을 맡기는 경로는 무엇이 다른가?
판단묻는 질문없으면 생기는 문제이 덱에서 주로 결정하는 곳
인증이 요청자는 누구인가?다른 사람을 사칭하거나 출처를 알 수 없는 요청을 사용자 요청처럼 처리한다.Keycloak 같은 IdP가 자격 증명·세션을 확인한다.
인가이 사용자가 이 자원에 이 행동을 해도 되는가?로그인했다는 이유만으로 일반 사용자가 관리자 작업까지 할 수 있다.앱·API가 token의 claim과 자기 권한 정책을 함께 보고 최종 결정한다.

인증은 인가의 입력을 만들지만 인가를 대신하지 않는다. 예를 들어 Keycloak이 sub=alice, groups=[finance]라는 claim을 넣은 access token을 발급할 수는 있다. 그러나 Alice가 결재 문서를 삭제해도 되는지는 그 문서를 소유한 앱이나 API의 정책이 판단한다.

token이 없거나 유효하지 않아 신원을 확인하지 못하면 보통 401 Unauthorized, 신원은 확인했지만 권한이 부족하면 403 Forbidden으로 구분한다. 이 덱의 실습도 이 경계를 직접 확인한다.

이름이 함께 등장한다고 모두 같은 층의 대안은 아니다. 아래 표에서 한 행 안의 항목이 같은 질문에 답하는 개념이다. 예를 들어 LDAP와 OIDC 중 하나를 고르는 것이 아니라, IdP가 디렉터리를 읽을 때는 LDAP를 쓰고 앱과 로그인 결과를 주고받을 때는 OIDC를 쓸 수 있다.

계층이 계층의 질문같은 층에 놓고 볼 개념
신원 원본사용자와 그룹은 어디에 저장되는가?AD / AD DS, Keycloak 로컬 사용자 저장소
원본 연결IdP는 외부 디렉터리를 어떻게 조회하는가?LDAP, TLS로 보호한 LDAPS
인증 제공자(IdP)누가 로그인과 인증 세션을 맡는가?Keycloak, AD FS
앱 로그인 프로토콜IdP와 앱은 인증 결과를 어떤 형식으로 주고받는가?OpenID Connect(OIDC), SAML 2.0
접근 권한 위임앱은 API 접근 권한을 어떻게 위임받는가?OAuth 2.0
권한 위임 흐름브라우저를 지나는 결과를 어떻게 token으로 바꾸는가?Authorization Code
code 보호 장치탈취한 code의 교환을 어떻게 막는가?PKCE
사용자가 겪는 결과여러 앱에서 로그인이 어떻게 느껴지는가?SSO

AD DS(Active Directory Domain Services)는 사용자·그룹 같은 디렉터리 객체를 계층 구조로 보관하는 서비스다. LDAP는 그런 디렉터리의 entry를 조회하고 bind로 자격 증명을 확인하는 접근 프로토콜이며, LDAPS는 그 통신을 TLS로 보호한다. 따라서 AD DS와 LDAP는 경쟁 제품이 아니라 “저장하는 곳”과 “접근하는 방법”의 관계다.

Keycloak과 AD FS는 모두 IdP 역할을 할 수 있다. 사용자를 인증하고 세션을 관리하며 앱이 검증할 수 있는 결과를 제공한다. AD FS는 AD DS와 이름이 비슷하지만, 사용자·그룹을 저장하는 디렉터리와는 다른 Windows Server 역할이다.

직접 운영하는 서버만 이 층에 있는 것은 아니다. Entra ID·Auth0 같은 관리형 서비스, 그리고 Firebase Auth나 Supabase의 GoTrue 기반 Auth처럼 BaaS 플랫폼에 내장된 인증 모듈도 같은 층의 대안이다 — 사용자를 인증하고 서명된 token을 발급한다는 뼈대가 같다. 차이는 목적이다. Keycloak은 여러 무관한 앱 앞에 세우는 범용 OIDC/SAML 제공자라 realm·client 등록·관리 위임 층이 두껍고, BaaS 내장형은 자기 플랫폼 백엔드(Supabase면 RLS)에 로그인시키는 것이 목적이라 그 층이 얇은 대신 앱 하나를 만들 때 간단하다. supabase 덱의 Auth 장에서 쓰는 로그인이 바로 이 층의 BaaS 내장형이다.

OIDC와 SAML 2.0은 IdP와 앱 사이에서 선택할 수 있는 같은 층의 로그인 프로토콜이다. OIDC는 OAuth 2.0 위에 ID token과 표준 claim을 더하고, SAML은 브라우저를 거쳐 서명된 XML assertion을 전달한다. SAML이 OIDC 위에서 동작하거나 OIDC의 한 흐름인 것은 아니다.

OIDC가 사용하는 OAuth 흐름과 보호 장치

섹션 제목: “OIDC가 사용하는 OAuth 흐름과 보호 장치”

이 네 항목도 서로 동급인 선택지가 아니다. 아래는 관계를 찾는 표이며, 각 규칙이 필요한 이유는 OAuth·OIDC·PKCE가 필요한 이유에서 사진 앱 예제로 따로 설명한다.

개념바로 위 개념과의 관계하는 일
OAuth 2.0기반 프레임워크앱이 제한된 API 접근 권한을 access token으로 받게 한다. 그 자체가 사용자 로그인 프로토콜은 아니다.
OIDCOAuth 2.0에 인증을 추가ID token과 표준 claim으로 앱이 로그인한 사용자를 확인하게 한다.
Authorization CodeOAuth 2.0에서 선택하는 흐름브라우저에는 access token 대신 짧게 쓰는 일회성 code를 전달하고, 앱이 그 code를 token으로 교환한다.
PKCEAuthorization Code에 붙는 보호 장치code_challenge와 code_verifier를 묶어, code를 훔친 다른 주체의 token 교환을 막는다.

SSO는 별도 프로토콜이 아니라 결과다

섹션 제목: “SSO는 별도 프로토콜이 아니라 결과다”

앱 A와 앱 B는 서로의 cookie를 공유하지 않는다. 두 앱이 각각 같은 IdP로 로그인 요청을 보냈을 때 IdP가 이미 있는 인증 세션을 재사용하면 사용자는 비밀번호를 다시 입력하지 않는다. 이 경험이 Single Sign-On(SSO)이다. OIDC나 SAML 중 어느 프로토콜을 쓰더라도 같은 원리로 만들 수 있다.

위 지도에서 AD DS → Keycloak → 앱 → API를 골라 보자. 실제 연결과 판단은 다음처럼 나뉜다.

  1. 원본 연결: Keycloak이 User Federation으로 AD DS를 조회한다. 이 통신의 규칙은 LDAP/LDAPS다.
  2. 로그인: 앱은 Keycloak에 OIDC 로그인을 요청한다. 이 덱에서는 Authorization Code 흐름에 PKCE를 붙여, 일회성 code를 token으로 교환한다.
  3. 앱의 판단: 앱은 ID token을 검증해 로그인한 사용자를 확인하고 자기 로그인 세션을 만든다.
  4. API의 판단: 앱이 access token으로 API를 호출하면, API가 token을 검증하고 claim과 대상 자원·행동에 대한 정책을 함께 확인한다.

로컬 사용자라면 외부 원본 연결이 필요 없다. SAML 앱이라면 로그인·결과 전달 부분을 SAML assertion 흐름으로 바꾸며, 그 흐름에 Authorization Code나 PKCE를 끼워 넣지 않는다.

회사 환경에서는 두 연결을 구분한다

섹션 제목: “회사 환경에서는 두 연결을 구분한다”

회사에 AD와 AD FS가 모두 있어도 Keycloak을 연결하는 경로는 하나로 고정되지 않는다. 자격 증명을 검증하는 주체와 브라우저가 이동하는 위치를 보면 두 경로를 가를 수 있다. 여기서 federation은 서로 다른 신원 시스템을 연결해 신원 정보를 이어 쓰는 관계를 넓게 가리킨다. 비교 기준으로 외부 연결이 전혀 없는 로컬 사용자를 먼저 놓으면 두 경로에서 무엇이 밖으로 넘어가는지가 보인다.

경로실제 연결인증하는 곳브라우저 이동선택 결과
(기준) Keycloak 로컬 사용자외부 연결 없음Keycloak이 자체 저장소의 credential 확인Keycloak 로그인 경로 안에 머묾realm 안에서 인증이 완결됨
Keycloak User FederationKeycloak → AD/AD DSKeycloak이 LDAP/LDAPS로 사용자를 찾고 사용자 bind를 요청Keycloak 로그인 경로 안에 머묾디렉터리 계정이 Keycloak 사용자 모델로 연결됨
Keycloak Identity BrokeringKeycloak → AD FSAD FS가 사용자를 인증하고 OIDC 또는 SAML 결과를 Keycloak에 반환Keycloak에서 AD FS 로그인 화면으로 이동외부 IdP 신원이 Keycloak realm 사용자와 연결됨

AD FS의 OIDC/OAuth 흐름과 SAML 지원은 Microsoft 공식 문서에서 확인할 수 있다. Keycloak의 external storage 설명은 LDAP·AD의 사용자와 자격 증명을 공통 사용자 모델로 연결하는 첫 번째 경로를 다룬다. Identity Brokering 설명은 외부 OIDC·SAML IdP가 인증한 결과를 받아 내부 앱으로 중계하는 두 번째 경로를 다룬다. 즉 AD DS와 AD FS를 같은 제품처럼 부르거나, AD가 있다는 이유만으로 연결 방식을 단정하면 안 된다.

회사에 무엇이 있느냐가 기본 선택을 정한다

섹션 제목: “회사에 무엇이 있느냐가 기본 선택을 정한다”
회사 환경기본 선택이유
AD DS만 있음User Federation인증 결과를 발급해 줄 외부 IdP가 없다. Keycloak이 LDAPS bind로 직접 검증하는 경로가 사실상 유일하다.
AD FS·사내 SSO가 이미 있음Identity Brokering비밀번호가 upstream 로그인 화면에만 입력되고 Keycloak을 거치지 않는다. AD 운영팀 입장에서도 제3 시스템에 LDAP bind를 열어 주는 것보다 relying party 등록이 노출이 작다.

기본 선택일 뿐 절대 규칙은 아니다. AD FS가 있어도 LDAP mapper로 디렉터리의 그룹·속성을 직접 가져와야 한다면 User Federation을 고를 수 있다 — 단 AD 운영팀이 bind 계정을 허용해야 가능한 선택이다. 반대로 brokering에서는 저장소를 조회할 수 없으므로 그룹 정보를 upstream IdP가 token claim으로 실어 줘야 하며, 그 구성도 upstream 운영팀과의 합의 대상이다.

조직 경계를 넘는 연결은 등록 신청으로 시작한다

섹션 제목: “조직 경계를 넘는 연결은 등록 신청으로 시작한다”

위의 어느 경로든 다른 팀이 운영하는 시스템과 연결하려면, 그쪽 등록부에 우리 쪽을 올려 달라는 신청이 먼저다. 무엇을 신청하는지가 자기 위치에 따라 다르다.

  • 앱 팀 → IdP 운영팀: 앱을 client로 등록한다. 앱을 식별할 서비스 URL과, 로그인 결과를 돌려받을 콜백 endpoint(OIDC redirect URI, SAML ACS URL)를 낸다. IdP는 등록된 콜백 주소로만 결과를 보내므로 개발·운영 등 환경마다 별도 client로 신청한다.
  • IdP 운영팀 → AD 운영팀: 경로에 따라 갈린다. User Federation이면 읽기 전용 bind 계정과 검색 시작 OU, LDAPS 방화벽·CA 체인을 신청하고, Brokering이면 AD FS에 Keycloak을 relying party로 등록해 달라고 신청한다 — 이때 콜백 endpoint는 앱 주소가 아니라 Keycloak의 broker 콜백이다.
앱 팀은 IdP에 client 등록을, IdP 운영팀은 AD 쪽에 연결 등록을 신청하는 조직 경계

AD 쪽 두 엣지는 대안 관계다 — 위 표의 두 경로 중 회사 환경에 맞는 하나를 고른다. 어느 쪽이든 AD 비밀번호를 다루는 곳은 신청으로 정한 경계 안쪽(디렉터리 bind 또는 AD FS 로그인 화면)에 머물고, 경계 밖의 앱에는 검증 가능한 token만 넘어온다.

  • 인증은 요청자가 누구인지 확인하고, 인가는 그 신원이 해당 작업을 해도 되는지 별도로 판단한다.
  • AD/AD DS는 디렉터리이고 LDAP/LDAPS는 그 디렉터리에 접근하는 프로토콜이다.
  • Keycloak과 AD FS는 IdP가 될 수 있고, 앱과는 OIDC나 SAML로 연결한다.
  • OAuth 2.0 access token은 API 권한 위임에 쓰며 OIDC가 사용자 인증을 더한다.
  • Authorization Code 흐름의 일회성 code를 PKCE가 보호하고, 공통 IdP 세션 재사용이 SSO 경험을 만든다.