RLS 뜻: 데이터베이스의 ‘행 단위 보안’을 쉽게 설명하면

RLS는 Row Level Security의 약자로, 같은 데이터베이스 테이블에서도 사용자마다 조회·추가·수정·삭제할 수 있는 행을 다르게 만드는 보안 기능이에요. 로그인은 사용자가 누구인지 확인하고 RLS는 그 사용자가 접근할 데이터를 정합니다.

핵심 요약

AI로 웹앱을 만들다 보면 이런 문장을 만납니다.

RLS를 활성화하세요.
RLS 정책이 없어서 데이터가 보이지 않습니다.
사용자별 RLS policy를 추가해야 합니다.

로그인이나 데이터베이스를 만들고 있었는데 갑자기 등장한 RLS는 무슨 뜻일까요?

RLS 뜻은 Row Level Security, 우리말로 ‘행 단위 보안’입니다. 데이터베이스 테이블의 각 행을 누가 조회하거나 추가·수정·삭제할 수 있는지 정하는 보안 기능이에요. 같은 테이블 안에서도 사용자마다 접근할 수 있는 데이터를 다르게 만들 때 사용합니다.

이 글에서는 SQL을 몰라도 이해할 수 있도록 RLS의 뜻과 역할만 먼저 살펴봅니다. 실제 Supabase 정책을 만드는 방법은 글 마지막의 별도 안내로 연결할게요.

RLS에서 Row, 행이란 무엇인가요?

데이터베이스의 테이블은 엑셀이나 구글 스프레드시트와 비슷하게 행과 열로 이루어집니다.

id 할 일 만든 사람
1 장보기 민지
2 보고서 쓰기 도윤
3 운동 예약하기 민지

가로 한 줄이 행(row)이고, 세로로 나뉜 id, 할 일, 만든 사람열(column)입니다.

RLS는 이 가로 한 줄마다 접근 가능 여부를 판단합니다. 민지가 로그인했다면 1번과 3번 행은 보여주고, 도윤이 만든 2번 행은 숨기는 식이에요.

민지로 로그인
→ 1번 행 허용
→ 2번 행 거부
→ 3번 행 허용

그래서 Row Level Security를 ‘행 수준 보안’ 또는 ‘행 단위 보안’이라고 부릅니다.

테이블 권한과 RLS는 무엇이 다른가요?

일반적인 테이블 권한은 “이 사용자가 이 테이블을 읽을 수 있는가?”를 판단합니다. RLS는 한 단계 더 들어가 “이 테이블에서 어느 행까지 읽을 수 있는가?”를 판단합니다.

테이블 권한
→ 민지는 todos 테이블을 읽을 수 있다

RLS 정책
→ 민지는 todos 테이블에서 만든 사람이 민지인 행만 읽을 수 있다

회원이 모두 같은 todos 테이블을 사용하더라도 각자 자신의 할 일만 보여야 합니다. 회사용 협업 도구라면 같은 팀의 문서는 볼 수 있지만 다른 회사의 문서는 볼 수 없어야 해요. 이런 조건을 데이터베이스에 정책으로 정하는 기능이 RLS입니다.

PostgreSQL 공식 문서도 RLS를 사용자에 따라 조회·추가·수정·삭제할 수 있는 행을 제한하는 정책으로 설명합니다. RLS는 Supabase가 만든 별도 기능이 아니라 PostgreSQL이 제공하는 기능이에요. PostgreSQL Row Security Policies 공식 문서 (새 탭에서 열림)

RLS는 로그인과 무엇이 다른가요?

로그인과 RLS는 확인하는 질문이 다릅니다.

구분 확인하는 질문 예시
로그인 이 사람은 누구인가요? 현재 사용자는 민지입니다
RLS 이 사람이 이 행에 접근해도 되나요? 민지가 만든 행만 허용합니다

로그인은 사용자의 신원을 확인하는 인증(authentication)입니다. RLS는 확인된 사용자에게 허용할 행동과 데이터를 정하는 권한 부여(authorization)에 해당합니다.

따라서 로그인 기능을 만들었다고 사용자별 데이터 보호가 자동으로 완성되는 것은 아닙니다. 앱이 현재 사용자를 알아낸 뒤, 그 사용자가 어느 행을 볼 수 있는지 정하는 규칙도 필요해요.

