멀티 테넌트 SaaS에서 IdP 테넌트 격리: 설계 원칙과 보안 검증 체크리스트
B2B SaaS 기업이 멀티 테넌트 환경에서 IdP를 운영할 때 테넌트 간 데이터 격리를 어떻게 설계하고 검증해야 하는지 정리합니다. 격리 아키텍처 비교, 라우팅 방식, 보안 체크리스트까지 실무 중심으로 다룹니다.
B2B SaaS에서 IdP(Identity Provider)를 멀티 테넌트로 운영한다는 것은, 하나의 시스템 안에 여러 기업의 인증 정보를 보관한다는 뜻입니다. A사의 OAuth 클라이언트 시크릿이 B사에 노출되거나, C사의 감사 로그에 D사의 사용자 기록이 섞이면 안 됩니다. 그런데도 이 문제를 본격적으로 검토하는 시점은 보통 데이터 유출 사고 이후입니다.
이 글은 멀티 테넌트 IdP에서 테넌트 격리가 왜 중요한지, 어떤 아키텍처 선택지가 있는지, 그리고 도입 전 반드시 확인해야 할 보안 체크리스트를 정리합니다.
테넌트 격리가 IdP에서 특히 중요한 이유
일반적인 SaaS와 달리, IdP는 보안의 최전선에서 동작합니다. IdP가 보관하는 데이터는 단순한 비즈니스 데이터가 아닙니다.
• 사용자 인증 정보: 이메일, 비밀번호 해시, MFA 시드 • 프로토콜 시크릿: OAuth client_secret, SCIM Bearer 토큰, SAML 서명 키 • 접근 기록: 감사 로그 전체 — 사용자가 언제, 어디에 접근했는지
이 데이터 중 하나라도 다른 테넌트에 노출되면, 공격자는 해당 정보를 바탕으로 연쇄적인 침투를 시도할 수 있습니다. 비즈니스 손실을 넘어 개인정보보호법 위반, SOC 2 Type II 탈락 등 법적·규제적 리스크로 직결됩니다.
테넌트 격리 아키텍처 3가지
멀티 테넌트 시스템의 격리는 세 가지 수준에서 설계할 수 있습니다.
1. 데이터베이스 수준 격리 (물리적 분리)
테넌트마다 별도의 데이터베이스 인스턴스를 할당합니다.
• 장점: 격리가 물리적으로 완전히 보장됨. 한 테넌트의 DB 접근이 다른 테넌트에 영향을 주지 않음 • 단점: 테넌트가 늘어날 때마다 DB 인스턴스를 관리해야 하므로 운영 비용이 급증. 스키마 마이그레이션을 모든 DB에 일괄 적용해야 하는 부담
소규모 테넌트 수(수십 개 이하)에서는 실용적이지만, SaaS 스케일에서는 운영 복잡도가 기하급수적으로 증가합니다.
2. 스키마 수준 격리
같은 데이터베이스 인스턴스 안에서 테넌트마다 별도 스키마를 생성합니다.
• 장점: DB 인스턴스는 공유하므로 비용 절감. 스키마 단위로 백업·복원 가능 • 단점: 연결 풀(Connection Pool) 관리가 복잡해짐. 테넌트 수가 많아지면 스키마 수도 증가
중간 수준의 격리가 필요한 경우에 적합하지만, SaaS 운영에서는 오히려 관리 부담이 큰 측면이 있습니다.
3. 행 수준 격리 (Shared Database)
모든 테넌트가 같은 테이블을 공유하되, 각 행에 tenant_id를 두어 논리적으로 분리합니다.
• 장점: 확장이 용이. 스키마 마이그레이션이 한 번만 수행됨. 인프라 비용이 가장 낮음
• 단점: 애플리케이션 레이어에서 모든 쿼리에 tenant_id 필터를 반드시 적용해야 함. 실수 한 번이 크로스 테넌트 노출로 이어질 수 있음
대부분의 성숙한 B2B SaaS IdP(AxiPass 포함)가 이 방식을 채택합니다. 운영 효율이 가장 높지만, 그만큼 격리 보장 메커니즘이 철저해야 합니다.
행 수준 격리의 핵심: 자동 스코핑
행 수준 격리를 신뢰할 수 있으려면, 개발자가 매 쿼리에 tenant_id 조건을 수동으로 넣는 방식이어서는 안 됩니다. ORM 수준에서 자동으로 tenant_id = ? 조건을 추가하는 메커니즘이 필요합니다.
Rails의 acts_as_tenant 같은 라이브러리가 이 역할을 합니다. 컨트롤러에서 테넌트 컨텍스트를 설정하면, 해당 요청의 모든 ActiveRecord 쿼리에 자동으로 tenant_id 조건이 포함됩니다. 개발자가 실수로 빼먹을 여지를 원천적으로 차단하는 것입니다.
라우팅 방식과 격리의 관계
테넌트를 식별하는 방식에 따라 세션·캐시·CSRF 보호의 격리 수준이 달라집니다.
Path-based 라우팅 (/t/:tenant_slug)
URL 경로에 테넌트 식별자가 포함됩니다. 예: axi-pass.app/t/acme/members
• 라우트 해석 단계에서 테넌트 컨텍스트가 확정되므로, 컨트롤러 진입 전에 tenant_id 스코핑이 완료됨
• 세션, 캐시 키, CSRF 토큰을 테넌트 단위로 분리하기 용이
• 하나의 도메인만 관리하면 되므로 SSL 인증서와 DNS 운영 부담이 적음
Subdomain 라우팅 (tenant.app.com)
테넌트별 서브도메인을 할당합니다.
• 쿠키의 도메인 스코프가 서브도메인으로 분리되어 세션 격리가 자연스럽게 보장됨 • 반면, 서브도메인 생성·삭제를 DNS에서 관리해야 하고, 와일드카드 SSL 인증서가 필요
도메인 기반 (customer-own domain)
고객사가 자체 도메인을 사용합니다. 예: auth.acme-corp.com
• 고객 입장에서 브랜드 경험이 가장 좋음 • 도메인별 SSL 인증서 발급, DNS 레코드 관리가 운영 부담으로 증가
어느 방식이든, 중요한 것은 라우팅 레이어에서 결정된 테넌트 컨텍스트가 세션 수명 전체에 걸쳐 일관되게 유지되는 것입니다.
배치 작업과 백그라운드 잡에서의 격리
웹 요청에서는 ORM이 자동 스코핑을 처리하지만, 백그라운드 작업에서는 다릅니다.
• ActiveJob이나 Sidekiq에서 tenant_id를 명시적으로 큐에 담아야 함
• 스케줄러가 테넌트를 순회할 때, 한 테넌트의 컨텍스트가 다음 테넌트로 유출되지 않아야 함
• 데이터베이스 쿼리가 아닌 외부 API 호출(SCIM 동기화, 메일 발송)에서도 테넌트 컨텍스트가 명확해야 함
이 검증을 소홀히 하면, A사의 오프보딩 처리가 B사의 SCIM 엔드포인트로 요청이 전송되는 심각한 사고로 이어질 수 있습니다.
감사 로그의 테넌트 분리
감사 로그는 컴플라이언스 증적의 핵심이므로, 테넌트 간 분리에 각별한 주의가 필요합니다.
• 로그 조회 화면에서 관리자가 다른 테넌트의 로그를 볼 수 없어야 함 • 로그 내보내기(CSV/PDF) 시 대상이 명확하게 테넌트 범위로 한정되어야 함 • 글로벌 관리자(운영자)만 전체 테넌트 로그에 접근할 수 있고, 그 권한도 감사 대상이어야 함
멀티 테넌트 IdP 평가 체크리스트
IdP를 도입하거나 구축할 때 테넌트 격리 측면에서 반드시 확인해야 할 항목입니다.
• 모든 쿼리에 tenant_id가 자동으로 필터링되는가 • API 레이어에서 테넌트 컨텍스트가 누락되면 요청이 거부되는가 • 배치 작업과 백그라운드 잡에서도 격리가 보장되는가 • 캐시(Redis, Solid Cache) 키에 tenant_id가 포함되는가 • 파일 스토리지(S3 등)에서 테넌트별 경로 분리가 되는가 • 감사 로그가 테넌트 단위로 격리되는가 • 테넌트 격리에 대한 자동 테스트(Integration Test)가 존재하는가
마지막 항목이 가장 중요합니다. 코드 리뷰와 수동 테스트만으로는 크로스 테넌트 노출을 완전히 방지할 수 없습니다. "테넌트 A의 요청이 테넌트 B의 데이터에 접근하면 실패한다"는 테스트 케이스가 CI에 포함되어야 합니다.
멀티 테넌트 IdP에서 테넌트 격리는 설계 단계에서 결정해야 할 첫 번째 보안 사항입니다. 아키텍처 선택부터 라우팅, 배치 작업, 감사 로그까지 전 계층에서 일관된 격리가 보장되어야 비로소 SaaS 고객에게 "여러분의 인증 정보는 안전하게 분리됩니다"라고 말할 수 있습니다.
AxiPass는 path-based 라우팅과 행 수준 격리를 결합하여, 모든 계층에서 테넌트 간 데이터 분리를 보장합니다. SaaS 기업의 인증 보안에 관심이 있으시다면 무료로 시작해 보세요.
