マルチテナンシーアーキテクチャ
Authrimのマルチテナンシーアーキテクチャは、単一のデプロイメント内で複数の隔離された顧客環境(テナント)を管理できます。このページでは、環境、テナント、クライアントの関係と、ドメイン命名パターンについて説明します。
アーキテクチャ概要
Authrimのマルチテナンシーモデルは、3つの主要概念に基づいています:
flowchart TB
subgraph env["環境 (独立したインスタンス)"]
subgraph tenant1["テナント: acme"]
client1a["クライアント: web-app"]
client1b["クライアント: mobile-app"]
client1c["クライアント: api-service"]
end
subgraph tenant2["テナント: widget-co"]
client2a["クライアント: dashboard"]
client2b["クライアント: api"]
end
subgraph tenant3["テナント: default"]
client3a["クライアント: admin"]
end
end
style env fill:#f0f8ff
style tenant1 fill:#fff8dc
style tenant2 fill:#fff8dc
style tenant3 fill:#fff8dc
1. 環境(インフラストラクチャレベル)
各環境は完全に独立したWorkersインスタンスとして動作します。
- 目的: ライフサイクルステージの分離(開発、テスト、ステージング、本番)
- 隔離: 独立したコードベースデプロイ、独立したデータベース、独立したKVストア
- ドメイン: 各環境は独自の
BASE_DOMAINを持つ - 独立性: 環境間でデータや設定を共有しない
例:
本番環境: BASE_DOMAIN = "authrim.com"ステージング: BASE_DOMAIN = "staging.authrim.com"テスト: BASE_DOMAIN = "test.authrim.com"開発: BASE_DOMAIN = "dev.authrim.com"2. テナント(隔離境界)
テナントは、環境内の隔離された顧客ワークスペースです。
- 目的: 顧客/組織データの隔離
- スコープ: すべてのデータ(ユーザー、セッション、トークン、ポリシー)はテナントにスコープされる
- ドメイン: サブドメインで識別(例:
acme.authrim.com) - 隔離: 完全な論理分離 — テナント間でデータの閲覧やアクセスは不可
主な特徴:
BASE_DOMAINが設定されている場合、マルチテナントモードは常に有効- 各テナントは以下を隔離:
- ユーザーディレクトリ
- クライアントアプリケーション
- セッションとトークン
- 監査ログ
- 認可ポリシー
- テナント間のデータ共有なし(明示的に連携しない限り)
3. クライアント(アプリケーション)
クライアントは、テナント内に登録されたアプリケーションです。
- 目的: ユーザーを認証するアプリケーションを表す
- スコープ: 正確に1つのテナントに属する
- 種類: Webアプリ、モバイルアプリ、SPA、バックエンドサービス、M2Mアプリケーション
- プロトコル: OAuth 2.0、OIDC、SAML 2.0
例:
- テナント:
acme- クライアント:
web-dashboard(OIDC, authorization_code + PKCE) - クライアント:
mobile-app(OIDC, authorization_code + PKCE) - クライアント:
api-service(OAuth 2.0, client_credentials) - クライアント:
legacy-app(SAML 2.0 SP)
- クライアント:
ドメインパターン
有効なパターン
Authrimはサブドメインベースのテナント隔離を使用します。単一レベルのサブドメインのみが許可されます。
本番環境 (BASE_DOMAIN = "authrim.com")
| ドメイン | テナントID | 説明 |
|---|---|---|
authrim.com | PRIMARY_TENANT_ID または default | ネイキッドドメイン(プライマリテナント) |
acme.authrim.com | acme | シンプルなテナント名 |
acme-corp.authrim.com | acme-corp | ハイフン付きテナント名 |
acme-prod.authrim.com | acme-prod | サフィックス付きテナント |
tenant123.authrim.com | tenant123 | 英数字テナント |
a.authrim.com | a | 1文字テナント |
ステージング環境 (BASE_DOMAIN = "staging.authrim.com")
| ドメイン | テナントID | 説明 |
|---|---|---|
staging.authrim.com | default | ネイキッドドメイン |
acme.staging.authrim.com | acme | ステージング環境のテナント |
widget-co.staging.authrim.com | widget-co | 別のテナント |
テスト環境 (BASE_DOMAIN = "test.authrim.com")
| ドメイン | テナントID | 説明 |
|---|---|---|
test.authrim.com | default | ネイキッドドメイン |
acme.test.authrim.com | acme | テスト環境のテナント |
無効なパターン(拒否される)
❌ サブサブドメインは許可されません
多階層サブドメインは、曖昧さを防ぎセキュリティを維持するために拒否されます。
| ドメイン | エラー | 理由 |
|---|---|---|
dev.acme.authrim.com | invalid_format (400) | サブサブドメインは不可 |
api.acme.authrim.com | invalid_format (400) | サブサブドメインは不可 |
auth.tenant.staging.authrim.com | invalid_format (400) | サブサブドメインは不可 |
acme.other.com | tenant_not_found (404) | BASE_DOMAINの不一致 |
-acme.authrim.com | invalid_format (400) | 先頭のハイフン |
acme-.authrim.com | invalid_format (400) | 末尾のハイフン |
tenant_name.authrim.com | invalid_format (400) | アンダースコア不可 |
サブサブドメインが禁止されている理由:
- 曖昧性:
dev.acme.authrim.com—devはサービスプレフィックス?それともテナント名の一部? - シンプルさ: 単一レベルのサブドメインは理解・管理が容易
- セキュリティ: DNSベースの攻撃や設定ミスを防止
- アーキテクチャ: 環境は独立したインスタンスであり、サブドメインではない
解決策: テナント名にハイフンを使用:
- ❌
dev.acme.authrim.com→ ✅acme-dev.authrim.com - ❌
api.tenant.authrim.com→ ✅tenant-api.authrim.com
環境設定
環境変数
各環境インスタンスには以下の変数が必要です:
# マルチテナントモード用のベースドメインBASE_DOMAIN="authrim.com"
# デフォルトテナントID(テナント未指定時に使用)DEFAULT_TENANT_ID="default"
# ネイキッドドメインアクセス用のプライマリテナント(オプション)PRIMARY_TENANT_ID="main"
# ユーザーIDフォーマット(uuid または nanoid)USER_ID_FORMAT="nanoid"ネイキッドドメインルーティング
ネイキッドドメイン(例: authrim.com)にアクセスした場合、Authrimは以下の優先順位を使用:
PRIMARY_TENANT_IDが設定されている → そのテナントにルーティングDEFAULT_TENANT_IDが設定されている → そのテナントにルーティング- フォールバック:
"default"テナントにルーティング
例:
BASE_DOMAIN="authrim.com"PRIMARY_TENANT_ID="main"DEFAULT_TENANT_ID="default"authrim.com→ テナント"main"にルーティングacme.authrim.com→ テナント"acme"にルーティングwidget.authrim.com→ テナント"widget"にルーティング
関係の例
例1: SaaSプラットフォーム
シナリオ: 複数の顧客を持つSaaS企業
本番環境 (BASE_DOMAIN = "myplatform.com"):├── テナント: acme│ ├── クライアント: web-dashboard (OIDC)│ ├── クライアント: mobile-app (OIDC)│ └── クライアント: reporting-api (OAuth M2M)├── テナント: widget-co│ ├── クライアント: admin-panel (OIDC)│ └── クライアント: public-api (OAuth M2M)└── テナント: default └── クライアント: platform-admin (OIDC)
ステージング環境 (BASE_DOMAIN = "staging.myplatform.com"):├── テナント: acme│ ├── クライアント: web-dashboard (テスト中)│ └── クライアント: mobile-app (テスト中)└── テナント: test-customer └── クライアント: demo-app (テスト中)ドメイン:
- 本番:
acme.myplatform.com,widget-co.myplatform.com - ステージング:
acme.staging.myplatform.com,test-customer.staging.myplatform.com
例2: シングルテナント(社内利用)
シナリオ: 社内認証にAuthrimを使用する企業
本番環境 (BASE_DOMAIN = "auth.company.com"):└── テナント: company (PRIMARY_TENANT_ID経由) ├── クライアント: employee-portal (OIDC) ├── クライアント: mobile-app (OIDC) ├── クライアント: legacy-intranet (SAML) └── クライアント: api-gateway (OAuth M2M)
テスト環境 (BASE_DOMAIN = "auth-test.company.com"):└── テナント: company └── クライアント: employee-portal (テスト中)設定:
# 本番BASE_DOMAIN="auth.company.com"PRIMARY_TENANT_ID="company"
# ユーザーはネイキッドドメイン経由でアクセス: auth.company.com → テナント"company"例3: マルチ環境開発
シナリオ: 複数の環境を持つ開発チーム
開発環境 (BASE_DOMAIN = "dev.authrim.com"):├── テナント: alice-dev│ └── クライアント: test-app└── テナント: bob-dev └── クライアント: test-app
テスト/CI (BASE_DOMAIN = "test.authrim.com"):├── テナント: ci-runner-1│ └── クライアント: automated-tests└── テナント: ci-runner-2 └── クライアント: automated-tests
ステージング (BASE_DOMAIN = "staging.authrim.com"):└── テナント: demo ├── クライアント: web-app └── クライアント: mobile-app
本番 (BASE_DOMAIN = "authrim.com"):├── テナント: customer-a│ ├── クライアント: web-app│ └── クライアント: mobile-app└── テナント: customer-b ├── クライアント: dashboard └── クライアント: apiベストプラクティス
1. 環境分離
✅ 推奨:
- 各環境に別々の
BASE_DOMAINを使用 - 各環境を独立したWorkersインスタンスとしてデプロイ
- 環境固有のデータベースとKVストアを使用
❌ 非推奨:
- 同じ環境でテストデータと本番データを混在させる
- サブサブドメインで環境を表現(例:
test.acme.authrim.com)
2. テナント命名
✅ 推奨:
- 小文字英数字とハイフンを使用
- テナント名は短く説明的に
- 複数単語の名前にはハイフンを使用:
acme-corp,widget-co
❌ 非推奨:
- ハイフンで開始/終了:
-acme,acme- - 特殊文字を使用:
acme_corp,acme@company - サブサブドメインを作成:
dev.acme.authrim.com
3. クライアント管理
✅ 推奨:
- 各アプリケーションを別々のクライアントとして登録
- 適切なクライアントタイプを使用(バックエンドはconfidential、SPA/モバイルはpublic)
- すべてのpublicクライアントでPKCEを有効化
- M2Mサービスにはclient_credentialsグラントを使用
❌ 非推奨:
- テナント間でクライアント認証情報を共有
- 複数の環境で同じclient_idを使用(環境ごとに別クライアントを使用)
- publicクライアントでPKCEを無効化
セキュリティ考慮事項
テナント隔離
- データベースレベルの隔離: すべてのクエリは自動的にテナントIDにスコープされる
- セッション隔離: セッションはテナント間で共有できない
- トークン隔離: アクセストークンは発行元テナントにバインドされる
- 監査隔離: 監査ログはテナントごとに分離
ドメイン検証
- Hostヘッダー検証: AuthrimはすべてのリクエストでHostヘッダーを検証
- BASE_DOMAIN強制:
*.BASE_DOMAINにマッチするリクエストのみ受け入れ - サブサブドメイン拒否: 多階層サブドメインは400 Bad Requestで拒否
- CORS強制: CORSポリシーはテナントスコープ
テナント間アクセス
デフォルトで、テナント間アクセスは禁止されています。連携アクセスが必要な場合:
- 外部IdPブリッジを使用: ソーシャルログインまたはエンタープライズSSOを設定
- SAMLフェデレーション: テナント間にSAML信頼を設定
- トークン交換: OAuth 2.0トークン交換(RFC 8693)を実装
マイグレーションシナリオ
シングルテナントからマルチテナントへ
シングルテナントデプロイメントから移行する場合:
- BASE_DOMAINを設定: ベースドメインを設定(例:
authrim.com) - PRIMARY_TENANT_IDを設定: ネイキッドドメインを既存テナントに向ける
- ユーザーを移行: 既存のすべてのユーザーはプライマリテナントに属する
- 新しいテナントを追加: Admin API経由で新しいテナントを作成
- DNSを更新:
*.authrim.comのワイルドカードDNSを設定
例:
# 移行前(シングルテナント)ISSUER_URL="https://auth.company.com"
# 移行後(マルチテナント)BASE_DOMAIN="auth.company.com"PRIMARY_TENANT_ID="company"# ネイキッドドメイン(auth.company.com)は引き続き動作 → テナント"company"にルーティング新しいテナントの追加
新しいテナントを追加するには:
- Admin API経由でテナントを作成:
POST /admin/tenants{ "tenantId": "new-customer", "displayName": "New Customer Inc."}- DNSを設定:
new-customer.authrim.comがWorkersに解決されることを確認 - クライアントを登録: 新しいテナント用のOAuth/OIDCクライアントを作成
- アクセスをテスト:
new-customer.authrim.comでログインを確認
トラブルシューティング
よくある問題
問題: tenant_not_foundエラー(404)
原因:
- ドメインがBASE_DOMAINと一致しない
- サブサブドメインを使用(例:
dev.acme.authrim.com) - データベースにテナントが存在しない
解決策:
- BASE_DOMAIN設定を確認
- 単一レベルのサブドメインを使用:
acme.authrim.com - Admin API経由でテナントを作成
問題: invalid_formatエラー(400)
原因:
- サブサブドメインを使用(例:
api.tenant.authrim.com) - サブドメインに無効な文字
- ハイフンが先頭または末尾
解決策:
- ハイフンを使用:
tenant-api.authrim.com - 英数字とハイフンのみ使用:
[a-z0-9-]+ - 先頭/末尾のハイフンがないことを確認
問題: missing_hostエラー(400)
原因: リクエストからHostヘッダーが欠落
解決策:
- HTTPクライアントがHostヘッダーを送信することを確認
- リバースプロキシ設定を確認
- Cloudflare設定を確認
関連ドキュメント
- アーキテクチャ - システム全体のアーキテクチャ
- エッジコンピューティング - エッジデプロイとグローバル配信
- はじめに - 初期セットアップと設定
- Admin API - プログラマティックなテナントとクライアント管理