블로그 목록으로
컴플라이언스·2026년 5월 25일·8분 분량

DSGVO를 준수하는 LLM 사용 — PII 마스킹, AVV 및 Zero Data Retention

Claude / Gemini / GPT를 GDPR에 맞게 프로덕션에서 사용하려는 독일 기업을 위한 실용 가이드. PII 마스킹 코드, 누구와 AVV를 체결해야 하는지, Anthropic / Google(Enterprise)과 직접 체결하는 Zero Data Retention, Request-ID 상관관계가 포함된 감사 로그 및 Schrems-II 문제를 다룹니다.

독일 기업에서 GDPR을 준수하며 LLM 사용하기 — Claude 또는 GPT를 프로덕션에 도입하기 전에 필요한 사항. PII 마스킹, 감사 로그, Anthropic / Google의 Zero Data Retention, 그리고 AVV 문제를 포함한 실용적인 설정입니다.

필수 구성 요소 3가지

  1. Upstream 호출 전에 PII 마스킹 — 개인의 평문 데이터를 필터링 없이 미국 공급자에게 보내서는 안 됩니다
  2. 데이터 처리 계약(AVV / GDPR 제28조) — 모델 제공업체(Anthropic, Google, OpenAI)와 직접 체결합니다. Kunavo는 AVV를 제공하지 않습니다
  3. 감사 추적 — 모든 호출을 추적 가능하게 하고 목적 제한에 따라 문서화

1) PII 마스킹 — 실무 부분

프롬프트가 자체 백엔드를 벗어나기 전에 마스킹 단계를 거칩니다. 이메일, 전화번호, 개인 이름, IBAN, 사회보장번호는 토큰으로 대체됩니다:

pii_mask.py
# Vor jedem LLM-Aufruf PII maskieren — niemals Klartext-Personendaten
# an die Upstream-API senden.
import re
from openai import OpenAI

PII_PATTERNS = [
    (re.compile(r"[\w.+-]+@[\w-]+\.[\w.-]+"), "<EMAIL>"),
    (re.compile(r"\b\d{4,}\b"), "<NUMBER>"),
    (re.compile(r"\b(?:\+49|0)\s*\d{2,4}\s*\d{4,8}\b"), "<PHONE_DE>"),
]

def redact(text: str) -> tuple[str, dict[str, str]]:
    redacted = text
    mapping: dict[str, str] = {}
    for i, (pat, tag) in enumerate(PII_PATTERNS):
        for match in pat.finditer(text):
            key = f"{tag}_{i}_{match.start()}"
            mapping[key] = match.group(0)
            redacted = redacted.replace(match.group(0), f"[{key}]")
    return redacted, mapping

def restore(text: str, mapping: dict[str, str]) -> str:
    for key, original in mapping.items():
        text = text.replace(f"[{key}]", original)
    return text

매핑 테이블은 로컬에만 남습니다. LLM 응답에 삽입된 개인 데이터를 다시 반환해야 하는 경우(예: “안녕하세요, 슈미트 부인”), 응답이 도착한 후에야 치환합니다. 따라서 upstream에는 항상 익명화된 텍스트만 표시됩니다.

2) AVV — 누가 어떤 계약을 필요로 하는가

  • 귀사 ↔ Kunavo: Kunavo는 GDPR 제28조에 따른 AVV를 제공하지 않습니다. 요청은 미국에서 처리되고 upstream 제공업체로 전달되며, 이들이 콘텐츠를 처리하는 방식은 자체 개인정보 보호 및 보존 약관으로 규정됩니다(/legal/privacy 참조).
  • 귀사 ↔ 모델 제공업체: 워크로드에 AVV가 필요하다면 Anthropic, OpenAI 또는 Google과 각 기업/Enterprise 약관에 따라 직접 체결하고 해당 제공업체에서 모델을 직접 호출하세요. Kunavo를 통해서는 하위 수탁자 체인을 승계하지 않습니다
  • Schrems II 위험: Anthropic과 OpenAI는 미국에 소재합니다. AVV가 없으면 Kunavo를 통한 미국 전송에 적용되는 표준계약조항(SCC)도 없습니다. 위험 평가에서 순수 EU 제공업체를 요구한다면 Kunavo는 적합하지 않습니다. 당사 카탈로그의 어떤 제공업체도 EU에 소재하지 않으며 모든 요청은 US-East의 당사 게이트웨이를 거칩니다

3) 감사 로그 — 모든 호출 기록

요청별: Request-ID, User-ID, 모델, 해시 처리된 프롬프트, 토큰 사용량, 지연 시간, 자체 로그의 상관관계 키로서의 Request-ID:

audit.py
# Jeder LLM-Aufruf wird in einem unveränderlichen Audit-Log festgehalten
import json, time, uuid
from datetime import datetime

