Skip to content

feat: VM 인가를 자원별 접근 목록으로 전환 - #31

Merged
yessjun merged 3 commits into
mainfrom
refactor/vm-access-resolver
Aug 9, 2026
Merged

feat: VM 인가를 자원별 접근 목록으로 전환#31
yessjun merged 3 commits into
mainfrom
refactor/vm-access-resolver

Conversation

@yessjun

@yessjun yessjun commented Aug 9, 2026

Copy link
Copy Markdown
Member

📝 작업내용

  • VM 인가 판정을 열 개 서비스에서 해석기 하나로 이관
  • 자원 역할 ResourceRole 4단 신설, 그룹 역할은 OWNER/MEMBER 2단으로 축소
  • 자원별 접근 목록 resource_access_grants 신설, 자원 종류 판별자를 갖고 이번 라운드는 VM만 연결
  • 기존 VM의 현 구성원을 현 등급으로 옮기고 그룹 역할을 2단으로 접는 변환을 V70에 포함
  • VM 승인 시 신청자를 자원 소유자로 시드하고 승인 시점에 신청자 자격 재확인
  • 그룹 구성원 제거와 계정 탈퇴 시 해당 사용자의 부여 연쇄 삭제
  • 그룹 소유자 복수 허용, 마지막 한 명의 강등과 제거 차단
  • 접근 권한 CRUD 4개 op 신설, 쓰기 3종은 재인증 대상
  • API 명세 v0.32.0, 권한 매트릭스에 자원 스코프 토큰을 신설해 144 op
  • VM 목록과 도메인 목록에서 부여 없는 VM을 서버가 이름, 상태, 소유자로 축소
  • VM 알림 수신자를 그룹 역할 기준에서 자원 접근 목록 기준으로 재정의

⭐️ 검증

  • scripts/verify.sh 통과, mvn verify와 테스트 701개
  • 권한 매트릭스와 런타임 리플렉션 대조 144 op
  • 자원 스코프 op 전수를 등급 4단, 미등재 구성원, 비구성원에 대해 MockMvc로 검증
  • 선행 리팩터 단계는 API 명세 스냅샷 무변경과 테스트 557개로 행동 불변 확인
  • V70 이행 검증 어서션을 마이그레이션 안에 포함

💬 리뷰 포인트

  • 그룹 소유자 상시권을 등급으로 환산하지 않고 별도 불리언으로 둔 판정 구조
  • V70에 스키마와 이행 변환을 함께 담은 구성과 검증 어서션의 범위
  • 목록 축소를 관리자 화면과 공유하는 DTO의 nullable 분기로 처리한 방식
  • 알림 수신자를 소유자, 책임자, 전체 셋으로 나눈 구분

yessjun added 3 commits August 9, 2026 14:59
Ten services each carried their own copy of the same three steps: load the
VM, look up the requester's role in its owning group, choose between the
masking 404 and a 403. Three of them were byte-identical apart from the
message text, and the 404 factory existed nine times over.

They now ask one resolver, which is what lets the coming per-resource
access list replace the role lookup without touching any caller. Behavior
is unchanged: every refusal keeps its status, code and wording, and each
call site keeps its own 403 text because that text names the operation.

Admin surfaces stay out of it deliberately. Their scope is the
organisation rather than group membership, and folding the two together is
how a bypass gets written by accident.
A VM role and a group role were the same enum, which only held while the
group role was the sole axis. Containers and API keys are next, and neither
has a group meaning, so the resource axis gets ResourceRole and the group
axis keeps GroupMemberRole.

Only the type moves here; the values, the ladder and every decision stay as
they were. The resolver still reads the group ladder and maps it across,
which is the one line the access list replaces next.

VmDetail.myGroupRole becomes myResourceRole, since after this it answers a
different question: what the requester may do to this VM, not what they are
in its group.
A rung in the owning group no longer implies reaching that group's VMs.
Each VM carries its own access list, a VM starts with only its requester
on it, and a member the list does not name sees that it exists and nothing
else.

The list is keyed by resource type rather than by vm_id. Containers, GPU
allocations and LLM API keys are all decided additions that ask the same
question, and each should arrive as a value plus an adapter rather than as
another table with the same five columns.

Group standing keeps three powers over the group's resources: see they
exist, delete them, and manage who reaches them. It is held as a flag
rather than a rung so that nothing inside a VM can be reached by owning
its group; an owner who needs inside grants themselves, and that leaves a
break-glass record.

V70 carries the schema and the move together, because the new judgment
reads grants: any gap between the two would be a gap in which nobody can
reach their own VM. It checks each grant against the membership it came
from while both still exist, since counting rows cannot catch a wrong rung.
@yessjun
yessjun merged commit 8d2b289 into main Aug 9, 2026
1 check passed
@yessjun
yessjun deleted the refactor/vm-access-resolver branch August 9, 2026 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant