Skip to content
Published on

SaaS 아키텍처 완전 가이드 — Multi-tenancy·Billing·Feature Flag·Audit·RBAC·SSO를 2025년 기준으로 한 번에 정리

Authors

프롤로그 — "API를 SaaS로 팔려면?"

당신에게 훌륭한 API(Ep 19)가 있다. 이걸 **SaaS(Software as a Service)**로 팔려면?

"그냥 signup 페이지 만들고 Stripe 연결하면 되죠?" — 2018년이라면. 2025년엔 더 어려워졌다:

  • Multi-tenancy: 고객 데이터 격리는 기본값
  • Billing: 월 구독, 사용량, 연간 할인, prorated 변경
  • Feature Flag: 일부 고객만 새 기능
  • Audit Log: 엔터프라이즈가 요구
  • RBAC/SSO: Admin/Viewer 권한, SAML 로그인
  • SOC 2: 보안 감사 준수
  • Usage Metering: API call당 과금
  • Data Export: 고객이 언제든 자기 데이터 가져가야

좋은 SaaS는 차별화된 기능이 아니라 신뢰할 수 있는 플랫폼에서 시작한다.

이 글은 Season 2 Ep 20 — SaaS 아키텍처. Multi-tenant 전략, Billing, Feature Flag, Audit, RBAC/ABAC, SSO, Usage Metering까지.


1부 — Multi-tenancy 3전략

1. Silo (격리) — DB per tenant

Tenant ADB-A
Tenant BDB-B
Tenant CDB-C

장점:

  • 강한 격리
  • Tenant별 성능/보안/규정 분리
  • "한 고객 데이터가 다른 고객에게 유출" 불가능

단점:

  • 비용 (DB 수백 개)
  • 마이그레이션 지옥 (스키마 변경 시 모든 DB)
  • 엔터프라이즈 단독 고객 적합

사용처: 금융, 의료, 정부. 고가 플랜.

2. Pool (공유) — 같은 DB, tenant_id로 구분

CREATE TABLE users (
  id UUID PRIMARY KEY,
  tenant_id UUID NOT NULL,
  email TEXT,
  ...
);
CREATE INDEX idx_users_tenant ON users(tenant_id);

Row-Level Security (Postgres):

ALTER TABLE users ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON users
  USING (tenant_id = current_setting('app.current_tenant')::UUID);

장점:

  • 비용 효율
  • 마이그레이션 쉬움
  • 스타트업 친화

단점:

  • 격리 약함 (코드 버그 시 cross-tenant 유출 위험)
  • Noisy neighbor (한 tenant가 DB 독점)
  • 규정 어려움

3. Bridge (하이브리드) — 플랜별 구분

Free, Starter: Pool DB
Pro: Pool DB + 격리된 schema
Enterprise: Silo (dedicated DB)

현실의 표준. 성장 단계별 다른 모델.

Schema-per-tenant (Postgres 특화)

CREATE SCHEMA tenant_abc;
CREATE TABLE tenant_abc.users (...);

-- connection string: search_path=tenant_abc,public

장점: 코드는 Pool, 격리는 Silo 중간 단점: Postgres는 스키마 1000+개부터 느려짐

테넌트 식별 전략

방법 1: Subdomain (acme.example.com)
방법 2: Path prefix (/t/acme/...)
방법 3: Header (X-Tenant-ID)
방법 4: JWT claim

2025 권장: Subdomain + JWT claim (안전 2중 확인).

Middleware 패턴

// Express middleware
async function tenantMiddleware(req, res, next) {
  const subdomain = req.hostname.split('.')[0];
  const tenant = await db.tenant.findFirst({ where: { slug: subdomain } });
  if (!tenant) return res.status(404).json({ error: 'Tenant not found' });

  req.tenant = tenant;
  // Row-Level Security용 세션 변수
  await db.$executeRaw`SET LOCAL app.current_tenant = ${tenant.id}`;
  next();
}

2부 — Billing 시스템 설계

과금 모델 5가지

