jongkwan.dev
개발 · Essay №059

LLM 보안(4) — Egress 게이트웨이로 마지막 안전망 만들기

외부 LLM 트래픽을 LiteLLM Proxy·Cloudflare AI Gateway·Portkey로 한 곳에 모으고, zero-retention 계약과 audit log 위에 정규식 차단을 마지막 안전망으로 얹는 구조를 정리합니다.

이종관2026년 5월 4일14 min read
Contents

게이트웨이 단계의 정규식 차단은 1차 방어가 아니라 마지막 안전망입니다. 그 위에 zero-retention 계약과 데이터 분류 라우팅, immutable audit log가 함께 놓여야 의미가 생깁니다.

외부 LLM 트래픽을 한 곳에 모아야 하는 이유

서비스가 커질수록 외부 LLM API 호출 지점이 흩어집니다. Agent 워크플로우, 별도 임베딩 파이프라인, 운영자가 직접 만든 임시 스크립트가 모두 자체 API 키와 자체 클라이언트로 외부에 나갑니다. 이 분산 상태에서는 어떤 데이터가 어떤 모델로 가고 있는지 추적할 수 없고, 사고가 났을 때 어디부터 차단해야 하는지 결정도 늦어집니다.

Egress 게이트웨이는 이 분산을 한 곳으로 모으는 장치입니다. 모든 외부 LLM 트래픽이 동일한 프록시를 거치게 하면, 인증, 모델 라우팅, 키 관리, rate limit, audit log, 마지막 단계의 PII 정규식 차단을 한 위치에서 강제할 수 있습니다. 사고 시에도 게이트웨이 한 군데만 차단해 외부 송신을 즉시 멈출 수 있습니다.

여기서 중요한 인식 하나를 짚어둡니다. 게이트웨이의 PII 정규식 차단은 1차 방어가 아니라 cascade의 마지막 안전망입니다. 1차 방어는 입력단 sanitize, 2차는 도구·RAG 단계의 마스킹이고, 게이트웨이는 그 모두를 통과한 잔여물을 마지막으로 한 번 더 거르는 위치입니다. 이 위치 인식을 빼면, 정규식이 PII를 못 잡았을 때 곧바로 누출이 됩니다.

게이트웨이가 제공하는 5가지 통제

산업에서 통용되는 Egress 게이트웨이는 LiteLLM Proxy, Cloudflare AI Gateway, Portkey 셋이 사실상 표준 후보입니다. 구현체는 다르지만, 공통으로 제공하는 통제는 다음 다섯입니다.

  1. 모델 라우팅 — 데이터 분류 등급에 따라 외부 모델/자체 vLLM/TEE를 선택. 카탈로그에 등록된 등급-모델 매핑을 강제합니다.
  2. API 키 추상화 — 클라이언트는 게이트웨이 키만 알고, 실제 벤더 키는 게이트웨이가 보관·로테이션합니다. 키 유출 폭이 줄고 회수가 빨라집니다.
  3. Rate limit + cost guardrail — 사용자·팀·모델별 호출 빈도와 비용 상한을 강제합니다. 무한 루프 도구 호출이 비용 폭탄으로 이어지는 사고를 막습니다.
  4. Audit log — 누가, 언제, 어떤 입력으로, 어떤 모델을 호출했는지 immutable하게 기록합니다.
  5. PII 정규식 차단 — cascade 최종 단계에서 출력·입력에 남은 식별자를 거릅니다.

세 게이트웨이의 차이는 운영 위치와 통합 깊이에 있습니다. LiteLLM은 자체 호스팅 가능한 Python 프록시로 OpenAI 호환 API를 100+ 모델에 제공합니다. callback hook으로 입출력 처리를 직접 코드로 박을 수 있어 자체 마스킹·가드레일과의 결합이 자유롭습니다. Cloudflare AI Gateway는 엣지에서 동작하는 매니지드 게이트웨이로 캐시·로깅·rate limit이 강점입니다. Portkey는 multi-provider 라우팅과 fallback, 분석 대시보드를 SaaS 형태로 제공합니다.

