[미래를 담아낸 뼈대 3/7] 관계로 풀어낸 권한

HR에서 가장 어려운 문제
이벤트가 신뢰성 있게 흐르는 레일이 깔렸을 때, flex가 가장 먼저 올린 것은 HR에서 가장 어려운 문제였습니다. 바로 권한이죠.
권한이 왜 어려운지, 구체적인 상황을 하나 그려보겠습니다.
"구성원 A는 인사팀 소속이면서, 마케팅 부서의 매니저를 겸임하고 있고, 신규 입사자 온보딩 프로젝트에 열람자로 참여하고 있다. A가 마케팅 부서 소속 구성원 B의 급여 명세서를 볼 수 있는가?"
이 질문에 답하려면, 단순히 "A가 어떤 역할인가"만으로는 부족합니다. A와 B의 조직적 관계, A가 속한 조직의 급여 열람 권한 범위, 매니저 역할에 부여된 하위 구성원 데이터 접근 정책, 급여 데이터의 민감도 등급 — 여러 도메인에 걸친 정보를 종합해야 합니다.
전통적인 RBAC(Role-Based Access Control)은 이 복잡성을 감당하기 어렵습니다. RBAC은 "이 사람이 어떤 역할인가"를 기준으로 권한을 판단합니다.
관리자, 매니저, 일반 구성원.
역할이 명확하고 고정적인 환경에서는 잘 작동합니다. 하지만 HR SaaS에서는 한 사람이 여러 역할을 동시에 갖고, 역할이 조직 구조에 따라 다르게 해석되며, 권한의 범위가 조직 관계에 따라 동적으로 변합니다. RBAC으로 이걸 표현하려면 역할의 수가 폭발적으로 늘어나고, 역할 간 관계를 표현할 방법이 없어서 예외 처리가 끝없이 추가됩니다.
ReBAC — "역할"이 아니라 "관계"를 묻는다

flex는 이 문제를 ReBAC(Relationship-Based Access Control)과 OpenFGA로 풀었습니다.
ReBAC의 핵심 아이디어는 간단합니다. "이 사람이 어떤 역할인가"가 아니라, "이 사람과 이 자원이 어떤 관계인가"를 질문합니다.
구체적으로 보겠습니다. RBAC에서는 "A에게 매니저 역할을 부여하고, 매니저 역할에 급여 열람 권한을 연결"합니다. 단순하지만, A가 어떤 조직의 매니저인지, 그 매니저 역할이 어디까지의 구성원에게 적용되는지를 표현할 수 없습니다. ReBAC에서는 "A는 마케팅 부서의 매니저이다", "마케팅 부서의 매니저는 해당 부서 구성원의 급여를 볼 수 있다"라는 관계를 직접 표현합니다. 관계의 종류(소속, 매니저, 열람자 등)와 대상(조직, 구성원, 프로젝트 등)이 모두 명시적입니다.
OpenFGA는 이 ReBAC 모델을 실행하는 엔진입니다. 관계 를 저장하고, "A가 B의 급여를 볼 수 있는가?"라는 질문에 대해 관계 그래프를 탐색하면서 답을 줍니다. 조직 구조가 바뀌거나 구성원의 역할이 변경되면, 해당 관계만 업데이트하면 됩니다. 수백 개의 역할을 관리하는 대신, 실제 비즈니스 관계를 그대로 모델링할 수 있습니다.
HR처럼 관계의 종류가 다양하고 동적으로 변하는 도메인에서, ReBAC은 RBAC보다 훨씬 유연하면서도 구조적입니다. "유연하다"는 건 아무 규칙 없이 자유롭다는 뜻이 아니라, 현실 세계의 관계 구조를 있는 그대로 표현할 수 있다는 뜻입니다.
인가 파이프라인 한눈에 보기

