Communitygithub.com

다중 테넌시

행 수준 및 스키마 기반 테넌트 격리, 서브도메인 라우팅, 테넌트별 구성, 데이터 파티셔닝

다중 테넌시란 무엇인가요?

이 스킬은 개발자가 SaaS 애플리케이션에 다중 테넌시(Multi-Tenancy)를 구현할 때 필요한 모범 사례를 제공합니다. 주요 패턴으로는 행 수준 격리(기본값), 스키마별 테넌트 격리, 서브도메인 라우팅, 사용자 정의 도메인 지원, 테넌트별 구성 저장소, PostgreSQL RLS(Row-Level Security), 미들웨어 기반 테넌트 추출 및 쿼리 필터링을 다룹니다. Next.js, Prisma, Postgres와 같은 현대적인 스택과 통합되어 있으며, 각 패턴에 대한 구체적인 코드 예제와 함께 테넌트 범위 누락, 인덱스 부재 등 일반적인 실수를 피하는 방법을 설명합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/YepAPI/skills/tree/HEAD/skills/multi-tenancy

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

다중 테넌시은(는) 무엇을 하나요?

규칙

  • 행 수준 격리(기본값): 모든 테넌트 범위 테이블에 tenantId 열을 추가하고, 미들웨어 또는 RLS(행 수준 보안)를 통해 적용합니다.
  • 스키마별 테넌트: 테넌트가 사용자 정의 스키마나 엄격한 데이터 격리가 필요할 때 사용합니다. 운영이 더 복잡하지만 격리 수준이 높습니다.
  • 서브도메인 라우팅: {tenant}.app.com에서 테넌트를 추출하여 미들웨어에서 해석하고, 요청 컨텍스트에 tenantId를 설정합니다.
  • 사용자 정의 도메인: CNAME을 앱으로 설정하고 Host 헤더로 테넌트를 조회합니다. 사용자 정의 도메인을 테넌트 ID에 매핑하는 domains 테이블을 사용합니다.
  • 테넌트별 구성: 테마(로고, 색상), 기능 플래그, 제한 사항을 tenant_settings 테이블에 저장하고 TTL(Time-To-Live)로 메모리에 캐시합니다.
  • RLS 패턴(Postgres): ALTER TABLE posts ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation ON posts USING (tenant_id = current_setting('app.tenant_id'))
  • 미들웨어: 서브도메인/헤더에서 테넌트를 추출하고, 컨텍스트에 설정한 후 모든 데이터베이스 쿼리에 적용합니다. 테넌트 범위 없이 쿼리가 실행되지 않도록 합니다.
  • 데이터 파티셔닝: 대규모 테이블의 경우 tenantId로 파티셔닝하여 쿼리 성능을 개선하고 테넌트별 백업/복원이 가능합니다.

행 수준 격리 패턴

// 미들웨어 - 서브도메인에서 테넌트 추출
function getTenantFromHost(host: string): string {
  const subdomain = host.split(".")[0];
  return subdomain; // 또는 tenants 테이블에서 조회
}

// Prisma 미들웨어 - tenantId로 자동 필터링
prisma.$use(async (params, next) => {
  if (TENANT_MODELS.includes(params.model)) {
    params.args.where = { ...params.args.where, tenantId: context.tenantId };
  }
  return next(params);
});

서브도메인 라우팅 (Next.js 미들웨어)

export function middleware(request: NextRequest) {
  const host = request.headers.get("host") ?? "";
  const tenant = host.split(".")[0];
  const response = NextResponse.next();
  response.headers.set("x-tenant-id", tenant);
  return response;
}

피해야 할 사항

  • 테넌트 범위 없는 쿼리 — WHERE tenantId = ? 하나라도 빠지면 테넌트 간 데이터가 유출됩니다.
  • 클라이언트에 테넌트 하드코딩 — 서버 측에서 서브도메인/도메인으로 해석합니다.
  • tenantId에 인덱스 없음 — 모든 테넌트 범위 테이블은 tenantId로 시작하는 복합 인덱스가 필요합니다.
  • 공유 캐시에 테넌트 데이터 혼합 — 캐시 키를 {tenantId}:{key}로 네임스페이스 처리합니다.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

YepAPI/skills

WCAG 2.1 AA — semantic HTML, keyboard navigation, screen readers.

YepAPI/skills

Experiment setup, variant splitting, statistical significance, and feature flag integration.

YepAPI/skills

CRUD generators, data tables, user management, role-based access, and bulk operations.

YepAPI/skills

Monitor what ChatGPT and Gemini say about your brand using YepAPI.

YepAPI/skills

Queue workers with BullMQ/Inngest/Trigger.dev, job retries, dead letter queues, concurrency.

YepAPI/skills

Commander.js, interactive prompts with Clack, spinners, colors, config files, exit codes, and npm publishing.

YepAPI/skills

cmdk integration, Cmd+K trigger, fuzzy search, grouped actions, keyboard navigation, and dynamic action registration.

YepAPI/skills

Content planning with trend and sentiment data from YepAPI.

YepAPI/skills

Content calendar, keyword-driven planning, and content briefs.

YepAPI/skills

Theme switching with CSS variables, system preference detection, next-themes, and persistence.

YepAPI/skills

Threaded comments, @mentions, reactions, moderation queue, optimistic UI, and cursor pagination.

YepAPI/skills

Competitive analysis between domains using YepAPI.

YepAPI/skills

Layout grids, KPI cards, data tables with sorting/filtering, sidebar navigation, and responsive breakpoints.

YepAPI/skills

Data encryption — TLS everywhere, AES-256-GCM for PII, bcrypt passwords, encrypted backups.

YepAPI/skills

Chart patterns with Recharts/Nivo/D3, responsive containers, color scales, and accessibility.

YepAPI/skills

Drizzle schema definition, push vs migrate, type-safe queries, relations, transactions, and prepared statements.

YepAPI/skills

Upload handling, resize/compress, CDN delivery, blur placeholders, and next/image patterns.

YepAPI/skills

Local business and Google Maps research using YepAPI.

YepAPI/skills

Cursor-based pagination, IntersectionObserver, virtualized lists with @tanstack/react-virtual, and scroll position restoration.

YepAPI/skills

Chat UI components, streaming responses with AI SDK, context window management, and RAG patterns.

관련 스킬