고객 데이터 다루기 · 고객 데이터를 다루는 규칙 · 실습
밖으로 내보낼 한 장 만들기
목표
개인정보가 섞인 고객 데이터에서 조사를 끝내고, 밖으로 나가도 되는 한 장을
만듭니다. 네 원칙(최소 수집 · 가명화 · 집계 반출 · 기록)을 각각 파일로 남깁니다.
환경
/root/pii 아래에서 작업합니다. python3, openssl, jq 가 들어 있습니다.
원본은 직접 만듭니다 — 아래는 준비이지 과제가 아닙니다.
mkdir -p /root/pii && cd /root/piipython3 - <<'PY'import csv, randomrandom.seed(7)names = ['김민준','이서연','박지호','최수아','정하윤','강도윤','조서준','윤지우']codes = ['TIMEOUT','DECLINED','INVALID_CARD','NETWORK','OK']rows = []for i in range(1, 201): n = random.choice(names) rows.append({ 'order_id': 'ORD-%04d' % i, 'created_at': '2026-09-%02dT%02d:%02d:00Z' % ( random.randint(1, 7), random.randint(0, 23), random.randint(0, 59)), 'name': n, 'email': 'user%03d@example.com' % i, 'phone': '010-%04d-%04d' % (random.randint(1000, 9999), random.randint(1000, 9999)), 'address': '서울시 어딘가 %d길 %d' % (random.randint(1, 90), random.randint(1, 300)), 'card_last4': '%04d' % random.randint(1000, 9999), 'amount': random.randint(1000, 90000), 'status': random.choice(['FAILED', 'FAILED', 'PAID']), 'error_code': random.choice(codes), })with open('orders.csv', 'w', newline='', encoding='utf-8') as f: w = csv.DictWriter(f, fieldnames=list(rows[0].keys())) w.writeheader(); w.writerows(rows)print(len(rows), '행')PY조사 목적은 하나입니다 — 결제 실패가 어떤 사유로 나는지 알아내는 것.
이름과 주소는 그 목적에 필요하지 않습니다.
만들 것
slim.csv 조사에 필요한 열만 남긴 사본pseudo.sh 같은 사람을 묶어야 할 때 쓰는 가명값 생성기masked.csv 육안 확인용 부분 마스킹본report.csv 밖으로 나가는 유일한 파일 — 사유별 집계scan.sh 반출 전 검사기access.log 무엇을 왜 봤는지handoff.md 무엇을 내보내고 무엇을 안 내보내는지, 그 근거채점 방식
3단계와 6단계는 채점기가 여러분의 스크립트를 직접 돌립니다.
pseudo.sh 같은 값(대소문자·공백만 다름) → 같은 결과여야 한다 키가 다르면 → 다른 결과여야 한다 출력 길이 → 32자 이상이어야 한다scan.sh 이메일이 든 파일 → 막아야 한다 전화번호가 든 파일 → 막아야 한다 집계만 든 파일 → 통과시켜야 한다단계
1. 원본을 만듭니다(위 준비 블록).
2. slim.csv — 조사에 필요한 열만 남깁니다. 행 수는 그대로입니다.
3. pseudo.sh — 값 하나를 받아 가명값 한 줄을 냅니다. 키는 PII_KEY
환경변수로 받습니다.
4. masked.csv — 전화번호를 010-****-1234 꼴로, 이메일도 가립니다.
5. report.csv — 사유별 건수. 합계가 원본 행 수와 같아야 합니다.
6. scan.sh — 파일 하나를 받아 개인정보가 있으면 0 이 아닌 코드로 끝냅니다.
7. access.log — 조회할 때마다 시각 · 대상 · 목적을 한 줄씩.
8. handoff.md — 무엇을 내보내고 무엇을 안 내보내는지, 마스킹 방식을 왜
그렇게 골랐는지.
참고
3단계에서 흔히 물리는 자리가 셋입니다. 정규화 없이 해시하면 대소문자만
달라도 같은 사람이 안 묶입니다. 키 없이 해시하면 전화번호나 이메일은
후보를 만들어 전수 대입할 수 있습니다. 그리고 8자로 잘라 쓰면 충돌이
납니다. 채점기가 셋을 따로 확인하니 어느 것이 걸렸는지 바로 알 수 있습니다.
7단계의 access.log 에도 개인정보를 적지 마세요. 감사 로그도 유출 경로입니다.
단계 8개
- 개인정보가 섞인 원본
- 필요한 열만 가져온다
- 같은 사람을 묶어야 할 때
- 육안 확인용 부분 마스킹
- 밖으로 나가는 것은 집계뿐
- 반출 전 검사기
- 무엇을 왜 봤는지 남긴다
- 무엇을 내보내고 무엇을 안 내보내나