3 minute read

요즘 RAG 데모를 많이 봄. 회사 문서를 임베딩하고 사용자 질문에 답하는 시스템. 잘 만든 데모는 인상적임. 그런데 어느 순간부터 같은 위화감이 반복됨.

“이 시스템, 누구든 모든 문서를 볼 수 있다고 가정하고 있구나.”

엔터프라이즈에서 이런 시스템은 절대 도입되지 않음. 5년간 ADFS · SAML · OIDC 기반 인가 시스템을 운영하면서 그 이유를 매일 보고 있음. 이 글은 RAG 커뮤니티에서 잘 다뤄지지 않는 “권한 공백” 이야기, 그리고 직접 풀어보고 있는 사이드 프로젝트 소개임.

1. RAG 데모는 권한이 없다

대부분의 RAG 튜토리얼이 그리는 파이프라인은 단순함.

사용자 질문  →  임베딩 검색  →  상위 K개 청크  →  LLM  →  답변

이 구조는 “코퍼스에 있는 모든 문서는 모든 사용자가 볼 수 있다”는 강력한 전제를 가짐. 개인 사이드 프로젝트와 PoC로는 충분함. 하지만 회사에 도입하는 순간 — 일반 직원이 임원 인사평가나 법무 케이스 문서를 검색 결과로 받게 됨. 데이터 유출임.

LangChain · LlamaIndex 사례 글들을 살펴봐도 권한은 대개 “metadata filter 한 줄 추가하시면 됩니다” 정도로 처리됨. 부서 코드 같은 단일 차원 필터링은 그렇게 됨. 그런데 실제 엔터프라이즈 권한은 그렇게 단순하지 않음.

2. IAM 엔지니어가 본 권한의 실체

회사의 권한은 최소 세 가지 차원이 동시에 작동함.

RBAC (Role-Based Access Control)

“팀장 이상은 팀원 인사평가를 본다.” 가장 익숙한 패턴. 역할에 기반한 접근.

ReBAC (Relationship-Based Access Control)

“보안 사고 문서는 보안팀이 부서를 가로질러 본다. 임원도 기본으로는 못 본다.” 조직 계층의 정점이 모든 것을 보지 않음. 보안 같은 횡단적(cross-functional) 역할은 계층이 아닌 기능과의 관계로 접근권을 가짐.

ABAC (Attribute-Based Access Control)

“외부 컨설턴트는 자기 프로젝트 + 계약 기간 내에서만 본다.” 사용자 속성(project_scope, start_date, end_date)과 문서 속성(project_id)을 매칭해서 접근권을 동적으로 평가함.

그리고 이들 위에 추가 레이어가 쌓임.

  • Self-access carve-out“본인의 인사평가나 경비처리는 누구든 본다.” 개인정보 주체 권리. GDPR · PIPA의 기본 요구사항임.
  • Case-based parties“이 법무 사건은 명시된 당사자만 본다.” 문서 자체가 “누가 볼 수 있는지”를 정의함.
  • Audit logging enforcement“감사 인력의 모든 접근은 별도 감사 로그에 남는다.”

ADFS Claim Rules와 SAML Attribute Filtering으로 이런 패턴들을 매일 짜는 사람 입장에서 RAG 시스템에 “단일 부서 필터”가 권한이라는 말은 너무나 빈약한 추상화임.

3. 그래서 무엇이 필요한가

권한이 검색 파이프라인의 별도 단계로 들어가야 함. 메타데이터 한 컬럼이 아니라.

        사용자 질문 + JWT
              │
              ▼
        [Auth 노드]              ← JWT 검증, claims 파싱
              │
              ▼
        [Query Rewrite 노드]    ← 권한 컨텍스트 반영해서 질의 변형
              │
              ▼
        [Retrieval 노드]         ← DB 레벨 권한 필터 + 의미 검색
              │
              ▼
        [Re-ranking 노드]        ← 권한 통과 문서 중 관련성 순위
              │
              ▼
        [Answer 노드]            ← LLM 답변 (필요 시 부인 응답 생성)
              │
              ▼
        [Audit Logger]           ← cross-cutting, 모든 접근 기록

핵심은 JWT claims가 RAG 파이프라인 전체를 가로지르는 컨텍스트라는 점임. 사용자의 role, department, project_scope, clearance_level이 검색 단계의 필터 조건이 되고, 답변 생성 단계의 거부 응답 트리거가 되고, 감사 로깅의 메타데이터가 됨.

LangGraph는 이런 노드 기반 구성에 잘 맞음. 각 단계가 명시적이고, 권한 검증이 어디서 일어나는지 그래프에서 보임. 단순 chain보다 감사 가능성(auditability)이 훨씬 좋음.

또 하나 중요한 점 — 권한 필터링은 DB 쿼리에서 일어나야 함. 검색기가 모든 문서를 받아서 사후에 걸러내는(post-filter) 방식은 timing 차이로 “이 문서가 존재하긴 하는구나”를 누출시킬 수 있음. 사이드 채널 공격의 시작점임.

4. permission-aware-rag 프로젝트

이 문제를 직접 풀어보기로 함. GitHub에 저장소를 열었음.

🔗 parkjongmin-ddam/permission-aware-rag

약 12주 일정으로 진행 중이고, 현재 M1 (디자인) 단계가 거의 끝남.

  • 가상 회사 BWCorp 시나리오 정의 — 페르소나 7종, 카테고리 6종, sub-type 24종
  • 권한 매트릭스 + 6개 조건부 규칙 + 평가 순서
  • 자주 깨지는 엣지케이스 5개 (메타데이터 누락 / 다중 태그 / 충돌 해결 / 문서 존재 누출 / 질의 패턴 사이드 채널)
  • 45개 샘플 문서로 모든 권한 패턴을 구체적으로 demonstrate
  • 영문 / 한글 이중 명세

다음 단계는 이렇게 이어짐.

Milestone 내용 예상 시점
M2 FastAPI + pgvector + LangGraph 3노드 e2e 4주차
M3 BGE Reranker v2 + RAGAS 평가 7주차
M4 AWS ECS Fargate 배포 + CI/CD 10주차
M5 Polish & 데모 영상 12주차

진행 과정은 이 블로그에 연재할 계획임. 다음 글은 M2의 핵심 — JWT claims 기반 권한 필터링을 LangGraph 노드로 구현하기를 다룰 예정임.

마무리

RAG는 흥미로운 기술이고 LLM 시대의 핵심 인프라가 되어가고 있음. 그런데 엔터프라이즈 도입의 가장 큰 장벽이 “권한 모델을 어떻게 RAG와 결합할 것인가”라는 사실은 커뮤니티에서 제대로 다뤄지지 않고 있다고 느낌.

이 프로젝트는 IAM 백그라운드에서 그 공백을 직접 만지는 시도임. IAM 쪽이든 RAG 쪽이든 관심 있으신 분의 피드백 언제든 환영.


이 글은 permission-aware-rag 프로젝트 연재 시리즈의 1편임.

  • 1편: 왜 권한 기반 RAG인가 (현재 글)
  • 2편 (예정): JWT claims 기반 권한 필터링 — LangGraph 구현
  • 3편 (예정): RAG에서의 사이드 채널 — 권한 누수의 미묘한 경로들
  • 4편 (예정): pgvector vs Qdrant — 권한 필터링 관점에서의 비교
  • 5편 (예정): RAGAS로 권한 인식 RAG 평가하기

Comments