모델예시특징
Flat-rateBasecamp단순, seat 무제한
Per-seatSlack, Notion사용자 수
TieredStripe, Twilio사용량 구간별
Usage-basedAWS, OpenAIAPI call당, 저장량
Hybrid기본 + 초과분현실의 표준

도구 비교

도구특징
Stripe Billing구독 + usage, 세금 자동(Stripe Tax), 사실상 표준
Lago (오픈소스)Event-driven, self-host, 복잡한 pricing 유연
Metronome복잡 usage-based SaaS 전용
PaddleMerchant of Record, 세금/환불 대행
Chargebee엔터프라이즈, 복잡한 workflow
RevenueCat모바일 앱 구독 전용
OrbUsage-based 2024 신흥

Stripe Billing 모델

Product — 논리적 상품 ("Pro Plan")
  └── Price — 실제 가격 ("Pro Monthly $10")
        └── Subscription — 고객의 구독
              └── Invoice — 월마다 생성
                    └── Charge — 실제 결제

Usage-based 구현

// 사용자가 API 호출할 때
await stripe.subscriptionItems.createUsageRecord(
  subscriptionItem.id,
  {
    quantity: 1,  // 또는 배치 처리 후 총합
    timestamp: Math.floor(Date.now() / 1000),
    action: 'increment',
  }
);

2025 best practice: Stripe의 usage를 실시간 X, **배치(시간당/일일)**로 집계 후 전송. 이벤트 로그 자체 보관.

흔한 함정

  1. Upgrade/Downgrade prorated — 계산 복잡, Stripe 자동 OK
  2. 무료 trial → paid 전환 — 실패 처리 (카드 만료, 잔액 부족)
  3. Tax 처리 — 한국 부가세, EU VAT, 미국 주별 세금
  4. Dunning (연체 추심) — 실패 시 3-7-14일 재시도
  5. Refund + partial refund
  6. Chargeback (사용자가 카드사에 이의 제기)

Revenue Recognition (매출 인식)

$120/연 일시불 → 매출 인식은 매월 $10씩 12개월
이유: 서비스 제공 시점에 매출 인식 (GAAP/IFRS)
도구: Stripe Revenue Recognition, Sage Intacct

3부 — Feature Flag

왜 필요한가

배포 = 릴리즈 분리
- 배포는 코드가 서버에 가는 것
- 릴리즈는 사용자에게 보이는 것
- Feature Flag가 둘을 분리

혜택:

  • Canary: 1% → 10% → 50% → 100%
  • Kill switch: 장애 시 즉시 끄기
  • A/B 테스트: 버전 A vs B 비교
  • Premium feature: 플랜별 기능 다르게
  • Dark launch: 내부만 먼저

도구 비교

도구특징
LaunchDarkly시장 선도, 비쌈
Unleash (오픈소스)Self-host, 기업 친화
FlagsmithSelf-host + Cloud
PostHogFeature flag + Analytics 통합
StatsigA/B 테스트 강력
ConfigCat단순, 저렴
OpenFeatureCNCF 표준 인터페이스

OpenFeature — 벤더 중립 표준

import { OpenFeature } from '@openfeature/server-sdk';

const client = OpenFeature.getClient();
const showNewFeature = await client.getBooleanValue('new-feature', false, {
  targetingKey: user.id,
  email: user.email,
  plan: user.plan,
});

장점: LaunchDarkly ↔ Unleash ↔ PostHog 교체 시 코드 변경 최소.

규칙 예시

flag: new-checkout-flow
defaultValue: false
rules:
  - if: plan == "enterprise"
    then: true
  - if: email endsWith "@example.com"
    then: true
  - percentage: 10  # 10%
    then: true

안티패턴

  1. Flag debt — 오래된 플래그 수천 개 → 분기 지옥
  2. Flag 안에 또 flag → 테스트 불가
  3. Kill switch만 쓰고 제거 안 함 → 영구 코드
  4. 매 요청 flag 서비스 호출 → 지연 폭발 (SDK는 캐싱 필수)