선택은 보통 컴플라이언스가 결정합니다. 한국 PIPA(개인정보 보호법) 환경에서 confidential 이상 데이터 트래픽이 위탁사 인프라를 거치는 것이 부담스럽다면, self-host LiteLLM이 무난합니다. Public·Internal 트래픽 비중이 크고 글로벌 분산 캐시가 가치 있다면 Cloudflare AI Gateway가 어울립니다.

Zero-retention 계약

게이트웨이가 데이터를 보내기 전에 먼저 확인할 것은 벤더 측 보존 정책입니다. 위탁사가 우리 요청을 학습이나 모델 개선에 쓰지 않도록 zero-retention 옵션을 계약으로 박아야 합니다.

이 통제가 마스킹보다 더 근본적인 이유는 모델 memorization 연구가 보고된 결과입니다. Carlini 2021과 Nasr 2023의 후속 작업은, 약 200달러어치 쿼리만으로 ChatGPT의 학습 데이터에서 5% 이상을 verbatim 추출할 수 있음을 보였습니다. 우리 쪽 마스킹이 완벽해도, 벤더 모델이 과거 다른 사용자의 PII를 기억하고 있다가 우리 응답에 섞어 내보낼 수 있다는 의미입니다. 그 누출은 우리가 차단할 수 없습니다.

법무·컴플라이언스 관점에서는 다음 3종 세트가 미니멈입니다.

  • PIPA: 국외 이전 동의·통지, 위탁 고지, 보유·파기 정책. 클라우드 LLM은 zero-retention 약관 + 한국 리전 + DPA(Data Processing Agreement) 3종 세트가 미니멈.
  • GDPR: SCC(Standard Contractual Clauses) + TIA(Transfer Impact Assessment) 필요.
  • HIPAA: BAA(Business Associate Agreement) 체결 가능 벤더(AWS Bedrock, Azure OpenAI 등)로 한정.

이 계약 위에서만 마스킹과 정규식 차단이 의미가 생깁니다. zero-retention 계약 없는 모델에는 어떤 마스킹 수준에서도 restricted 데이터를 송신하지 않는다는 정책을 카탈로그에 강제합니다.

데이터 분류 라우팅

게이트웨이가 받는 모든 요청에는 메타데이터로 데이터 등급이 붙어 있어야 합니다. 등급별 라우팅은 다음과 같이 강제됩니다.

등급추론 경로
Public외부 LLM OK (원문)
Internal외부 LLM + 마스킹
Confidential외부 LLM (zero-retention DPA) 또는 H100 CC TEE
Restricted (PII/PHI/시크릿)vLLM in VPC 또는 H100 CC TEE only — 외부 송신 금지

게이트웨이는 등급 메타데이터가 없거나 잘못된 라우팅이 들어오면 즉시 거절합니다. 정규식 차단보다 라우팅 결정이 더 강한 통제입니다 — 정규식은 패턴을 못 잡으면 통과시키지만, 라우팅은 등급이 맞지 않으면 호출 자체가 일어나지 않습니다.

이 단계에서 한 가지 자주 빠지는 항목이 있습니다. 임베딩도 같은 등급 시스템에 포함시켜야 합니다. 임베딩 inversion 연구가 누적되면서, 임베딩만 보관해도 원문에 가깝게 복원될 수 있다는 결론이 나왔기 때문입니다(Vec2Text 재현 BLEU 98.5 보고). confidential 이상 데이터의 임베딩은 self-host 벡터 DB로 보내고, 외부 임베딩 API에 같은 데이터를 보내지 않도록 라우팅에서 끊습니다.

정규식 차단

cascade 최종 단계의 정규식 차단은, 앞단의 마스킹이 못 잡은 것을 거르는 자리입니다. LiteLLM의 callback hook을 예로 들면 다음과 같은 형태가 됩니다.