이미 깔린 레일 위에 올린 것
여기서 이 시리즈의 인과관계가 다시 드러납니다.
ReBAC 기반 인가 시스템이 제대로 작동하려면, 관계 변경이 실시간으로 반영되어야 합니다. 조직이 개편되었는데 인가 시스템에는 여전히 이전 조직 구조가 남아 있다면, 퇴사한 사람이 여전히 데이터에 접근할 수 있거나, 새 로 부임한 매니저가 팀원의 정보를 볼 수 없는 상황이 벌어집니다.
flex에서 이 관계 변경 이벤트가 흐르는 파이프라인은 이렇습니다.
조직/역할 변경 → DB 트랜잭션 + Outbox 기록 → Debezium CDC → Kafka → Authorization Consumer → OpenFGA
어디서 많이 본 구조 아닌가요? 2화에서 이야기한 Transactional Outbox + Debezium CDC + Kafka 파이프라인을 그대로 활용하고 있습니다. 새로운 메시징 인프라를 구축한 게 아닙니다. 이미 모든 도메인이 사용하고 있는, 신뢰성이 검증된 이벤트 스트리밍 레일 위에 인가 시스템을 올린 겁니다.
이 연결이 중요한 이유는, "인프라 투자의 복리 효과"를 보여주기 때문입니다. 2화에서 이야기한 이벤트 인프라는 원래 도메인 간 데이터 전달을 위해 만들어졌습니다. 하지만 그 인프라가 신뢰성 있게 작동하고 있었기 때문에, 인가라는 전혀 다른 문제를 풀 때도 기반 인프라를 새로 만들 필요가 없었습니다. 앞의 투자가 다음 문제의 출발점을 높여준 것입니다.
왜 OpenFGA인가
ReBAC을 구현할 엔진을 고를 때도 선택지가 있었습니다. 자체 구현, Casbin, OPA, 그리고 OpenFGA. 자체 구현은 관계 그래프 탐색의 성능과 정합성을 직접 보장해야 하는 부담이 컸습니다. Casbin은 Policy 기반으로 유연하지만, HR SaaS에서 필요한 깊이 있는 관계 체인(조직 → 하위조직 → 구성원 → 데이터)의 재귀적 탐색에 구조적 한계가 있었습니다. OPA/Rego는 범용 정책 엔진이지 관계 모델링 전용 도구가 아니었습니다.
OpenFGA는 Google Zanzibar 논문의 구현체로, 관계 튜플 저장과 그래프 탐색에 특화되어 있습니다. "A는 마케팅 부서의 매니저이다"를 'user:A, relation:manager, object:org:marketing'이라는 튜플로 표현하고, "A가 B의 급여를 볼 수 있는가?"라는 질문에 대해 관계 체인을 따라가며 답을 줍니다. 관계 모델을 DSL로 선언하면, 엔진이 탐색 전략을 최적화합니다. HR의 복잡한 조직 구조를 있는 그대로 모델링하면서도 성능을 유지할 수 있는 구조였습니다.
전사적 인가가 가능했던 이유
HR SaaS의 권한 문제는 어느 한 팀이 해결할 수 있는 성격이 아닙니다. 조직 도메인, 구성원 도메인, 급여, 평가, 채용 — 모든 도메인이 권한과 얽혀 있습니다. 인가 시스템을 설계하려면 각 도메인이 어떤 관계를 가지고 있는지, 어떤 데이터에 어떤 수준의 접근 제어가 필요한 지를 전체적으로 파악해야 합니다.
이 파악이 가능했던 건, 1화에서 이야기한 구조의 일관성 덕분입니다. 모든 도메인이 같은 헥사고날 구조를 따르기 때문에, 각 도메인의 Port를 조사하면 "어떤 데이터가 어떤 경로로 접근되는지"를 기계적으로 파악할 수 있었습니다. 구조가 다른 10개의 서비스를 각각 분석해야 했다면, ReBAC 같은 전사적 인가 체계를 설계하겠다는 시도 자체가 나오기 어려웠을 겁니다.
다음 화에서는,
이 투자의 복리가 돌아옵니다. 클라우드를 바꿔야 할 때, 도메인 코드를 한 줄도 고치지 않아도 되는 이유를 주제로 이야기해 보겠습니다.