Cleanup 전략

Flag 생성 시 deprecation date 설정
30일 후 자동 알림
90일 후 강제 제거 issue 생성

4부 — Audit Log 설계

왜 필요한가

  • SOC 2, ISO 27001, GDPR 요구
  • 보안 사고 포렌식
  • 내부 조사 (누가 뭘 언제 했나)
  • 고객 요구 (엔터프라이즈 필수)

이벤트 포맷 (CloudEvents 호환)

{
  "id": "aud_01HX...",
  "specversion": "1.0",
  "type": "user.permission.granted",
  "source": "/api/users/123",
  "time": "2026-04-15T12:34:56Z",
  "subject": "usr_abc",
  "data": {
    "actor": { "type": "user", "id": "usr_admin", "email": "admin@example.com" },
    "target": { "type": "user", "id": "usr_abc" },
    "action": "permission.granted",
    "before": { "role": "viewer" },
    "after": { "role": "admin" },
    "ip": "1.2.3.4",
    "userAgent": "...",
    "requestId": "req_xyz"
  }
}

저장소 선택

옵션 1: Postgres (간단한 경우)
  + ACID, 기존 DB
  - 스케일 한계

옵션 2: ClickHouse / BigQuery (대규모)
  + 빠른 분석
  - 별도 시스템

옵션 3: S3 + Athena (아카이브)
  + 매우 저렴
  - 쿼리 느림

옵션 4: 전용 SaaS (Vanta, OneSchema)

2025 패턴: Primary는 Postgres, 30일 이후 S3 아카이브, ClickHouse로 분석.

위변조 방지

  • Append-only: UPDATE/DELETE 금지, 트리거로 강제
  • Hash chain: 블록체인 아이디어 (각 레코드가 이전 hash 포함)
  • Database-level audit: pgaudit, AWS RDS audit
  • WORM storage: Write Once Read Many (S3 Object Lock)

쿼리 UX

고객이 볼 수 있는 Audit Log UI:

  • Filter: actor, action, date range, resource
  • Export: CSV, JSON
  • Webhook: 특정 이벤트 발생 시 알림

민감정보 처리

  • 비밀번호, 토큰은 절대 기록 X
  • PII는 해시화 또는 마스킹
  • GDPR: 사용자 삭제 시 audit log는 보존 의무와 충돌 → 법무 확인

5부 — RBAC vs ABAC vs PBAC

RBAC (Role-Based) — 간단

Role: Admin, Editor, Viewer
Permission: read/write/delete + resource

Admin → 모든 권한
Editor → read/write
Viewer → read only

장점: 단순, 이해 쉬움 단점: 세밀한 권한 표현 어려움 ("A 프로젝트만 편집")

ABAC (Attribute-Based) — 유연

rule: allow if
  user.role == "editor" AND
  resource.owner == user.id AND
  environment.ip.country == "KR"

도구:

  • OPA (Open Policy Agent) + Rego
  • Cedar (AWS, 2023)
  • Casbin
  • Oso

Cedar 예시

permit(
  principal == User::"alice",
  action == Action::"read",
  resource
) when {
  resource.owner == principal ||
  resource.sharedWith.contains(principal)
};

RBAC 구현 (Postgres)

CREATE TABLE roles (id UUID PRIMARY KEY, name TEXT);
CREATE TABLE permissions (id UUID PRIMARY KEY, action TEXT, resource TEXT);
CREATE TABLE role_permissions (role_id UUID, permission_id UUID, PRIMARY KEY (role_id, permission_id));
CREATE TABLE user_roles (user_id UUID, role_id UUID, PRIMARY KEY (user_id, role_id));

실전 조합

Core RBAC (Admin/Editor/Viewer)
+ Resource-level permissions (Project membership)
+ Attribute rules (Time, IP, MFA)

2025 도구

  • Permit.io, Oso, Cerbos — 권한 SaaS
  • Clerk, Kinde, WorkOS — 인증 + 권한 SaaS

6부 — SSO (Single Sign-On)

