데이터 마스킹이란? PostgreSQL Anonymizer로 민감 데이터 보호하기
Nishant Sharma
2025년 9월 5일
데이터 마스킹은 개발·테스트·교육 환경에서 민감 데이터를 안전하게 활용하기 위한 핵심 보호 기법입니다. 이 글에서는 데이터 마스킹(data masking)과 데이터 리덕션(data redaction)의 차이를 살펴보고, PostgreSQL Anonymizer(pg_anonymizer)를 이용한 정적·동적 마스킹과 셔플 기능을 예제로 알아봅니다.
데이터 마스킹이란?
데이터 프라이버시가 무엇보다 중요한 시대에 민감한 정보 보호는 단순한 권장 사항을 넘어 필수 요건이 됐습니다. GDPR, HIPAA 같은 규제 프레임워크는 개인 식별 정보(Personally Identifiable Information, PII)에 엄격한 통제를 요구합니다. 데이터베이스 관리자가 이를 위해 활용할 수 있는 핵심 도구가 데이터 마스킹과 데이터 리덕션입니다.
Wikipedia에 따르면 데이터 마스킹은 민감한 데이터를 소프트웨어와 권한 있는 사용자는 활용할 수 있지만, 권한 없는 사용자에게는 거의 가치가 없도록 수정하는 과정입니다. 핵심은 허구이지만 현실적인 데이터를 만드는 데 있습니다.
예를 들어 실제 이름 'Amul Sul'을 'Jeevan Chalke'로 바꾸거나, 실제 신용카드 번호를 겉보기에 유효해 보이는 가짜 번호로 대체할 수 있습니다. 이 과정에서 원본 데이터는 데이터베이스 내에서 영구적으로 변경됩니다.
반면 데이터 리덕션은 데이터를 변경하지 않습니다. 특정 사용자에게 표시할 때만 일부를 가리거나 대체합니다. 예를 들어 주민등록번호의 마지막 4자리만 보여주고 나머지는 숨기는 방식입니다.
| 구분 | 데이터 마스킹 | 데이터 리덕션 |
|---|---|---|
| DB 내 데이터 | 영구적으로 변경됨 | 원본 그대로 유지됨 |
| 데이터 현실성 | 허구이지만 그럴듯함 | 비현실적(예: xxx-xx-9567) |
| 목적 | 민감 데이터 보호 | 민감 데이터 보호 |
PostgreSQL Anonymizer로 데이터 마스킹하기
PostgreSQL Anonymizer는 PostgreSQL, EPAS, PGE에서 데이터를 마스킹하거나 대체할 수 있는 확장(extension)입니다.
프라이버시 중심 설계(privacy by design)를 특징으로 하며, PostgreSQL의 데이터 정의 언어(Data Definition Language, DDL)에 직접 마스킹 규칙을 포함할 수 있습니다.
지원하는 주요 방식은 다음과 같습니다.
- Anonymous Dumps:
pg_dump를 통해 마스킹된 데이터를 SQL 파일로 내보내 백업이나 테스트 환경 생성에 활용 - Static Masking: 실제 DB 데이터를 영구적으로 바꿔 민감 정보를 인공값으로 대체
- Dynamic Masking: 특정 역할(role)만 데이터를 마스킹된 값으로 보게 하고, 다른 역할은 원본을 그대로 볼 수 있도록 설정(데이터 리덕션의 한 형태)
- Masking Views: 마스킹된 데이터를 보여주는 뷰 생성
- Masking Data Wrappers: 외부 데이터 소스에도 외부 데이터 래퍼(Foreign Data Wrapper, FDW)로 마스킹 적용
PostgreSQL Anonymizer의 주요 마스킹 함수
- Destruction: 데이터 영구 삭제
- Noise 추가: 데이터에 무작위 변동치 추가
- Randomization: 특정 범위 내 무작위 값 생성
- Faking: 이름, 주소 등 현실적인 가짜 데이터로 대체
- Advanced Faking: 더 복잡한 페이크 값 생성
- Pseudonymization: 가역적 가명으로 대체
- Hashing: 단방향 해시로 변환
- Partial Scrambling: 데이터 문자열 일부만 섞음
- Conditional Masking: 조건부로 마스킹 적용
- Generalization: 나이 → 나이 구간 등 범주화
- pg_catalog 활용: Postgres 내장 함수 사용
- Image Blurring: 이미지 블러 처리
- Custom Mask 작성: 직접 마스킹 함수 작성 가능
실습 예제: Dynamic Masking과 Static Masking 비교
Dynamic Masking 설정
Dynamic Masking은 개발·교육 환경에서 유용하며, 사용자 역할(role)에 따라 서로 다른 데이터를 보여줄 수 있습니다.
\connect edb edb
CREATE ROLE masked_user LOGIN;
SECURITY LABEL FOR anon ON ROLE masked_user IS 'MASKED';
GRANT pg_read_all_data TO masked_user;
다음 단계로, Dynamic Masking을 활성화하고 특정 컬럼에 마스킹 함수를 적용합니다. 여기서는 anon.fake_first_name() 함수를 사용합니다.
ALTER DATABASE edb SET anon.transparent_dynamic_masking TO true;
SECURITY LABEL FOR anon ON COLUMN test.name IS 'MASKED WITH FUNCTION anon.fake_first_name()';
- 일반 사용자 조회 결과
\connect edb edb
SELECT * FROM test;
name | phone
------+-------
ABCD | 12345
EFGH | 67890
- masked_user 조회 결과
\connect - masked_user
SELECT * FROM test;
name | phone
---------+-------
Hayley | 12345
Olivia | 67890
Static Masking 설정
정적 마스킹(Static Masking)은 데이터를 영구적으로 익명화해야 할 때 사용합니다. 예를 들어 운영 데이터베이스 덤프를 개발팀에 전달하기 전에 민감 정보를 보호해야 하는 경우에 적합합니다.
edb 역할로 접근하면 원본 데이터는 다음과 같이 보입니다.
\connect - edb
SELECT * FROM test;
name | phone
------+-------
ABCD | 12345
EFGH | 67890
데이터를 영구적으로 익명화하려면 anonymize_table 함수를 실행하면 됩니다.
SELECT anon.anonymize_table('test');
anonymize_table
-----------------
t
이제 테이블의 데이터는 영구적으로 변경됩니다.
SELECT * FROM test;
name | phone
---------+-------
Phillip | 12345
Mariah | 67890
Shuffle 개념: 컬럼 값을 세로로 섞기
shuffle_column() 함수는 pg_anonymizer 확장의 독특한 기능 중 하나입니다. 전통적인 마스킹 방식과 달리 컬럼 내 값을 세로 방향으로 섞는 기능을 제공합니다. 따라서 Dynamic Masking에는 사용할 수 없습니다.
예를 들어 이름(name)과 ID(id)를 가진 테이블에서 id 컬럼을 셔플하면 각 이름과 ID 사이의 기존 매핑 관계가 무너져 특정 이름을 원래 ID와 연결하기 어려워집니다.
SELECT * FROM test;
name | alpha | id
------+-------+----
A | a | 1
B | b | 2
C | c | 3
D | d | 4
id 컬럼을 셔플한 뒤의 결과는 다음과 같습니다.
SELECT anon.shuffle_column('test', 'id', 'id');
SELECT * FROM test;
name | alpha | id
------+-------+----
C | c | 3
A | a | 2
B | b | 4
D | d | 1
데이터 마스킹 활용 사례
데이터 마스킹은 단순한 보안 조치를 넘어 다양한 비즈니스 및 개발 상황에서 전략적 도구로 쓰입니다.
- 소프트웨어 개발: 개발자가 운영 데이터 복사본에서 데이터 유출 위험 없이 현실적인 데이터를 활용 가능
- 소프트웨어 테스트: 운영 환경을 모방한 데이터로 철저한 테스트 가능, 개인정보 침해 우려 없음
- 사용자 교육 & 세일즈 데모: 익명화된 데이터로 현실적인 시나리오 제공
- 컴플라이언스 & 거버넌스: 운영 외 환경에서도 민감 데이터가 보호되도록 하여 규제 요건 충족
데이터 마스킹 FAQ
데이터 마스킹이란 무엇인가요?
데이터 마스킹은 민감한 원본 데이터를 허구이지만 현실적인 값으로 바꾸는 보호 기법입니다. 원본 데이터는 데이터베이스 안에서 영구적으로 변경됩니다.
데이터 마스킹과 데이터 리덕션의 차이는 무엇인가요?
데이터 마스킹은 데이터베이스의 원본 값을 영구적으로 변경합니다. 데이터 리덕션은 원본을 유지하면서 특정 사용자에게 표시할 때만 일부 값을 가리거나 대체합니다.
PostgreSQL Anonymizer는 어떤 마스킹 방식을 지원하나요?
PostgreSQL Anonymizer는 Anonymous Dumps, Static Masking, Dynamic Masking, Masking Views, Masking Data Wrappers를 지원합니다. 다양한 마스킹 함수를 사용해 데이터 삭제, 무작위화, 가명화, 해싱, 일반화 등의 규칙을 적용할 수 있습니다.
Dynamic Masking과 Static Masking은 언제 사용하나요?
Dynamic Masking은 역할에 따라 원본 또는 마스킹된 값을 보여줘야 하는 개발·교육 환경에 유용합니다. Static Masking은 운영 데이터베이스 덤프를 개발팀에 전달하기 전처럼 데이터를 영구적으로 익명화해야 할 때 적합합니다.
pg_anonymizer의 shuffle_column() 함수는 무엇을 하나요?
shuffle_column() 함수는 컬럼 안의 값을 세로 방향으로 섞어 기존 값의 매핑 관계를 무너뜨립니다. 이 기능은 Dynamic Masking에는 사용할 수 없습니다.
결론
데이터 마스킹은 현대 데이터베이스 관리에서 민감 정보를 보호하기 위한 필수 관행입니다. pg_anonymizer 확장은 선언적 방식으로 데이터베이스 스키마에 직접 마스킹 규칙을 적용할 수 있어, 조직이 개발·테스트·운영 환경 전반에서 프라이버시를 설계 단계부터 보장하도록 돕습니다.
또한 완전한 데이터 리덕션 기능이 필요하다면 EPAS의 DBMS_REDACT를 참고할 수 있습니다.
참고 자료
pg_anonymizer확장 상세 정보: [PostgreSQL_Anonymizer]- 데이터 마스킹 & 리덕션 관련 EDB 블로그: [여기], [여기], [여기]
- EPAS & PGE에서의
pg_anonymizer설치 가이드: [Installing pg_anonymizer]