인증(Authentication)과 권한 부여(Authorization)의 이해
인증은 ‘당신이 누구인가’를 확인하며, 권한 부여는 ‘무엇을 할 수 있는가’를 결정합니다. Rails에서는 Devise가 인증에, Pundit이 권한 부여에 주로 사용됩니다.
기존 Rails 권한 부여 방식의 한계
- 암묵적 권한 부여: 쿼리 스코프를 이용한 초기 방식은 단순하지만 비즈니스 로직과 권한 규칙이 혼합되어 확장성이 떨어집니다.
- CanCan:
ability.rb
로 규칙을 중앙화했으나, 앱 규모가 커지면 파일이 비대해져 관리 및 리팩토링이 매우 어려워집니다. - Pundit: 리소스별 정책 클래스로 유연성을 제공하지만, 대규모 앱에서는 다음과 같은 한계에 직면합니다: 리팩토링의 어려움(암묵적 의존성), 성능 문제(N+1 쿼리, 캐싱 어려움), 감사 및 디버깅의 어려움(접근 원인 추적 불가), 역방향 조회 불가(데이터 미저장).
Fine-Grained Authorization (FGA) / 관계 기반 접근 제어 (Relationship-Based Access Control)의 도입
Google Zanzibar 프로젝트 기반의 FGA는 엔티티 간의 관계를 ‘튜플(subject, relationship, object)’ 형태로 저장하고, 이 관계 데이터를 그래프로 활용하여 권한 규칙을 정의합니다. 권한 확인은 그래프 내 특정 경로 존재 여부로 판단합니다.
granity
젬을 통한 Rails 구현
granity
는 Rails에서 FGA를 지원하는 젬입니다. 스키마 정의를 통해 리소스, 관계, 권한을 명시하고 튜플을 생성하여 관계 데이터를 관리합니다.
FGA의 장점
- 쉬운 리팩토링: 명시적 스키마와 그래프 객체를 통해 의존성 파악이 용이합니다.
- 향상된 성능: ID 기반 튜플 탐색 및 스마트 캐싱을 통해 불필요한 데이터 로딩과 재평가를 줄입니다.
- 뛰어난 감사 가능성: 권한 확인 시 접근 경로를 반환하여 디버깅 및 감사에 용이합니다.
- 역방향 조회 지원: 관계 데이터를 저장하므로 특정 권한을 가진 주체를 쉽게 조회할 수 있습니다.
외부 FGA 서비스
OpenFGA, OSO, Permit.io 등은 분산 시스템 환경에서 권한 부여를 중앙 집중화하고 최적화된 성능을 제공하는 대안입니다.