왜 엔터프라이즈가 요구

  • IT 관리: 직원 입/퇴사 시 한 곳(Okta, Entra)에서 관리
  • 보안: MFA 한 번, 모든 앱 공통
  • 감사: 중앙 로그

프로토콜

프로토콜연식특징
SAML 2.02005엔터프라이즈 표준, XML
OIDC (OpenID Connect)2014OAuth 2.0 기반, JSON, 현대적
OAuth 2.02012인증 아닌 인가 (자주 혼동)
SCIM2015사용자 프로비저닝 (직원 입/퇴사)

SAML 기본 흐름

1. 사용자 → SP (Service Provider, 우리 SaaS)
2. SPIdP (Identity Provider, Okta)로 redirect
3. IdP: 사용자 인증 (MFA)
4. IdP → 브라우저 → SPSAML Response 전달
5. SP: 서명 검증 → 세션 생성

OIDC 기본 흐름

Authorization Code + PKCE:
1. Client/authorize (IdP)
2. 사용자 로그인
3. IdPClient로 code 반환
4. Client/token으로 code 교환 → access_token + id_token(JWT)

구현 방법

옵션 1: 직접 구현

  • passport-saml, openid-client
  • 장점: 통제
  • 단점: 복잡, 고객별 설정 지옥

옵션 2: SSO SaaS (2025 권장)

  • WorkOS: B2B SSO 전문
  • Clerk: SSO + 인증 전반
  • Auth0 (Okta): 엔터프라이즈
  • Supabase Auth, Firebase Auth: 스타트업

장점: 수백 개 IdP 통합 지원, IT 관리자 셀프 서비스 UI.

SCIM — 자동 프로비저닝

회사 A가 직원 50명 입사:
OktaSCIM → 우리 SaaS에 자동 생성

직원 퇴사 시:
OktaSCIM → 계정 비활성화

수동 관리 안 해도  (엔터프라이즈 필수)

7부 — Usage Metering

이벤트 수집 파이프라인

AppKafka/KinesisAggregatorBilling engine → Invoice
                            Analytics DB (ClickHouse)

설계 원칙

  1. 이벤트는 불변 (절대 수정 X)
  2. 멱등성: 같은 event_id 두 번 받아도 1번 계산
  3. Idempotency 윈도우: 중복 제거 7일까지
  4. Ordered? No: 분산 시스템에서 순서 기대 X
  5. Granularity: 원본 이벤트 보관 (집계만 보관하면 회귀 불가)

Aggregation 예시

-- 시간별 집계 (ClickHouse)
SELECT
  tenant_id,
  toStartOfHour(timestamp) as hour,
  count() as api_calls,
  sum(bytes) as bytes_total
FROM events
WHERE timestamp >= today()
GROUP BY tenant_id, hour;

Lago / Metronome

Lago (오픈소스):
- Event ingestion API
- Aggregation (count, sum, max, unique)
- Pricing rules (tier, package, graduated)
- Invoice 자동 생성
- Stripe 연동

Metronome (상용):
- 더 복잡한 enterprise pricing
- Commitment, Credits 모델

8부 — Customer Data Isolation

Tenant-level Encryption

각 tenant마다 고유 암호화 키
Master KeyTenant Key (envelope encryption)
Tenant Key로 데이터 암호화

장점: 규정 (HIPAA, PCI) 만족
도구: AWS KMS, HashiCorp Vault

BYOK (Bring Your Own Key)

엔터프라이즈 고객이 자신의 KMS 키 가져옴 → 해지 시 데이터 사용 불가.

Data Residency

미국 고객 → US region
EU 고객 → EU region (GDPR)
한국 고객 → AP region (금융 규정)

구현: tenant 레코드에 region 저장 → 라우팅
복잡: cross-region 백업, 장애 조치

9부 — SOC 2, ISO 27001, GDPR

SOC 2 (미국 엔터프라이즈 필수)

Type I: 설계 감사 (한 시점)
Type II: 운영 감사 (6-12개월)

