요약
vLLM·SGLang·TensorRT-LLM 같은 최신 LLM 서빙 엔진은 글로벌 프리픽스 캐시(global prefix cache)를 켠 채 운영하는 것이 사실상 표준이다. 여러 사용자가 보내는 요청 중 앞부분 토큰 시퀀스가 겹치면 그 부분의 KV 캐시를 재사용해 TTFT를 크게 줄일 수 있다. 하지만 이 최적화가 API에서 관측 가능한 타이밍 사이드채널을 만든다는 사실은 지금까지 상대적으로 조용히 지나갔다.
2026년 8월에 공개된 SafeKV(arXiv:2508.08438, "Selective KV-Cache Sharing to Mitigate Timing Side-Channels in LLM Inference")는 이 문제를 서빙 시스템 관점에서 정면으로 다룬다. 논문은 두 가지 실험을 함께 제시한다. 첫째, 특권 없는 원격 공격자가 표준 API만 사용해서 다른 사용자의 프롬프트를 토큰 단위로 재구성할 수 있음을 실증한다. 둘째, KV 캐시 항목을 생성 시점에 민감/비민감으로 분류해 비민감 항목만 공유하는 SafeKV를 제안하고, 타이밍 공격의 94–97%를 완화하면서 사용자별 완전 격리 대비 TTFT를 최대 40.58% 개선하고 처리량을 최대 2.66배로 회복함을 보인다.
이 글은 문제의 정확한 형태, 공격이 실제로 어떻게 동작하는지, SafeKV의 3-컴포넌트 구조와 통합 라딕스 트리 설계, 그리고 이걸 운영에 붙일 때 서빙 엔지니어가 확인해야 할 항목들을 다룬다.
배경: 프리픽스 캐시 공유가 왜 사이드채널이 되는가
vLLM의 PagedAttention, SGLang의 RadixAttention, TensorRT-LLM의 KV Cache Reuse는 모두 같은 아이디어에 뿌리를 둔다. 같은 토큰 시퀀스가 앞에 붙은 요청들 사이에서 KV 캐시를 공유해 프리필 비용을 없앤다. 시스템 프롬프트, 함수 정의, RAG 문서, 코드 컨텍스트처럼 여러 요청에서 반복되는 큰 프리픽스를 한 번만 계산하고 재사용하기 위한 목적이다.
그런데 이 공유는 사용자 사이의 경계도 함께 흐리게 만든다. 요청 A와 B가 같은 프리픽스를 공유하면, B의 첫 토큰까지 시간(TTFT)은 A가 먼저 그 프리픽스를 처리해 뒀는지에 관측 가능하게 달라진다. 캐시가 있을 때와 없을 때 TTFT는 프리픽스 길이에 비례해 수십 ms에서 수 초까지 벌어질 수 있다.
공격의 형태
SafeKV 논문이 재현하는 공격은 이 timing gap을 사전 지식 없이 원격에서 검출한다. 공격자는 서빙 API의 정당한 사용자로 등록만 되어 있으면 된다.
- 후보 시퀀스 준비: 공격자는 대상 사용자가 입력했을 법한 후보 토큰 시퀀스 집합을 준비한다. 예를 들어 병원 챗봇이라면 후보 문장은 특정 병명·약제명·검사 결과가 삽입된 문장들일 수 있다.
- 탐색 요청 발사: 각 후보를 프롬프트로 API에 던지고 TTFT를 측정한다.
- 캐시 히트 판정: TTFT가 임계값 아래로 떨어지는 후보는 최근 다른 사용자가 이미 처리해 캐시된 프리픽스와 일치하는 것으로 판정한다.
- 토큰별 확장: 이진 탐색이 아니라 토큰 단위로 후보를 확장한다. 캐시가 확인된 프리픽스에 다음 토큰 후보들을 붙여 다시 TTFT를 측정하면 어느 토큰이 이어지는지 알 수 있다. 이 과정을 반복해 문장을 재구성한다.
논문은 이 절차가 특권 없는 API 접근만으로 성공한다는 것을 실증했고, 동시 접속한 다른 사용자의 민감한 입력을 토큰 단위로 재구성할 수 있음을 확인했다. 이 위협 모델은 표준적인 멀티테넌트 LLM 서빙 환경—인퍼런스 게이트웨이 뒤에 여러 고객이 요청을 보내는 형태—에서 그대로 성립한다.
왜 지금인가
이 공격이 새롭게 부각된 이유는 세 가지가 겹쳤기 때문이다.
- 글로벌 캐시 공유의 기본화. vLLM/SGLang은 기본값이 공유 활성이다. 개별 사용자·개별 요청 격리는 옵트인이다.
- 긴 컨텍스트의 정착. 128K–1M 토큰 프롬프트가 흔해지면서 프리필 비용은 커졌고, 그만큼 캐시 히트/미스의 timing gap도 확장됐다.
- 에이전트 워크로드. 도구 호출과 관찰 결과가 프롬프트에 흡수되면서 프리픽스 재사용률이 높아졌고, 사용자 간 프리픽스 겹침의 실제 발생 빈도도 커졌다.
즉 이 사이드채널은 서빙 최적화가 잘 될수록 더 잘 뚫린다.
SafeKV의 3-컴포넌트 구조
SafeKV의 접근은 단순하다. "공유하되, 민감한 것은 공유하지 않는다." 문제는 어떤 KV 캐시 항목이 민감한가를 언제·어떻게 결정하는가다. SafeKV는 이 판정을 생성 시점에 3-단계 파이프라인으로 처리한다.
컴포넌트 1: 하이브리드 다층 검출 파이프라인
토큰이 프리필될 때, SafeKV는 다음 세 층을 순서대로 통과시킨다.
- 규칙 기반 패턴 매칭(rule-based pattern matching): 신용카드 번호·주민등록번호·이메일·API 키·JWT 등 표현이 명확한 PII 패턴을 정규식과 사전으로 잡는다. 가장 빠른 층이고 오탐이 거의 없다.
- 범용 개인정보 탐지기(general-purpose privacy detector): 이름·주소·병명·회사 내부 코드 등 문맥 없이도 민감한 개체명(NER 기반)을 잡는다. 규칙만으로는 놓치는 것들을 커버.
- 문맥 인식 검증(context-aware validation): 앞 두 층이 놓쳤거나 확신이 낮은 경우, 주변 문맥과 함께 소형 판별 모델로 최종 판정한다. 예를 들어 "1234-5678-9012-3456"이 카드번호인지 주문번호인지는 문맥으로 결정된다.
결과는 두 가지 라벨 중 하나다. public(공유 가능) 또는 private(공유 금지). 라벨은 KV 캐시 항목이 저장되는 시점에 함께 붙어 계층 저장소로 내려간다.
컴포넌트 2: 통합 라딕스 트리(unified radix-tree)
기존 서빙 엔진의 프리픽스 캐시는 대개 라딕스 트리(SGLang) 혹은 페이지 테이블(vLLM)로 관리된다. SafeKV는 이 자료구조를 하나로 통합하되 public/private 두 종류의 잎(leaf)을 함께 담는다.
- public 잎: 모든 사용자 요청에서 공유 가능. 히트 시 재사용.
- private 잎: 소유자 사용자 ID와 함께 저장. 다른 사용자 요청은 miss로 처리해야 하지만, 트리 구조는 같이 사용한다.
핵심은 트리 구조가 하나이기 때문에 프리픽스 매칭 자체는 여전히 O(depth)이고, 계층 메모리(HBM → DRAM → SSD)에 걸친 저장 관리도 하나의 인덱스로 통일된다는 점이다. Private 잎은 계층의 어느 층에서도 저장 가능하지만, 읽기 권한은 소유자로 제한된다.
컴포넌트 3: 엔트로피 기반 접근 모니터링
앞 두 층이 완벽하면 좋겠지만 실제로는 완벽하지 않다. 특히 다층 검출 파이프라인은 재현율(recall)을 100%로 만들면 정밀도(precision)가 크게 떨어져 공유 가능한 항목까지 private로 라벨링해 성능이 나빠진다. 실전 파이프라인은 재현율을 높게 유지하되 소량의 누출은 감수하는 지점에 캘리브레이션된다.
SafeKV는 이 잔여 누출을 엔트로피 기반 접근 모니터링으로 잡는다. 특정 프리픽스 하위에서 비정상적으로 좁은 범위의 후보 토큰만 반복해서 조회되는 패턴은 timing probe의 전형적인 서명이다. SafeKV는 각 캐시 노드의 접근 분포를 엔트로피로 요약하고, 임계값 이하로 떨어지면 해당 서브트리를 임시 private로 전환한다. 공격자 관점에서는 방금 성공했던 probe 경로가 갑자기 미스로 바뀌어 재구성이 중단된다.
아키텍처 한눈에 보기
정확한 성능 트레이드오프
SafeKV가 흥미로운 이유는 완전 공유(vanilla)와 완전 격리(per-user isolation) 두 극단 사이에서 실용적인 지점을 잡기 때문이다.
세 가지 운영 모드 비교
| 모드 | 공유 정책 | TTFT | 처리량 | 사이드채널 취약성 |
|---|---|---|---|---|
| Vanilla 글로벌 공유 | 모든 항목 공유 | 최적 | 최적 | 완전 노출 |
| Per-user isolation | 사용자별 격리 | 최악 | 최악 | 없음 |
| SafeKV | public만 공유 | 격리 대비 최대 40.58% 개선 | 격리 대비 최대 2.66× | 94–97% 차단 |
Qwen3-235B에서의 실측을 보면 다중턴 채팅 워크로드에서 캐시가 유발하는 TTFT 오버헤드가 완전 격리 시 50.41%까지 올라가는데, SafeKV는 이걸 11.74%로 낮춘다. 이는 vanilla 글로벌 공유의 성능 이득의 상당 부분을 되찾은 것이고, 대부분의 민감 데이터가 실제 프롬프트의 일부에만 존재한다는 관찰과 일치한다.
왜 완전 회복은 아닌가
SafeKV가 vanilla 성능에 완전히 도달하지는 못한다. 세 가지 이유가 있다.
- 민감으로 분류된 항목은 캐시 히트를 잃는다. 이는 원래 목적이므로 트레이드오프의 필수 비용이다.
- 검출 파이프라인의 오탐. 실제로는 비민감인데 민감으로 분류되면 공유 가능성을 잃는다. Precision을 낮추면 성능이 오르지만 취약성도 커진다.
- 엔트로피 감시가 정상 트래픽을 잘못 잡는 경우. 인기 있는 쿼리가 반복 조회되는 정상 상황에서도 엔트로피가 낮아질 수 있다. 저자들은 사용자·세션 분포까지 함께 보는 확장 지표로 이 오탐을 낮췄다고 보고한다.
관련 연구: KV 캐시 프라이버시 계열
SafeKV는 2026년 여름 이후 급격히 나타난 KV 캐시 보안 연구 흐름의 한 축이다. 함께 볼 만한 최근 논문들:
- Shadow in the Cache(arXiv:2508.09442): KV 캐시 자체가 남긴 값에서 원본 프롬프트를 복원할 수 있음을 보이고, 가역 행렬 기반 난독화(KV-Cloak)를 제안. SafeKV가 "접근 패턴"의 사이드채널을 다뤘다면 이 논문은 "저장된 값"의 유출을 다룬다.
- CachePrune(arXiv:2605.23640): 프라이버시-인식 파인그레인드 KV 캐시 공유. SafeKV와 목표는 유사하나 축출 시점에 검사한다.
- Agent-Assisted Side-Channel Attacks on Non-Prefix KV Cache in RAG(arXiv:2606.21842): 비-프리픽스 KV(문서 청크 단위 캐시)에서도 유사한 공격이 성립함을 실증. SafeKV의 방어를 RAG 스토어까지 확장해야 하는 근거.
이 흐름은 공유가 곧 정보 유출 경로라는 명확한 프레임을 만들었다. 서빙 엔진의 기본값 설정에도 이미 영향을 주기 시작했다.
서빙 스택 관점의 함의
SafeKV의 접근을 실제 프로덕션에 반영하려면 서빙 엔진 자체가 변해야 한다. 논문은 vLLM/SGLang을 참조 구현으로 언급하며, 이들에 어떤 훅이 필요한지 명시한다.
필요한 훅
- 프리필 시점 라벨링 훅: 토큰별로 public/private 라벨을 붙일 수 있는 콜백. SGLang의 RadixAttention 노드 생성 경로가 가장 자연스러운 지점.
- 라딕스 트리의 잎 메타데이터 확장: 소유자 사용자 ID와 라벨을 담을 필드가 필요.
- 검색 경로에서 소유자 필터: 프리픽스 매칭 시 private 잎은 요청 사용자가 소유자일 때만 히트로 계산.
- 접근 로그 축약: 엔트로피 계산을 위한 노드별 접근 히스토그램. 대규모 캐시에서 메모리 오버헤드가 되지 않도록 확률적 자료구조(HyperLogLog 등) 사용을 저자들은 제안한다.
검출 파이프라인의 지연
가장 큰 우려는 검출 파이프라인이 프리필 경로에 지연을 추가하지 않는가다. 저자들은 세 층을 비동기 파이프라인으로 구성해 프리필과 병렬 실행하며, 라벨링이 완료되지 않은 항목은 기본적으로 private로 취급(공유하지 않음)해 안전 실패(fail-safe)를 보장한다. 첫 응답 이후 라벨이 확정되면 이후 요청부터 공유가 열린다.
저장 계층과 상호작용
KV 캐시 계층 오프로딩(HBM → DRAM → SSD → 오브젝트 스토리지)이 실무화되면서 private 항목의 위치도 정책적으로 결정해야 한다. SafeKV의 통합 라딕스 트리는 계층에 걸쳐 인덱스를 유지하되, private 항목은 소유자 세션이 종료되면 축출 우선순위를 올린다. 이는 노출 시간을 줄이려는 명시적 선택이다.
도입 체크리스트
- [ ] 현재 사용 중인 서빙 엔진의 프리픽스 캐시가 사용자 경계를 넘어 공유되는 기본값인지 확인했는가 (vLLM
--enable-prefix-caching, SGLang RadixAttention 기본, TensorRT-LLMenable_kv_cache_reuse) - [ ] 멀티테넌트 배포에서 요청 사용자 ID가 서빙 엔진까지 명시적으로 전달되는가 (게이트웨이가 사용자 정보를 헤더/JWT로 전달)
- [ ] 프롬프트에 실려 오는 PII·민감 정보가 어떤 층에서 유입되는지 매핑했는가 (사용자 입력, 시스템 프롬프트, RAG 청크, 도구 결과)
- [ ] TTFT의 캐시 히트/미스 분포를 로깅해 timing gap이 얼마나 큰지 측정했는가 (공격 실현 가능성의 정량 지표)
- [ ] 캐시 공유를 완전 격리로 강제할 경우의 TTFT/처리량 회귀를 실측했는가 (SafeKV 같은 선택적 공유 도입의 근거)
- [ ] 검출 파이프라인이 사용자 도메인에 맞게 튜닝되는가 (의료·금융·법률 등 도메인 특화 PII는 범용 NER만으로 부족)
- [ ] 캐시 노드 접근 히스토그램을 저장할 여유 메모리 예산이 있는가 (엔트로피 감시의 필수 자원)
- [ ] Public/Private 라벨링이 감사(audit) 로그로 남는가 (규제 대응 시 어떤 데이터가 언제 공유되었는지 재구성 가능해야 함)
한계와 열린 문제
검출 완전성
Rule-based + NER + context validator 조합은 견고하지만 언어·도메인 특화 PII를 100% 잡지는 못한다. 저자들도 엔트로피 감시를 안전망으로 두는 이유가 여기 있다고 언급한다.
엔트로피 감시의 우회
정교한 공격자는 정상 트래픽을 모사하며 probe를 분산 실행해 엔트로피 임계를 회피할 수 있다. 논문은 이를 open problem으로 남긴다.
캐시 히트율의 근본적 감소
SafeKV는 사용자 격리 대비 성능을 크게 회복하지만, vanilla 글로벌 공유의 성능 상한에는 못 미친다. 대량 트래픽·짧은 컨텍스트 워크로드에서는 이 차이가 상대적으로 커질 수 있다.
규제 관점의 라벨 정확도
민감성 판정을 시스템이 자동으로 하는 것은 GDPR·HIPAA 같은 규정 관점에서는 감사 대상이다. SafeKV의 라벨링 파이프라인이 어떻게 튜닝되어 있는지 설명 가능해야 하며, 잘못된 라벨이 유출로 이어졌을 때 책임 구분이 필요하다.
정리
프리픽스 캐시 공유는 LLM 서빙의 표준 최적화지만, 최근 연구는 이 공유가 API에서 관측 가능한 타이밍 사이드채널임을 확실히 했다. 특권 없는 원격 공격자가 표준 API만으로 다른 사용자의 프롬프트를 토큰 단위로 재구성할 수 있다는 위협 모델은 멀티테넌트 서빙 환경에 그대로 적용된다.
SafeKV(arXiv:2508.08438)의 해법은 실용적이다. KV 캐시 항목을 생성 시점에 민감/비민감으로 분류하고, 비민감 항목만 사용자 사이에서 공유하며, 잔여 누출은 엔트로피 감시로 잡는다. 그 결과 사용자별 완전 격리 대비 TTFT를 최대 40.58% 개선하고 처리량을 최대 2.66배로 회복하면서 타이밍 공격의 94–97%를 차단한다.
핵심 메시지: 캐시 공유의 기본값을 재검토해야 한다. 성능만 보던 자리에 프라이버시가 함께 앉는다는 뜻이고, 서빙 엔진의 다음 세대 인터페이스는 이 축을 명시적으로 노출해야 한다. Vanilla 공유는 편하지만, 프로덕션 멀티테넌트 서비스에는 이제 위험한 기본값이다.
References
- arXiv:2508.08438 — Selective KV-Cache Sharing to Mitigate Timing Side-Channels in LLM Inference: https://arxiv.org/abs/2508.08438
- SafeKV: Safe KV-Cache Sharing in LLM Serving — MLArchSys 2025 workshop: https://openreview.net/pdf?id=jhDsbd5eXL
- arXiv:2508.09442 — Shadow in the Cache: Unveiling and Mitigating Privacy Risks of KV-cache in LLM Inference: https://arxiv.org/abs/2508.09442
- arXiv:2605.23640 — CachePrune: Privacy-Aware and Fine-Grained KV Cache Sharing for Efficient LLM Inference: https://arxiv.org/abs/2605.23640
- arXiv:2606.21842 — Agent-Assisted Side-Channel Attacks on Non-Prefix KV Cache in RAG: https://arxiv.org/abs/2606.21842
- Promptfoo LLM Security Database — KV-Cache Sharing Timing Side-channel: https://www.promptfoo.dev/lm-security-db/vuln/kv-cache-sharing-timing-side-channel-37989546
- Promptfoo LLM Security Database — LLM Prefix Cache Reconstruction: https://www.promptfoo.dev/lm-security-db/vuln/llm-prefix-cache-reconstruction-437934e8/
- vLLM Prefix Caching design doc: https://docs.vllm.ai/en/stable/design/prefix_caching/
- SGLang RadixAttention blog: https://lmsys.org/blog/2024-01-17-sglang/