Computer >> 컴퓨터 >  >> 프로그래밍 >> 데이터베이스

SQL Server 2016 행 수준 보안(RLS) 완벽 가이드: 개념부터 구현까지

Microsoft®는 SQL Server®의 보안에 지속적으로 힘을 기울여 왔으며, 거의 모든 버전에서 기존 보안 기능을 강화하거나 새로운 보안 기능을 도입해 왔습니다. SQL Server 2016에서는 사용자가 데이터를 더욱 효과적으로 보호할 수 있도록 행 수준 보안(Row-Level Security, RLS), Always Encrypted, 동적 데이터 마스킹(Dynamic Data Masking) 등 다양한 새로운 보안 기능이 선보였습니다.

개요

이전 글에서는 SQL Server 2016의 동적 데이터 마스킹 기능을 다루었습니다. 이번 글에서는 테이블 내 특정 행(row)에 대한 사용자 접근을 제어할 수 있는 행 수준 보안(RLS) 기능을 소개합니다.

RLS를 활용하면 쿼리를 실행하는 사용자의 특성(속성)을 기반으로 데이터 접근 제한을 구현할 수 있습니다. 애플리케이션을 전혀 수정하지 않고도 서로 다른 사용자에게 완전히 투명한 방식으로 데이터 접근을 손쉽게 통제할 수 있다는 점이 가장 큰 장점입니다.

RLS가 필요한 이유

실무에서는 특정 사용자에게 선택된 데이터만 반환해야 하는 경우가 자주 발생합니다. 과거에는 이러한 요구 사항을 뷰(View)를 생성하고 해당 뷰에 대해 사용자에게 SELECT 권한만 부여하는 방식으로 해결했습니다.

그러나 데이터 양과 사용자 수가 증가함에 따라 관리해야 할 뷰의 개수가 기하급수적으로 늘어나면서 이 방식은 감당하기 어려워졌습니다. 이러한 상황에서 Microsoft는 새로운 보안 요구 사항을 충족하기 위해 RLS를 도입했습니다.

RLS는 테이블 내 행 단위로 세밀한(fine-grained) 접근 제어를 가능하게 하며, 어떤 사용자가 어떤 데이터에 접근할 수 있는지 애플리케이션에 완전히 투명한 상태로 손쉽게 관리할 수 있도록 지원합니다.

이 기능에서는 현재 사용자의 접근 권한이 아닌 쿼리 실행 컨텍스트(execution context)를 기준으로 행이 필터링됩니다. 유연하고 견고한 보안 정책(security policy)을 설계하여 어떤 사용자가 어떤 행을 볼 수 있는지 결정하는 논리 규칙을 만들고, 원하는 행이나 데이터를 제한할 수 있습니다. 아래 이미지를 참고하세요.

SQL Server 2016 행 수준 보안(RLS) 완벽 가이드: 개념부터 구현까지

이미지 출처: https://sqlwithmanoj.com/2015/07/13/implementing-row-level-security-rls-with-sql-server-2016/

RLS의 주요 특징

  • 세분화된 접근 제어: 특정 행에 대한 읽기와 쓰기를 모두 제어 가능
  • 애플리케이션 투명성: 애플리케이션 변경 없이 적용 가능
  • 중앙화된 접근 관리: 데이터베이스 내부에서 접근 로직 중앙 관리
  • 손쉬운 구현 및 유지보수

RLS의 작동 방식

RLS를 구현하려면 다음 세 가지 핵심 요소를 이해해야 합니다.

  • 조건자 함수(Predicate Function)
  • 보안 조건자(Security Predicates)
  • 보안 정책(Security Policy)

각 요소를 하나씩 살펴보겠습니다.

1. 조건자 함수(Predicate Function)

조건자 함수는 인라인 테이블 반환 함수(inline table-valued function)로, 쿼리를 실행하는 사용자가 정의된 논리에 따라 해당 데이터에 접근할 권한이 있는지 검사합니다. 이 함수는 사용자가 접근이 허용되는 각 행에 대해 1을 반환합니다.

2. 보안 조건자(Security Predicates)

보안 조건자는 조건자 함수를 테이블에 바인딩하는 역할을 합니다. RLS는 두 가지 유형의 보안 조건자를 지원합니다.

필터 조건자(Filter Predicate)는 조건자 함수에 정의된 논리에 따라 다음 작업에 대해 오류를 발생시키지 않고 조용히 데이터를 필터링합니다.

  • SELECT
  • UPDATE
  • DELETE

