Files
llm-wiki/wiki/concepts/multi-tenancy-isolation-patterns.md
T

11 KiB
Raw Blame History

title, source_type, status, confidence, tags, related_projects, last_reviewed
title source_type status confidence tags related_projects last_reviewed
Multi-tenancy Isolation 패턴 (Pool vs Silo vs Bridge) llm-generated draft medium
multi-tenancy
saas
isolation
ca-skeleton
2026-05-22

Multi-tenancy Isolation 패턴 (Pool vs Silo vs Bridge)

Layer: wiki/concepts/ — 일반 개념. 실제 적용은 wiki/projects/ 또는 raw 브랜치 노트 참조.

Summary

Multi-tenancy isolation은 "여러 tenant가 같은 소프트웨어 인스턴스를 어느 수준까지 공유하는가"의 스펙트럼이다. AWS SaaS Lens는 이를 Silo / Pool / Bridge 3분류로 정리하고, Hibernate는 ORM 레벨에서 DATABASE / SCHEMA / DISCRIMINATOR 3 strategy로 공식 지원하며, Azure는 Deployment Stamps 패턴으로 hybrid를 다룬다. ca-tmpl은 opt-in(APP_TENANT_ENABLED=true 시만 활성) + shared DB + tenant_id column(ULID) + JWT claim 우선 resolution 조합을 baseline으로 채택한다. 이는 AWS Pool 모델 + Hibernate DISCRIMINATOR 전략에 해당하며, B2B 초기 단계(tenant 수 수십수백 단위)에 isolation 비용 대비 운영 단순성을 우선한 의도적 선택이다. opt-in 설계의 의의는 single-tenant deployment에서는 tenant 로직 자체를 비활성화하여 skeleton의 적용 범위를 넓힌 점에 있다. Migration trigger 3가지는 (a) 규제(금융·의료) isolation 강제, (b) tenant 수 수백수천 + 단일 row 수 수억 도달, (c) enterprise tier 등장으로 isolation을 가격에 반영해야 할 때다.

Standard (공식 정의)

AWS SaaS Tenant Isolation Strategies (Whitepaper) — Silo / Pool / Bridge

  • Silo: tenant마다 별도 stack(compute/DB/network까지 분리). isolation 최강, 비용 최대.
  • Pool: 모든 tenant가 동일 infra와 schema를 공유, tenant_id 컬럼으로 row-level 구분.
  • Bridge: 일부 리소스는 silo, 일부는 pool. 예) DB는 silo, app server는 pool.
  • AWS는 "Authentication is not isolation. You must enforce isolation at the resource layer"라고 명시한다.

Hibernate ORM Multi-tenancy — DATABASE / SCHEMA / DISCRIMINATOR

  • DATABASE: tenant별 별도 데이터베이스.
  • SCHEMA: 동일 DB, tenant별 별도 schema.
  • DISCRIMINATOR: 동일 schema, tenant_id 컬럼. Hibernate 6부터 native 지원(이전엔 Filter로 우회).
  • 활성화는 hibernate.tenant_identifier_resolver + hibernate.multi_tenant_connection_provider 설정으로 수행. CurrentTenantIdentifierResolver가 ThreadLocal/SecurityContext에서 tenant를 결정.

Azure Architecture Center — Deployment Stamps (Hybrid)

  • Tenancy를 "fully shared → shared compute, isolated DB → isolated stamp → isolated subscription" 스펙트럼으로 정의.
  • Deployment Stamps: 동일한 스택을 단위(stamp)로 복제하고, stamp 안에 N개 tenant를 pool. tier별로 stamp 크기와 isolation 수준을 다르게 둘 수 있음.
  • Microsoft는 "There's no single right approach to multitenancy"라고 명시 — 비즈니스 모델·규제·확장성·비용에 따라 모델이 달라진다.

Tenant Resolution 방식 (isolation과 직교)

  • JWT claim: token 서명 검증으로 위변조 방지. 가장 안전.
  • Subdomain ({tenant}.app.com): UX 친화적, 단 wildcard DNS/TLS 필요.
  • Custom header (X-Tenant-Id): 단순하나 외부 trust boundary에서 단독 신뢰 금지.
  • Path (/t/{tenant}/...): routing 자연스럽지만 모든 client URL 변경.

한계 / 주의점

각 대안의 한계는 다음과 같다.

shared DB + tenant_id (Pool / Hibernate DISCRIMINATOR)

  • Noisy neighbor: hot tenant가 같은 인스턴스 전체에 영향.
  • 규제 isolation 불가: application bug 한 줄로 cross-tenant leak 가능. HIPAA·FedRAMP·금융권은 storage 레벨 분리를 요구하는 경우가 있어 Pool로 충족 어려움.
  • Index 비용: tenant로 filter하는 모든 index에 tenant_id를 leading column으로 포함해야 plan이 효율적.
  • Native query/JDBC bypass 위험: JPQL 경로 외에서 tenant filter 누락 시 leak.