RLS 정책은 어떻게 작동하나요?

RLS를 사용하는 테이블에는 접근을 허용할 조건을 정책(policy)으로 만듭니다. 사용자가 데이터를 요청하면 데이터베이스가 이 조건을 검사하고, 통과한 행만 돌려줍니다.

예를 들어 todos 테이블의 각 행에 user_id가 저장되어 있다고 해볼게요. 정책의 뜻을 우리말로 쓰면 다음과 같습니다.

현재 로그인한 사용자의 ID와
이 행의 user_id가 같을 때만 허용한다.

Supabase에서는 이런 조건을 다음처럼 표현하는 경우가 많습니다.

(select auth.uid()) = user_id

auth.uid()는 현재 로그인한 사용자의 고유 ID를 돌려줍니다. 이 값과 행의 user_id가 같으면 자신의 데이터이고, 다르면 다른 사람의 데이터라고 판단할 수 있어요.

중요한 점은 화면에서 데이터를 숨기는 것이 아니라 데이터베이스가 직접 접근을 막는다는 것입니다. 사용자가 브라우저의 코드를 바꾸거나 임의의 요청을 보내더라도 같은 정책이 적용됩니다.

Supabase 공식 문서는 RLS 정책을 모든 쿼리에 자동으로 붙는 WHERE 조건처럼 생각할 수 있다고 설명합니다. Supabase Row Level Security 공식 문서 (새 탭에서 열림)

Supabase를 쓰면 RLS가 자주 보이는 이유

Supabase는 브라우저나 모바일 앱에서 Data API를 통해 PostgreSQL 데이터에 접근할 수 있게 해줍니다.

브라우저 또는 모바일 앱
→ Supabase Data API
→ PostgreSQL 데이터베이스

이 구조에서는 사용자의 요청이 Data API를 통해 데이터베이스까지 도착합니다. 브라우저에 있는 버튼을 숨기거나 화면 코드에서 다른 사람의 데이터를 제외하는 것만으로는 충분하지 않아요. 데이터베이스가 마지막 단계에서 허용할 행을 다시 검사해야 합니다.

Supabase 공식 문서도 브라우저에서 안전하게 데이터에 접근하려면 노출된 스키마의 테이블에 RLS를 활성화해야 한다고 안내합니다. Supabase Auth와 RLS를 함께 사용하면 현재 로그인한 사용자를 기준으로 정책을 만들 수 있어요.

반대로 모든 데이터 요청이 내가 만든 서버 API를 거치고, 서버만 PostgreSQL에 직접 연결하는 구조라면 권한을 서버 코드에서 검사할 수도 있습니다.

브라우저
→ 내가 만든 서버 API
→ PostgreSQL 데이터베이스

이 경우에도 사용하는 데이터베이스 역할과 보안 설계에 따라 RLS를 추가 방어선으로 적용할 수 있습니다. 다만 “Supabase를 쓰면 무조건 같은 RLS 설정을 해야 한다”기보다, 누가 어떤 경로와 권한으로 데이터베이스에 접근하는지 먼저 확인해야 해요.

RLS를 켜면 어떤 일이 생기나요?

RLS를 이해할 때는 활성화 여부와 정책 유무를 나누어 봐야 합니다.

상태 일반적인 결과
RLS 꺼짐 테이블 권한을 가진 역할은 허용된 작업에서 모든 행에 접근할 수 있습니다
RLS 켜짐, 정책 없음 기본적으로 모든 행의 접근이 거부됩니다
RLS 켜짐, 정책 있음 정책 조건을 통과한 행과 작업만 허용됩니다

PostgreSQL은 RLS를 켰는데 적용할 정책이 없으면 기본 거부(default deny)로 처리합니다. 그래서 Supabase에서 RLS를 활성화한 뒤 데이터가 갑자기 안 보일 수 있어요.

이때 데이터가 삭제된 것은 아닐 수 있습니다. 현재 요청에 데이터를 보여주는 정책이 없어서 조회 결과가 비어 보이는 경우가 많아요. 보안을 끄기 전에 필요한 정책이 있는지부터 확인해야 합니다.

