행 수준 보안 정책
사용자별로 행을 자동 필터링합니다.
행 수준 보안 정책은(는) CoddyKit의 무료 SQL Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
행 수준 보안이란 무엇인가요
행 수준 보안(RLS)은 특정 데이터베이스 사용자나 역할이 테이블의 어떤 행을 조회하거나 수정할 수 있는지 제어하는 PostgreSQL 기능입니다. 모든 질의에서 행을 필터링하는 대신 정책을 한 번 정의하면 PostgreSQL이 모든 SELECT, INSERT, UPDATE, DELETE에 대해 자동으로 적용합니다.
특정 질의가 아니라 테이블 자체에 연결된 보이지 않는 WHERE 절이라고 생각하면 됩니다.
테이블에서 RLS 활성화
RLS는 기본적으로 비활성화되어 있습니다. 각 테이블에 ALTER TABLE ... ENABLE ROW LEVEL SECURITY를 사용해 명시적으로 활성화해야 합니다. 활성화한 후에는 테이블 소유자가 아닌 역할에 대해 정책이 하나 이상 생성될 때까지 행이 하나도 표시되지 않습니다.
-- Create a sample table
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
owner TEXT NOT NULL,
amount NUMERIC(10,2)
);
-- Enable RLS
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;첫 번째 정책 만들기
정책은 CREATE POLICY로 만듭니다. 정책 이름을 지정하고 테이블을 정한 다음 USING 표현식을 제공합니다. USING 절은 각 행에 대해 평가되는 부울 표현식입니다. 표현식이 TRUE를 반환하는 행만 사용자에게 표시됩니다.
-- Allow each user to see only their own orders
CREATE POLICY orders_owner_policy
ON orders
FOR SELECT
USING (owner = current_user);USING과 WITH CHECK 절
정책에는 서로 다른 목적을 가진 두 가지 필터 절이 있습니다:
- USING — 읽기 작업(SELECT, UPDATE, DELETE)에서 행을 필터링합니다. USING의 결과가 TRUE인 경우에만 행이 표시됩니다.
- WITH CHECK — 쓰기 작업(INSERT, UPDATE)에서 행을 검증합니다. WITH CHECK의 결과가 TRUE인 경우에만 쓰기 작업이 허용됩니다. 생략하면 USING이 쓰기 검사를 위해 재사용됩니다.
-- Allow users to select and insert only their own rows
CREATE POLICY orders_isolation
ON orders
FOR ALL
USING (owner = current_user)
WITH CHECK (owner = current_user);정책 범위: FOR SELECT, INSERT, UPDATE, DELETE
하나의 정책으로 모든 명령(FOR ALL)을 적용하거나 특정 명령 하나에만 적용할 수 있습니다. 명령별로 정책을 분리하면 세밀하게 제어할 수 있습니다. 예를 들어 모든 사용자가 모든 행을 읽을 수 있게 하면서 자신이 소유한 행만 수정하도록 할 수 있습니다.
-- Everyone can read all orders
CREATE POLICY read_all_orders
ON orders
FOR SELECT
USING (true);
-- But each user can only update their own orders
CREATE POLICY update_own_orders
ON orders
FOR UPDATE
USING (owner = current_user)
WITH CHECK (owner = current_user);session_user와 current_user 사용
PostgreSQL은 정책 표현식 내부에서 활성 사용자를 식별할 수 있는 기본 제공 함수를 제공합니다:
- current_user — 현재 권한이 활성화된 ROLE입니다(SET ROLE 이후 변경될 수 있습니다).
- 세션 사용자 — 연결을 연 ROLE입니다(세션 중에는 변경되지 않습니다).
대부분의 RLS 정책은 ROLE 전환 후의 유효한 ROLE을 반영하는 current_user에 의존합니다.
-- Inspect the current identity inside a query
SELECT current_user, session_user;특정 ROLE에 RLS 적용하기
기본적으로 정책은 PUBLIC(모든 역할)에 적용됩니다. TO 절을 사용하면 특정 ROLE로 제한할 수 있습니다. 일반 사용자에게 적용할 정책과 관리자 ROLE에 적용할 다른 정책을 각각 만들고 싶을 때 유용합니다.
-- Policy only for the 'app_user' role
CREATE POLICY app_user_policy
ON orders
FOR SELECT
TO app_user
USING (owner = current_user);
-- Separate permissive policy for 'admin' role
CREATE POLICY admin_full_access
ON orders
FOR ALL
TO admin
USING (true)
WITH CHECK (true);PERMISSIVE 정책과 RESTRICTIVE 정책
동일한 TABLE에 여러 정책이 있으면 두 가지 방식으로 상호 작용할 수 있습니다:
- PERMISSIVE(기본값) — 모든 PERMISSIVE 정책을 OR로 결합합니다. 하나라도 허용하는 PERMISSIVE 정책이 있으면 행에 access할 수 있습니다.
- RESTRICTIVE — RESTRICTIVE 정책을 PERMISSIVE 결과와 AND로 결합합니다. 행이 RESTRICTIVE 정책을 통과하고 하나 이상의 PERMISSIVE 정책도 통과한 경우에만 access할 수 있습니다.
-- Restrictive policy: block access to archived orders for everyone
CREATE POLICY no_archived_rows
ON orders
AS RESTRICTIVE
FOR SELECT
USING (amount > 0);RLS 우회: BYPASSRLS와 테이블 소유자
TABLE 소유자와 슈퍼 사용자는 기본적으로 RLS를 우회하므로 항상 모든 행을 볼 수 있습니다. 슈퍼 사용자가 아니면서 제한 없는 access가 필요한 ROLE에는 BYPASSRLS 속성을 부여할 수 있습니다. 반대로 FORCE ROW LEVEL SECURITY를 사용하면 소유자에게 RLS를 강제로 적용할 수 있습니다.
-- Force the table owner to also obey RLS policies
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
-- Grant BYPASSRLS to a trusted service account
ALTER ROLE service_account BYPASSRLS;정책 수정 및 삭제
기존 정책은 ALTER POLICY로 수정하거나 DROP POLICY로 완전히 삭제할 수 있습니다. RLS가 계속 활성화된 상태에서 모든 정책을 삭제하면 소유자가 아닌 ROLE은 어떤 행에도 access할 수 없습니다. RLS를 완전히 제거하려면 ALTER TABLE로 비활성화해야 합니다.
-- Rename a policy
ALTER POLICY orders_owner_policy ON orders
RENAME TO user_isolation_policy;
-- Update the USING expression
ALTER POLICY user_isolation_policy ON orders
USING (owner = current_user AND amount >= 0);
-- Remove a policy
DROP POLICY admin_full_access ON orders;
-- Disable RLS entirely on the table
ALTER TABLE orders DISABLE ROW LEVEL SECURITY;실제 패턴: 멀티 테넌트 데이터 격리
멀티 테넌트 서비스형 소프트웨어 앱에서 흔히 사용하는 RLS 패턴은 모든 TABLE에 테넌트 식별자 열을 저장하고, 연결 시 세션 수준 변수(set_config)를 사용해 테넌트 식별자를 전달하는 것입니다. 그런 다음 정책에서 각 행의 테넌트 식별자와 해당 설정을 비교합니다.
-- Table with tenant isolation column
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
tenant_id TEXT NOT NULL,
title TEXT
);
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
-- Policy reads the tenant from a session variable
CREATE POLICY tenant_isolation
ON documents
FOR ALL
USING (tenant_id = current_setting('app.tenant_id'))
WITH CHECK (tenant_id = current_setting('app.tenant_id'));
-- Application sets the variable before running queries
SELECT set_config('app.tenant_id', 'tenant_42', true);
-- Now only tenant_42 documents are visible
SELECT * FROM documents;이해도 확인
PostgreSQL의 행 수준 보안 정책에 대한 이해도를 확인해 보세요.
레슨 요약
이번 레슨에서는 행 수준 보안이 데이터베이스 수준에서 정책에 따라 행을 자동으로 필터링하는 방법을 배웠습니다:
- ALTER TABLE ... ENABLE ROW LEVEL SECURITY를 사용해 TABLE에서 RLS를 활성화합니다.
- CREATE POLICY와 USING 절을 사용해 읽을 수 있는 행을 필터링하고, WITH CHECK 절을 사용해 기록되는 행을 검증합니다.
- TO 절을 사용해 정책을 특정 명령(SELECT, INSERT, UPDATE, DELETE, ALL)과 특정 ROLE로 제한합니다.
- PERMISSIVE(OR 논리) 정책과 RESTRICTIVE(AND 논리) 정책을 결합해 여러 단계의 access 제어를 구성합니다.
- TABLE 소유자와 슈퍼 사용자는 기본적으로 RLS를 우회합니다. 이를 재정의하려면 FORCE ROW LEVEL SECURITY를 사용합니다.
- current_setting()을 사용하는 멀티 테넌트 패턴은 RLS를 실제 환경에 적용하는 강력한 방법입니다.
RLS는 모든 애플리케이션 쿼리에 WHERE 절을 흩어 놓지 않고 데이터 격리를 깔끔하고 일관되게 적용하는 표준적인 방법입니다.
자주 묻는 질문
“행 수준 보안 정책” 강의는 무료인가요?
네 — “행 수준 보안 정책” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Academy 강의 전체를 잠금 해제할 수 있습니다. SQL Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“행 수준 보안 정책”에서 뭘 배우나요?
사용자별로 행을 자동 필터링합니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
SQL Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 SQL Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“행 수준 보안 정책” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 SQL Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 SQL Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.