python
# pseudo-code
async def pre_call_hook(data, user_api_key_dict, call_type):
    text = extract_text(data)
    if has_pii_pattern(text):  # 주민등록번호, 카드번호, 계좌번호, 이메일 등
        raise BlockedRequest("egress PII pattern matched")
    log_audit(user_api_key_dict, data, redacted=False)
    return data

이 코드의 흐름은 단순합니다. 요청 본문에서 텍스트를 뽑아 정규식 패턴 매칭을 돌리고, 잡히면 호출 자체를 거절합니다. audit log는 매 요청에 대해 무조건 기록합니다.

정규식이 잡는 것은 형식이 명확한 식별자(주민등록번호, 카드번호, 계좌번호, 이메일, 전화번호)에 한정됩니다. 자연어로 표현된 식별자나 간접 식별자(나이+직장+질병)는 정규식이 잡을 수 없으므로, 이 책임은 입력단 SLM cascade가 가져갑니다. 게이트웨이의 정규식은 명확한 패턴만 잡고, 나머지는 차단하지 않는다는 점을 알고 있어야 안전하다는 착각을 피할 수 있습니다.

Audit log

게이트웨이가 만드는 가장 큰 가치는 사고 시 추적 가능성입니다. 누가, 언제, 어떤 입력으로, 어떤 모델을 호출했는지를 immutable하게 보관해야 사고 직후 영향 범위를 산정할 수 있습니다.

  • append-only — 한 번 쓴 레코드는 수정·삭제 불가. SHA-256 해시 체인을 걸어 prev_hash로 무결성을 검증합니다.
  • WORM(Write Once Read Many) 저장 — S3 Object Lock의 Compliance 모드로 retention 기간 동안 삭제 불가하게 잠급니다.
  • 분리 권한 — audit log를 쓰는 ID와 읽는 ID를 분리해, 운영자가 자기 호출 이력을 지울 수 없도록 합니다.

GDPR Art. 32(Security of processing)는 "적절한 기술적 조치"의 증거로 audit log를 인정하는 흐름이 있고, PIPA 시행령 제30조의 안전성 확보 조치 강화 증거로도 활용됩니다. immutable log 자체가 컴플라이언스 산출물이 됩니다.

Phase 0

게이트웨이를 처음 도입할 때 1주 내 끝낼 수 있는 항목은 다음과 같습니다.

  • LiteLLM/AI Gateway 등 egress proxy 설치 + 외부 LLM 엔드포인트 화이트리스트 (등록되지 않은 모델로의 호출 차단)
  • 게이트웨이 통과 키만 클라이언트에 배포, 벤더 키는 게이트웨이가 보관
  • 모든 destructive tool에 LangGraph interrupt() 강제
  • LangSmith hide_inputs/hide_outputs + Presidio callable 또는 self-hosted Langfuse
  • Audit log를 S3 Object Lock의 Compliance 모드로 즉시 잠금

확장은 그다음 1개월 동안 zero-retention 계약 갱신, 데이터 분류 카탈로그 4등급 정책, PII 골든셋 200개 회귀 테스트 도입으로 이어집니다.

정리

Egress 게이트웨이는 외부 LLM 트래픽을 한 곳에 모아 모델 라우팅·키 추상화·rate limit·audit log·PII 정규식 차단을 동시에 강제하는 장치입니다. LiteLLM Proxy(self-host), Cloudflare AI Gateway(엣지 매니지드), Portkey(SaaS) 중 컴플라이언스 요구에 맞는 것을 고릅니다.

정규식 차단은 cascade의 마지막 안전망일 뿐입니다. zero-retention 계약·데이터 등급 라우팅·immutable audit log가 함께 놓여야 의미가 생깁니다.

임베딩도 같은 등급 시스템에 포함시킵니다. 등급이 맞지 않는 호출은 정규식이 아니라 라우팅에서 끊습니다.

마지막 글은 출력 가드레일과 관측·삭제권을 다루며 시리즈를 마무리합니다.