jongkwan.dev
개발 · Essay №057

LLM 보안(2) - 입력단 PII 익명화와 가역 매핑

사용자 입력에 섞인 PII를 외부 LLM에 보내기 전에 가리고, 응답에서 다시 원래대로 되돌리는 입력단 방어 패턴을 정리합니다.

이종관2026년 5월 2일10 min read
Contents

입력단 방어는 외부 LLM에 보내기 전에 PII를 가리고, 돌아온 답에서 필요한 값만 다시 복원하는 구조입니다.

입력단이 첫 번째 방어선인 이유

외부 LLM API에 요청을 보내는 순간, 본문에 담긴 텍스트가 위탁사 인프라로 넘어갑니다. 그 안에 회원 이름이나 전화번호가 있으면, 우리가 통제할 수 없는 곳에 원문으로 도착합니다.

입력단에서 PII를 가리는 일은 가장 앞쪽의 방어선입니다. 여기서 줄인 노출은 RAG, 도구 호출, 관측 로그로 이어지는 후속 경로의 위험도 함께 줄입니다.

입력단 방어는 탐지와 치환으로 나뉩니다. 탐지는 어떤 토큰이 PII인지 찾고, 치환은 찾아낸 토큰을 가짜 값으로 바꿔 LLM에 보냅니다.

두 단계를 분리해야 합니다. 그래야 탐지 정확도와 치환 자연스러움을 따로 튜닝할 수 있습니다.

Microsoft Presidio

탐지 도구로는 Microsoft Presidio가 많이 쓰입니다. 내부에는 AnalyzerEngine(탐지)과 AnonymizerEngine(치환)이 분리돼 있습니다.

탐지기는 spaCy, Stanza, Transformers NER, 정규식, 체크섬 검증, 사용자 정의 recognizer를 함께 씁니다.

영어권 기본 엔티티에는 PERSON, EMAIL_ADDRESS, PHONE_NUMBER, CREDIT_CARD, IP_ADDRESS, LOCATION, US_SSN, DATE_TIME 등이 있습니다.

영어 텍스트라면 설치 직후부터 상당량을 잡습니다. 한국어는 이름, 주소, 주민등록번호, 계좌번호 같은 항목을 별도로 보강해야 합니다.

한국어 보강

한국어 NER 모델로 이름·지명·기관을 찾고, 한국 특유의 식별자는 PatternRecognizer로 별도 등록합니다.

  • klue/bert-base-ner 또는 KPF-bert-ner로 PERSON·LOC·ORG 보강
  • 주민등록번호·계좌번호·사업자등록번호는 정규식 + 체크섬을 단 PatternRecognizer
  • nlp_engine_provider에 한국어 spaCy(ko_core_news_lg) 또는 transformers 백엔드 주입

Presidio의 정확도는 NER 모델의 한국어 학습 분포에 좌우됩니다. 의료·금융·HR처럼 도메인이 바뀌면 false negative 패턴도 달라집니다.

운영 환경에서는 누락 사례를 골든셋으로 모아 분기마다 점검합니다.

가역 익명화

탐지만으로는 부족합니다. 치환된 값이 LLM 응답에 그대로 남으면 사용자가 자기 이름 대신 가짜 이름을 보게 됩니다.

LangChain의 PresidioReversibleAnonymizer는 치환 매핑을 보관합니다. 응답이 돌아온 뒤에는 그 매핑을 이용해 필요한 값을 다시 원본으로 복원합니다.

python
from langchain_experimental.data_anonymizer import PresidioReversibleAnonymizer
 
anonymizer = PresidioReversibleAnonymizer(
    analyzed_fields=["PERSON", "PHONE_NUMBER", "EMAIL_ADDRESS", "KR_RRN"],
    faker_seed=42,
    add_default_faker_operators=True,
)
 
safe_prompt = anonymizer.anonymize("저는 홍길동, 010-1234-5678 입니다.")
answer = llm.invoke(safe_prompt)
final = anonymizer.deanonymize(answer)

위 코드에서 anonymizeanalyzed_fields에 등록된 엔티티를 찾아 가짜 값으로 바꿉니다. 치환 매핑은 deanonymizer_mapping에 저장됩니다.

LLM 응답이 돌아오면 deanonymize가 그 매핑을 보고 가짜 값을 원본으로 복구합니다. KR_RRN은 한국 주민등록번호용으로 직접 등록한 식별자입니다.

여기에 한 가지 철칙이 붙습니다. deanonymizer_mapping은 세션·요청 스코프 in-memory에서만 살려두고, 영속화하지 않습니다.

