PII Shield는 애플리케이션과 LLM 사이에서 개인식별정보(PII)를 탐지·익명화하고, 필요할 때 LLM 응답을 다시 원본 값으로 복원하는 오픈소스 프라이버시 프록시다. Microsoft Presidio, FastAPI, Redis, OpenTelemetry를 조합해 여러 AI 앱이 공통으로 쓰는 개인정보 보호 경계로 배치할 수 있다.
배경 문제
LLM 애플리케이션은 고객 지원 티켓, CRM 메모, 대출 신청서, RAG 문서처럼 민감 정보가 섞인 텍스트를 자주 다룬다. 모델이 Azure OpenAI, Foundry 배포, 자체 호스팅 OSS 모델 중 어디에 있든 프롬프트는 SDK, 게이트웨이, 로깅, 관찰성 파이프라인을 거친다. 이 경로 중 한 곳이라도 원문 PII를 저장하면 GDPR, HIPAA, CCPA, PCI-DSS, 인도 DPDP Act 같은 규제 리스크가 커진다.
간단한 정규식 마스킹은 이메일·전화번호처럼 구조가 고정된 값에는 유용하지만, 이름·주소·조직명처럼 문맥이 필요한 엔티티에는 약하다. PII Shield는 이 문제를 중앙 프록시 계층으로 풀려고 한다.
핵심 아키텍처
PII Shield는 애플리케이션 -> PII Shield -> LLM 흐름으로 동작한다. 애플리케이션은 원문 프롬프트를 먼저 PII Shield에 보내고, PII Shield는 민감 정보를 플레이스홀더나 해시·암호문·가짜 값으로 바꾼 뒤 LLM에 전달할 안전한 텍스트를 반환한다.
주요 구성요소는 다음과 같다.
| 구성요소 | 역할 |
|---|---|
| FastAPI REST API | /anonymize_unique, /deanonymize, /apps, /apps/{id}/config 엔드포인트 제공 |
| Presidio Engine | Microsoft Presidio Analyzer/Anonymizer 기반 탐지·익명화 처리 |
| NLP 백엔드 | spaCy, ONNX, Stanza, Hugging Face Transformers 중 선택 |
| 커스텀 recognizer | Aadhaar, PAN, UPI ID, 인도 운전면허, PIN code 등 인도 식별자 탐지 |
| Redis | 짧은 TTL의 세션 매핑과 장기 앱별 정책 설정 저장 |
| OpenTelemetry | traces, metrics, logs를 Azure Monitor 또는 Grafana LGTM으로 전송 |
| Streamlit UI | Playground와 Admin UI로 탐지 결과 테스트·앱 정책 관리 |
샌드위치 패턴
PII Shield의 기본 사용 패턴은 익명화(anonymize)와 복원(deanonymize)이 LLM 호출을 감싸는 구조다.
- 앱이
POST /anonymize_unique로 원문을 보낸다. - PII Shield가
{{PERSON_1}},{{EMAIL_ADDRESS_1}},{{IN_AADHAAR_1}}같은 안정적인 플레이스홀더를 만든다. - 앱은 익명화된 텍스트만 LLM에 보낸다.
- LLM 응답을 같은 세션 ID와 함께
POST /deanonymize에 보낸다. - PII Shield가 응답 안의 플레이스홀더를 원본 값으로 복원한다.
같은 요청 안에서 같은 사람이 여러 번 등장하면 같은 플레이스홀더를 사용한다. 그래서 LLM은 실제 이름을 모르더라도 동일 인물에 대한 지시 관계(coreference)를 유지할 수 있다. 세션 매핑은 Redis에 짧은 TTL로 저장되어 원문 PII가 오래 남지 않도록 설계되어 있다.
익명화 전략
PII Shield는 엔티티 유형별로 서로 다른 전략을 설정할 수 있다. 앱을 POST /apps로 등록하고 X-App-Id 헤더를 보내면 앱별 정책을 적용한다.
| 전략 | 특징 | 적합한 용도 |
|---|---|---|
replace | 플레이스홀더로 치환하고 매핑을 보관 | LLM 호출 후 원문 복원이 필요한 챗봇·에이전트 |
hash | SHA-256 기반 비가역 값으로 변환 | 분석·집계처럼 원문 복원이 필요 없는 경우 |
encrypt | ML-KEM-768 + AES-256-GCM 또는 Fernet으로 암호화 | 매핑 저장 없이 복원 가능해야 하는 규제 민감 흐름 |
fake | Faker 기반 합성 값으로 대체 | 데모, 테스트 데이터, 합성 데이터셋 생성 |
이 설계는 단순 PII 제거기가 아니라 조직 공통 정책 엔진에 가깝다. 예를 들어 고객 지원 앱은 이름을 replace로 복원 가능하게 두고, 분석 파이프라인은 이메일을 hash로만 남기며, 데모 환경은 모든 식별자를 fake로 바꿀 수 있다.
설치와 실행
라이브러리 모드로는 Python 패키지를 직접 불러와 배치 작업에 사용할 수 있다.
pip install -e .
python -m spacy download en_core_web_lgfrom pii_shield import PiiShieldEngine
engine = PiiShieldEngine()
result = engine.anonymize("Rahul Sharma's Aadhaar is 2345 6789 0123")
print(result.anonymized_text)
restored = engine.deanonymize(result.anonymized_text, result.entity_mapping)서비스 모드에서는 Docker Compose로 PII Shield 앱, Redis, Grafana LGTM 스택을 함께 띄울 수 있다.
docker compose up --buildNLP 엔진은 NLP_ENGINE=spacy, onnx, transformers, stanza로 선택한다. ONNX 백엔드는 CPU 추론 속도를 높이기 위해 INT8 양자화 모델을 사용할 수 있고, Transformers 백엔드는 도메인별 Hugging Face NER 모델로 교체할 수 있다.
언제 쓰면 좋은가
- 여러 AI 앱이 같은 조직 안에서 LLM을 호출하고, 개인정보 마스킹 정책을 한 곳에서 강제해야 하는 경우
- 고객 지원, 금융, 보험, 의료, HR처럼 프롬프트에 이름·연락처·정부 식별자·계좌 정보가 자주 섞이는 경우
- LLM 게이트웨이, 에이전트 미들웨어, RAG 파이프라인 앞단에 감사 가능한 프라이버시 경계를 추가하려는 경우
- 단순 정규식 파일이 커져서 유지보수가 어렵고, 문맥 기반 NER와 규칙 기반 recognizer를 함께 써야 하는 경우
한계와 주의사항
PII Shield는 개인정보 노출 위험을 크게 줄이는 보안 레이어지만 완전한 익명화 보장은 아니다. NER 모델의 미탐지, 도메인 특화 식별자 누락, LLM이 플레이스홀더를 변형하는 문제는 여전히 테스트해야 한다. 특히 고위험 서비스에서는 대표 PII 픽스처셋으로 회귀 테스트를 만들고, recognizer 임계값과 앱별 정책을 운영 데이터에 맞게 조정해야 한다.
또한 샌드위치 패턴은 플레이스홀더가 응답에 남아 있을 때 가장 안정적이다. 모델이 플레이스홀더를 삭제하거나 다른 표기로 바꾸는 작업에는 프롬프트 제약, 후처리 검증, 실패 시 재시도 로직을 함께 둬야 한다.
라이선스
MIT License.
관련 문서
- pii-proxy — LLM 호출 전 개인정보를 로컬에서 마스킹하는 미들웨어 아키텍처 패턴
- openai-privacy-filter — 온프레미스 PII 탐지·마스킹을 위한 양방향 토큰 분류 모델
- pii-proxy-tutorial-llm-redact — Node.js로 로컬 AI 프록시 구현하기
참고 자료
- Introducing PII Shield: A Privacy Proxy for Every LLM Call — Microsoft Developer Community Blog (2026-05-12)
- vikasgautam18/pii-shield — GitHub 공식 저장소