メインコンテンツへ

認証・権限

一言でいうと

「誰が」「何を」「どこまで」できるかを決めるモジュール。認証は JWT ベース、権限モデルは Discord のロール方式(1ユーザーに複数ロールを割り当て、ロールごとに権限を付与)を採用している。認可判定そのもののアルゴリズムと primitives(ResourceType × Action × Scope)の詳細は 認可モデル にまとめてあるので、このページはモジュールの構造に絞る。

主要ドメイン概念

概念役割
DynamicRoleテナントごとに定義できるロール。position(階層順位)を持つ
UserRoleユーザー ↔ ロールの多対多割り当て(Discord 方式:1人が複数ロールを持てる)
PermissionRule権限の最小単位。ResourceType + Action + Scope の3値からなる sealed class(GeneralRule 等)
RolePermissionロール ↔ PermissionRule の割り当て
AuthContext / AuthenticatedUserContextリクエストごとの認証済みユーザー・テナント文脈

Backend 構造

core/auth/role の概念も内包している(domain/model/DynamicRole.kt 等はここにあり、別モジュールに role は存在しない)。

  • api/controller/: AuthController(ログイン/ログアウト)、AuthSetupController / BuiltInAuthController(初期セットアップ・組み込み認証)、RoleController / RolePermissionController / UserRoleController(ロール・権限・割り当て CRUD)、PermissionControllerPlatformAdminController(運営者向け横断操作)、MyTenantsControllerResourceResolverControllerDemoAuthController
  • domain/service/AuthorizationService: 権限・ロール管理の中心サービス("Centralized authorization service")。AuthorizationCache でキャッシュし、CacheEvictionService が変更時に無効化する
  • domain/service/RoleHierarchyService: ロールの階層順位(position)を扱う。「自分より上位のロールは操作できない」といったガードの土台
  • domain/service/UserRoleService: ユーザーへのロール割り当て・同期("following Discord's model where users can have multiple roles"、syncRolesForUser / syncMembersForRole は差分計算してから適用する Discord 方式の同期)
  • infrastructure/jwt/: JwtClaimsExtractorTenantAwareJwtAuthenticationConverter(JWT からテナント文脈付きの認証情報へ変換)
  • infrastructure/security/: Spring Security 設定
  • domain/model/PermissionRule.kt: ResourceType + Action + Scope の3値からなる sealed class。「文字列処理は一切ビジネスロジックで行わない」とコメントされており、DB 文字列表現への変換は Mapper 層に閉じている

Frontend 構造

backend の auth(role を含む)は frontend では authrole の2モジュールに分かれている。

  • app/modules/auth/: composables/useDesktopAuth.ts(Tauri デスクトップの認証)、useDesktopSessionGuard.tsusePlatformAdmin.tsuseSetup.ts(初期セットアップ)、repositories/AuthSetupRepository.ts
  • app/modules/role/: composables/useRoles.tsuseRoleForm.tsuseRoleHierarchy.tsuseRolePermissions.ts(ロール CRUD・階層・権限編集の UI ロジック)

他モジュールとの辺

  • 全モジュール: @PreAuthorize + AuthorizationService によるチェックはほぼ全 Controller が通る(認可モデル 参照)
  • membership / tenant(frontend tenant): テナントメンバーシップ・招待は別モジュール。ロール割り当ての対象になるユーザーはここから来る
  • office(WOPI): WopiAccessTokenAuthentication のようにモジュール固有の認証方式が authAuthentication 実装として追加されることがある(SandboxRenderAuthenticationServiceAccountAuthenticationMediaAccessAuthentication など多数)
  • rolesync: 外部システムとのロール同期(RoleSyncResult モデルはこの auth 内にある)

テナント・主キーの指定はエンドポイントの種類ごとに規約が固定されている(ルート CLAUDE.md 参照):in-tenant エンドポイントは X-Tenant-Id ヘッダー(TenantContextFilter が RLS context を設定)、platform-admin の横断エンドポイントは /tenants/{tenantId}/ パス変数。query param でテナントを渡すのはどちらの規約にも当てはまらない逸脱として禁止されている。新しい認可判定を書く前に、同種 Controller が @PathVariable@RequestHeader のどちらでテナントを取っているかを確認してから合わせること。