차단 조건자(Block Predicate)는 조건자 함수의 논리를 위반하는 데이터에 대해 다음 작업을 시도할 때 명시적으로 오류를 발생시키고 사용자의 작업을 차단합니다.

  • AFTER INSERT
  • AFTER UPDATE
  • BEFORE UPDATE
  • BEFORE DELETE

3. 보안 정책(Security Policy)

보안 정책 객체는 조건자 함수를 참조하는 모든 보안 조건자를 하나로 묶어 그룹화하는 역할을 하며, RLS 구현 시 생성됩니다.

활용 사례

다음은 RLS를 실무에 적용할 수 있는 대표적인 설계 예시입니다.

  • 병원: 간호사가 담당 환자의 데이터 행만 조회할 수 있도록 보안 정책 구성
  • 은행: 직원의 소속 부서나 직무 역할에 따라 재무 데이터 행 접근을 제한하는 정책 구성
  • 멀티 테넌트(Multi-tenant) 애플리케이션: 각 테넌트의 데이터 행을 논리적으로 분리하는 정책 구성. 여러 테넌트의 데이터가 하나의 테이블에 저장되므로 처리 효율이 높아지며, 각 테넌트는 자신의 데이터 행만 조회할 수 있습니다.

RLS 구현 예제

다음은 RLS를 단계별로 구현하는 예제입니다.

1단계: 아래 코드를 실행하여 테스트용 데이터베이스 RowFilter와 두 명의 사용자를 생성합니다.

CREATE DATABASE RowFilter;
GO
USE RowFilter;
GO
CREATE USER userBrian WITHOUT LOGIN;
CREATE USER userJames WITHOUT LOGIN;
GO

2단계: 샘플 데이터가 포함된 테이블을 생성하고, 새로 만든 사용자들에게 SELECT 권한을 부여합니다.

CREATE TABLE dbo.SalesFigures (
[userCode] NVARCHAR(10),
[sales] MONEY)
GO
INSERT  INTO dbo.SalesFigures
VALUES ('userBrian',100), ('userJames',250), ('userBrian',350)
GO
GRANT SELECT ON dbo.SalesFigures TO userBrian
GRANT SELECT ON dbo.SalesFigures TO userJames
GO

3단계: 필터 조건자 함수를 추가합니다.

CREATE FUNCTION dbo.rowLevelPredicate (@userCode as sysname)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS rowLevelPredicateResult
WHERE @userCode = USER_NAME();
GO

4단계: dbo.SalesFigures 테이블에 필터 조건자를 추가합니다.

CREATE SECURITY POLICY UserFilter
ADD FILTER PREDICATE dbo.rowLevelPredicate(userCode)
ON dbo.SalesFigures
WITH (STATE = ON);
GO

5단계: 2단계에서 생성한 사용자로 결과를 테스트합니다.

EXECUTE AS USER = 'userBrian';
SELECT * FROM dbo.SalesFigures;
REVERT;
GO

위 코드는 두 개의 행을 반환합니다.

SQL Server 2016 행 수준 보안(RLS) 완벽 가이드: 개념부터 구현까지
EXECUTE AS USER = 'userJames';
SELECT * FROM dbo.SalesFigures;
REVERT;
GO

위 코드는 한 개의 행을 반환합니다.

SQL Server 2016 행 수준 보안(RLS) 완벽 가이드: 개념부터 구현까지

권한(Permissions)

보안 정책을 생성, 변경 또는 삭제하려면 ALTER ANY SECURITY POLICY 권한이 필요합니다.

또한 보안 정책을 생성하거나 삭제하려면 스키마에 대한 ALTER 권한이 필요합니다.

추가로, 추가되는 각 조건자마다 다음 권한들이 요구됩니다.

  • 조건자로 사용되는 함수에 대한 SELECTREFERENCES 권한
  • 정책에 바인딩되는 대상 테이블에 대한 REFERENCES 권한
  • 대상 테이블에서 인수로 사용되는 모든 열에 대한 REFERENCES 권한

보안 정책은 데이터베이스 소유자(DBO) 사용자를 포함한 모든 사용자에게 적용됩니다. DBO 사용자는 보안 정책을 변경하거나 삭제할 수 있지만, 이러한 변경 사항은 감사(audit)될 수 있습니다. sysadmin이나 db_owner와 같은 고권한 사용자는 문제 해결이나 데이터 검증을 위해 모든 행을 확인해야 하는 경우가 있으므로, 이를 허용하도록 보안 정책을 작성해야 합니다.

