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

143 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Multi-tenancy Isolation 패턴 (Pool vs Silo vs Bridge)
source_type: llm-generated
status: draft
confidence: medium
tags: [multi-tenancy, saas, isolation]
related_projects: [ca-skeleton]
last_reviewed: 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
- [[wiki/projects/ca-tmpl/multi-tenancy-isolation-patterns]] — ca-tmpl 의사결정 기록 (현재 `documented-only`, Phase C2 미진입). 실제 구현 여부는 project 문서 참조.
ca-tmpl은 본 개념을 다음 위치에서 적용·문서화한다. concept 문서는 등급을 매기지 않으며, 검증 수준은 각 프로젝트/브랜치 노트에서 판정한다.
- [[raw/branch-notes/feature-tenant-context-policy]] — tenant resolution(JWT > header admin only > subdomain fallback) + isolation SSOT
- [[raw/branch-notes/feature-repository-access-permission-contract]] — `CROSS_TENANT_ADMIN` capability, repository 레벨 tenant filter 강제 contract
- [[raw/project-notes/ca-skeleton-operational-contract]] — §10 Repository Access Permission Contract, §29 Topic 6 Multi-tenancy Isolation
## 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
- [AWS Whitepaper — SaaS Tenant Isolation Strategies](https://docs.aws.amazon.com/whitepapers/latest/saas-tenant-isolation-strategies/saas-tenant-isolation-strategies.html) — Silo/Pool/Bridge 분류 baseline
- [Hibernate ORM User Guide — Multi-tenancy](https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#multitenacy) — DATABASE/SCHEMA/DISCRIMINATOR 공식 strategy
- [Azure Architecture Center — Multitenant SaaS](https://learn.microsoft.com/en-us/azure/architecture/guide/multitenant/overview) — Deployment Stamps / hybrid spectrum
- [Citus — Designing your SaaS DB for High Scalability](https://www.citusdata.com/blog/2016/10/03/designing-your-saas-database-for-high-scalability/) — schema vs shared schema 한계치 (company-tech-blog, needs-confirmation)
- [Auth0 — Multi-tenant applications](https://auth0.com/docs/get-started/auth0-overview/create-tenants/multiple-tenants) — tenant resolution(subdomain/JWT/header) 비교
- [Vercel — Multi-tenant Next.js Guide](https://vercel.com/guides/nextjs-multi-tenant-application) — subdomain routing 실무
- [AWS APN Blog — Hybrid Tenant Isolation](https://aws.amazon.com/blogs/apn/) — tier-based hybrid 사례
- [Atlassian Engineering — Cloud Architecture Guidelines](https://www.atlassian.com/engineering/cloud-architecture-and-guidelines) — shard 단위 isolation + tenant context propagation 사례
- [[raw/official-docs/multitenancy-aws-saas-tenant-isolation-whitepaper]]
- [[raw/official-docs/multitenancy-hibernate-user-guide]]
- [[raw/official-docs/multitenancy-azure-architecture-patterns]]
- [[raw/company-tech-blogs/multitenancy-stripe-citus-schema-per-tenant]]
- [[raw/company-tech-blogs/multitenancy-auth0-tenant-resolution]]
- [[raw/company-tech-blogs/multitenancy-subdomain-resolution-patterns]]
- [[raw/company-tech-blogs/multitenancy-hybrid-pooled-siloed-mix]]
- [[raw/company-tech-blogs/multitenancy-atlassian-tenant-context]]
- [[raw/project-notes/ca-skeleton-operational-contract]] — §10, §29 Topic 6