5 Trust Services Criteria:
- Security (필수)
- Availability
- Processing Integrity
- Confidentiality
- Privacy

핵심 요구:

  • 접근 제어 (MFA, 최소 권한)
  • 변경 관리 (Code review, CI)
  • 침입 탐지 (SIEM)
  • Audit log
  • 백업 + DR
  • Vendor management

도구

  • Vanta, Drata, Secureframe: SOC 2 자동화 ($20K-50K/년)
  • Vanta AI Questionnaire: 보안 설문 자동 응답

GDPR (EU)

  • Data export (right to access)
  • Data deletion (right to be forgotten)
  • Consent (cookie banner)
  • DPA (Data Processing Agreement)
  • Breach notification (72시간 이내)

코드에 녹여놓기

// 사용자 삭제
async function deleteUser(userId: string) {
  await db.$transaction(async (tx) => {
    await tx.user.update({
      where: { id: userId },
      data: {
        email: `deleted-${userId}@example.com`,
        name: 'Deleted User',
        phoneNumber: null,
        deletedAt: new Date(),
      },
    });
    await tx.session.deleteMany({ where: { userId } });
    await tx.auditLog.create({
      data: { action: 'user.deleted', userId, ... },
    });
  });
  // 비동기: 백업, S3, 외부 시스템 삭제
  await jobs.enqueue('gdpr.delete', { userId });
}

10부 — Onboarding과 Activation

Time-to-Value (TTV) 최소화

좋은 SaaS의 목표: 회원가입 → 첫 "와우" 순간까지 5분 이내

나쁜 예:
1. 회원가입 → 이메일 인증 (5)
2. 긴 설정 위저드 (10)
3. 샘플 데이터 직접 추가 (20)

좋은 예:
1. Google OAuth (10)
2. 샘플 프로젝트 자동 생성
3. 즉시 "와우" 경험

체크리스트 패턴

"완료 진행 4/10"
- [x] 프로필 작성
- [x] 팀 초대
- [ ] 첫 프로젝트 만들기
- [ ] Integration 연결
...

Product Tour

  • Intro.js, Shepherd.js — 오픈소스
  • Pendo, Userflow, Chameleon — SaaS

Empty States

Before: "No data" (나쁨)
After: "첫 프로젝트를 만들어 보세요" + 가이드 + 샘플 템플릿

11부 — Analytics와 Observability

3가지 Analytics

  1. Product Analytics — Mixpanel, Amplitude, PostHog
  2. Marketing Analytics — GA4, Plausible (privacy)
  3. Business Metrics — MRR, Churn, LTV (Baremetrics, ChartMogul)

SaaS KPI 10개

지표설명
MRR (Monthly Recurring Revenue)예측 가능한 월 매출
ARR연 매출 (MRR × 12)
Churn이탈률 (월 5% = 위험)
Net Revenue Retention (NRR)기존 고객 매출 유지/확장
CAC (Customer Acquisition Cost)고객 획득 비용
LTV (Lifetime Value)고객 생애 가치
LTV:CAC3:1 이상 권장
Payback PeriodCAC 회수 기간
Activation Rate가입 → 핵심 행동 %
DAU/MAU참여도

PostHog — 오픈소스 올인원

import posthog from 'posthog-js';

posthog.init('<api_key>', { api_host: 'https://app.posthog.com' });

posthog.identify(user.id, { email: user.email, plan: user.plan });
posthog.capture('project_created', { project_id: '...', template: 'blank' });

기능: Events, Feature Flag, Session Replay, A/B test, Heatmap, Funnels.


12부 — 운영 체크리스트

Day-one SaaS Checklist

  • Multi-tenant 모델 결정 (Pool/Silo/Bridge)
  • Stripe Billing + Webhook
  • SSO 준비 (OIDC + SAML 지원)
  • Audit Log 인프라
  • Feature Flag (OpenFeature + 벤더)
  • Rate Limiting per tenant
  • Email (Resend, Postmark) + template
  • Support chat (Intercom, Crisp, Front)
  • Docs (Mintlify, Docusaurus)
  • Status page (Atlassian Statuspage, Better Stack)
  • Uptime monitoring (Pingdom, Better Uptime)
  • Error tracking (Sentry)
  • Analytics (PostHog)
  • SOC 2 준비 (Vanta)

