"RLS"와 "다중 테넌트"는 해당 주제에 대해 이미 게시된 거의 모든 콘텐츠에서 나란히 발견됩니다. 이는 많은 SaaS 아키텍처에 대한 합법적인 선택이지만, 자체 클라이언트를 서로 분리하려는 Aurabase의 선택은 아닙니다. 이번 포스팅에서는 단순화된 마케팅 설명이 아닌, 실제 프로비저닝 엔진과 실제로 적용된 RLS 정책과의 차이점을 설명합니다. Aurabase의 Managed Postgres 엔진이 격리를 넘어 다루는 내용에 대한 개요는 데이터베이스설명서를 참조하세요.
필수사항
- 프로젝트 간에 Aurabase는 RLS 단독이 아닌 전용 Postgres 기반으로 격리합니다. 각 프로젝트는 전용 CNPG 클러스터(회사 수준) 또는 자체 조직(무료/프로/팀)의 CNPG 클러스터에 자체 물리적 기반을 가지며 다른 조직과 공유하지 않습니다.
- RLS(
auth.uid(),auth.role(),auth.jwt())는 활성 상태로 유지되며 자체 사용자를 격리하기 위해 기반 내에서 권장됩니다(Supabase와 동일한 규칙). service_role및 프로젝트 기반 관리 역할은 설계상 RLS를 우회합니다(BYPASSRLS): 결함이 아닌 서버 운영을 위한 가정된 아키텍처 선택입니다.- 이 저장소에서 이미 수정된 회귀(이전 공유 스키마에서 오류로 부여된
PUBLIC권한)는 기본 수준의 경계가 순전히 애플리케이션 경계보다 더 잘 저항하는 이유를 구체적으로 보여줍니다.
대부분의 다중 테넌트 RLS 가이드가 취하는 지름길
다중 테넌트 Postgres에 대해 가장 문서화된 패턴은 단일 베이스, 각 테이블의 tenant_id 열, 이 열을 JWT에서 추출된 값과 비교하는 RLS 정책의 세 줄로 구성됩니다. 연결 풀, 다이어그램, 실행할 단일 인스턴스 등 경제적이며 테넌트가 많고 작으며 개별 지분이 낮은 경우에 잘 작동합니다.
타협은 현실입니다. 두 클라이언트 사이의 경계는 테이블별로 평가되는 SQL 표현식이 됩니다. 새 테이블에서 잊혀진 정책, 수퍼유저 역할로 실행되는 연결, 실시간으로 실행되는 디버그 스크립트 등 이러한 각 사건은 비록 작동상 사소한 것일지라도 동시에 모든 테넌트의 라인을 자동으로 노출할 수 있습니다. 보안 경계와 기술 경계(기본)는 정확히 동일합니다.
이는 그 자체로는 나쁜 선택이 아니며 많은 제품에 대한 올바른 절충안입니다. 이 게시물의 요점은 다른 곳에 있습니다. 이는 Aurabase가 자체 클라이언트(잠재적으로 규정 준수 요구 사항이 다른 전체 프로젝트)를 서로 분리하기 위해 만든 타협이 아닙니다.
두 개의 아키텍처, 프로젝트 간에 공유되는 기반 없음
최근 프로비저너 통합(코드에 "작업 12"로 표시됨) 이후 Aurabase의 활성 Postgres 프로젝트는 정확히 두 가지 아키텍처에 속합니다. 여러 프로젝트 간에 실제로 공유되는 베이스가 있는 이전 모델은 프로비저닝 경로에서 제거되었습니다.
프로젝트 수준에 따라 두 가지 중 어느 것이 적용되는지 결정됩니다. 대시보드에서 선택한 상자가 아니라 결정하는 것은 코드입니다.
| 치수 | FullyDedicated(회사) | SharedClusterDedicated(무료/프로/팀) |
|---|---|---|
| CNPG 클러스터 | 이 하나의 프로젝트에 전념 | 공유되지만 두 조직 간에는 공유되지 않음 |
| 포스트그레스 데이터베이스 | 앱, 그 앱에서만 프로젝트 가능 | project_<uuid>, 클러스터의 프로젝트당 하나 |
| PostgreSQL 로그인 | 클러스터의 단일 프로젝트: 멤버 간 위험 없음 | 프로젝트별 로그인(F-013), 해당 역할의 구성원이 테넌트_<uuid> |
두 아키텍처 모두에서 기본 또는 클러스터는 서로 다른 두 조직을 호스팅하지 않습니다. 따라서 문제는 "데이터가 격리되어 있습니까?"가 아니라 "프로젝트에 컴퓨팅 CloudNativePG이 모두 자체적으로 포함되어 있습니까, 아니면 동일한 조직의 다른 프로젝트와 공유합니까?"입니다.
두 아키텍처의 이러한 통합은 최근에 이루어졌습니다. 이전에 코드는 두 개의 추가 경로, 즉 여러 프로젝트가 동일한 데이터베이스에 공존하고 다이어그램으로만 격리된 "공유 마스터"와 postgrest_dedicated_shared_db변형을 전달했습니다. 전용 마이그레이션을 통해 이를 제거하고 projects 테이블의 제약 조건을 나머지 두 값으로만 강화했습니다. 이는 공유 스키마 모델이 아래 설명된 버그의 소스였기 때문입니다.
전용 기반이 고객 간에 공유되는 EPIRB보다 뛰어난 이유
별도의 Postgres 데이터베이스는 행 수준 경계가 아닌 연결 수준 경계입니다. 프로젝트 A의 데이터베이스에 연결된 애플리케이션 역할은 프로젝트 B의 테이블을 쿼리할 수 없습니다. 즉, 열려 있는 세션이 없습니다. 이 속성은 RLS 정책이 제대로 작성되지 않았거나, 테이블에서 누락되었거나, 높은 역할에 의해 우회된 경우에도 유지됩니다. 최악의 경우는 단일 데이터베이스 내에 국한됩니다.
이 보증금에는 반대 위험을 보여주는 실제 버그의 흔적도 있습니다. 이전 공유 스키마 모델(철회 이후)에서 provision_postgres_schema는 실수로 각 프로젝트 스키마에 GRANT ALL ... TO PUBLIC 권한을 부여했습니다. PUBLIC는 멤버십 조건 없이 데이터베이스의 모든 역할에 적용되며 프로젝트별로 격리된 로그인은 다른 스키마를 읽고 쓸 수 있습니다. 수정 마이그레이션(066)을 통해 기존 권한에서 이러한 권한이 제거되었습니다.
패치는 누출을 막기 위해 RLS 정책을 하나 더 추가하지 않았습니다. 두 프로젝트가 데이터베이스를 공유할 가능성을 제거했습니다. 현재 두 가지 아키텍처에 대해 provisioning.rs의 주석은 이를 흑백으로 문서화합니다. "각 프로젝트에는 이미 자체 물리적 Postgres 데이터베이스가 있습니다." 기본 수준 경계는 항상 올바르게 작성되는 모든 정책에 의존하는 대신 이러한 버그의 전체 클래스에 도달할 수 없도록 만듭니다.
2026년 8월 23일의 패치는 같은 방향으로 진행됩니다. 프로비저너가 무조건 배치한 REVOKE ALL ON SCHEMA public는 이전 공유 데이터베이스 모델에 대한 실제 격리만 제공했기 때문에 토폴로지에서 조건부로 만들어졌습니다. 현재 두 아키텍처에서는 public.<table>을 명시적으로 참조하는 SQL 덤프 가져오기를 이점 없이 차단했습니다.
EPIRB는 사용자를 위해 데이터베이스에 그대로 유지됩니다.
위의 어느 것도 EPIRB를 쓸모 없게 만들지 않습니다. 단지 바닥만 바꿀 뿐입니다. 에서 프로젝트 데이터베이스에 들어가면 Aurabase는 Supabase에서 사용하는 PostgREST 규칙을 정확하게 노출합니다. request.jwt.claims의 게이트웨이에서 설정한 JWT 클레임을 읽는 세 가지 SQL 함수입니다.
이러한 도우미는 귀하를 위해 문서화되는 것이 아니라 Aurabase 자체의 실제 정책에서 사용됩니다. 다음은 저장소에 배치된 storage_objects를 보호하는 정책입니다(읽기 위해 여러 줄로 형식화됨).
애플리케이션 테이블을 운반하는 자체 project_<uuid>스키마에서 Aurabase는 의도적으로 사용자를 대신하여 어떤 정책도 배치하지 않습니다. 코드는 이를 "Supabase 모델"로 문서화합니다. 테이블의 RLS는 동일한 기능, 동일한 구문을 사용하여 계속해서 사용자의 책임입니다.
service_role은 RLS를 우회합니다. 의도적으로 설계된 것이지 우연이 아닙니다.
Postgres는 기본적으로 모든 정책을 무시하는 역할 속성, BYPASSRLS을 제공합니다. Aurabase는 aura_service_role(브라우저 측에 노출되지 않는 서버 역할)와 ALTER SCHEMA ... OWNER TO와 같은 DDL 작업 중에 사용되는 각 프로젝트별 관리 역할이라는 두 가지 역할 계열에서 이를 자발적으로 사용합니다.
요청을 처리하는 역할 anon/authenticated — tenant_<uuid> —에는 BYPASSRLS이 없습니다. RLS는 예외 없이 정상적으로 적용됩니다. 보너스로, 각 프로젝트에 특정한 시스템 다이어그램(_auth, _storage, _platform)은 정책 없이 활성화된 RLS를 수신합니다. 따라서 기본적으로 우회가 아닌 역할에 대한 전체 거부, 애플리케이션 경로가 어느 날 실수로 액세스하는 경우를 대비한 심층적인 방어입니다.
상승된 서버 역할로 RLS를 우회하는 것은 Aurabase에만 국한된 것이 아닙니다. 이는 Supabase 측의 service_role과 동일한 구성입니다. 요점은 BYPASSRLS을 피하는 것이 아니라 클라이언트에서 액세스할 수 있는 역할에 이를 부여하지 않고 단일 프로젝트로 제한하는 것입니다.
이 서버 역할은 보안 및 RBAC페이지에 자세히 설명된 사전 정의된 역할, 사용자 정의 RBAC, 감사 로그 등 광범위한 상태의 일부입니다.
공유 클러스터에서는 데이터베이스가 모든 작업을 단독으로 수행하지 않습니다.
SharedClusterDedicated수준에서는 동일한 조직의 여러 프로젝트가 단일 CNPG 클러스터에 공존합니다. 물리적 데이터베이스는 이미 프로젝트를 서로 분리하지만 PostgreSQL 역할은 데이터베이스가 아닌 클러스터에 대한 전역 개체입니다. 따라서 Aurabase는 프로젝트별로 별도의 PostgreSQL 로그인 계층을 추가합니다.
각 프로젝트는 자체 로그인으로 연결되며 자체 tenant_<uuid> / tenant_<uuid>_admin 역할의 구성원만 연결되며 동일한 클러스터에 있는 다른 프로젝트의 구성원은 절대 연결되지 않습니다. 데이터베이스는 이미 데이터를 격리합니다. 프로젝트별 이 로그인은 연결되는 ID도 격리하므로 프로젝트의 인시던트는 해당 로그인에 다른 로그인에 상속할 멤버십을 제공하지 않습니다.
RLS 단독 또는 전용 기반: 자체 SaaS를 결정하는 방법
Aurabase의 선택은 보편적인 규칙이 아닙니다. 특정 사례에 대한 절충안입니다. 즉, 클라이언트가 제어할 수 없는 플랫폼에서 잠재적으로 서로 다른 규정 준수 요구 사항을 가진 클라이언트를 서로 격리하는 것입니다. 자체 SaaS를 구축하는 경우 다른 규모로 동일한 질문이 발생합니다.
- RLS(공유 베이스
tenant_id포함) — 테넌트가 많고 개별적으로 지분이 낮으며 테넌트당 기본 비용이 불균형한 경우에 적합합니다. 예외 없이 각 테이블에서pg_prove를 사용하여 각 정책을 테스트합니다. - 전용 기반 또는 다이어그램 — 테넌트에 자체 규정 준수 문제(의료, HR, 공공 부문)가 있을 때마다 관련되며, 성능 격리를 정당화하는 볼륨 또는 두 특정 클라이언트 간의 누수 비용이 추가 인프라 비용에 비례하지 않습니다.
The Aurabase pricing level applies this same arbitration to its own clients: shared base by organization by default, dedicated cluster when the challenge of the project justifies it. For RLS patterns inside your own database — ownership, multi-tenant by organization, role hierarchy — the RLS guide in production details the three cases with pgTAPtests. And if the auto-generated API on your diagram interests you beyond REST, the comparison on pg_graphql versus Hasura and PostGraphile covers the other half of the Postgres surface exposed by Aurabase.