Subdomain-based resolution

  • Wildcard DNS와 wildcard TLS 인증서 필요. custom domain 지원 시 per-domain 인증서 자동화 추가.
  • Let's Encrypt rate limit은 "registered domain당 주 50개 인증서"로 보고되나 — 정확 수치와 적용 범위는 needs-confirmation (raw 발췌 기준).
  • DNS propagation 지연, subdomain takeover 위험(tenant 삭제 후 DNS record 미정리), CORS/cookie domain 설정 복잡성.
  • Local dev는 lvh.me/nip.io/hosts 수정 필요.

JWT claim only

  • claim 검증을 한 곳이라도 빠뜨리면 cross-tenant 위험.
  • token 재발급 없이 tenant 전환 불가 → admin/support 운영 동선 제약.
  • IdP와 강결합 → tenant 정보 변경 시 token rotation 정책 필요.

Schema-per-tenant (Hibernate SCHEMA)

  • Postgres metadata(pg_class, pg_attribute) overhead가 tenant 수 증가에 따라 누적.
  • Stripe/Citus 자료에 따르면 "수백~수천 tenant"에서 catalog bloat·autovacuum·plan cache miss가 문제로 보고됨 — 다만 정확한 임계 수치 인용은 needs-confirmation.
  • Connection pooling 난이도: search_path 전환이 plan cache를 무효화. HikariCP per tenant vs single pool 설계 선택 필요.
  • 마이그레이션이 tenant 수만큼 반복(Flyway schemas 옵션으로 일괄 처리 가능하나 추가/삭제 자동화 필요).

Database-per-tenant (Silo)

  • Isolation 가장 강함, 운영 비용 폭증: 마이그레이션·백업·모니터링이 모두 tenant 수에 비례.
  • Connection pool이 (tenant 수 × pool size)로 폭발 → connection multiplexing(예: PgBouncer) 필수.
  • AWS 계정·서비스 limit에 부딪힐 수 있음.
  • 비용은 silo > bridge > pool 순.

Hybrid (Azure Deployment Stamps / AWS Bridge)

  • 두 가지 이상 모델을 동시 운영 → 운영 복잡도 최고.
  • Tier 승급(pool → silo) 시 데이터 이동 절차 필요.
  • Routing layer + tenant catalog가 사실상 control plane이 되어, 가용성 single point가 되지 않도록 분산 필요.
  • 작은 팀에서 도입하면 ROI 부정. 일반적으로 product-market fit 이후 단계에서 검토.

공통 오해

  • "Pool이면 무조건 싸다"는 거짓 — 노이즈/검증 비용이 일정 규모 이상에선 silo와 역전될 수 있음.
  • "Subdomain이면 자동 isolation" 거짓 — resolution과 isolation은 직교. subdomain은 routing일 뿐 storage 분리를 보장하지 않음.
  • "JWT claim만 있으면 안전" 거짓 — repository·query 레이어에서 tenant filter를 강제하지 않으면 claim의 의미가 없음.

Project Application

Interview Questions

  • AWS SaaS Lens의 Pool/Silo/Bridge는 무엇이 다르고, 어떤 상황에서 어떤 모델을 선택하나?
  • Tenant ID를 JWT claim과 HTTP header 중 어디서 읽어야 하며, 둘을 동시에 허용한다면 어떤 trust 기준을 두는가?
  • shared DB + tenant_id에서 schema-per-tenant 또는 db-per-tenant로 마이그레이션을 트리거하는 조건은 무엇인가?
  • Cross-tenant 침해를 막기 위해 어느 레이어(JWT 검증 / SecurityContext / repository / DB)에 어떤 방어가 필요한가?
  • Tenant 식별자에 ULID와 UUID 중 어느 쪽을 쓰는 게 적합하며, 각 선택의 trade-off는 무엇인가?

Do Not Overclaim

  • "shared DB + tenant_id가 항상 우월하다"고 말하지 말 것 — 규제 산업·data residency 요구가 있는 도메인에서는 Silo가 필수 또는 사실상 강제다.
  • Stripe/Citus의 schema-per-tenant 한계치(예: "정확히 N tenant에서 한계")는 정확 인용 wording이 미완이며 raw 자료는 needs-confirmation 상태다. 면접/이력서에서는 "수백~수천 단위에서 catalog overhead가 보고된다" 정도로 출처(Citus blog)와 함께만 언급할 것.
  • "Atlassian이 그렇게 하니까 best practice"라고 말하지 말 것 — company-tech-blog 사례는 관점·증거이지 공식 기준이 아니다.
  • "JWT claim만 검증하면 multi-tenant가 안전하다"는 단정 금지 — claim은 입구일 뿐 storage layer 강제가 별도로 필요하다.
  • ca-tmpl 적용 사실(예: ULID 채택 이유, capability 설계)은 본 concept 문서가 아니라 wiki/projects/ 또는 branch-notes에서 검증 등급과 함께 진술할 것. "내가 했다"는 표현은 concept 레이어에 두지 않는다.

Sources