Day-1K Customers Checklist

  • 다중 리전 배포
  • Dedicated enterprise 인프라
  • BYOK (Bring Your Own Key)
  • SCIM 프로비저닝
  • IP allowlist per tenant
  • Data export API
  • 24/7 on-call rotation
  • SLA 문서
  • ISO 27001, SOC 2 Type II

13부 — 6개월 로드맵

1개월차: Multi-tenant 모델 결정, RLS(Postgres) 적용, 기본 인증 2개월차: Stripe Billing, Webhook, Subscription lifecycle 3개월차: Feature Flag (OpenFeature), Audit Log 기본 4개월차: SSO (OIDC + SAML), WorkOS 연동, SCIM 기본 5개월차: RBAC + ABAC(OPA), tenant-level encryption 6개월차: SOC 2 준비 (Vanta), Data export, GDPR 대응


14부 — 체크리스트 12개

  • Multi-tenant 데이터 격리 (RLS or 분리 DB)
  • Stripe Billing + 재시도 + Dunning
  • Feature Flag 도구 도입 (OpenFeature)
  • Audit Log 수집 + 보관 정책
  • RBAC + Resource-level permission
  • SSO (OIDC 기본, SAML 엔터프라이즈)
  • SCIM 프로비저닝
  • Rate Limiting per tenant
  • Data export (GDPR)
  • SOC 2 준비 (Vanta)
  • Status page + uptime monitor
  • PostHog 또는 Mixpanel로 product analytics

15부 — 안티패턴 10가지

  1. Multi-tenancy를 나중에 결정 → 재구조화 지옥
  2. Billing을 직접 구현 → 세금, 환불, prorated에서 자멸
  3. Feature Flag 없이 배포 → Kill switch 없는 장애
  4. Audit Log 없음 → 엔터프라이즈 포기
  5. RBAC 없이 if문 분기 → 권한 지옥
  6. SSO 안 지원 → 엔터프라이즈 영업 실패
  7. Free plan에 제한 없음 → 악용 + 비용 폭탄
  8. Data export 없음 → 고객 락인 불만
  9. Rate limit 없음 → API 남용 + DB 부하
  10. SOC 2 "나중에" → 큰 계약 놓침

마무리 — "SaaS는 신뢰 게임"

2025년 SaaS의 본질은 신뢰:

  • 데이터 격리 = 신뢰
  • Audit Log = 신뢰
  • SSO/SCIM = 기업 IT 신뢰
  • SOC 2 = 감사 신뢰
  • Status page = 투명성
  • Feature Flag = 점진적 신뢰

"기능 더 많이"가 아니라 **"덜 망가지고, 안전하게, 예측 가능하게"**가 엔터프라이즈 판매의 본질.

Season 2의 기술 딥다이브는 여기까지. 다음은 기술을 넘어선 것들.

다음 글은 Season 2 Ep 21 — 엔지니어링 매니지먼트 완전 가이드. 1:1, 피드백, Hiring, Performance Review, Tech Debt 협상, IC → Manager 전환까지. 시스템을 만들었다면, 시스템을 만드는 사람들을 이끄는 법.


다음 글 예고 — "엔지니어링 매니지먼트 완전 가이드: 1:1·피드백·Hiring·Tech Debt·Career Ladder"

Season 2 Ep 21은:

  • 1:1 미팅 베스트 프랙티스
  • Feedback: SBI, Radical Candor
  • Hiring: Scorecard, Interview Loop
  • Performance Review + Calibration
  • Tech Debt 협상 (Product와)
  • IC vs Manager trade-offs
  • Career Ladder (Junior → Staff → Principal)
  • 팀 건강 (Retention, Burnout)

코드보다 사람이 더 복잡하다. 다음 글에서.