korean-pii-gateway 구조와 오탐 처리
LLM API 앞단에서 한국어 개인정보를 마스킹·차단하는 OpenAI/Anthropic 호환 프록시. 구조, 오탐을 줄이는 검증 규칙, PyPI Trusted Publishing 설정.
LLM API로 나가는 요청에서 한국어 개인정보를 탐지해 마스킹하거나 차단하는 프록시. OpenAI·Anthropic 프로토콜을 지원한다. 코드는 GitHub.
pip install korean-pii-gateway구조
OpenAI 호환 프록시라서 클라이언트는 base_url만 바꾸면 된다. SDK, 프롬프트, 나머지 코드는 그대로다.
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8500/v1", # 이 줄만 바꾼다
api_key="...",
)요청의 메시지 본문을 검사하고, 개인정보가 있으면 마스킹하거나 차단한 뒤 업스트림으로 전달한다.
패키지는 두 개다.
korean-pii: 탐지·마스킹 엔진. 외부 의존성 없음(정규식 + 표준 라이브러리). 개인정보를 다루는 코드라 공급망 검토 대상을 늘리지 않으려고 뺐다korean-pii-gateway: 이 엔진을 쓰는 FastAPI 프록시
오탐 줄이기
13자리·16자리 숫자는 주문번호, 로그 ID, 타임스탬프, 상품 코드에도 흔하다. 형식만 보고 잡으면 오탐이 많아서 탐지기마다 검증 단계를 뒀다.
주민등록번호
- 체크섬: 앞 12자리에 가중치를 곱한 합으로 마지막 자리를 검증한다. 무작위 13자리가 통과할 확률은 약 1/11
- 하이픈 없는 13자리는 체크섬이 맞아야만 판정:
9012311234567은901231-1234567보다 우연한 숫자열일 가능성이 높다 - 날짜·성별 자리: 생년월일이 실제 존재하는 날짜인지, 성별 자리가 유효한지 확인
카드번호
Luhn 검증을 통과한 16자리만 잡는다.
그 외
- 전화번호, 계좌번호, 이메일, API 키 같은 시크릿 패턴
- 주변 단어로 판단하는 문맥 기반 탐지기
- 판정 결과는 테스트 261개로 고정해 뒀다. 규칙을 고칠 때 오탐이 늘어나는 회귀를 잡는 용도
Anthropic 프로토콜
- OpenAI 형식과 별도로 Anthropic 네이티브
/v1/messages경로를 지원한다. 요청 구조와 스트리밍 응답 형식이 다르다 - 검사 대상:
system블록,tool_result,tool_use.input, 문서 블록 등 텍스트가 들어갈 수 있는 모든 위치 - 이미지 같은 비텍스트 블록은 그대로 통과
- 에러는 각 프로토콜 형식으로 반환한다. 클라이언트 SDK가 파싱할 수 있어야 한다
PyPI 배포: Trusted Publishing
태그를 푸시하면 GitHub Actions가 PyPI에 올린다. API 토큰은 쓰지 않는다.
jobs:
publish:
environment: pypi
permissions:
id-token: write # OIDC 토큰 발급 권한
steps:
- uses: pypa/gh-action-pypi-publish@release/v1GitHub Actions가 OIDC로 신원을 증명하고, PyPI가 그 신원을 보고 발행을 허용한다. 저장소 시크릿에 장수명 토큰을 둘 필요가 없고 만료·교체 관리도 없다.
한계
- 보조 방어 계층이다. 법적·규제적 컴플라이언스를 보장하지 않는다
- 정규식 기반이라 이름·주소처럼 형식이 정해지지 않은 개인정보는 안정적으로 잡지 못한다
- 게이트웨이를 통과했다고 개인정보가 없다는 뜻은 아니다
Open WebUI 필터와 Claude Code 플러그인 형태로도 쓸 수 있다. 설치 방법은 GitHub 저장소 참고.