role·권한·RLS
“작업 테이블을 조회할 수 있다”와 “내 작업만 조회할 수 있다”는 다른 요구다. 전자는 GRANT, 후자는 행 정책으로 표현한다. 둘을 함께 만족해야 접근이 가능하다.
이 장에서 처음 나오는 말3개
GRANT- role에 객체 사용·조회·변경 등의 권한을 부여한다.
RLSRow-Level Security- 쿼리를 실행하는 신원에 따라 접근 가능한 행을 제한하는 기능.
owner객체 소유자- 테이블 등 객체를 소유하고 정의를 관리하는 role. 일반 실행 role과 분리한다.
앱의 권한을 나누는 이유
섹션 제목: “앱의 권한을 나누는 이유”관리자 role로 개발하면 모든 쿼리가 성공해 권한 오류를 늦게 발견하기 쉽다.
실제 앱은 필요한 읽기·쓰기만 허용하고, 테이블을 변경하는 마이그레이션 role은 별도로 둔다.
LOGIN 가능 여부와 객체 권한도 별개다. 로그인할 수 있어도 특정 테이블을 읽지 못할 수 있다.
(GRANT,
role)
내 작업만 보이게 하기
섹션 제목: “내 작업만 보이게 하기”공통 예제의 일회용 로컬 DB에서 관리자 postgres로 실행한다.
테스트용 alice role은 새로 만들고 마지막에 트랜잭션 전체를 취소한다.
BEGIN;CREATE ROLE alice NOLOGIN;GRANT USAGE ON SCHEMA public TO alice;GRANT SELECT, UPDATE (done) ON public.tasks TO alice;
ALTER TABLE public.tasks ENABLE ROW LEVEL SECURITY;CREATE POLICY own_tasks ON public.tasks TO alice USING (assignee = current_user) WITH CHECK (assignee = current_user);
SET LOCAL ROLE alice;SELECT id, title FROM public.tasks ORDER BY id;UPDATE public.tasks SET done = true WHERE id = 2 RETURNING id;ROLLBACK;SELECT에는 Alice의 ID 1만 보이고, Bob의 ID 2를 수정하는 UPDATE는 0행이다. RLS가 행을 숨기는 경우 반드시 권한 오류가 나는 것은 아니다. ROLLBACK하면 role·GRANT·정책·RLS 활성화가 모두 취소된다.
여기서는 PostgreSQL role 이름을 담당자와 직접 비교했다. 앱 사용자마다 DB role을 만들라는 설계가 아니라 SQL만으로 정책의 효과를 보려는 작은 예다.
USING과 WITH CHECK
섹션 제목: “USING과 WITH CHECK”USING은 기존 행을 보거나 변경 대상으로 삼을 수 있는지 판단한다.
WITH CHECK는 INSERT·UPDATE 뒤 새 행의 상태가 정책을 만족하는지 판단한다.
예를 들어 자기 행을 다른 담당자 소유로 바꾸는 권한까지 허용하려면 그 결과가 정책상 합당한지도 따져야 한다.
(CREATE POLICY)
RLS를 켜고 적용되는 정책을 만들지 않으면 일반 role에는 기본적으로 행 접근이 거부된다.
하지만 superuser와 BYPASSRLS role은 우회하고, 소유자도 보통 우회한다.
FORCE ROW LEVEL SECURITY는 소유자에게도 정책을 적용할 때 쓰지만 superuser 우회를 없애지 않는다.
따라서 앱이 실제로 쓰는 role로 테스트해야 한다.
(행 보안 정책)
Supabase에서는 신원이 어디서 오나
섹션 제목: “Supabase에서는 신원이 어디서 오나”Supabase의 API 요청에서는 인증 토큰과 DB role·요청 문맥이 연결된다.
auth.uid()를 쓰는 정책은 이 연결을 전제로 하며 순수 PostgreSQL의 기본 함수가 아니다.
일반 PostgreSQL에 같은 SQL을 복사하면 동작하지 않는다.
(Supabase RLS)
서버가 전달하는 사용자 문맥은 검증된 인증 정보에서 만들어야 한다. 임의 클라이언트가 바꿀 수 있는 세션 변수만으로 사용자 신원을 보증할 수는 없다. 풀링 환경에서는 요청이 끝나면 문맥도 초기화되어야 한다.
이해 확인: 관리자 SQL Editor에서 모든 행이 보이면 RLS가 고장 난 것일까? 우선 실행 role이 정책을 우회하는지 확인한다. 일반 사용자 요청과 같은 신원으로 재현해야 한다.