메인 콘텐츠로 건너뛰기
맞춤형 PII 정책 추가가 콘솔에서 정책을 만들고 적용하는 절차를 다룬다면, 이 페이지는 규칙의 내용을 다룹니다 — 무엇을 어느 필드에 적어야 탐지 엔진이 정확하게 동작하는지, 그리고 규칙들이 서로 충돌하지 않도록 우선순위를 어떻게 설계하는지. 모든 예시는 Starfort가 제공하는 기본 PII 정책(한국형 주민등록번호·여권·운전면허·휴대폰·계좌·카드 등 27개 정규식 + NER 3종 + 키워드)에서 발췌했습니다.

정책 구조와 처리 순서

PII 정책은 세 가지 규칙 배열로 구성됩니다. 허용되는 최상위 키는 ner, regex, keyword이며, 엔진은 항상 Keyword → Regular Expression → NER 순서로 검사합니다. 앞 단계가 확정한 텍스트는 뒤 단계에 가려진 상태로 전달되므로, 앞 단계의 판정이 그 텍스트에 대해 최종입니다.
규칙 유형특성적합한 대상
Keyword대소문자 구분 정확 일치. 가장 빠르고 결정적내부 코드네임, 알려진 안전 값(allowlist)
Regular Expression패턴 일치. 결정적형식이 고정된 식별자(주민등록번호, 전화번호, 카드번호, 이메일)
NER EntityAI 모델 탐지. 문맥 이해문맥에 의존하는 정보(이름, 주소), 패턴이 놓치는 변형

우선순위 설계

규칙을 늘릴수록 규칙끼리의 상호작용이 결과를 좌우합니다. 세 가지 우선순위를 기억하세요.
  1. 규칙 유형 우선순위: Keyword > Regular Expression > NER. 앞 단계가 확정한 텍스트는 뒤 단계가 다시 판정하지 않습니다.
  2. PASSING은 allowlist입니다. policy_type: "PASSING" 규칙이 매치한 텍스트는 안전으로 확정되어, 이후 어떤 마스킹·차단 규칙도 덮어쓰지 못합니다. 같은 유형 안에서 같은 텍스트를 두 규칙이 매치하면 id가 낮은 규칙이 우선합니다.
  3. action 우선순위: BLOCK > MASK > PASS. 요청 안에서 규칙 하나라도 BLOCK을 결정하면, 다른 규칙이 마스킹만 했더라도 요청 전체가 차단됩니다.
기본 정책은 이 원칙을 그대로 활용합니다. 실데이터 마스킹 정규식(id 10 이상)보다 앞선 id(0–9)에 테스트 패턴 PASSING 규칙을 배치해, 문서 예시나 QA에 쓰이는 더미 값이 마스킹되지 않게 합니다:
{
  "id": 0,
  "rule_id": "test_data:_resident_number_test_pattern",
  "regex": "(?<!\\d)(?:(\\d)\\1{5}[-\\. ]\\1{7}|(?:000000|111111|222222|333333|999999|123456|000101|010101|990101)[-\\. ](?:0000000|1111111|2222222|9999999|1234567))(?!\\d)",
  "description": "000000-0000000, 111111-1111111, 123456-1234567 (주민번호 테스트)",
  "policy_type": "PASSING",
  "mask_word": "TEST_DATA",
  "alert_message": "test data pattern - allowed"
}
같은 목적의 keyword 규칙도 있습니다 — 예시 문서의 단골 이름 홍길동을 PASSING으로 선점해, NER 이름 규칙이 마스킹하지 못하게 합니다. Keyword 단계가 NER보다 먼저 실행되기 때문에 확실하게 동작합니다.

Regular Expression 규칙 작성

기본 정책의 주민등록번호 규칙입니다:
{
  "id": 10,
  "rule_id": "resident_number:_all_gender_with_separators",
  "regex": "(?<!\\d)(?:[0-9]{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12][0-9]|3[01]))[-\\. ][1-8]\\d{6}(?!\\d)",
  "description": "901231-1234567, 901231-5234567, 901231.1234567, 901231 1234567",
  "policy_type": "MASKING",
  "mask_word": "RESIDENT_NUMBER",
  "alert_message": "resident number detected"
}
이 규칙이 보여주는 작성 관행:
  • 숫자 경계를 고정하세요. 앞뒤의 (?<!\d) / (?!\d)가 없으면 더 긴 숫자열(계좌번호, 바코드)의 중간 조각이 주민등록번호로 오탐됩니다.
  • description에 매치 예시를 기록하세요. 이 필드는 탐지에 쓰이지 않지만, 나중에 규칙을 검토하는 사람이 패턴을 다시 해독하지 않아도 되게 합니다.
  • 다른 규칙과의 충돌을 패턴에서 해결하세요. 기본 정책의 휴대폰 규칙은 후행 (?![-\.]?\d) 가드를 두어, 013-12345678-901 같은 은행 계좌번호의 앞부분을 전화번호로 선점하지 않게 합니다.