RLS는 읽기만 제한하는 기능이 아니에요

RLS는 데이터를 보여줄지뿐 아니라 추가하고 수정하고 삭제할 권한도 제어합니다.

작업 RLS가 판단하는 내용
SELECT 어떤 행을 볼 수 있나요?
INSERT 어떤 값으로 새 행을 만들 수 있나요?
UPDATE 어떤 행을 어떤 값으로 바꿀 수 있나요?
DELETE 어떤 행을 삭제할 수 있나요?

조회 정책만 있으면 목록은 보이지만 저장이 실패할 수 있습니다. 추가 정책만 있으면 저장은 되었는데 다시 읽지 못할 수도 있어요.

RLS의 뜻을 이해했다면 다음 단계에서는 화면이 실제로 사용하는 작업을 기준으로 정책을 하나씩 확인해야 합니다. “자신의 데이터만 접근”이라는 한 문장도 조회·추가·수정·삭제에서 검사할 내용이 서로 다를 수 있어요.

RLS가 모든 보안을 해결하지는 않아요

RLS는 강력하지만 데이터베이스 보안 전체를 대신하지는 않습니다.

특히 Supabase의 service_role처럼 RLS를 우회할 수 있는 권한은 브라우저에 넣으면 안 됩니다. RLS 정책을 잘 만들었더라도 우회 권한이 담긴 비밀 키가 공개되면 정책이 보호 장치로 작동하지 못해요.

RLS 뜻에 관해 자주 묻는 질문

RLS는 무엇의 약자인가요?

RLS는 Row Level Security의 약자입니다. 데이터베이스 테이블에서 사용자나 역할에 따라 접근할 수 있는 행을 제한하는 보안 기능입니다.

RLS를 한국어로 어떻게 읽나요?

보통 알파벳 그대로 ‘알엘에스’라고 읽습니다. 뜻은 ‘행 수준 보안’ 또는 ‘행 단위 보안’으로 옮깁니다.

RLS는 Supabase만의 기능인가요?

아니요. Supabase가 사용하는 PostgreSQL의 기능입니다. Supabase는 PostgreSQL RLS를 Auth와 Data API에 연결해 사용자별 정책을 적용합니다.

RLS를 켰는데 데이터가 안 보이는 이유는 무엇인가요?

RLS를 활성화했지만 현재 요청을 허용하는 SELECT 정책이 없을 가능성이 큽니다. RLS는 정책이 없으면 기본적으로 접근을 거부합니다. 데이터가 삭제된 것인지, 정책 때문에 조회되지 않는 것인지 구분해야 해요.

로그인 기능이 있으면 RLS는 필요 없나요?

로그인은 사용자가 누구인지 확인하고, RLS는 그 사용자가 어느 데이터에 접근할 수 있는지 정합니다. 브라우저가 Supabase Data API로 직접 데이터에 접근하는 구조라면 로그인과 별도로 RLS 정책이 필요합니다.

RLS는 언제 사용하나요?

여러 사용자의 데이터가 같은 테이블에 있고 각자 또는 소속 팀의 데이터만 보여야 할 때 주로 사용합니다. 할 일, 메모, 프로필, 주문, 예약, 팀 문서처럼 소유자나 조직에 따라 접근 범위가 달라지는 데이터가 대표적입니다.

한 줄로 정리하면

RLS는 Row Level Security의 약자로, 같은 데이터베이스 테이블 안에서도 사용자마다 접근할 수 있는 행을 다르게 만드는 보안 기능입니다.

RLS의 뜻을 이해했다면 다음에는 현재 프로젝트가 브라우저에서 Supabase Data API에 직접 접근하는지, 서버를 거쳐 PostgreSQL에 접근하는지 확인해보세요.

Supabase에서 실제 정책을 만들어야 한다면 RLS 정책과 auth.uid(), 조회·추가·수정·삭제 설정을 설명한 글로 이어가세요. 서버 접근 구조와 비교하고 싶다면 Supabase를 연결하는 두 가지 방법도 함께 볼 수 있습니다.

#기초#RLS#Row Level Security#데이터베이스#PostgreSQL#Supabase#보안#바이브코딩

인스타그램 @ddukddak.build · 페이스북 뚝딱