2025-10-01 22:16

Tags: 데이터베이스

RLS(Row-Level Security, 행 수준 보안)

  • 데이터베이스 자체에서 데이터 접근 권한을 행(row) 단위로 제어하는 강력한 보안 기능이다.
  • 애플리케이션 코드 수정 없이 중앙화된 보안 정책을 통해 여러 사용자와 역할을 관리하며, 복잡한 데이터 접근 제어 요구사항을 해결한다.
  • 데이터베이스에 접속한 사용자가 누구인지에 따라, 같은 쿼리를 실행하더라도 서로 다른 결과(행의 집합)를 보도록 만드는 기능이다.
  • 마치 보이지 않는 WHERE 절이 모든 쿼리에 자동으로 추가되는 것과 같다.

핵심 구성 요소: 보안 정책(Security Policy)

  • 특정 테이블에 대해 특정 사용자가 어떤 조건의 행에 접근할 수 있는지를 정의하는 규칙의 집합이다.
  • 정책(Policy):
    • 규칙 그 자체. 예를 들어, “사용자는 자신의 데이터만 볼 수 있다”는 정책.
  • 대상 테이블(Target Table):
    • 정책이 적용될 테이블. 예를 들어, employees 테이블.
  • 조건(Predicate / Expression):
    • 행의 접근 가능 여부를 판단하는 TRUE 또는 FALSE를 반환하는 조건식.
    • 이 조건식이 RLS의 핵심이다. employee_id = current_user_id() 와 같은 형태다.
  • 적용 대상 명령어(Commands):
    • SELECT, INSERT, UPDATE, DELETE 등 어떤 명령어에 정책을 적용할지 지정한다.
  • 적용 대상 역할(Roles):
    • 특정 데이터베이스 역할(사용자 그룹)에만 정책을 적용할 수 있다. 동작 메커니즘: 쿼리 재작성(Query Rewriting)
  • 사용자가 쿼리를 실행하면, 데이터베이스의 옵티마이저(Query Planner)는 쿼리를 분석하고 실행 계획을 세운다.
  • 이때, RLS 정책이 활성화된 테이블에 대한 쿼리가 감지되면 옵티마이저는 다음과 같은 일을 수행한다.
  1. 사용자가 SELECT * FROM sales_records; 라는 쿼리를 실행한다.
  2. 옵티마이저는 sales_records 테이블에 “팀장은 자기 팀의 데이터만 볼 수 있다”는 RLS 정책이 걸려있는 것을 확인한다.
  3. 정책의 조건식은 team_id = get_user_team_id(current_user) 이다.
  4. 옵티마이저는 사용자의 원래 쿼리를 내부적으로 다음과 같이 재작성한다. SELECT * FROM sales_records WHERE team_id = get_user_team_id(current_user);
  5. 재작성된 쿼리에 대한 최적의 실행 계획을 수립하고 실행한다.