[데이터 엔지니어링 디자인 패턴] 07. 데이터 보안
[데이터 엔지니어링 디자인 패턴] 07. 데이터 보안
데이터 엔지니어링 디자인 패턴 시리즈의 글입니다.
우리가 만든 데이터셋은 중요한 비즈니스 자산이다.
비즈니스 자산에 대한 악의적 접근을 막기 위해, 보안 측면도 고려를 해야한다.
CDPR, CCPA등의 컴플라이언스 준수 필요
7.1 데이터 제거
개인 데이터 제거 요청(사용자에게 요청을 받은 경우 해당 데이터를 삭제해야함) 등, 데이터 제거로 대응해야하는 경우들이 존재
수직 파티셔너
Vertical Partitioner Pattern
- 문제
- 컴플라이언스때문에 개인 데이터 제거 파이프라인을 설계해야함
- 개인데이터에는 불변속성과 가변속성이 모두 존재
- 불변 속성을 한번만 저장할것을 요청받음
- 해결책
- 불변속성 / 가변속성을 나누는것부터 시작.
- 수평 파티셔닝 : 관련속성을 지는 모든 레코드를 함께 모음
- ex. 날짜 기반 파티션
- 증분 데이터 처리에 주로 사용됨
- 수직 파티셔닝 : 레코드를 분할하여 서로 다른 위치에 기록.
- 개인 데이터 제거 파이프라인에 유용
- 이벤트속성과 불변속성을 별개의 스토리지 공간에 write
- 계산관점 / 재정관점 모두에서 비용이 적게듬
- 서로 다른 데이터 접근 / 보존 규칙 적용이 가능해짐
- 결과
- 쿼리 성능
- 일종의 데이터 정규화
- 따라서, 쓰기성능은 최적화되지만
- 분할된 레코드를 조인해야하므로 읽기성능이 저하됨
- 쿼리 복잡성
- 데이터가 분리되었기때문에
- 쿼리에 약간에 복잡성이 추가됨
- view , 데이터 문서화 등으로 문제 완화 가능
- 폴리글랏 세계의 복잡성
- polyglot persistence : 하나의 시스템에서 데이터 성격에 따라 여러 종류의 데이터 저장소를 함께 사용하는 방식
- ex. 데이터 = RDB, 캐시= NoSQL
- 저장소가 나뉘므로, 여러 저장소 모두에 수직 파티셔닝을 적용해야할수도.
- 원시 데이터
- 일정 기간동안 raw 데이터를 보관해야하는경우 데이터 제거 처리 보완 해결책이 필요
- 쉽게는 분할되지 않은 데이터 보존기간을 짧게 설정.. → 백필링 가용성 감소
- 쿼리 성능
제자리 덮어쓰기
In-Place Overwriter Pattern
- 문제
- 이미 수평 파티션에 저장된 레거시시스템을 받음
- 이때 정부의 새로운 개인정보 보호 규정을 준수해야해서
- 사용자 요청시 개인 데이터를 제거하는 기능을 추가해야함.
- 해결책
- 구현은 데이터 스토리지 기술에 의존
- in-place operation지원한다면 DELETE~WHERE로 삭제
- 데이터 블록 회수(VACUUM)까지 진행해야함.
- 지원하지않는다면, staging area에서 해당 데이터를 제거하는 job을 실행 한 뒤, 데이터 승격 job을 실행하는 방식으로 데이터 품질문제를 방지.
- 결과
- I/O 오버헤드
- 파일 조회 / 덮어쓰기 모두 i/o 오버헤드 발생
- 스토리지 공간도 커지고 처리량도 증가됨
- 필터조건과 관련없는 파일을 읽지 않는다면 오버헤드를 줄일 수 있음
- ex. parquet의 통계 메타데이터 활용
- 비용
- 모든 데이터를 조회해야해서 vertical partitioning pattern보다 비용이 많이드는 해결책임
- 데이터 제거 요청을 grouping하여 실행해서 비용을 아끼자.
- I/O 오버헤드
7.2 접근제어
승인된 사용자만 데이터의 중요 섹션에 접근할 수 있어야함.
테이블에 대한 세밀한 접근자
Fine-Grained Accessor for Tables Pattern
- 문제
- hdfs/hive → data warehouse로 migration
- 기존 사용자 - 테이블 접근 관리는 가능
- 추가로 컬럼 / 레코드 (저수준 자원) 단위 접근제어가 필요
- 해결책
- 컬럼 기반 접근
- GRANT 연산자 사용으로 쉽게 구현 가능
GRANT SELECT(col_A, col_B) ON my_table TO some_user;
- 데이터 카탈로그에 정책태그를 생성하고 특정 컬럼에 태그를 설정
- 데이터 마스킹 기능 구현
CREATE FUNCTION ip_mask(ip STRING) RETURN '.';
- GRANT 연산자 사용으로 쉽게 구현 가능
- 레코드 기반 접근
WHERE조건 추가 등 동적 함수에 의존- ex. data bricks : ROW FILTER
- ex. Amazon Redshift : Row-level Security
- 혹은 접근조건이 있는 뷰에서 테이블을 노출
- 컬럼 기반 접근
- 결과
- DB에서 기본 지원하는 기능이라, 단점은 상대적으로 적음
- 레코드 수준 보안 제한
- row수준 보안은 ip, user name 등 세션에서 얻을수 있는 정보 기반으로 제어하기때문에 제한적
- 데이터 유형
- nested column처럼 복합타입인경우 간단한 컬럼 기반 접근 전략은 적용 불가능할수도 있음
- 비중첩화 후 다른테이블에서 노출하거나 데이터셋 구체화기 패턴을 사용해야함
- 쿼리 오버헤드
- 쿼리에 동적으로 SQL 함수를 적용하는 경우 오버헤드가 생겨 예상치 못한 지연을 유발할수도
- 전용 테이블 / 뷰 생성으로 완화 가능함
자원에 대한 세밀한 접근자
Fine-Grained Accessor for Resources Pattern
- 문제
- 보안감사에서 클라우드 계정의 지나치게 광범위한 권한이 발견됨
- 시스템의 각 구성요소에 필요한 최소 권한을 적용해야함.
- 해결책
- 대부분의 클라우드 제공 업체는 최소 권한 원칙에 대한 구현을 제공
- 자원기반 접근 제한
- 특정 버킷에 IAM정책 할당
- ID기반 (사람 or 어플리케이션) 접근제한
- IAM에 특정 자원들에대한 정책을 할당
- 결과
- 원칙에 따른 보안 trade-off
- 최소권한원칙은 훌륭하지만,
- 복잡한 환경에서 유지관리 어려운 작은 정책을 많이 만들어낼수있음
- 와일드카드 기반 접근으로 완화 가능
- 복잡성
- 자원기반 / ID기반을 모두 사용하면 너무 복잡해짐
- 가능하면 더 많은 사례를 다루는 해결책 하나로 통일하는것을 권장
- 할당량
- 접근정책 생성 갯수 제한이 있음.
- 제공업체에 확대 요청 가능.
- 원칙에 따른 보안 trade-off
7.3 데이터 보호
- 데이터 자체를 보안하는것
- 예상치 못한 사용으로부터 보호하는것
암호화기
Encryptor Pattern 접근제어가 손상되더라도 데이터를 사용할 수 없도록 할 수 있음
- 문제
- 데이터 보안을 더 강화해야하는 상황
- 권한이 없는 사람이 데이터를 가로채거나, 서버에서 물리적으로 데이터를 도난당할것을 방어해야함
- 해결책
- 저장된 데이터를 암호화함
- 클라가 데이터를 저장하기 전에 암호화하고, 암호화 키도 관리함
- 혹은 서버에서 모든 암호화/암호화 키 관리를 맡고 데이터를 발행함
- 서버측 암호화는 클라우드 제공업체에서 보통 추상화하여 제공함
- KMS (Key Vault서비스) 제공
- 전송중인 데이터도 암호화가 필요함
- 보통 SDK수준의 보안 통신 활성화
- 프로토콜 버전을 구성하면됨
- 저장된 데이터를 암호화함
- 결과
- 암호화/복호화 오버헤드
- 암/복호화 작업에 CPU overhead 발생
- 쓰기 및 읽기요청이 CPU에 추가 압력을 가하게됨
- 데이터 손실 위험
- 암호화 키 분실 or 접근권한 분실 등으로 데이터 손실 위험
- 보통 클라우드 제공어벷는 키 복원 유예기간을 줌
- 프로토콜 갱신
- 최신 상태로 버전이 유지되어야함
- ex. HTTPS의 TLS프로토콜 (현재는 1.2 버전만 valid)
- 보통 클라우드에서는 단순화되어 프로토콜 버전 업그레이드만 잘 챙겨주면 됨
- 암호화/복호화 오버헤드
익명화기
Anonymizer Pattern
- 문제
- 데이터셋에 PII(개인 식별 정보) 속성이 포함됨
- 공유데이터셋이 개인정보보호규정을 준수하도록 하는 파이프라인 작성을 해야하는 상황
- 해결책
- 데이터 제거 : 해당 컬럼을 데이터셋에서 제거
- 데이터 변조 : 값이 다른 의미를 갖도록 입력값에 노이즈를 추가
- 합성 데이터 대체 : 값을 합성 데이터 생성기에서 나오는 값으로 치환
- 결과
- 정보유실
- 데이터셋이 기존과 달라짐
- 최종 데이터 사용자 입장에서는 해당컬럼 사용이 불가능해짐
- 잘못된 데이터 예측모델 / 부정확한 데이터 인사이트 등 문제를 야기
- 정보유실
의사 익명화기
Pseudo-Anonymizer
- 문제
- 익명화된 데이터셋으로는 대부분의 비즈니스 쿼리가 불가능
- 실제 PII 값은 숨기지만, 사용 가능한 형태로 대체하는 데이터셋 제공을 요청받음
- 해결책
- 데이터 마스킹 : 데이터를 문자열 / 대체값으로 바꿈. ex. 91XXXX
- 데이터 토큰화 : 데이터를 가상의값으로 대체. 매핑값은 vault에 저장
- 해싱 : 민감한 값을 되돌릴 수 없게 대체. (ex. SHA-256 해싱)
- 암호화 : 암호화 키로 암호화. (키가 있다면 복호화 가능)
- 결과
- 잘못된 보안 인식
- 데이터는 흐려지지만 익명 보장 정도가 약함
- PII컬럼을 데이터셋 결합을 통해 추정할수있게됨
- ⇒ 즉 사실상 익명화가 무용해짐
- 정보 유실
- 일부 숫자(or 문자)만 보존됨으로써 정보가 유실됨
- 데이터 타입 손실
- 잘못된 보안 인식
7.4 연결성
- 데이터는 지속적으로 흐름
- 데이터를 접근할때 보안전략이 필요
비밀 포인터
Secrets Pointer Pattern
- 문제
- id / pw로 외부 API에 접근하고있었음
- id / pw가 유출되어 청구 금액이 증가
- id / pw 저장하는 방식을 피하고싶음
- 해결책
- 자격증명을 어디에도 저장하지 않고, 대신 참조(pointer)만 한다
- ex AWS Secret Manager 활용
- 장점
- 중앙 장소에서 민감한 데이터를 관리 → 모니터링이 쉬움
- 구성요소 관리가 용이
- 컨슈머는 민감한 매개변수값을 저장할 필요 X
- 결과
- 캐싱 무효화 / 스트리밍 잡
- 자격증명을 캐시하면 최신자격증명인지 알기 어려움
- 실행시간 최적화 필요
- 자격증명을 새로 고칠 수 있어야함
- 로그
- 자격증명이 로그에 포함되면 여전히 유출 위험 존재
- 비밀은 비밀로 남는다
- secret manager에 secret value를 생성하는 consumer가 있어야함
- 사람이 직접하거나.. IaC스택으로..
- 캐싱 무효화 / 스트리밍 잡
비밀 없는 커넥터
Secretless Connector Pattern 관리할 자격 증명이 전혀 없다면 더 편할것이다
- 문제
- 데이터 처리 시스템을 통합 후, 자원가 상호작용을 위해 API Key를 사용하기로함
- 그러나 이런 작은 API관리에 공수를 들이고싶지않음
- 코드에서 참조할 어떤 종류의 작겨 증명도 없이 자원에 접근하고싶음
- 해결책
- 클라우드 제공업체에서 제공하는 IAM 서비스를 사용
- 자원은 IAM서비스에서 요청한 어플리케이션이 권한을 가지고있는지 검사
- 권한을 가지고있다면 응답
- 아니면 인증서 기반 인증을 사용
- IAM서비스 대신 CA(인증기관)에서 발행한 인증서로 권한 검증
- 클라우드 제공업체에서 제공하는 IAM 서비스를 사용
- 결과
- 일하지 않는 듯한 인상
- 자격증명 없는 접근을 활용하도록 엔티티를 구성
- 교체
- 인증서 기반 인증에서는 정기적으로 접근 키를 교체해야함
- (유출 위험을 줄이기 위해)
- 인증서, 로그인, 패스워드 → 추가적인 관리 오버헤드 발생
-
새로운 자격 증명을 발행하고 컨슈머와 공유해야함
- 일하지 않는 듯한 인상