빈 문자열에 매치될 수 있는 패턴(\d*, secret|)은 아무것도 탐지하지 못하고 건너뛰어집니다. 또한 패턴 앞뒤의 공백은 저장 시 정리되므로, 의도적인 경계 공백은 \s[ ]처럼 패턴 안에 표현하세요.

NER Entity 규칙 작성

NER 규칙에서 AI 모델에 전달되는 필드는 Name, Description, Positive Examples, Negative Examples 네 가지뿐입니다. Policy Type, Mask Word, Alert Message는 탐지 이후의 처리만 결정하며 탐지 자체에는 영향을 주지 않습니다. 즉, 탐지 정확도를 좌우하는 것은 앞의 네 필드입니다. 기본 정책의 한국 주소 규칙을 설명에 맞춰 간추린 예시입니다. 이 규칙의 핵심은 구체성의 경계입니다 — 같은 “위치 이야기”라도 특정 개인·사업장을 찾아갈 수 있을 만큼 구체적이면 민감정보이고, 일반적인 위치 언급이면 아닙니다. 아래 각 절이 예시의 어느 부분을 가리키는지 보면서 읽어보세요:
{
  "id": 2,
  "name": "주소 (한국)",
  "description": "특정 개인이나 사업장의 위치를 식별할 수 있는 한국 주소. 반드시 도로명+건물번호 또는 동/리+번지 같은 구체적 요소를 포함해야 하며, 동·호·층 같은 상세 정보가 따라올 수 있다. 랜드마크, 지하철역 출구, 건물명 단독, 번지 없는 행정구역 같은 일반적인 위치 언급은 주소가 아니다.",
  "policy_type": "MASKING",
  "mask_word": "ADDRESS",
  "alert_message": "주소 감지됨",
  "positive_examples": [
    "서울특별시 강남구 테헤란로 152 강남파이낸스센터 28층 →테헤란로 152 강남파이낸스센터 28층",
    "거주지: 서울 서초구 반포동 123-45 래미안 아파트 503동 201호 →반포동 123-45 래미안 아파트 503동 201호",
    "사무실 주소는 종로구 새문안로 76 에스타워 12F입니다 →새문안로 76 에스타워 12F"
  ],
  "negative_examples": [
    "강남역 11번 출구에서 만나",
    "스타벅스 종로점에서 보자",
    "신사동 가로수길 카페 추천"
  ]
}

Description — 정의 + 구체성 조건

위 Description은 네 가지 요소를 순서대로 담고 있습니다: 정의(개인·사업장 위치 식별), 필수 구체성 조건(“도로명+건물번호 또는 동/리+번지”), 허용 변형(동·호·층 상세), 그리고 제외 조건(랜드마크, 지하철역 출구, 건물명 단독, 번지 없는 행정구역). 민감/비민감을 가르는 경계선을 Description이 문장으로 그어주는 것입니다 — 모델은 “이 경우는 아니다”라고 적힌 케이스에 NO라고 답하도록 지시받으므로, 제외 조건은 실제로 동작합니다. 아래 시나리오 3이 이 경계가 실전에서 갈리는 모습을 그대로 보여줍니다.

Positive Examples — 화살표 규약

모든 긍정 예시는 문맥 →값 형태로 작성합니다. 모델은 뒤가 탐지해야 할 정확한 값이라고 학습합니다.
  • 앞의 문장은 언제 발동할지(재현율)를, 뒤의 값은 정확한 출력 형태(정밀도)를 가르칩니다.
  • 값은 마스킹 범위도 가르칩니다. 위 세 예시 모두 값이 광역 단위(서울특별시, 서초구 등)를 빼고 구체 요소부터 시작합니다 — 규칙이 어디서부터 어디까지를 민감정보로 볼지, 예시의 값으로 알려주는 것입니다.
  • 값은 입력에서 다시 찾을 수 있어야 합니다. 나타난 그대로 적는 것이 가장 안전하며(공백 차이 정도는 허용), 도로명과 건물명을 재배열하는 식으로 재구성한 값은 위치를 찾지 못해 버려집니다.
  • 위 세 예시는 실제로 등장할 표면 형태를 하나씩 가르칩니다: 도로명 주소 기본형, 지번(동+번지)과 호실이 붙는 변형, 레이블 없이 서술문 안에 박힌 주소. 놓치면 안 되는 형태마다 예시를 하나씩 두세요.
  • 잡으려는 데이터의 언어로 예시를 쓰세요 — 한국 주소라면 한국어 예시로.

Negative Examples — 오탐 방어막