매핑을 디스크나 데이터베이스에 저장하면 그 저장소가 그림자 DB가 됩니다. 평문 PII와 가짜 값을 1:1로 묶어 보관하기 때문입니다.

LangGraph 환경이라면 매핑은 PrivateState(in-memory)에만 둡니다. PublicState(checkpoint 가능)에는 마스킹된 텍스트만 흘립니다.

Prϵϵmpt 스타일 라우팅

PresidioReversibleAnonymizer의 기본 동작은 Faker로 무작위 가짜 값을 만듭니다. 자연스러운 이름·주소를 채우는 데는 좋지만, 같은 회원이 여러 번 등장할 때 문제가 생깁니다.

매번 다른 가짜 값으로 바뀌면 참조 무결성이 깨집니다. 예컨대 "이 회원의 거래 상위 5건"이라는 질의에서 회원 ID가 호출마다 다른 값으로 치환되면, LLM은 같은 사람을 동일인으로 인식하지 못합니다.

논문 Prϵϵmpt(arXiv:2504.05147)는 토큰의 역할에 따라 두 가지 메커니즘을 섞어 적용하는 dual-strategy sanitizer를 제안했습니다.

토큰 종류메커니즘가역 키
카드/계좌/전화/회원IDFPE (FF3-1) + KMS 키클라이언트 보유
나이/금액/거리 등 수치형mDP exponential mechanism비가역 (ε 보장)
이름/주소Faker 또는 LOPSIDED 가명세션 in-memory

FPE(Format-Preserving Encryption)는 형식을 보존하는 결정론 암호입니다. 같은 입력은 같은 출력으로 매핑되므로, 카드번호처럼 형식이 중요한 토큰에 적합합니다.

mDP(Metric Differential Privacy)는 수치형 값에 가까운 값을 더 높은 확률로 할당하는 노이즈 주입입니다. 정확한 값은 가리되, LLM이 "비슷한 크기"라는 정보는 활용할 수 있게 합니다.

LangGraph에서는 노드 한 개를 추가해 토큰 종류별로 라우팅하는 형태로 구현할 수 있습니다. Faker 단일 사용에서 결정론 FPE를 도입하는 것이 가장 비용이 적은 업그레이드입니다.

SLM cascade

Presidio, 정규식, NER는 직접 PII를 잘 잡습니다. 하지만 결합으로 식별 가능해지는 간접 식별자는 놓칠 수 있습니다.

"강남역 인근에서 일하는 50대 부장이 작년에 폐 수술을 받았다"는 문장에는 직접 PII가 없습니다. 그래도 회사 위치, 나이, 직급, 질병이 결합되면 한 사람을 특정할 수 있습니다.

이 잔여물을 잡으려고 소형 언어 모델(small language model, SLM)을 cascade에 추가합니다. 후보로는 다음이 있습니다.

  • SEAL (Self-Refining Anonymizer, arXiv:2506.01420) — adversarial distillation으로 학습된 8B SLM. GPT-4 anonymizer와 동급의 privacy-utility를 보고하고, 단일 GPU(L4/A10)에 vLLM으로 띄울 수 있습니다.
  • LOPSIDED (arXiv:2510.27016) — 의미 적합 가명 재배치. 직급·연령·관계의 일관성을 유지하면서 가명을 부여합니다.
  • Anonymizer-SLM 0.6B/1.7B/4B 시리즈 — 경량 옵션.

cascade는 비용도 줄입니다. 1차 정규식·NER가 통과한 잔여물만 SLM으로 보내면, 모든 입력에 대형 모델을 쓰지 않아도 됩니다.

입력단 cascade 전체 모양

위 도구들을 묶으면 입력단 파이프라인은 다음 흐름이 됩니다.

각 단계는 cascade로 작동합니다. 앞 단계가 못 잡은 것을 뒤 단계가 보완하고, 단일 sanitizer에 의존하지 않는 구조입니다.

정리

입력단은 탐지·치환·가역 매핑을 분리한 cascade로 설계합니다. Presidio와 한국어 recognizer로 1차 탐지하고, 토큰 성격에 따라 Faker·FPE·mDP·LOPSIDED를 나눠 씁니다.

가역 매핑은 세션 스코프 in-memory에만 두고 영속화하지 않습니다. 간접 식별자는 SLM cascade로 한 번 더 거르고, Faker 단일 사용에는 결정론 FPE 라우팅을 추가하는 것이 현실적인 업그레이드입니다.

다음 글은 두 번째 경로인 RAG·도구·MCP 단계 방어를 다룹니다.