サイトアイコンmaita tomoya dev io

SaaSプロダクトを作る場合: マルチテナント・課金・認証・API設計

case-studies

SaaSプロダクトを作る場合: マルチテナント・課金・認証・API設計

はじめに

SaaS(Software as a Service)は、クラウド経由でソフトウェアを提供するビジネスモデルです。Slack、Notion、Figmaなどが代表例です。SaaSの技術的な特徴は、複数の企業(テナント)が同じシステムを共有して利用する「マルチテナント」アーキテクチャにあります。

身近な例えで理解するSaaS

SaaSは「賃貸マンション」のようなものです。

  • マルチテナント = マンション。複数の世帯(企業)が同じ建物(システム)に住んでいるが、各部屋(データ)は完全に隔離されている
  • 課金 = 家賃。月額いくら、何人で住むか(シート数)で料金が変わる
  • 認証 = エントランスのセキュリティ。鍵(パスワード)やカードキー(SSO)で入館管理
  • API = 郵便受け。外部のサービス(郵便)とデータをやり取りするインターフェース

全体アーキテクチャ

推奨構成: Next.js + NestJS + PostgreSQL + Stripe

                    +-------------------+
                    |   CloudFront      |
                    |   (CDN + WAF)     |
                    +--------+----------+
                             |
                    +--------v----------+
                    |   Next.js         |
                    |   (Frontend)      |
                    |   on Vercel       |
                    +--------+----------+
                             |
                    +--------v----------+
                    |   API Gateway     |
                    |   (認証/レート    |
                    |    リミット)      |
                    +--------+----------+
                             |
              +--------------+--------------+
              |              |              |
      +-------v------+ +----v-------+ +----v--------+
      |Core API      | |Auth        | |Billing      |
      |NestJS        | |Service     | |Service      |
      |(ビジネス     | |(認証/認可) | |(課金/請求)  |
      | ロジック)    | |            | |             |
      +-------+------+ +----+-------+ +----+--------+
              |              |              |
       +------v------+  +---v--------+ +---v--------+
       |PostgreSQL   |  |Auth0 /     | |Stripe      |
       |(Aurora)     |  |Cognito     | |Billing     |
       |テナント     |  +------------+ +------------+
       |分離対応     |
       +------+------+
              |
       +------v------+
       |Redis         |
       |(ElastiCache) |
       |セッション/   |
       |キャッシュ    |
       +-------------+

       +-------------------------------------------+
       |  バックグラウンド処理                      |
       |  - SQS: 非同期ジョブ                      |
       |  - Lambda: Webhook処理、通知               |
       |  - EventBridge: スケジュールタスク          |
       |  - S3: ファイルアップロード                 |
       +-------------------------------------------+

マルチテナントアーキテクチャ

3つのマルチテナント方式

方式説明データ分離コスト運用複雑度
DB分離テナントごとに別DB最高高い高い
スキーマ分離テナントごとに別スキーマ高い
行レベル分離(RLS)全テナント同一テーブル、行で分離低い低い

方式の詳細比較

【DB分離】
Tenant A → Database A (PostgreSQL)
Tenant B → Database B (PostgreSQL)
Tenant C → Database C (PostgreSQL)

メリット: 完全なデータ分離、テナント別のバックアップ/復旧
デメリット: テナント数に比例してDBコストが増加、マイグレーション管理が大変

【スキーマ分離】
Database (PostgreSQL)
├── Schema: tenant_a
│   ├── users
│   ├── projects
│   └── ...
├── Schema: tenant_b
│   ├── users
│   ├── projects
│   └── ...
└── Schema: shared (共通データ)
    ├── plans
    └── features

メリット: 良好なデータ分離、1つのDBで管理可能
デメリット: スキーマ数が増えるとパフォーマンス低下

【行レベル分離(RLS)】
Database (PostgreSQL)
└── Table: users
    ├── id=1, tenant_id='A', name='田中'
    ├── id=2, tenant_id='A', name='鈴木'
    ├── id=3, tenant_id='B', name='佐藤'
    └── id=4, tenant_id='B', name='山田'

メリット: シンプル、コスト最小、スケーラブル
デメリット: SQLミスでデータ漏洩のリスク(RLSで軽減)

推奨: 行レベル分離(RLS)

PostgreSQLのRLS(Row Level Security)を使うことで、行レベルの分離をDBレベルで強制できる。

-- RLSの設定例
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON projects
    USING (tenant_id = current_setting('app.current_tenant')::uuid);

認証・認可

認証方式の比較

方式説明適したケース
メール + パスワード最も基本的な認証全般
SSO(SAML/OIDC)企業のIdPと連携エンタープライズ
ソーシャルログインGoogle、GitHub等スタートアップ
マジックリンクメールでログインURL送信パスワードレス

認証サービスの比較

サービス料金(月額)SSO対応特徴
Auth0無料〜$23/1000MAU対応最も機能が充実
Clerk無料〜$25/1000MAU対応DX最高、React統合が優秀
AWS Cognito無料〜$0.0055/MAU対応AWS統合、安い
Supabase Auth無料〜$25/月対応PostgreSQL統合
Firebase Auth無料〜$0.06/MAU対応Google統合

推奨: Clerk or Auth0

  • スタートアップ: Clerk(DXが最高、React/Next.jsとの統合が簡単)
  • エンタープライズ: Auth0(SSO、MFA、コンプライアンス対応が充実)

RBAC(Role-Based Access Control)

ロール権限
Owner全権限 + 請求管理 + テナント削除
Adminメンバー管理 + 設定変更 + 全データアクセス
Memberデータの作成/編集/閲覧
Viewerデータの閲覧のみ
Guest招待されたプロジェクトのみアクセス

課金・請求

課金モデルの比較