형식은 비슷하지만 구체성이 부족한 근접 사례를 담으세요. 위 세 negative는 각각 다른 오탐 경로를 막습니다: 강남역 11번 출구(만남 장소로 쓰이는 랜드마크 — 숫자가 있어도 주소가 아님), 스타벅스 종로점(상호+지점명), 신사동 가로수길(번지 없는 동네 이름). 셋 다 Description의 제외 조건과 짝을 이룹니다. NER 규칙은 소규모 배치로 함께 스크리닝되므로, 한 규칙의 부실한 negative가 이웃 규칙의 과탐까지 유발할 수 있습니다.

Keyword 규칙 작성

Keyword는 대소문자를 구분하는 정확 일치입니다. 문맥을 보지 않으므로 짧고 일반적인 단어는 피하세요.
  • 좋은 BLOCKING 키워드: PROJECT-ORION 같은 내부 코드네임 — 어디서 나오든 그 자체로 민감.
  • 좋은 PASSING 키워드: 기본 정책의 홍길동 — 알려진 안전 값을 선점해 뒤 단계가 건드리지 못하게 하는 allowlist.
  • 나쁜 키워드: 계정 같은 일반 명사 — 등장하는 모든 곳에서 무차별 발동.

예시 시나리오

기본 PII 정책이 할당된 Guardian에 요청을 보냈을 때의 동작입니다.

시나리오 1 — 휴대폰 번호 마스킹

“제 번호는 010-2543-2513입니다. 010.5364.1451로도 연락 돼요.”
휴대폰 정규식이 두 값을 모두 매치합니다. 결과는 "action": "MASK", 본문은 제 번호는 [PHONE_NUMBER_1]입니다. [PHONE_NUMBER_2]로도 연락 돼요. — 마스크 단어에는 등장 순서대로 인덱스가 붙습니다.

시나리오 2 — 테스트 데이터는 통과, 실데이터는 마스킹

“테스트 계정 주민번호는 990101-1234567, 실계정은 901231-1234567입니다.”
990101-1234567은 날짜가 유효해 주민등록번호 마스킹 규칙(id 10)에도 매치되지만, 잘 알려진 테스트 값이라 PASSING 테스트 패턴(id 0)이 먼저 선점해 그대로 통과합니다. 901231-1234567만 마스킹되어 결과는 ... 990101-1234567, 실계정은 [RESIDENT_NUMBER_1]입니다. — allowlist 규칙이 실데이터 규칙보다 낮은 id를 가진 이유입니다.

시나리오 3 — 구체적인 주소만 민감정보

“미팅은 강남역 11번 출구 앞 카페에서 해요. 계약서는 서울 강남구 테헤란로 152 강남파이낸스센터 28층으로 보내주세요.”
같은 문장에 위치 언급이 두 번 나오지만 판정이 갈립니다. 강남역 11번 출구는 숫자가 있어도 만남 장소 수준의 일반 언급이라 — Description의 제외 조건과 negative example이 학습시킨 대로 — 통과합니다. 도로명+건물번호가 있는 구체 주소만 마스킹되고, 값이 가르친 대로 마스킹 범위는 구체 요소부터 시작합니다: 미팅은 강남역 11번 출구 앞 카페에서 해요. 계약서는 서울 강남구 [ADDRESS_1]으로 보내주세요.

시나리오 4 — BLOCK은 전부를 이깁니다

마스킹 규칙 열 개가 매치하고 BLOCKING 규칙 하나가 매치하면, 결과는 "action": "BLOCK"이고 마스킹된 본문은 반환되지 않습니다. 유출 자체를 막아야 하는 값(사내 기밀 코드네임 등)에만 BLOCKING을 쓰고, 나머지는 MASKING으로 두는 것이 좋습니다.

체크리스트

  • 정규식에 숫자·단어 경계((?<!\d), (?!\d))를 넣었는가?
  • 테스트·예시 값이 있다면 PASSING 규칙으로 먼저 선점했는가?
  • NER Description에 정의 + 구체성·문맥 조건 + 제외 조건을 적었는가?
  • Positive Examples를 문맥 →값 형태로, 값이 마스킹 범위를 정확히 가리키게 적었는가?
  • Negative Examples에 구체성이 부족한 근접 사례를 담았는가?
  • BLOCKING은 정말 차단이 필요한 규칙에만 썼는가?
규칙 정의 전체는 Starfort 기본 PII 정책에서 볼 수 있습니다 — 콘솔의 JSON 편집기로 불러온 뒤 필요한 규칙만 남기고 다듬는 것이 가장 빠른 시작 방법입니다. 콘솔 정책 페이지의 TIP 버튼에서도 이 가이드의 요약을 볼 수 있습니다.
규칙 수와 예시 분량은 곧 탐지 비용입니다. 모든 호출에 규칙 정의 전체가 전달되므로, 지나치게 장황한 정책은 응답을 느리게 하고 극단적으로는 모델 입력 한도를 넘겨 요청을 실패시킵니다. 규칙당 날카로운 예시 5~10개가 망라식 나열보다 낫습니다.