korean-pii-gateway 구조와 오탐 처리

LLM API 앞단에서 한국어 개인정보를 마스킹·차단하는 OpenAI/Anthropic 호환 프록시. 구조, 오탐을 줄이는 검증 규칙, PyPI Trusted Publishing 설정.

korean-pii-gateway 구조와 오탐 처리

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/v1

GitHub Actions가 OIDC로 신원을 증명하고, PyPI가 그 신원을 보고 발행을 허용한다. 저장소 시크릿에 장수명 토큰을 둘 필요가 없고 만료·교체 관리도 없다.

한계

  • 보조 방어 계층이다. 법적·규제적 컴플라이언스를 보장하지 않는다
  • 정규식 기반이라 이름·주소처럼 형식이 정해지지 않은 개인정보는 안정적으로 잡지 못한다
  • 게이트웨이를 통과했다고 개인정보가 없다는 뜻은 아니다

Open WebUI 필터와 Claude Code 플러그인 형태로도 쓸 수 있다. 설치 방법은 GitHub 저장소 참고.