Tenant設定ガイド(開発者向け)
📍 このドキュメントの位置づけ
対象読者: Phase 1(how-to 01-05)完了済みの開発者
このドキュメントで学べること:
- 本番運用に向けた詳細なTenant設定
- ユースケース別の設定パターン
- 高度な機能(Extension、カスタムスコープ、カスタムクレーム)
- セキュリティとパフォーマンスのベストプラクティス
How-toガイドとの違い:
| ドキュメント | 目的 | 内容 |
|---|---|---|
| How-to | 最小構成で動かす | 実践的な手順(動作確認重視) |
| Developer Guide | 本番設定を理解する | 詳細仕様と設計パターン |
前提知識:
- how-to-01: 組織初期化完了
- how-to-02: OAuth/OIDC認証の最小設定完了
- OAuth 2.0/OpenID Connectの基礎理解
🧭 Tenantアーキテクチャの理解
Tenantとは
Tenant(テナント)は、マルチテナント環境における完全に独立した認証・認可ドメインです。
Organization vs Tenant
┌─────────────────────────────────────────────────────────┐
│ Organization (企業A) │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Organizer Tenant │ │ Public Tenant │ │
│ │ (組織管理用) │ │ (アプリ用) │ │
│ ├──────────────────┤ ├──────────────────┤ │
│ │ - 組織管理者 │ │ - Client 1 │ │
│ │ - テナント管理 │ │ - Client 2 │ │
│ │ │ │ - Users │ │
│ └──────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────┘
データ分離の仕組み
各Tenantで完全に分離されるもの:
- ユーザーデータ: 認証情報、プロファイル
- クライアント設定: OAuth/OIDCクライアント
- 認証ポリシー: パスワードポリシー、MFA設定
- トークン設定: 有効期限、署名鍵
- セキュリティイベントログ: 監査ログ
テナント種別
| 種別 | 説明 | 作成方法 | 用途 |
|---|---|---|---|
ADMIN | システム管理用テナ ント | システム初期化時に自動作成 | システム管理・初期設定用 |
ORGANIZER | 組織管理用テナント | 組織作成(Onboarding API)時に自動作成 | 組織管理者の管理操作用 |
PUBLIC | アプリケーション用テナント | 組織レベルAPIで作成 | 通常のアプリケーション用 |
実装リファレンス:
ADMIN: IdpServerStarterContextCreator.java:78ORGANIZER: OnboardingContextCreator.java:82PUBLIC: TenantManagementRegistrationContextCreator.java:68
重要: 組織レベルAPI(POST /v1/management/organizations/{org-id}/tenants)で作成されるテナントは常にtype: "PUBLIC"です。ADMINとORGANIZERは手動で作成できません。
📖 API仕様リファレンス
テナント作成・更新のAPI詳細仕様(リクエスト/レスポンススキーマ、全パラメータ説明)は、OpenAPI仕様書を参照してください。
📖 OpenAPI仕様書:
- swagger-cp-tenant-ja.yaml - テナント管理API仕様
🎯 シナリオ別設定例
実際のユースケースに応じた認可サーバー設定例を紹介します。
| # | シナリオ | ユースケース | 主なポイント | 詳細 |
|---|---|---|---|---|
| 1 | Webアプリケーション(標準) | ユーザーがWebブラウザから安全にログインし、セッション中は再認証なしでサービスを利用する | • Opaque Token • Access Token: 30分 • Refresh Token: 1時間 | 詳細 |
| 2 | モバイルアプリ(PKCE) | モバイルユーザーが再ログインなしで長期間(30日)アプリを利用し続ける | • PKCE必須 • 長期Refresh Token(30日) • EXTENDS戦略 | 詳細 |
| 3 | 金融グレード(FAPI) | 銀行顧客が口座・取引情報に安全にアクセスし、厳格なセキュリティ基準を満たす | • Private Key JWT / mTLS • Pairwise Subject • Access Token: 10分 | 詳細 |
| 4 | SaaS型マルチテナント | 企業ユーザーが所属組織・部署情報を含 むトークンでSaaSサービスにアクセスする | • JWT Token • カスタムクレーム • M2M通信対応 | 詳細 |
📋 シナリオ詳細設定
1. Webアプリケーション向け(標準)
要件:
- Authorization Code Flow
- Refresh Token使用
- Access Token: 30分
- Refresh Token: 1時間
ユースケース: 一般的なWebアプリケーション、SPA
設定JSON例を表示
{
"tenant": {
"id": "web-app-tenant",
"name": "Web Application Tenant",
"domain": "https://app.example.com",
"authorization_provider": "idp-server"
},
"authorization_server": {
"issuer": "https://app.example.com/web-app-tenant",
"authorization_endpoint": "https://app.example.com/web-app-tenant/v1/authorizations",
"token_endpoint": "https://app.example.com/web-app-tenant/v1/tokens",
"userinfo_endpoint": "https://app.example.com/web-app-tenant/v1/userinfo",
"jwks_uri": "https://app.example.com/web-app-tenant/v1/jwks",
"scopes_supported": ["openid", "profile", "email"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"response_types_supported": ["code"],
"token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
"extension": {
"access_token_type": "opaque",
"access_token_duration": 1800,
"refresh_token_duration": 3600,
"rotate_refresh_token": true
}
}
}
設定ポイント:
access_token_type: "opaque": 高速な不透明トークンrotate_refresh_token: true: セキュリティ向上のためリフレッシュトークンをローテーション
2. モバイルアプリ向け(PKCE対応)
要件:
- Authorization Code Flow + PKCE
- 長期間のRefresh Token(30日)
- カスタムスコープ(プッシュ通知、オフラインアクセス)
ユースケース: iOS/Androidアプリ、ネイティブアプリ
設定JSON例を表示
{
"tenant": {
"id": "mobile-app-tenant",
"name": "Mobile Application Tenant",
"domain": "https://mobile.example.com",
"authorization_provider": "idp-server"
},
"authorization_server": {
"issuer": "https://mobile.example.com/mobile-app-tenant",
"authorization_endpoint": "https://mobile.example.com/mobile-app-tenant/v1/authorizations",
"token_endpoint": "https://mobile.example.com/mobile-app-tenant/v1/tokens",
"userinfo_endpoint": "https://mobile.example.com/mobile-app-tenant/v1/userinfo",
"jwks_uri": "https://mobile.example.com/mobile-app-tenant/v1/jwks",
"scopes_supported": [
"openid",
"profile",
"email",
"offline_access",
"notifications:push"
],
"grant_types_supported": ["authorization_code", "refresh_token"],
"response_types_supported": ["code"],
"token_endpoint_auth_methods_supported": ["none"],
"extension": {
"access_token_type": "opaque",
"access_token_duration": 3600,
"refresh_token_duration": 2592000,
"rotate_refresh_token": true,
"refresh_token_strategy": "EXTENDS"
}
}
}
設定ポイント:
token_endpoint_auth_methods_supported: ["none"]: PKCE専用(Client Secretなし)refresh_token_duration: 2592000: 30日間の長期トークンrefresh_token_strategy: "EXTENDS": リフレッシュの度にトークン有効期限を延長(ユーザー体験向上)
3. 金融グレード(FAPI準拠)
要件:
- FAPI 1.0 Advanced Profile準拠
- 強力なクライアント認証(Private Key JWT, mTLS)
- Pairwise Subject(プライバシー保護)
- カスタムスコープ(OpenBanking)
ユースケース: オンラインバン キング、金融API、機密データアクセス
設定JSON例を表示
{
"tenant": {
"id": "banking-tenant",
"name": "Online Banking Platform",
"domain": "https://banking.example.com",
"authorization_provider": "idp-server"
},
"session_config": {
"use_secure_cookie": true,
"cookie_same_site": "Strict",
"switch_policy": "STRICT"
},
"cors_config": {
"allow_origins": ["https://banking.example.com"]
},
"authorization_server": {
"issuer": "https://banking.example.com/banking-tenant",
"authorization_endpoint": "https://banking.example.com/banking-tenant/v1/authorizations",
"token_endpoint": "https://banking.example.com/banking-tenant/v1/tokens",
"userinfo_endpoint": "https://banking.example.com/banking-tenant/v1/userinfo",
"jwks_uri": "https://banking.example.com/banking-tenant/v1/jwks",
"scopes_supported": [
"openid",
"profile",
"email",
"openbanking:accounts",
"openbanking:transactions",
"openbanking:payments"
],
"grant_types_supported": ["authorization_code", "refresh_token"],
"response_types_supported": ["code"],
"response_modes_supported": ["query", "jwt"],
"token_endpoint_auth_methods_supported": [
"private_key_jwt",
"tls_client_auth"
],
"subject_types_supported": ["pairwise"],
"extension": {
"access_token_type": "jwt",
"access_token_duration": 600,
"refresh_token_duration": 3600,
"authorization_code_valid_duration": 300,
"fapi_baseline_scopes": ["openbanking:accounts", "openbanking:transactions"],
"fapi_advance_scopes": ["openbanking:payments"],
"id_token_strict_mode": true
}
}
}
設定ポイント:
token_endpoint_auth_methods_supported:private_key_jwt,tls_client_authのみ許可subject_types_supported: ["pairwise"]: ユーザー識別子を分離(プライバシー保護)access_token_type: "jwt": JWT形式で署名検証可能access_token_duration: 600: 10分の短い有効期限(セキュリティ向上)fapi_baseline_scopes/fapi_advance_scopes: FAPI検証スコープswitch_policy: "STRICT": 別ユーザー認証を拒否(ログアウト必須)
FAPI準拠の利点:
- 金融機関レベルのセキュリティ
- 国際標準への準拠
- 監査対応の容易さ
4. SaaS型マルチテナント
要件:
- 複数企業の従業員が利用
- カスタムクレーム(企業ID、部署、権限)
- JWT形式のAccess Token
- M2M通信(Client Credentials Grant)
ユースケース: B2B SaaS、企業向けプラットフォーム
設定JSON例を表示
{
"tenant": {
"id": "saas-tenant",
"name": "SaaS Platform Tenant",
"domain": "https://saas.example.com",
"authorization_provider": "idp-server"
},
"authorization_server": {
"issuer": "https://saas.example.com/saas-tenant",
"authorization_endpoint": "https://saas.example.com/saas-tenant/v1/authorizations",
"token_endpoint": "https://saas.example.com/saas-tenant/v1/tokens",
"userinfo_endpoint": "https://saas.example.com/saas-tenant/v1/userinfo",
"jwks_uri": "https://saas.example.com/saas-tenant/v1/jwks",
"scopes_supported": [
"openid",
"profile",
"email",
"claims:organization_id",
"claims:department",
"claims:role"
],
"grant_types_supported": ["authorization_code", "refresh_token", "client_credentials"],
"response_types_supported": ["code"],
"extension": {
"access_token_type": "jwt",
"access_token_duration": 3600,
"custom_claims_scope_mapping": true
}
}
}
設定ポイント:
custom_claims_scope_mapping: true: カスタムクレームをスコープでマッピングclaims:organization_id,claims:department: 企業・部署情報をトークンに含めるgrant_types_supported:client_credentialsを追加(M2M通信)access_token_type: "jwt": クレーム情報をトークン内に含める
⚙️ 高度な設定
Extension設定の詳細
extensionオブジェクトには、idp-server固有の拡張設定を含めます。
トークン設定
| フィールド | デフォルト値 | 説明 | 推奨値 |
|---|---|---|---|
access_token_type | opaque | トークン形式(opaque / jwt) | Web: opaque, SaaS: jwt |
access_token_duration | 1800秒 (30分) | アクセストークン有効期限 | 30分~1時間 |
id_token_duration | 3600秒 (60分) | IDトークン有効期限 | 1時間 |
refresh_token_duration | 3600秒 (60分) | リフレッシュトークン有効期限 | Web: 1時間、Mobile: 30日 |
rotate_refresh_token | true | リフレッシュトークンローテーション | true 推奨 |
refresh_token_strategy | FIXED | 期限戦略(FIXED / EXTENDS) | Mobile: EXTENDS |
認可フロー設定
| フィールド | デフォルト値 | 説明 | 推奨値 |
|---|---|---|---|
authorization_code_valid_duration | 600秒 (10分) | 認可コード有効期限 | 5~10分(RFC 6749推奨) |
oauth_authorization_request_expires_in | 1800秒 (30分) | 認可リクエスト有効期限 | 30分 |
authorization_response_duration | 60秒 (1分) | 認可レスポンス有効期限 | 1分 |
default_max_age | 86400秒 (24時間) | デフォルト最大認証有効期間 | 24時間 |
セキュリティ設定
| フィールド | デフォルト値 | 説明 |
|---|---|---|
id_token_strict_mode | false | IDトークン厳密モード(OIDC仕様準拠、詳細は下記参照) |
id_token_strict_mode - IDトークンクレーム制御
目的: IDトークンに含めるクレームの判定ロジックをOIDC仕様に厳密準拠させます。
デフォルト値: false
動作の違い:
| モード | scope=profileのみ指定 | claimsパラメータで明示的要求 | 用途 |
|---|---|---|---|
false(デフォルト) | name, given_name等を全て含める | 明示的に要求されたクレームのみ | 後方互換性・利便性優先 |
true(厳密モード) | クレームを含めない | 明示的に要求されたクレームのみ | OIDC仕様準拠・FAPI準拠 |
OIDC仕様の解釈:
- OpenID Connect Core 1.0 Section 5.4: "
profilescopeはUserInfoエンドポイントでクレームへのアクセスを要求する" - IDトークンへの包含は、
claimsパラメータでの明示的要求が推奨される
実装における挙動:
// GrantIdTokenClaims.java:218-221
if (idTokenStrictMode) {
return idTokenClaims.hasName(); // claimsパラメータでの明示的要求のみ
}
return scopes.contains("profile"); // scopeだけで含める(非厳密モード)
使用例:
非厳密モード(id_token_strict_mode: false、デフォルト):
GET /authorize?scope=openid profile&...
→ IDトークンに name, given_name, family_name 等が含まれる
厳密モード(id_token_strict_mode: true):
GET /authorize?scope=openid profile&claims={"id_token":{"name":null}}&...
→ nameのみIDトークンに含まれる(claimsで明示的要求)
推奨設定:
- 一般的なアプリケーション:
false(利便性優先) - 金融グレード(FAPI):
true(仕様準拠・最小限のデータ公開) - OIDC4IDA:
true(検証済みクレームの厳密制御)
判断基準:
| 設定値 | 選択条件 | 理由 |
|---|---|---|
true | FAPI/OIDC仕様への厳密準拠が必要 | FAPI、OIDC4IDAではIDトークンのクレームを明示的に要求することが求められる |
true | クライアントがclaimsパラメータに対応済み | OIDC仕様に準拠した実装が可能 |
false | クライアントがclaimsパラメータに対応困難 | レガシーシステム、既存実装の改修コストが高い |
false | 開発・テスト環境での利便性を優先 | クレーム取得を簡素化して開発効率を向上 |
移行戦略:
新規プロジェクトの場合:
- 最初から
trueで設計: 将来的な規制対応を見据える - クライアント実装時に
claimsパラメータを考慮
既存プロジェクトの場合:
- 段階的移行:
- Phase 1:
falseのまま、クライアントにclaimsパラメータ実装 - Phase 2: 検証環境で
trueに変更してテスト - Phase 3: 本番環境で
trueに変更
- Phase 1:
- 互換性確認: UserInfoエンドポイントで同じクレームが取得できることを確認
関連設定:
custom_claims_scope_mapping: カスタムクレームのclaims:スコープマッピングclaims_supported: サポートするクレームの宣言(Discovery)
実装リファレンス:
FAPI設定
| フィールド | デフォルト値 | 説明 |
|---|---|---|
fapi_baseline_scopes | [] | FAPI Baseline検証スコープ |
fapi_advance_scopes | [] | FAPI Advanced検証スコープ |
実装リファレンス: AuthorizationServerExtensionConfiguration.java
カスタムスコープ
標準スコープ(openid, profile, email)に加えて、独自のスコープを定義できます。
定義方法
scopes_supportedにカスタムスコープを追加:
{
"scopes_supported": [
"openid",
"profile",
"email",
"identity_verification_application",
"notifications:push",
"api:read",
"api:write"
]
}
スコープ命名規則
| パターン | 例 | 用途 |
|---|---|---|
domain:action | api:read, notifications:push | 機能別アクセス制御 |
claims:field | claims:vip_status | カスタムクレームアクセス |
| 単独名 | offline_access | 標準的な追加スコープ |
Claims(クレーム)設定
OpenID Connectでは、**クレーム(claim)**とはユーザーに関する情報項目(名前、メール、 電話番号等)を指します。
claims_supported - サポートするクレームの宣言
目的: 認可サーバーが返却可能なクレーム(ユーザー情報項目)を宣言します。
OpenID Connect Discovery仕様: OpenID Connect Discovery 1.0 Section 3
設定例:
{
"claims_supported": [
"sub",
"name",
"email",
"email_verified",
"preferred_username",
"given_name",
"family_name",
"picture",
"phone_number",
"phone_number_verified"
]
}
標準クレーム(OIDC Core仕様):
| クレーム | 説明 | 例 |
|---|---|---|
sub | Subject(ユーザー識別子) | 248289761001 |
name | フルネーム | Jane Doe |
given_name | 名 | Jane |
family_name | 姓 | Doe |
email | メールアドレス | janedoe@example.com |
email_verified | メール検証済みフラグ | true |
preferred_username | 優先ユーザー名 | jane.doe |
phone_number | 電話番号 | +1 (555) 123-4567 |
phone_number_verified | 電話番号検証済みフラグ | true |
picture | プロフィール画像URL | https://example.com/jane.jpg |
profile | プロフィールページURL | https://example.com/jane |
website | ウェブサイトURL | https://janedoe.com |
gender | 性別 | female |
birthdate | 生年月日 | 1990-01-01 |
zoneinfo | タイムゾーン | Asia/Tokyo |
locale | ロケール | ja-JP |
address | 住所(JSON構造) | {"formatted": "..."} |
参照: OpenID Connect Core 1.0 Section 5.1 - Standard Claims
実装における重要な注意点:
claims_supportedは宣言のみであり、実際に返却されるかはUserInfoエンドポイントやIDトークンの実装に依存します- クライアントは
scopeやclaimsリクエストパラメータでクレームを要求します - 未実装のクレームを宣言すると、クライアントが誤動作する可能性があります