モデル説明
フラットレート固定月額Basecamp
シートベースユーザー数 x 単価Slack、Notion
使用量ベース使った分だけAWS、Twilio
ティアベースプランごとに固定料金GitHub、Figma
ハイブリッド基本料金 + 使用量Vercel

Stripe Billingの活用

[課金フローの全体像]

1. プラン選択
   フロント → Stripe Checkout → 決済完了

2. Webhook受信
   Stripe → Webhook → NestJS → DB更新

3. 月次請求
   Stripe(自動課金) → Webhook → DB更新 → メール通知

4. プラン変更
   フロント → Stripe API → 比例配分(proration)計算 → 請求調整

5. 解約
   フロント → Stripe API → 期間終了時にアクセス停止

Stripe Billingの主要概念

概念説明
Customer課金対象の顧客(テナント)
Subscription定期課金の設定
Productプラン(Free、Pro、Enterprise等)
Price価格設定(月額$10、年額$100等)
Invoice請求書
Payment Method支払い方法(クレジットカード等)
Webhook決済イベントの通知

API設計

REST vs GraphQL

項目RESTGraphQL
エンドポイントリソースごとに複数単一エンドポイント
データ取得量固定(over-fetching/under-fetching)クライアントが指定(必要な分だけ)
キャッシュHTTP標準キャッシュ専用キャッシュ必要
学習コスト低い
ドキュメントSwagger/OpenAPIGraphQL Playground
リアルタイム別途WebSocketSubscription対応

推奨: REST API(NestJS + Swagger)

SaaSのAPIは外部公開する可能性が高いため、最も広く理解されているRESTが無難。GraphQLはフロントエンド内部での利用に限定するか、BFF(Backend For Frontend)パターンで活用。

APIバージョニング

方式メリットデメリット
URLパス/api/v1/users分かりやすいURLが変わる
ヘッダーApi-Version: 2URLが変わらない見えにくい
クエリパラメータ/api/users?version=1シンプルキャッシュに影響

推奨: URLパス方式(/api/v1/...)

レートリミット

プランリクエスト上限バースト上限
Free100リクエスト/分10リクエスト/秒
Pro1,000リクエスト/分50リクエスト/秒
Enterprise10,000リクエスト/分200リクエスト/秒

実装方法: Redis + Sliding Window方式


チーム規模と開発スケジュール

MVP(3ヶ月)

役割人数担当範囲
フロントエンド2人ダッシュボード、設定画面
バックエンド2人API、認証、課金連携
インフラ1人AWS構築、CI/CD
デザイン1人UI/UXデザイン
PM1人進捗管理、要件定義
合計7人3ヶ月

MVPの機能:

  • テナント作成/管理
  • ユーザー認証(メール + Google)
  • RBAC(Owner、Admin、Member)
  • コア機能(プロダクト固有)
  • Stripe課金(Free、Proプラン)
  • ダッシュボード

本格展開(追加6ヶ月)

追加機能必要人数期間
SSO(SAML/OIDC)1人2ヶ月
外部API公開1人2ヶ月
監査ログ1人1ヶ月
Webhook配信1人1ヶ月
レポート/分析2人3ヶ月
モバイル対応2人4ヶ月

コスト見積り

MVPフェーズ(〜100テナント、〜1,000ユーザー)

サービス構成月額
VercelProプラン$20
ECS/Fargate2タスク$40
Aurora PostgreSQLdb.t3.medium$130
ElastiCache Rediscache.t3.micro$25
Auth0/Clerk無料枠内$0
Stripe手数料のみ変動
S310GB$1
合計約$216/月

成長フェーズ(〜1,000テナント、〜10,000ユーザー)

サービス構成月額
VercelTeamプラン$100
ECS/Fargate4タスク x 1vCPU$200
Aurora PostgreSQLdb.r6g.large + Replica$600
ElastiCache Rediscache.r6g.large$200
Auth0Professionalプラン$240
Stripe手数料のみ変動
S3 + CloudFront100GB$15
SQS/Lambda非同期処理$10
合計約$1,365/月

エンタープライズ対応

エンタープライズ顧客を獲得するために必要な機能:

機能説明実装優先度
SSO(SAML)企業のIdPと連携
SCIMユーザーの自動プロビジョニング
監査ログ全操作の記録
データエクスポートCSV/JSON形式でデータ出力
SLA99.9%以上の可用性保証
SOC2/ISO27001セキュリティ認証中〜高
カスタム契約年間契約、請求書払い
専任サポートテクニカルアカウントマネージャー
データ所在地特定リージョンでのデータ保存
IP制限特定IPからのみアクセス許可低〜中

セキュリティのベストプラクティス

対策実装方法
テナント間データ分離PostgreSQL RLS
認証Auth0/Clerk + MFA
APIセキュリティレートリミット、CORS、APIキー
データ暗号化通信: TLS、保存: AES-256
脆弱性スキャンSnyk、Dependabot
WAFAWS WAF(SQLインジェクション、XSS防御)
監査ログ全API呼び出しのログ記録
ペネトレーションテスト年1回以上の外部テスト

まとめ

推奨技術スタック

レイヤー技術理由
フロントエンドNext.jsSSR、SEO、React エコシステム
バックエンドNestJSTypeScript、モジュール構造、API設計
データベースPostgreSQL (Aurora)RLS、信頼性
キャッシュRedisセッション、レートリミット
認証Clerk or Auth0SSO、MFA、RBAC
課金Stripe Billingサブスクリプション管理
APIREST + OpenAPI標準的、外部公開しやすい
インフラAWS (ECS/Fargate)スケーラブル

SaaSプロダクトは技術的な完成度だけでなく、「顧客が安心して使えるか」が重要。セキュリティ、可用性、サポート体制の3つを軸に技術選定を行うことが成功のカギである。


参考リンク