보안 정책이 SCHEMABINDING = OFF로 생성된 경우, 사용자가 대상 테이블을 쿼리하려면 조건자 함수와 그 안에서 사용되는 추가 테이블, 뷰, 함수에 대해 SELECT 또는 EXECUTE 권한이 필요합니다. 반면 기본값인 SCHEMABINDING = ON으로 생성된 경우에는 사용자가 대상 테이블을 쿼리할 때 이러한 권한 검사가 생략됩니다.

SQL Server 2016 RLS 수정하기

특정 정책에 대해 SQL Server RLS를 비활성화하려면 다음 작업을 수행합니다.

  • 보안 정책 UserFilterState = off로 변경(ALTER)

필터와 보안 정책을 완전히 제거하려면 다음 작업을 수행합니다.

  • 보안 정책 UserFilter 삭제(DROP)
  • 함수 dbo.rowlevelPredicate 삭제(DROP)

모범 사례(Best Practices)

Microsoft가 권장하는 모범 사례는 다음과 같습니다.

  • RLS 관련 객체(조건자 함수와 보안 정책)는 별도의 스키마로 분리하여 생성하는 것이 좋습니다.
  • ALTER ANY SECURITY POLICY 권한은 고권한 사용자(예: 보안 정책 관리자)에게만 부여해야 합니다. 보안 정책 관리자는 자신이 보호하는 테이블에 대한 SELECT 권한이 없어도 됩니다.
  • 잠재적인 런타임 오류를 방지하려면 조건자 함수 내에서 형식 변환(type conversion)을 피해야 합니다.
  • 성능 저하를 방지하려면 조건자 함수에서 재귀(recursion)를 최대한 피해야 합니다. 쿼리 옵티마이저는 직접 재귀를 탐지하려고 시도하지만, 간접 재귀(예: 두 번째 함수가 조건자 함수를 호출하는 경우)를 반드시 찾아낸다고 보장할 수 없습니다.
  • 성능을 극대화하려면 조건자 함수 내에서 과도한 테이블 조인(join)을 피해야 합니다.

RLS의 제한 사항

RLS에는 다음과 같은 몇 가지 제약이 적용됩니다.

  • 조건자 함수는 반드시 SCHEMABINDING 옵션으로 생성해야 합니다. SCHEMABINDING 없이 생성된 함수를 보안 정책에 바인딩하려고 하면 오류가 발생합니다.
  • RLS가 적용된 테이블 위에는 인덱싱된 뷰(Indexed View)를 생성할 수 없습니다.
  • 메모리 최적화 테이블(In-memory table)은 RLS를 지원하지 않습니다.
  • 전체 텍스트 인덱스(Full-text index)는 지원되지 않습니다.

결론

SQL Server 2016의 RLS 기능을 활용하면 애플리케이션 수준의 변경 없이 데이터베이스 수준에서 레코드 보안을 제공할 수 있습니다. 조건자 함수와 새로운 보안 정책 기능을 기존 코드와 함께 사용하면, 데이터베이스의 DML(Data Manipulation Language) 코드를 전혀 수정하지 않고도 RLS를 구현할 수 있습니다.

궁금한 점이나 의견이 있다면 피드백 탭을 통해 남겨 주세요.

전문가와 함께 환경 최적화하기

Rackspace의 애플리케이션 서비스 (RAS) 전문가들은 폭넓은 애플리케이션 포트폴리오 전반에서 다음과 같은 전문 및 관리형 서비스를 제공합니다.

  • e커머스 및 디지털 경험 플랫폼
  • 엔터프라이즈 리소스 플래닝(ERP)
  • 비즈니스 인텔리전스(BI)
  • Salesforce 고객 관계 관리(CRM)
  • 데이터베이스
  • 이메일 호스팅 및 생산성 솔루션

Rackspace가 제공하는 것:

  • 편향 없는 전문성: 즉각적인 가치를 창출하는 역량에 집중하여 현대화 여정을 안내합니다.
  • Fanatical Experience™: '프로세스 우선, 기술 차후(Process first. Technology second.)' 철학과 전담 기술 지원을 결합해 종합적인 솔루션을 제공합니다.
  • 타의 추종을 불허하는 포트폴리오: 풍부한 클라우드 경험을 바탕으로 올바른 기술을 올바른 클라우드에 배포할 수 있도록 돕습니다.
  • 애자일한 서비스 제공: 고객의 여정 어느 단계에서든 함께하며 고객의 성공과 우리의 성공을 일치시킵니다.

지금 바로 채팅으로 시작해 보세요.