kisenon

데이터 마스킹

브랜치 생성 시 PII 익명화 — 마스킹 정책, 내장 함수 라이브러리, 그리고 마스크가 커밋될 때까지 마스킹된 브랜치가 봉인 상태로 유지되는 방식.

데이터 마스킹브랜치 가 생성되는 바로 그 순간에 민감한 컬럼을 익명화합니다. 브랜치 생성 호출에 마스킹 정책 을 연결하면, 새 브랜치의 일치하는 컬럼이 브랜치에 접근할 수 있게 되기 전에 — 해시되거나, 널 처리되거나, 잘리거나, 대체되어 — 되돌릴 수 없게 다시 작성됩니다. 부모 브랜치는 결코 변경되지 않습니다.

프로덕션 형태의 데이터를 그 안의 PII는 넘기지 않으면서 개발, CI, 또는 외부 계약자에게 건네주고자 할 때 사용합니다. 실제 테이블 형태, 실제 행 수, 가짜 이메일입니다.

How it works

마스킹 정책은 프로젝트 범위의, 이름이 붙은 규칙 집합입니다. 각 규칙은 패턴으로 컬럼을 매칭하고 내장 마스킹 함수를 지정합니다.

FieldMeaning
schema_pattern스키마 이름 패턴(% 또는 * = 임의, _ = 한 문자). 기본값은 *.
table_pattern테이블 이름 패턴.
column_pattern컬럼 이름 패턴.
masking_fn아래 내장 함수 중 하나.
fn_args함수 인자(mask_constant 만 하나를 받습니다: value).

브랜치 생성 시점에 masking_policy_id 가 제공되면:

  1. 브랜치는 평소처럼 부모에서 포크됩니다(카피 온 라이트 — 즉시).
  2. 브랜치가 masking 상태로 진입합니다. 엔드포인트가 프로비저닝되지 않고 프록시가 그에 대한 연결을 거부합니다. 마스킹되기 전 데이터를 읽을 수 있는 없습니다.
  3. 마스킹 워커가 최소 권한 롤로 브랜치의 컴퓨트에 연결하여 스키마를 탐색하고, 사용자의 규칙을 그에 매칭한 다음, 모든 재작성을 단일 트랜잭션으로 실행합니다.
  4. 브랜치가 ready 에 안착하고 엔드포인트가 올라옵니다 — 이제 마스킹된 데이터만 제공합니다. 실패가 발생하면 브랜치는 failed 에 안착하고 봉인된 채로 남습니다. 삭제한 뒤 재시도하세요.

규칙 입력은 SQL이 아니라 데이터로 취급됩니다. 식별자는 따옴표로 묶이고 인자 값은 실행 시 파라미터로 바인딩되므로, 악의적인 컬럼 이름이나 상수가 재작성을 벗어날 수 없습니다.

Built-in functions

FunctionEffect
mask_emailmd5(value)@masked.invalid
mask_nameName_ + 8자 해시 접두사
mask_nullNULL(컬럼은 nullable이어야 함)
mask_constant사용자가 제공하는 고정 값(fn_args.value)
mask_ssn_partial***-**-1234 — 마지막 4자리 유지
mask_credit_card****-****-****-1234 — 마지막 4자리 유지
mask_ip0.0.0.0
mask_date_year연도는 유지하고 1월 1일로 잘라냄
mask_hashmd5(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 에 안착하며 절반만 마스킹된 채로 노출되는 일은 결코 없습니다.