해당 글에서는 BaaS, Backend as a Service 기반에 Supabase의 주요 서비스에 대한 이해를 돕기 위해 작성한 입니다
1) 백엔드 인프라(BaaS, Backend as a Service)에 대한 필요성
💡 백엔드 인프라(BaaS, Backend as a Service)에 대한 필요성 - 현재 개발 중인 앱이 있습니다. 해당 앱은 유튜브 영상을 링크를 복사해서 해당 앱에 붙여 넣기를 하면, 영상을 분석하여서 레시피를 텍스트 형태로 보고, 구간별 영상도 확인할 수 있는 앱입니다.
- 이 앱에서는 사용자별 레시피 관리를 위해 로그인 기능이 필요했고, 이에 따라 백엔드 인프라(API 서버, 인증 서버, OAuth, SMTP, DB 사용자 관리 등) 다양한 인프라 구축과 배포, 그에 따른 관리 포인트가 늘어나는 문제가 있었습니다.
2) Supabase
💡 Supabase
- ‘The Open Source Firebase Alternative’라는 슬로건을 내세운 오픈소스 백엔드 서비스(BaaS, Backend as a Service)입니다. - 구글의 Firebase와 유사한 기능을 제공하지만, NoSQL인 Firebase는 다르게 관계형 데이터베이스인 PostgreSQL을 기반으로 한다는 점이 가장 큰 차별점입니다. - Supabase의 주요한 기능으로는 PostgreSQL 데이터베이스, 사용자 인증, 즉시 사용 가능한 API, 엣지 함수, 실시간 구독, 스토리지 및 벡터 임베딩 등의 기능을 제공합니다.
https://supabase.com/
1. 백엔드 서비스(BaaS, Backend as a Service)
💡 백엔드 서비스(BaaS, Backend as a Service)
-개발자가 개발에 필요한 백엔드 인프라(서버, DB, 인증, 스토리지, API 등)를 직접 구축하거나 관리하지 않고, 클라우드 업체가 제공하는 API를 통해서 필요한 기능을 API/SDK 형태로 즉시 사용을 하는 방식을 의미합니다.
https://www.back4app.com/backend-as-a-service-ko
분류
설명
예시
BaaS (Backend as a Service)
인증, DB, 스토리지 등 백엔드 기능을 API로 제공, 프론트엔드 개발에 집중 가능
Firebase, Supabase, AWS Amplify
SaaS (Software as a Service)
완성된 소프트웨어를 구독 형태로 제공
Gmail, Slack, Notion, Figma
IaaS (Infrastructure as a Service)
서버, 스토리지, 네트워크 등 인프라를 제공
AWS EC2, Azure VM, GCP Compute Engine
PaaS (Platform as a Service)
개발 플랫폼(런타임, DB 등)을 제공, 인프라 관리 불필요
Heroku, Google App Engine, AWS Elastic Beanstalk
2. Supabase Price
💡 Supabase Price - BaaS, Backend as a Service 플랫폼을 사용하는 데의 Price & Fee입니다. - Free Plan을 사용하더라도, 최대 MAU(Monthly Active Users)를 50,000명까지 수용할 수 있으며, DB 스토리지도 500MB로 사용자가 없는 초기 운영에서 사용해 볼 수 있다는 점이 좋았던 것 같습니다. - 추후 Pro Plan을 구독한다면 월간 25달러(약 37,000원)의 가격에 MAU(Monthly Active Users) 10만까지 커버가 가능하며 필요에 따라 스케일 업을 할 수 있다는 점이 좋다고 판단되었습니다.
https://supabase.com/pricing
[ 더 알아보기 ] 💡 MAU(Monthly Active Users)은 어떻게 측정이 될까?
- 공식 사이트에서는 로그인하거나 토큰(JWT)을 갱신하는 고유 사용자 수에 따라 요금이 부과된다고 합니다. 각 고유 사용자는 인증 횟수와 관계없이 청구 주기당 한 번만 계산이 됩니다. - 예를 들어서, 청구 주기는 1월 1일부터 1월 31일까지라고 가정했을 때, 사용자 1(User-1)이 여러 번 로그인했더라도 이번 청구 주기에서는 단일 월간 활성 사용자(MAU)로 계산됩니다.
💡 Firebase vs Supabase - 대표적인 BaaS (Backend as a Service) 플랫폼인 Firebase와의 차이점을 확인해 봅니다.
- Firebase는 구글에서 제공하는 모바일 및 웹 애플리케이션 개발 플랫폼입니다. - 개발자가 인프라 관리나 서버 측 로직에 쏟는 시간을 줄이고, 클라이언트 앱의 기능과 사용자 경험(UX)에 집중할 수 있도록 돕는 BaaS(Backend as a Service) 모델의 대표 주자입니다.
💡 그래서 무엇을 사용하는 것이 좋을까? 1. Supabase - SQL/관계형 DB 선호, 자체 호스팅, 오픈소스, AI 기능이 필요한 프로젝트에 적합
2. Firebase - 빠른 MVP, 실시간 기능, 모바일 앱, Google 생태계와 깊게 연동된 프로젝트에 적합
3) Supabase 서비스 기능
1. 관계형 데이터 베이스: Database(PostgreSQL)
💡 관계형 데이터 베이스: Database(PostgreSQL)
- 완전 관리형으로 단순히 DB 래핑이 아닌 PostgreSQL 그 자체를 제공합니다. - 벤더 종속 없이 표준 SQL 그대로 사용 가능하며, PostgreSQL의 모든 기능 (트리거, 함수, 뷰, 인덱스 등) 사용이 가능합니다. - 데이터 간의 관계 설정(Foreign Key)이나 복잡한 쿼리 처리에 매우 강력합니다.
https://supabase.com/database
[ 더 알아보기 ] 💡 완전 관리형 PostgreSQL은 뭘 의미하는 걸까?
- 설치 및 설정, 백업, 업데이트/패치, 확장, 가용성에 대해서 직접 구성하고 관리를 하는 것에 대해서 클라우드사에서 이를 관리하고 처리하게끔 지원을 하는 것을 의미합니다.
구분
직접 관리 (Self-hosted)
완전 관리형 (Managed)
설치 및 설정
OS 설치, 포트 설정, 방화벽 구성
클릭 한 번으로 생성 완료
백업 (Backup)
스케줄러 짜고 저장소 관리 필요
자동 백업 및 시점 복구 지원
업데이트/패치
보안 취약점 체크 및 직접 업데이트
클라우드사가 자동으로 최신 패치
확장 (Scaling)
서버 사양 수동 교체, 데이터 이전
콘솔에서 사양 클릭 시 즉시 확장
가용성 (HA)
서버 죽으면 직접 복구해야 함
다중화 구성을 통해 99.9% 가용성 보장
💡 관리형 데이터베이스 아키텍처 구조입니다.
- KONG API Gateway를 통해서 각각에 맞게 라우팅을 해주며, Supabase가 직접 만든 서비스가 아닌 PostgreSQL + 오픈소스 툴 조합 + 관리 플랫폼을 의미합니다. https://supabase.com/docs/guides/self-hosting/docker
💡 Supabase 관계형 데이터베이스 둘러보기 -1: Database & Table
- 아래와 같이 일반 데이터베이스와 같이 Supabase 내에 데이터베이스, 테이블을 두고 데이터 관리가 가능합니다.
💡 Supabase 관계형 데이터베이스 둘러보기 -2: Supabase Schema Visualizer
- 아래와 같이 Supabase Schema Visualizer 기능으로 테이블을 E-R Diagram 형태로 가시적으로 확인이 가능합니다.
💡 Supabase 관계형 데이터베이스 둘러보기 -3: IDEA UI
- 테이블 데이터도 IDEA와 같이 조회할 수 있습니다.
💡 Supabase 관계형 데이터베이스 둘러보기 -4: IDEA UI
- 아래와 같이 SQL문을 통해서 테이블 데이터 조회도 가능합니다.
2. 인증 : Authentication
💡 인증 : Authentication - Supabase의 인증은 JWT 기반 인증 시스템으로, Auth 스키마에 유저 정보를 저장하고 관리합니다. Row Level Security(RLS)와 긴밀하게 연동이 되는 서비스입니다. - 익명 로그인에서 이메일/비밀번호 기반의 일반 로그인은 물론, Google, GitHub, Apple 등 다양한 소셜 로그인(OAuth)을 지원합니다. 세션 관리와 사용자 보안을 자동으로 처리하는 것을 제공합니다.
https://supabase.com/auth
2.1. 일반 로그인
💡 일반 로그인
- Supabase에서 제공하는 일반 로그인 인증 방식으로는 아래와 같은 방식들을 지원합니다.
방식
설명
익명 로그인
UUID만 발급, 이메일이 없는 로그인 방식
이메일 + 비밀번호
전통적인 이메일/패스워드 로그인 방식
Magic Link
이메일로 링크 전송 → 클릭으로 로그인 방식
이메일 OTP
이메일로 6자리 코드 전송 로그인 방식
SMS/전화 OTP
문자로 6자리 코드 전송
Web3
Ethereum / Solana 지갑 서명
💡 기본적으로 로그인을 수행하는 경우
- 로그인은 JWT를 기반으로 인증되는 시스템으로 Supabase에서는 사용자의 인증을 수행하면 Session이 발급이 됩니다. 이러한 세션은 Access Token, Refresh Token으로 구성이 되어 있으며 이를 통해 사용자의 유효 세션이 관리가 됩니다. - 각각 사용자의 세션 유효 시간에 대해서도 Supabase 대시보다 내에서도 관리가 가능합니다.
💡 사용자 UID
- 사용자가 회원가입을 하게 되면 auth.users 테이블에 사용자 정보가 저장이 됩니다. 그리고 이 사용자는 각각의 고유한 UID를 가지게 됩니다. - 이메일/패스워드 회원가입 후 생성, OAuth 로그인 후 생성, Masic Link 링크 선택 시 생성 등에 해당 UID가 발급이 됩니다.
[활용 예시]
- 아래와 같이 이메일/비밀번호를 기반으로 하는 회원가입의 경우, BaaS를 이용하지 않는 경우는 사용자 DB, Security, SMTP 전송 프로세스, 이메일 OTP 프로세스, 이메일 템플릿 구성에 대한 추가적인 개발이 필요하지만, Supabase 내에서는 회원가입을 위한, Email 전송을 위한 메서드 호출만 하면 됩니다.
- 실제적으로 관여한 Back-end 구축 및 환경 구축은 하나도 사용하지 않았습니다.
💡 실제적으로 아래와 같이 회원가입이 완료가 되면 Auth.users 테이블에서 관리가 됩니다.
[ 더 알아보기]
💡 일반 로그인을 할 때, 이메일 회원가입이 있던데? 그럼 이메일 전송을 위한 SMTP까지 제공해 주는 것인가?
- Supabase에서 제공해 주는 noreply@mail.supabase.io 형태나 커스텀으로 내 이메일을 구성하여서 전송이 가능합니다. 또한, AWS SES, SendGrid, Mailgun, Resend과 연동이 가능합니다.
- Custom Email 연결하면 하루 500건이 무료라고 합니다.
💡 아래와 같이 이메일 템플릿도 지정이 가능합니다.
2.2. 소셜 로그인
💡 소셜 로그인
- Supabase에서 제공하는 소셜 로그인입니다.
💡 아래와 같은 다양한 Provider를 통해 인증(Authentication)을 위임하여 간편하게 가입 및 로그인을 수행할 수 있습니다.
https://supabase.com/features/social-login
💡 Spring Boot OAuth 2.0 프로세스를 비교하였을 때, Supabase 프로세스입니다.
- 기존 Spring Boot OAuth 2.0 내에서는 소셜 로그인을 위해서 Spring Security 기반 Auth Code 교환, JWT 발급, 검증, Refresh Token 처리, 클라이언트로 Redirect 과정을 처리해야 했습니다. - Supabase 환경에서는 인증의 복잡한 부분(OAuth 중개, JWT 발급, 유저 관리)은 Supabase에 위임하여 signInWithOAuth() 함수 호출로 이를 대체할 수 있습니다.
💡 Spring Boot OAuth 2.0 프로세스
💡 Supabase 프로세스
항목
Spring Boot OAuth
Supabase OAuth
token 교환 주체
Client (백엔드)
Supabase Auth 서버
PKCE 처리
직접 구현
자동 처리
사용자 DB 저장
직접 구현
auth.users 자동 저장
Session 발급
JWT 직접 생성
Supabase Session 자동 발급
프론트 호출
-
signInWithOAuth() 한 줄
3. 엣지 함수: Edge Functions
💡 엣지 함수: Edge Functions - Supabase에서 제공하는 서버리스 함수 실행 환경으로, Deno 런타임 기반으로 동작하며 전 세계 엣지 서버에서 실행됩니다. - Node.js를 지원하여 100만 개 이상의 NPM 모듈 지원을 통해 함수를 구성할 수 있습니다. - TypeScript/JavaScript 기본 지원하며, Javascript V8 엔진 기반으로 빠른 콜드 스타트를 제공합니다.
https://supabase.com/edge-functions
💡 아래와 같이 각각 Edge Function를 구성을 합니다.
💡 아래와 같이 TypeScript/JavaScript을 지원하여서 코드 구성이 가능합니다.
💡 아래와 같이 Javascritpt에 연결하여 호출하는 방법도 제공해 줍니다.
💡 또한 추가적으로, 진행 중인 Edge Function에 대해서도 모니터링을 제공합니다.
4. 실시간 데이터 처리 : Realtime
💡 실시간 데이터 처리 : Realtime - Supabase Realtime은 데이터베이스 변경사항을 WebSocket으로 실시간 전달하는 기능을 의미합니다. - 데이터베이스의 변경 사항(Insert, Update, Delete)을 클라이언트에 실시간으로 푸시해 줍니다. 채팅이나 실시간 알림 기능을 만들 때 유용합니다.
https://supabase.com/realtime
4.1. 실시간 데이터 처리 프로세스
💡 실시간 데이터 처리 프로세스 - 앱 사용자 A, B, C가 있고 이들이 동일한 채팅방에서 채팅을 한다는 가정하에 있습니다. 사용자 A, B, C는 ‘open-chat’이라는 채널을 구독(subscribe)하고 있습니다.
1. 사용자 A는 채팅을 위해서 “안녕하세요”라는 텍스트를 입력합니다. 2. 이 텍스트 데이터 row는 Supabase DB에 저장이 됩니다. 3. 저장이 되면 이를 감지하여 Supabase Realtime에서는 ‘open-chat’ 채널로 Broadcast를 하여서 구독 중인 수신자인 사용자 B, C에게 전달을 합니다.
- WebSocket에서 Publisher(발행), Subscriber(구독)의 개념이 아닌 DB INSERT로 Publish(발행)가 된다는 점이었습니다.
[Realtime 서비스를 활용한 채팅 구현 사례]
- 아래와 같이 로그인을 수행한 사용자를 기반으로 전체 채팅방을 구현을 하였습니다. - 채팅방을 구현을 위해서 Publisher(발행자)는 채널에 접근하고, Message라는 테이블 내에 데이터를 INSERT를 하고, Subscriber(구독자)는 채널에 접근하여 구독을 하면, 서로 실시간 채팅방이 구현이 되었습니다. - 만약 이를 이용하지 않았다면, 별도의 소켓서버, Redis 구축 등 다양한 환경을 구축해야 헀습니다.
💡 사용자 A가 채팅으로 입력을 합니다.
💡 아래와 같이 텍스트가 데이터 베이스에 저장이 되고
💡 이를 구독하고 있던 다른 사용자에게 전달이 됩니다.
5. 저장소: Storage
💡 저장소: Storage - 이미지, 동영상 등의 대용량 파일을 저장하고 관리할 수 있습니다. CDN이 기본 포함되어 있어 파일 전송 속도가 빠릅니다. - S3 호환 오브젝트 스토리지로, 이미지/영상/문서 등 파일을 저장·관리하는 서비스입니다. 내부적으로 AWS S3 또는 S3 호환 스토리지(MinIO 등) 위에서 동작을 합니다.
https://supabase.com/storage
💡 Supabase Storage가 내부적으로 AWS S3 호환 방식으로 설계되어 있어서, S3의 용어를 그대로 차용한 Burket을 이용합니다.
분류
설명
예시
Public Burket
URL만 알면 누구나 접근 가능하며 별도의 인증이 필요없는 공간
프로필 이미지, 공개 에셋, 썸네일 등
Private Burket
인증 토큰 또는 Signed URL 필요하며 별도의 인증이 필요한 공간
계약서, 개인정보 파일, 결제 영수증 등
4) BaaS 플랫폼 보안적 취약점
1. 크로스 플랫폼 내에서 Supabase 활용 구조
💡 크로스 플랫폼 내에서 Supabase 활용 구조
1. 모바일 내에서 .env 환경 파일 내에 Supbase URL과 Publishable key를 관리합니다. 2. 이를 기반으로 Supbase와의 통신을 위한 공통 Client를 구성합니다. 3. 클라이언트로 Supabase의 조회 쿼리를 구성하여 Supabase의 Database를 직접 조회를 합니다.
2. Supabase 연결
💡 Supabase 연결
- Supabase를 연결하기 위해서 Front → Supabase로 바로 연결하는 구조를 구성합니다. - 해당 부분에서는 Publishable key를 이용하여서 ‘anno(손님)’이라는 권한을 받아서 우선 수행을 합니다.
분류
설명
Project URL
- Supabase 프로젝트의 API 엔드포인트 주소를 의미합니다. - REST API, Auth, Storage, Realtime 등 모든 요청이 이 URL로 들어감
Publishable key
- anon(손님) 권한으로 서명된 JWT를 의미합니다. - 클라이언트가 Supabase API에 요청할 때 Authorization 헤더에 자동으로 붙음 - 프론트 상에서 사용되는 키를 의미합니다.
Secret Key
- service_role(관리자) 권한으로 서명된 JWT를 의미합니다. - 클라이언트가 Supabase API에 요청할 때 Authorization 헤더에 자동으로 붙음 - 서버 상에서 사용되는 키를 의미합니다.
const RecipeService = {
/**
* Supabase 연결 상태 확인
*/
checkConnection: async (): Promise<boolean> => {
const { error } = await supabaseClient.from('recipes').select('id').limit(1);
if (error) {
console.error('Supabase 연결 실패:', error.message);
return false;
}
console.log('Supabase 연결 성공');
return true;
},
/**
* 전체 레시피 목록 조회
*/
selectRecipeList: async (): Promise<MainDataType.Recipe[]> => {
const { data, error } = await supabaseClient
.from('recipes')
.select('*')
.order('extracted_at', { ascending: false });
if (error) {
throw new Error(error.message);
}
return (data as TableDataType.RecipeRow[]).map(mapToRecipe);
},
/**
* 레시피 단건 조회 (id 기준)
*/
selectRecipeById: async (id: string): Promise<MainDataType.Recipe> => {
const { data, error } = await supabaseClient.from('recipes').select('*').eq('video_id', id).single();
if (error) {
throw new Error(error.message);
}
return mapToRecipe(data as TableDataType.RecipeRow);
},
/**
* 레시피 단건 조회 (video_id 기준)
*/
selectRecipeByVideoId: async (videoId: string): Promise<MainDataType.Recipe> => {
const { data, error } = await supabaseClient.from('recipes').select('*').eq('video_id', videoId).single();
if (error) {
throw new Error(error.message);
}
return mapToRecipe(data as TableDataType.RecipeRow);
},
}
5. 보안적 취약점
💡 보안적 취약점 - .env 파일 내에서 직접적으로 Supabase 접속 엔드포인트와 호출 및 접근 가능한 Publishable key를 이용하고 있습니다. - 해당 키가 ‘anno(손님) 권한’으로 서명된 JWT라고 하더라도, 손님에 대한 정책(Policy)을 지정하지 않는다면, 모든 데이터에 접근이 가능하며 노출 시 보안적인 취약점이 발생할 수 있습니다.
5) MoltBook으로 본 Supabase의 사례
💡 MoltBook
- MoltBook이라는 AI 에이전트를 위한 소셜 네트워크로 AI 에이전트들이 글을 올리고, 토론하고, 추천하는 플랫폼이며 인간은 관찰자로 참여가 가능한 플랫폼이 있습니다. - 즉, AI 에이전트들이 모여서 노는 SNS 공간에 인간이 관찰자로 참여를 하는 플랫폼입니다.
- .env 파일 내에서 직접적으로 Supabase 접속 엔드포인트와 호출 및 접근 가능한 Publishable key를 이용하고 있습니다. - 해당 키가 ‘anno(손님) 권한’으로 서명된 JWT라고 하더라도, 손님에 대한 정책(Policy)을 지정하지 않는다면, 모든 데이터에 접근이 가능하며 노출 시 보안적인 취약점이 발생할 수 있습니다. - 이와 같은 사례로 MoltBook 해킹으로 150만 개의 API 키가 노출된 사례에 대해 알아봅니다.
https://v.daum.net/v/Y1M6G1Kphd
💡 사건 요약
- 2026년 1월 31일, 보안 연구원 Jameson O'Reilly가 Moltbook의 전체 데이터베이스가 공개적으로 노출되어 있다는 사실을 발견했습니다. -노출된 키를 기반으로 이메일 주소, 인증 토큰, 모든 에이전트의 API 키에 접근 가능한 상태였습니다.
- 재미있는 사항은 창업자 Matt Schlicht은 "Moltbook을 위해 단 한 줄의 코드도 직접 작성하지 않았다. AI가 현실로 만들었다"라고 공개적으로 밝혔습니다. 즉, 바이브 코딩만으로 구성을 하였다고 합니다.
- 즉, 해당 사건의 핵심 원인은 Supabase의 이였습니다. Row Level Security(RLS)를 활성화하지 않았다고 합니다. - 해당 문제는 즉각적으로 해결이 되었다고 하지만, 150만 개의 키가 노출이 되었다는 큰 이슈였습니다.
- PostgreSQL의 RLS 기능을 Supabase가 활용한 것으로 테이블의 각 행(Row)에 대한 접근을 사용자별로 제어하는 보안 메커니즘을 의미합니다. - 이를 활성화하지 않으면 API 키만으로 모든 데이터에 접근할 수 있습니다.
- Supabase 내에서는 클라이언트(앱) 내에 Publishable key를 포함하기에, 손님(Anno)에 대한 권한으로 제공을 하지만, 활성화가 되어 있지 않으면 사실상 데이터베이스에 모든 접근이 되기에, 이에 따르는 RLS에 대한 설정된 정책(Policy)을 지정하여 허용된 데이터만 노출되도록 해야 합니다.
1. 클라이언트는 발급받은 JWT를 Supabase로 전달을 합니다. 2. Supabase Auth Layer에서는 auth.uid() / auth.role() 추출하여 확인합니다. 3. RLS 활성화 여부 확인하여, 비 활성화 되어 있다면, ‘전체 접근 허용’이 되는 것이고, 아니라면 Policy를 확인합니다. 4. Policy를 확인하여서 허용되지 않으면 데이터는 조회되지 않을 것이고, 허용된다면 PostgreSQL을 통해서 쿼리가 실행됩니다. 5. 결과적으로 필터링된 결과를 반환합니다.
- 위에 Moltbook 사례를 보더라도 RLS 활성화 여부를 확인하지 않았다면, 데이터베이스 접근은 모두 ‘전체 접근 허용’이 되었을 것입니다.
2. RLS 적용 방법
2.1. Enable RLS for this table
💡 Enable RLS for this table
- 테이블에 대해서 RLS를 적용합니다.
2.2. ‘Add RLS policy’를 적용합니다
2.3. 직접 Policy를 지정할 수 있고, Template도 제공이 됩니다.
3. RLS Policy Templates
💡 RLS Policy Templates
- 기본적으로 제공하는 RLS Policy Template입니다. 이를 이용하여서 기본적인 설정 구성이 가능합니다.
태그
정책명
설명
SELECT
Enable read access for all users
SELECT로 모든 유저에게 읽기 권한 부여
INSERT
Enable insert for authenticated users only
인증된 유저에게만 INSERT 권한 부여
DELETE
Enable delete for users based on user_id
user_id 컬럼이 본인 ID와 일치하는 행만 삭제 가능
INSERT
Enable insert for users based on user_id
user_id 컬럼이 본인 ID와 일치하는 행만 삽입 가능
UPDATE
Policy with table joins
테이블 JOIN을 활용한 고급 RLS 규칙 (teams, members 테이블 예시)
ALL
Policy with security definer functions
Security Definer 함수로 다대다 관계의 링킹 테이블 접근 제어
SELECT
Policy to implement Time To Live (TTL)
생성 후 24시간 이내 행만 조회 가능 (Instagram 스토리 / Snapchat 방식)
SELECT
Enable users to view their own data only
본인 데이터만 읽기 가능하도록 제한
4. Custom Row Level Security policy
💡 Custom Row Level Security policy
- 위에 템플릿을 이용한 경우 외에 커스텀으로 Policy 지정이 가능합니다.
💡 Supabase 내에서 각각에 맞는 설정이 가능합니다.
3.1. 테이블 단위가 아닌 행(Row) 단위로 접근 제어
💡 테이블 단위가 아닌 행(Row) 단위로 접근 제어
-- RLS 활성화
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
3.2. 정책(Policy) 구조
💡 정책(Policy) 구조 - 정책을 구성하는 SQL입니다. FOR: 어떤 작업에 적용할지(SELECT | INSERT | UPDATE | DELETE | ALL) TO: 누구에게 적용할지(authenticated | anon | public | 특정롤) USING vs WITH CHECKUSING(읽기 조건) — "이 행을 볼 수 있는가?"에 대한 지정 WITH CHECK(쓰기 조건) — "이 값을 쓸 수 있는가?”에 대한 지정
CREATE POLICY "정책명"
ON 테이블명
FOR [SELECT | INSERT | UPDATE | DELETE | ALL]
TO [authenticated | anon | public | 특정롤]
USING (조건) -- 읽기 조건 (SELECT, UPDATE, DELETE)
WITH CHECK (조건); -- 쓰기 조건 (INSERT, UPDATE)
💡 예시 -1 - post라는 테이블에 대해서 RLS를 적용합니다 - post는 로그인된 본인의 데이터만 조회, 삽입, 수정, 삭제만 가능하도록 정책을 지정합니다.
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY "본인 데이터 조회"
ON posts FOR SELECT
TO authenticated
USING (auth.uid() = user_id);
CREATE POLICY "본인 데이터 삽입"
ON posts FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "본인 데이터 수정"
ON posts FOR UPDATE
TO authenticated
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "본인 데이터 삭제"
ON posts FOR DELETE
TO authenticated
USING (auth.uid() = user_id);