Back-End/Supabase

Supabase에서의 RLS(Row-Level Security)

봉의일상 2025. 5. 7. 15:16

Supabase를 쓰다 보면 반드시 마주치게 되는 개념 중 하나가 바로 RLS(Row-Level Security)입니다.

이 글에서는 RLS가 무엇이고, 왜 필요한지, Supabase에서는 어떻게 설정하고 활용하는지를 정리했습니다.


RLS란 무엇인가?

RLS(Row-Level Security)는 테이블의 각 행(row)에 대해 접근 권한을 제어하는 보안 기능입니다. PostgreSQL의 고급 기능 중 하나로, Supabase는 이 기능을 적극 활용해 사용자 단위 데이터 보호를 제공합니다.

예를 들어, 사용자가 자신의 할 일 목록만 조회할 수 있게 하려면 어떻게 해야 할까요?

전통적인 백엔드라면 쿼리마다 user_id 조건을 직접 걸어줘야겠지만, RLS를 활용하면 DB 레벨에서 정책(policy)을 설정해서 자동으로 필터링할 수 있습니다.


RLS가 없으면 생기는 문제

// 로그인된 유저가 아니라도 전체 todos를 다 조회할 수 있음
const { data } = await supabase.from('todos').select('*');

이런 코드가 있다면 모든 유저의 데이터가 노출될 수 있습니다.


Supabase에서의 RLS 활용

Supabase는 로그인한 사용자의 ID를 auth.uid()로 제공합니다. 이를 활용해 RLS 정책을 구성할 수 있습니다.

1. RLS 활성화

alter table todos enable row level security;

2. 행 단위 접근 정책(policy) 추가

create policy "Users can view own todos"
on todos for select
using (auth.uid() = user_id);

3. 삽입/수정 권한 제어도 가능

create policy "Users can insert their own todos"
on todos for insert
with check (auth.uid() = user_id);

프론트엔드에서는 어떻게 달라질까?

RLS 정책이 적용되면, 프론트엔드에서 다음처럼 단순한 쿼리를 날려도 안전합니다.

const { data } = await supabase.from('todos').select('*');

이제는 이 쿼리가 자동으로 로그인한 사용자에 해당하는 데이터만 반환합니다.


RLS는 Supabase에만 있는 개념일까?

아닙니다. RLS는 PostgreSQL의 기본 기능입니다. Supabase는 이를 래핑(wrapping)해서 더 쉽게 다룰 수 있도록 콘솔 UI와 API에서 제공할 뿐입니다.

구분 설명
Supabase PostgreSQL 기반, auth.uid() 제공, RLS 정책 쉽게 구성 가능
PostgreSQL 원래 RLS 기능이 존재, 직접 SQL로 구성 필요

Supabase에서 RLS를 강조하는 이유

Supabase는 PostgreSQL 기반이기 때문에, PostgreSQL의 RLS 기능을 그대로 활용할 수 있습니다. 특히 BaaS 백엔드에서 클라이언트가 직접 쿼리를 날리는 구조이다 보니, RLS 없이 보안사고가 발생할 가능성이 높습니다. 그래서 RLS가 보안 핵심 기능으로 강조되는 것입니다.

 

요약

  • RLS는 사용자마다 다른 행(row)에 접근하도록 제한하는 데이터 보안 기능입니다.
  • Supabase에서는 auth.uid()를 통해 로그인 사용자의 ID를 받아 정책을 구성할 수 있습니다.
  • 프론트엔드에서는 단순한 쿼리만 작성해도 자동으로 보안이 적용되어 편리하고 안전합니다.