데이터 마스킹
브랜치 생성 시 PII 익명화 — 마스킹 정책, 내장 함수 라이브러리, 그리고 마스크가 커밋될 때까지 마스킹된 브랜치가 봉인 상태로 유지되는 방식.
데이터 마스킹 은 브랜치 가 생성되는 바로 그 순간에 민감한 컬럼을 익명화합니다. 브랜치 생성 호출에 마스킹 정책 을 연결하면, 새 브랜치의 일치하는 컬럼이 브랜치에 접근할 수 있게 되기 전에 — 해시되거나, 널 처리되거나, 잘리거나, 대체되어 — 되돌릴 수 없게 다시 작성됩니다. 부모 브랜치는 결코 변경되지 않습니다.
프로덕션 형태의 데이터를 그 안의 PII는 넘기지 않으면서 개발, CI, 또는 외부 계약자에게 건네주고자 할 때 사용합니다. 실제 테이블 형태, 실제 행 수, 가짜 이메일입니다.
How it works
마스킹 정책은 프로젝트 범위의, 이름이 붙은 규칙 집합입니다. 각 규칙은 패턴으로 컬럼을 매칭하고 내장 마스킹 함수를 지정합니다.
| Field | Meaning |
|---|---|
schema_pattern | 스키마 이름 패턴(% 또는 * = 임의, _ = 한 문자). 기본값은 *. |
table_pattern | 테이블 이름 패턴. |
column_pattern | 컬럼 이름 패턴. |
masking_fn | 아래 내장 함수 중 하나. |
fn_args | 함수 인자(mask_constant 만 하나를 받습니다: value). |
브랜치 생성 시점에 masking_policy_id 가 제공되면:
- 브랜치는 평소처럼 부모에서 포크됩니다(카피 온 라이트 — 즉시).
- 브랜치가
masking상태로 진입합니다. 엔드포인트가 프로비저닝되지 않고 프록시가 그에 대한 연결을 거부합니다. 마스킹되기 전 데이터를 읽을 수 있는 창 은 없습니다. - 마스킹 워커가 최소 권한 롤로 브랜치의 컴퓨트에 연결하여 스키마를 탐색하고, 사용자의 규칙을 그에 매칭한 다음, 모든 재작성을 단일 트랜잭션으로 실행합니다.
- 브랜치가
ready에 안착하고 엔드포인트가 올라옵니다 — 이제 마스킹된 데이터만 제공합니다. 실패가 발생하면 브랜치는failed에 안착하고 봉인된 채로 남습니다. 삭제한 뒤 재시도하세요.
규칙 입력은 SQL이 아니라 데이터로 취급됩니다. 식별자는 따옴표로 묶이고 인자 값은 실행 시 파라미터로 바인딩되므로, 악의적인 컬럼 이름이나 상수가 재작성을 벗어날 수 없습니다.
Built-in functions
| Function | Effect |
|---|---|
mask_email | md5(value)@masked.invalid |
mask_name | Name_ + 8자 해시 접두사 |
mask_null | NULL(컬럼은 nullable이어야 함) |
mask_constant | 사용자가 제공하는 고정 값(fn_args.value) |
mask_ssn_partial | ***-**-1234 — 마지막 4자리 유지 |
mask_credit_card | ****-****-****-1234 — 마지막 4자리 유지 |
mask_ip | 0.0.0.0 |
mask_date_year | 연도는 유지하고 1월 1일로 잘라냄 |
mask_hash | md5(value) |
mask_shuffle | 해시 기반 스크램블(전체 문자 셔플은 예정됨) |
mask_phone | 합성된 +1-555-XXXX 번호 |
mask_uuid | 새로운 무작위 UUID |
카탈로그는 API로도 제공됩니다.
curl -s https://api.test.kisenon.com/v1/masking-functions \
-H "Authorization: Bearer $KISENON_API_KEY"Managing policies
데이터 마스킹은 출시 중 입니다. 여기서 설명하는 정책 편집기와 브랜치 생성 드롭다운은 점진적으로 활성화되고 있습니다. 사용자의 계정에서 마스킹이 활성화되기 전까지 API는
501 not_implemented로 응답하고 콘솔은 "아직 사용할 수 없음" 안내를 표시합니다. 그동안 프로젝트는 영향을 받지 않습니다.
콘솔에서 Project settings → Data masking 을 열어 정책을 생성합니다. 이름을 지정하고, 규칙(패턴 컬럼 + 함수 드롭다운)을 추가하고, 저장합니다. 동일한 기능이 API에도 존재합니다.
curl -s -X POST \
https://api.test.kisenon.com/v1/projects/$PROJECT_ID/masking-policies \
-H "Authorization: Bearer $KISENON_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "dev-safe",
"rules": [
{"table_pattern": "users", "column_pattern": "email", "masking_fn": "mask_email"},
{"table_pattern": "users", "column_pattern": "phone", "masking_fn": "mask_null"},
{"table_pattern": "%", "column_pattern": "%ssn%", "masking_fn": "mask_ssn_partial"}
]
}'그런 다음 일반 브랜치 생성 호출에 정책을 추가하여 마스킹된 브랜치를 생성합니다.
curl -s -X POST \
https://api.test.kisenon.com/v1/projects/$PROJECT_ID/branches \
-H "Authorization: Bearer $KISENON_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "masked-dev", "masking_policy_id": "'$POLICY_ID'"}'재작성이 실행되는 동안 브랜치는 state: "masking" 으로 보고합니다. 콘솔에서(실시간,
프로젝트 이벤트 스트림 을 통해) 또는 GET /v1/branches/{id} 를
폴링하여 ready 로 전환되는 것을 지켜보세요.
Good to know
- 마스킹은 생성 시점의 일회성입니다. 정책을 편집해도 이미 그것으로 생성된 브랜치는 결코 건드리지 않습니다 — 브랜치는 태어날 때의 데이터 형태를 유지합니다. 새 규칙을 적용하려면 브랜치를 다시 생성하세요.
- 사용 중인 정책은 삭제할 수 없습니다. 라이브 브랜치가 그것으로 생성된 정책을
삭제하면
409 policy_in_use를 반환합니다. 해당 브랜치를 먼저 삭제하세요. - 매칭되지 않은 규칙은 치명적이지 않고 건너뜁니다. 스키마가 변경되어 패턴이 아무것도 매칭하지 않더라도 브랜치는 여전히 완료됩니다 — 마스킹을 예상한 컬럼이 여전히 실제 데이터 형태를 갖고 있으면 규칙 패턴을 확인하세요.
- 타입 불일치는 브랜치를 실패시킵니다. 함수가 재작성할 수 없는 컬럼을
매칭하는 규칙(예:
integer에 대한mask_email)은 전체 마스크를 중단시킵니다 — 브랜치는failed에 안착하며 절반만 마스킹된 채로 노출되는 일은 결코 없습니다.