본문 바로가기
C.W.K.
Stream
Lesson 04 of 06 · published

PII, Compliance, Access Control

~11 min · pii, security, compliance

Level 0구경꾼
0 XP0/47 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

프로의 최저선

Production 데이터 엔지니어라면 누구나 결국 PII (개인 식별 정보) 를 다루게 돼. 최저선은 이거야: 본인 테이블에서 뭐가 PII 인지 알고, 누가 읽을 수 있는지 통제하고, 누가 읽었는지 남기고, 삭제 요청이 오면 처리할 수 있을 것. 규제의 세부는 지역마다 달라도 (EU 의 GDPR, California 의 CCPA, 한국의 개인정보보호법) 밑에 깔린 엔지니어링 모양은 비슷해.

4가지 엔지니어링 통제

  • Tagging. 모든 column 에 메타데이터 카탈로그나 dbt schema.yml 에서 PII / sensitive / public 딱지를 붙여.
  • Masking. 권한 없는 사용자는 hash 나 가림 처리된 값을 보고, 권한 있는 사용자는 진짜 값을 보되 그 접근이 기록에 남아.
  • Row-level security. 같은 테이블이 role 마다 다르게 걸러져 — region 담당 분석가는 자기 region 만.
  • Right-to-be-forgotten 전파. 사용자가 삭제를 요청하면 그 삭제가 모든 파생 테이블까지 흘러가야 해. 그 사람 데이터가 어디 남아 있는지 모르면, 지웠다고 정직하게 말할 수가 없어.

분석가가 할 수 없어야 하는 것

PII 가 든 테이블을 개인 노트북으로 통째로 export 하는 것. Production warehouse (Snowflake, BigQuery, row-level security 있는 Postgres) 는 전부 이걸 막는 정책을 지원해. 새 분석가 계정의 default 는 이래야 해: aggregated mart 에 read-only, PII 없음, 승인 절차 없는 export-to-CSV 없음. 권한은 나중에 죄는 것보다 default 로 죄어 두는 게 천 배 쉬워.

Code

dbt schema.yml 의 PII tagging — meta tag 가 model 과 함께 이동·yaml
version: 2

models:
  - name: dim_customers
    description: "고객 dimension. PII 포함."
    meta:
      contains_pii: true
      access_classification: restricted
    columns:
      - name: customer_id
        meta:
          pii: false
          column_classification: pseudonymous_id
      - name: email
        meta:
          pii: true
          column_classification: personal_contact
      - name: phone
        meta:
          pii: true
          column_classification: personal_contact
      - name: country
        meta:
          pii: false
          column_classification: demographic
PostgreSQL row-level security — enforce 하는 메커니즘·sql
ALTER TABLE fact_orders ENABLE ROW LEVEL SECURITY;

-- 누가 뭘 볼지는 세션 변수가 아니라 테이블이다.
CREATE TABLE analyst_regions (
    db_user  NAME PRIMARY KEY,
    region   TEXT NOT NULL
);

-- Region 분석가는 인증된 사용자에서 유도된 자기 region 만 봄
CREATE POLICY region_filter ON fact_orders
    FOR SELECT TO region_analyst_role
    USING (region = (SELECT ar.region
                     FROM   analyst_regions ar
                     WHERE  ar.db_user = current_user));

-- Global admin 은 다 봄
CREATE POLICY admin_all ON fact_orders
    FOR ALL TO admin_role
    USING (true);

-- 커스텀 GUC 로 정책을 걸지 마:
--   USING (region = current_setting('app.current_region'))
-- 커스텀 GUC 는 USERSET 이라, psql 로 직접 붙은 분석가가 그냥
--   SET app.current_region = 'US';
-- 하고 지역을 하나씩 다 볼 수 있어. current_user 는 그렇게 못 바꿔.

External links

Exercise

본인이 다루는 production 테이블 하나를 골라 모든 column 을 나열하고 PII / sensitive / public 딱지를 붙여 봐. PII column 마다 세 가지를 적어: (a) 본인 조직에서 raw 값을 읽어야 하는 사람이 누구인지, (b) 오늘 그걸 강제하는 메커니즘이 뭔지, (c) 그 메커니즘이 warehouse 안에 있는지 아니면 BI 도구 안에만 있는지. 이 감사에서 구멍이 하나도 안 나오는 경우는 드물어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.