RBAC
Lumie의 authorization 모델은 계층적으로 구성됩니다.
- 거친 수준의 identity와 role은 auth 모듈과 JWT claim에서 옵니다
- 테넌트 범위 staff permission은 staff 모듈에 존재합니다
- 모듈 service는 ownership, 수명주기, quota 규칙 같은 business-state check를 추가합니다
이 페이지는 현재 모델을 다루는 레퍼런스 문서입니다.
소스 경로
| 경로 | 역할 |
|---|---|
libs/common/src/main/java/com/lumie/common/auth/Role.java | 전역 역할 hierarchy와 legacy alias parsing |
libs/common/src/main/java/com/lumie/common/auth/AuthorizationGuard.java | 공용 OWNER-only guard |
modules/staff/src/main/java/com/lumie/staff/domain/entity/Permission.java | 테넌트 범위 권한 카탈로그 |
modules/staff/src/main/java/com/lumie/staff/domain/entity/StaffPermission.java | staff-to-permission assignment 행 |
modules/staff/src/main/java/com/lumie/staff/domain/vo/AccessLevel.java | permission access level enum |
modules/staff/src/main/java/com/lumie/staff/application/service/StaffCommandService.java | staff 수명주기 작업에서 역할 hierarchy 강제 |
modules/staff/src/main/java/com/lumie/staff/adapter/in/web/PermissionController.java | permission 쿼리 인터페이스 |
적용 계층
전역 역할 계층
공용 Role enum은 네 가지 상위 역할을 정의합니다.
| 역할 | 권한 수준 | 일반적인 의미 |
|---|---|---|
OWNER | 가장 높음 | 테넌트 OWNER |
MANAGER | 높음 | 관리 staff |
INSTRUCTOR | 중간 | 교사 또는 일반 staff 역할 |
STUDENT | 가장 낮음 | student-facing user |
중요한 helper method 두 가지:
hasAuthority(required)는 같은 권한이거나 더 높은 권한을 뜻합니다canManage(target)은 대상보다 명확히 높은 권한만 허용합니다
Role.fromString(...)은 또한 legacy alias를 보존합니다.
ADMIN -> INSTRUCTORDEVELOPER -> MANAGER
이 alias 동작은 과거 데이터나 오래된 client가 예전 역할 이름을 여전히 보낼 때 중요합니다.
테넌트 범위 Staff 권한 모델
staff 모듈은 staff 사용자에 대해 두 번째 authorization 계층을 추가합니다.
| 유형 | 저장 역할 |
|---|---|
Permission | code, name, category, description를 가진 catalog 행 |
StaffPermission | staff_id + permission_code로 식별되는 join 행 |
AccessLevel | NONE, READ, WRITE |
중요한 경계 사실:
Permission은TenantScopedEntity를 상속하므로 권한 카탈로그도 테넌트 범위입니다.StaffPermission은 base class를 상속하지 않지만, insert 시tenant_id를 명시적으로 씁니다.- permission 쿼리 엔드포인트는
/v1/permissions아래에 있습니다. - staff permission 할당 흐름은 staff service에 있으며, Spring Security가 이를 전역적으로 자동 적용하지는 않습니다.
현재 백엔드가 RBAC를 적용하는 방식
계층 1: 인증과 상위 역할 구분
JwtAuthenticationFilter는 사용자 role을UserContextHolder에 기록합니다.- Spring Security는
/internal/**를 syntheticROLE_INTERNAL에 매핑합니다.
계층 2: 명시적인 공통 가드
AuthorizationGuard.requireOwner()는 homepage 게시나 테넌트 관리, 내보내기
일부처럼 OWNER만 수행할 수 있는 작업에 사용됩니다.
계층 3: 모듈 서비스 규칙
가장 분명한 예시는 StaffCommandService입니다.
- 생성은
MANAGER또는INSTRUCTOR만 허용 - 요청자는 자신을 관리할 수 없음
- 요청자는
canManage(...)를 통해 대상보다 명확히 높은 권한을 가져야 함 - 역할 check를 통과해도 billing quota와 배정된 class가 작업을 막을 수 있음
중요한 아키텍처 포인트는 이것입니다. RBAC만으로 authorization 결정이 끝나지 않습니다. 비즈니스 불변식은 역할 평가 이후에도 계속 적용됩니다.