보안(Security) — 비밀값(Secrets), API 키 로테이션(API Key Rotation), 감사 로그(Audit Logs), 가드레일(Guardrails)
중앙 집중식 비밀값 저장소(vault)인 HashiCorp Vault, AWS Secrets Manager, Azure Key Vault를 사용해 비밀값이 사방에 흩어지는 비밀값 스프롤(secret sprawl) 문제를 없앱니다. 자격 증명(credential)을 설정 파일, 버전 관리 시스템(VCS) 안의 환경 파일(.env), 스프레드시트에 저장하지 않습니다. 정적 키(static key) 대신 IAM 역할(IAM role)을 사용하고, CI/CD에는 OIDC를 사용합니다. AI 게이트웨이 패턴(AI-gateway pattern)이 2026년의 표준 해법입니다. 애플리케이션(apps) → 게이트웨이(gateway) → 모델 제공자(model provider) 구조에서 게이트웨이가 실행 시점(runtime)에 비밀값 저장소에서 자격 증명을 가져옵니다. 비밀값 저장소에서 로테이션(rotate)하면 모든 애플리케이션이 몇 분 안에 새 키를 사용하게 됩니다. 재배포(redeploy)도 필요 없고, 슬랙(Slack)에서 "새 키 누가 갖고 있어요?"를 묻는 일도 사라집니다. 로테이션 주기(rotation policy)는 90일 이하로 둡니다. 모든 커밋(commit)에서 TruffleHog, GitGuardian, Gitleaks 같은 도구로 스캔(scan)합니다. 제로 트러스트(Zero-trust) 자세는 다중 인증(MFA), 통합 인증(SSO), 역할 기반·속성 기반 접근 제어(RBAC/ABAC), 짧은 수명의 토큰(short-lived tokens), 디바이스 상태 점검(device posture)을 포함합니다. 개인 식별 정보(PII) 마스킹은 엔티티 인식(entity recognition)을 활용해 외부로 전달(forward)하기 전에 보건 정보(PHI)와 PII를 가립니다. 일관된 토큰화(consistent tokenization; Mesh 방식)는 민감한 값(sensitive value)을 안정적인 자리표시자(stable placeholder)에 매핑해 LLM이 코드와 관계 구조의 의미(semantics)를 그대로 유지하도록 합니다. 네트워크 송신(network egress)은 LLM 서비스를 별도의 가상 네트워크(VPC/VNet) 서브넷에 두고 api.openai.com, api.anthropic.com 같은 도메인만 화이트리스트(whitelist)에 두며, 그 외 모든 외부 통신은 차단합니다. 2026년에 이 주제를 끌어올린 사건은 Vercel 공급망 공격(supply-chain attack)으로, 탈취된 CI/CD 자격 증명을 통해 수천 개의 고객 배포에서 환경 변수(env vars)가 유출되었습니다.
유형: Learn
언어: Python (stdlib, 학습용 PII 스크러버(scrubber) + 감사 로그 작성기)
선수 지식: Phase 17 · 19 (AI Gateways), Phase 17 · 13 (Observability)
예상 시간: 약 60분
학습 목표
- 비밀값 관리(secret management)의 네 가지 안티 패턴(VCS에 들어간 설정 파일, 하드코딩된 환경 변수, 스프레드시트, 정적 키)을 열거하고 각각의 대체 방법을 말합니다.
- AI 게이트웨이가 비밀값 저장소에서 자격 증명을 가져오는 패턴(AI-gateway-pulls-from-vault)이 왜 2026년의 운영 환경 표준인지 설명합니다.
- 같은 값이 항상 같은 자리표시자로 매핑되는 일관된 토큰화를 적용한 PII 스크러버를 구현해, 의미가 손상되지 않도록 합니다.
- 2026년 Vercel 공급망 사건을 이름으로 식별하고, 그 사건이 CI/CD 자격 증명 위생(credential hygiene)에 대해 가르친 교훈을 말합니다.
문제
신입(intern)이 API 키가 담긴 .env를 커밋합니다. 본인은 바로 삭제했지만 키는 이미 깃 이력(git history)에 들어가 버렸습니다. GitGuardian 스캔이 이를 잡아냅니다. 그런데 우리의 로테이션 절차는 "팀에 슬랙으로 알리고, 40개의 설정 파일을 수정하고, 모든 서비스를 재배포한다"는 식입니다. 결과적으로 8시간이 지나도 서비스의 절반만 새 키로 살아나 있고, 나머지 절반은 배포 윈도우(deploy window)를 기다리고 있습니다.
또 다른 상황입니다. 사용자 프롬프트(prompt)에 "My SSN is 123-45-6789."가 포함됩니다. 이 프롬프트는 그대로 OpenAI로 전달됩니다. 사업제휴협약(BAA)은 맺어 두었지만, 내부 정책은 외부 전송 전에 PII를 가리는 것이었습니다. 그러나 실제로는 그 마스킹이 일어나지 않았습니다.
세 번째 상황입니다. EKS 클러스터의 LLM 파드(pod)는 인터넷의 모든 호스트에 접근할 수 있습니다. 누군가 공격자가 통제하는 도메인으로 DNS 조회(DNS lookup)를 보내 데이터를 유출(exfiltrate)합니다. 이를 막아 주는 장치는 어디에도 없었습니다.
LLM 서비스의 보안은 이 세 가지 공격 경로(vector)를 모두 다뤄야 합니다. 비밀값 저장소에 기반한 자격 증명, PII 마스킹, 네트워크 송신 필터링, 감사 로그가 모두 필요합니다.
개념
중앙 집중식 비밀값 저장소(Vault)와 IAM 역할 기반 인증
비밀값 저장소(Vault): HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager가 있습니다. 자격 증명의 단일 진실 출처(single source of truth) 역할을 합니다.
IAM 역할(IAM role): 애플리케이션이나 게이트웨이는 정적 키가 아니라 자기 자신의 IAM 신원으로 인증합니다. 비밀값 저장소는 토큰 수명 동안 해당 비밀값을 반환합니다.
AI 게이트웨이 패턴(AI-gateway pattern): 게이트웨이가 요청 시점마다 비밀값 저장소에서 OPENAI_API_KEY를 가져옵니다. 저장소에서 키를 로테이션하면 그 다음 요청부터 새 키가 사용됩니다. 재배포가 필요 없습니다.
로테이션 주기 90일 이하
모든 API 키, 비밀값 저장소의 루트 토큰(root token), CI/CD 자격 증명에 적용합니다. 가능한 경우 자동 로테이션(automated rotation)을 사용합니다. 수동 로테이션도 반드시 로그로 남기고 추적합니다.
비밀값 스캐닝(Secret scanning)
- TruffleHog — 커밋에서 정규식과 엔트로피(entropy)를 함께 사용해 탐지합니다.
- GitGuardian — 상용 제품이며 탐지 정확도가 높습니다.
- Gitleaks — 오픈 소스(OSS)이며 CI 안에서 실행됩니다.
모든 커밋에서 실행합니다. 새 비밀값이 발견되면 PR을 차단(block)합니다.
제로 트러스트(Zero-trust) 자세
- 모든 계정에 다중 인증(MFA)을 요구합니다.
- SAML 또는 OIDC를 통한 통합 인증(SSO)을 사용합니다.
- 세분화된 권한(fine-grained access)을 위해 역할 기반 접근 제어(RBAC; role-based) 또는 속성 기반 접근 제어(ABAC; attribute-based)를 사용합니다.
- 토큰은 짧은 수명(short-lived)으로 둡니다. 단위가 일(day)이 아니라 시간(hour)이어야 합니다.
- 디바이스 상태 점검(device posture) — 디스크 암호화가 적용된 회사(corp) 단말기에서만 접근을 허용합니다.
PII / PHI 마스킹
프롬프트가 우리 인프라(infra)를 떠나기 전에 다음을 수행합니다.
- 엔티티 인식(entity recognition; spaCy NER, Presidio, 상용 솔루션).
- 식별된 엔티티를 마스킹(mask)합니다. 예를 들어
"My SSN is 123-45-6789"는 "My SSN is [SSN_TOKEN_A3F]"로 바뀝니다.
- 일관된 토큰화(consistent tokenization; Mesh 방식): 같은 값은 항상 같은 자리표시자로 매핑되어, LLM이 엔티티 사이의 관계를 그대로 추론할 수 있습니다.
- 필요한 경우 LLM 응답에 역방향 매핑(reverse mapping)을 적용해 자리표시자를 원래 값으로 복원합니다.
정적 정규식 필터(static regex filter)는 기본적인 패턴을 잡아 주고, 엔티티 인식은 더 폭넓은 경우를 잡아 줍니다. 둘 다 함께 사용합니다.
입력 + 출력 가드레일(Guardrails)
입력(input): 알려진 탈옥(jailbreak) 시도와 금지 주제(forbidden topic)를 차단하고, 사용자별로 요청 빈도 제한(rate-limit)을 적용합니다.
출력(output): 응답에 새어 나간 비밀값(API 키 패턴, 거부 응답 안에 섞여 들어간 이메일 패턴 등)을 정규식으로 마스킹하고, 정책 위반은 분류기(classifier)로 잡습니다.
네트워크 송신 화이트리스트(Network egress whitelist)
LLM 서비스를 전용 서브넷(dedicated subnet)에 둡니다.
- 화이트리스트:
api.openai.com, api.anthropic.com, 벡터 데이터베이스 엔드포인트, 비밀값 저장소 엔드포인트.
- 그 외 트래픽: 모두 차단(drop)합니다.
- DNS는 허용 목록(allowlist)만 받아들이는 리졸버(resolver)를 사용합니다. 이는 DNS 터널링(DNS-tunneling)을 통한 유출을 방지하기 위해서입니다.
감사 로그(Audit log)
모든 LLM 호출에 대해 변경 불가능한(immutable) 로그를 남깁니다. 다음 항목을 기록합니다.
- 타임스탬프(timestamp).
- 사용자 / 테넌트(tenant).
- 프롬프트 해시(prompt hash). 개인정보 보호를 위해 원본 프롬프트는 저장하지 않습니다.
- 모델 이름과 버전.
- 토큰 수(token counts).
- 비용(cost).
- 응답 해시(response hash).
- 가드레일 발동 여부(guardrail trips).
보관 기간은 규제 요구 사항을 따릅니다. SOC 2는 1년, HIPAA는 6년입니다.
2026년 Vercel 사건
공급망 공격(supply-chain attack)이었습니다. 탈취된 CI/CD 자격 증명을 통해 수천 개의 고객 배포에서 환경 변수가 유출되었습니다. 교훈은 분명합니다. CI/CD 자격 증명은 운영 환경과 동등한(prod-equivalent) 수준의 권한을 가집니다. 비밀값 저장소에 보관하고, 권한 범위(scope)를 좁히고, 공격적으로 로테이션해야 합니다.
기억해 두어야 할 숫자
- 로테이션 주기: 90일 이하.
- 모든 커밋에서 스캔: TruffleHog / GitGuardian / Gitleaks.
- Vercel 2026: CI/CD 자격 증명이 탈취되며 수천 개 고객의 환경 변수가 유출.
- 감사 로그 보관 기간: SOC 2 = 1년, HIPAA = 6년.
사용해보기
code/main.py는 일관된 토큰화와 추가 전용(append-only) 감사 로그를 갖춘 학습용 PII 스크러버를 구현합니다.
산출물 만들기
이 강의는 outputs/skill-llm-security-plan.md를 만듭니다. 적용되는 규제 범위(regulatory scope)와 현재 상태(current state)가 주어지면 비밀값 저장소 마이그레이션, 스크러버, 네트워크 송신 정책, 감사 로그를 계획합니다.
연습문제
- 쉬움:
code/main.py를 실행합니다. 같은 주민등록번호(SSN)를 참조하는 프롬프트 두 개를 보내고, 두 결과가 모두 같은 자리표시자(placeholder)로 치환되는지 확인합니다.
- 중간: OpenAI, Anthropic, Weaviate를 호출하는 vLLM-on-EKS 배포에 대한 네트워크 송신 정책을 설계합니다.
- 중간: 깃 이력에서 2년 전에 들어간 키를 발견했습니다. 올바른 대응은 무엇입니까? 키 로테이션입니까, 깃 이력 정리입니까, 아니면 둘 다입니까? 근거를 설명합니다.
- 어려움: 감사 로그가 하루 10GB씩 증가합니다. 보관 계층(retention tier)을 설계합니다(핫(hot) 30일, 웜(warm) 12개월, 콜드(cold) 6년).
- 어려움: LLM 응답에 실제 값을 다시 끼워 넣는 역방향 토큰화(reverse-tokenization)가 자리표시자를 그대로 보여 주는 방식에 비해 추가 복잡도를 감수할 가치가 있는지 논증합니다.
핵심 용어
| 용어 | 흔한 설명 | 실제 의미 |
|---|
| 비밀값 저장소(Vault) | "비밀값 보관소" | 자격 증명을 중앙에서 관리하는 서비스 |
| IAM 역할(IAM role) | "신원 기반 인증" | 애플리케이션이 가정(assume)하는 역할로, 짧은 수명의 자격 증명을 반환 |
| CI/CD용 OIDC(OIDC for CI/CD) | "클라우드 발급 토큰" | CI에 정적 키를 두지 않고 OIDC로 신원을 증명 |
| TruffleHog / GitGuardian / Gitleaks | "비밀값 스캐너(secret scanner)" | 커밋 시점에 비밀값을 탐지 |
| RBAC / ABAC | "접근 제어" | 역할 기반(RBAC) 대 속성 기반(ABAC) |
| PII 마스킹(PII scrubbing) | "데이터 마스킹" | 민감한 엔티티를 제거하거나 토큰으로 치환 |
| 일관된 토큰화(Consistent tokenization) | "안정적인 자리표시자" | 같은 값은 매번 같은 토큰으로 매핑 |
| Mesh 방식(Mesh approach) | "Mesh 토큰화" | 의미를 보존하는 토큰화 패턴 |
| 송신 화이트리스트(Egress whitelist) | "송신 허용 목록" | 허용된 도메인만 외부에 도달 가능 |
| 감사 로그(Audit log) | "변경 불가 이력" | 컴플라이언스를 위한 추가 전용(append-only) 기록 |
더 읽을거리