def call_with_audit(user_id: str, prompt: str, model: str) -> dict:
    request_id = str(uuid.uuid4())
    redacted_prompt, mapping = redact(prompt)

    # Audit-Log VOR dem Call schreiben
    audit_log.write({
        "request_id": request_id,
        "user_id": user_id,
        "timestamp": datetime.utcnow().isoformat(),
        "model": model,
        "prompt_redacted": redacted_prompt,
        "prompt_hash": hashlib.sha256(prompt.encode()).hexdigest(),
        "pii_tags_count": len(mapping),
    })

    resp = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": redacted_prompt}],
        extra_headers={
            "X-Request-ID": request_id,  # nur für deine eigenen Logs; Kunavo wertet ihn nicht aus
        },
    )

    response_text = resp.choices[0].message.content
    # Bei Bedarf PII zurück mergen (nur in der lokalen DB)
    final_text = restore(response_text, mapping)

    audit_log.write({
        "request_id": request_id,
        "response_redacted": response_text,
        "tokens": resp.usage.model_dump(),
        "duration_ms": int((time.time() - start) * 1000),
    })
    return {"text": final_text, "request_id": request_id}

X-Request-ID는 귀사의 자체 키입니다. Kunavo는 이 헤더를 분석하거나 저장하지 않으며, 사용량 대시보드에는 어떤 upstream 제공업체가 호출을 처리했는지 표시되지 않습니다. 대시보드에서는 호출별 Kunavo 자체 Call-ID, 시각, 모델, 토큰, 비용 및 지연 시간을 확인할 수 있습니다. 자체 감사 로그와의 대조는 시각과 모델을 기준으로 수행하세요.

Zero Data Retention(ZDR) — 모델 제공업체와 직접 계약한 경우에만

기본적으로 Anthropic과 Google은 악용 모니터링을 위해 프롬프트 로그를 각각 30일(Anthropic) 및 60일(Google) 동안 저장합니다. GDPR에 민감한 워크로드의 경우 자체 계약에 따라 제공업체에 ZDR을 직접 요청할 수 있습니다. Kunavo는 ZDR 라우팅이나 ZDR 티어를 제공하지 않습니다. Kunavo를 통한 요청은 미국에서 처리되고 upstream 제공업체로 전달되며, 해당 제공업체의 자체 보존 규칙이 적용됩니다.

  • Anthropic ZDR: Anthropic과 직접 계약한 Enterprise 고객에게 제공됩니다. Kunavo를 통해서는 이용할 수 없습니다
  • Google Vertex AI: 자체 Google Cloud 계약에 따라 유사한 조건이 적용되며 EU 리전(europe-west4 / 네덜란드)을 선택할 수 있습니다. Kunavo는 EU 리전을 통해 라우팅하지 않습니다
  • OpenAI: OpenAI와 직접 계약한 Enterprise 티어에서만 Zero Data Retention을 제공합니다. Kunavo를 통해 중개할 수 없습니다

데이터 상주성

  • Kunavo 라우팅: 게이트웨이에서 단일 리전(US-East, Ashburn)을 사용합니다. 앞단의 Anycast Edge만 사용자의 근처에서 TLS를 종료합니다
  • 계정 데이터의 영속성: 일일 암호화 볼륨 스냅샷이 생성되는 US-East의 단일 기본 데이터베이스를 사용합니다. EU 전용 라우팅은 제공하지 않습니다
  • 부가가치세: Checkout에는 부가가치세가 표시되지 않으며 청구서도 생성되지 않습니다. 회계 증빙이 필요하면 contact@kunavo.com으로 문의하세요

대부분의 컴플라이언스 팀이 놓치는 사항

  • 이름이 포함된 프롬프트 내용은 개인정보입니다 — 사용자가 “Müller”를 입력하지 않고 단지 “제 이름은 페트라입니다”라고 입력한 경우에도 마찬가지입니다. 마스킹은 휴리스틱 방식으로 이름과 고유명사를 우선 감지해야 합니다
  • 귀사 데이터 학습은 Anthropic과 Google에서 기본적으로 비활성화되어 있습니다(ChatGPT 소비자용과 다름). Kunavo 자체는 귀사의 콘텐츠로 학습하지 않지만 upstream 제공업체의 처리 방식은 해당 제공업체의 자체 약관에 따릅니다. Kunavo는 이에 대해 계약상 보증을 제공하지 않습니다
  • 출력 콘텐츠 해시 — 귀사의 DPA가 요구하는 경우 전체 텍스트가 아니라 해시만 저장합니다
  • 삭제 권리 — GDPR 제17조에 따른 요청이 들어오면 로그에서 프롬프트를 삭제할 수 있어야 합니다. 이는 감사 로그를 삭제 가능하게 구성한 경우에만 가능합니다(즉, append-only 블록체인 구조에 저장해서는 안 됩니다)

법적 고지 및 쿠키 배너

완전한 준수 절차는 § 5 DDG에 따른 당사의 /legal/impressum 및 /legal/privacy의 개인정보 처리방침을 참조하세요. 쿠키 배너는 자체 웹사이트에서 관리해야 합니다(예: Usercentrics, Cookiebot 또는 Klaro). Kunavo 자체는 기능성 쿠키만 설정합니다.

준비되셨나요? 무료 가입 후 $10부터 충전하고 Pay-as-you-go 방식으로 사용하세요. 잔액은 절대 만료되지 않습니다. 워크로드에 AVV, ZDR 또는 EU 데이터 거주가 필요하다면 모델 제공업체와 직접 계약하세요.