ai-보안
AI가 당신의 Stripe 키를 보지 않고도 사용하는 방법
AI 모델의 컨텍스트에 키가 절대 들어가지 않으면서도 lodos가 당신의 Stripe 키로 고객에게 청구할 수 있게 해주는 런타임 secret 주입 패턴을 소개해요.
모든 "AI 에이전트" 제품이 마주하는 불편한 거래가 있어요. 유용한 작업을 하려면 에이전트는 당신의 자격 증명이 필요합니다. 고객에게 청구하려면 Stripe 키가 필요하고, 배포하려면 클라우드 토큰이 필요해요. 흔한 해법은 그 secret들을 모델에 넘겨주고 아무것도 새지 않기를 바라는 것입니다.
저희는 바라고 싶지 않았어요. 그래서 lodos는 누출이 구조적으로 불가능하도록 만들어졌고, 누군가 그 원칙을 깨뜨리면 빌드 자체가 실패하도록 설계했습니다.
모델에게 secret을 주는 것의 문제
평문 secret이 언어 모델의 컨텍스트에 한번 들어가면, 당신은 그것에 대한 통제권을 잃어요. 그 값은 대화 기록(transcript)에, 도구 호출에, 로그에, 모델이 나중에 작성하는 요약에, 또는 교묘하게 표현된 후속 질문에 대한 답변에 드러날 수 있습니다. 프롬프트 인젝션, 즉 에이전트가 읽는 웹 페이지나 이메일, 문서에 숨겨진 악의적인 명령은 그 잠재된 위험을 능동적인 유출 경로로 바꿔버려요.
솔직한 결론은 모델이 애초에 secret을 절대 보지 말아야 한다는 것입니다. 그 밖의 모든 것은 설계 결함 위에 덧붙인 완화책일 뿐이에요.
참조하고, 주입하고, 감사한다
lodos는 모든 자격 증명을 세 단계로 처리해요.
1. 참조 (Referenced)
당신의 AI는 절대 값(value)을 다루지 않아요. 플레이스홀더를 다룹니다.
{{secrets.stripe.sk_live}}
그 참조가 모델이 보는 전부예요. 채팅에서도, 워크플로에서도, 작업에서도요. 모델은 Stripe 키를 한 번도 손에 쥐지 않고도 그 키를 사용하는 것에 대해 추론할 수 있습니다.
2. 주입 (Injected)
작업이 실제로 자격 증명을 필요로 할 때, lodos는 그것을 로컬에서 복호화해서 격리된 서브프로세스에 환경 변수로 전달해요. 모델의 시야 밖에서요. 그리고 작업이 끝나는 순간 사라집니다.
# The agent asked to run this; lodos resolved the reference and
# injected the real value into the subprocess environment only.
STRIPE_API_KEY={{secrets.stripe.sk_live}} ./charge-customer.sh
모델은 왼쪽의 줄을 봅니다. 서브프로세스는 오른쪽의 값을 받아요. 이 둘은 대화 기록 안에서 절대 만나지 않습니다.
3. 감사 (Audited)
모든 접근은 변조가 드러나는(tamper-evident) HMAC-SHA256 체인에 추가돼요. 로그는 secret이 사용되었다는 사실만 기록하고, 어떤 값인지는 절대 기록하지 않습니다. 필드 경로는 불투명(opaque)하며, 기록을 바꾸려는 어떤 시도도 체인을 깨뜨려요.
왜 단지 정책을 신뢰하지 않는가
"AI는 secret을 드러내지 않도록 설정되어 있습니다"라고 적고 넘어가기는 쉬워요. 하지만 저희는 강제 집행이 없다면 그것은 아무 가치가 없다고 생각합니다. 그래서 그 보장을 릴리스 프로세스에 직접 새겨 넣었어요.
빌드 타임 불변식 검사(invariant scan)가 모든 릴리스마다 실행되며, 다음 중 하나라도 위반되면 빌드를 실패시킵니다.
- 어디에도 평문 secret 값을 반환하는 도구가 없어요.
- 원시(raw) 모델 API 제공자가 없어요. 오직 당신의 로그인으로 동작하는 임베디드 Claude Code만 있습니다.
- 어떤 렌더링 경로에도
eval,Function,vm,child_process가 없어요. - 알 수 없는 도구는 fail closed로 처리돼요. 절대 조용히 허용되지 않습니다.
- 에이전트는
bash가 명시적으로 비활성화된 상태로 실행됩니다. - 어떤 단일 권한 부여도 비공개 데이터 + 신뢰할 수 없는 콘텐츠 + 유출이라는 "치명적 삼중주(lethal trifecta)"를 완성할 수 없어요.
- 워크플로는 선언적(declarative)일 뿐이에요. 실행할 코드 경로가 없습니다.
만약 미래의 커밋이 모델에 secret을 넘겨주는 도구를 추가한다면, 그 릴리스는 그냥 배포되지 않아요.
우리가 거부한 것, 그리고 대신 출시한 것
이 벽은 더 적은 기능이 아니라 더 나은 설계를 강제했어요.
| 우리가 거부한 것 | 대신 출시한 것 |
|---|---|
| AI가 직접 호출하는 원시 모델 API | 당신의 로그인으로 동작하는 임베디드 Claude Code |
| AI가 호스트 명령(bash)을 실행하게 두는 것 | secret을 보지 못하는 런타임 서브프로세스 주입 |
워크플로 안의 eval() |
선언적 YAML, 실행할 코드 경로 없음 |
| 이미지 생성 덱(클라우드 송신) | 오프라인 텍스트 덱, 네트워크 사용 제로 |
누출을 거부한다고 해서 기능이 사라지지는 않았어요. 오히려 그 기능을 집중시켰습니다.
핵심 요약
당신은 AI 에이전트에게 자격 증명을 주지 않고도 실제로 자격 증명이 필요한 작업을 맡길 수 있어요. secret은 당신의 기기에서 암호화된 채로 머무르고, 사용하는 그 순간에만 서브프로세스에 들어가며, 모델의 컨텍스트로는 절대 넘어가지 않습니다.
그것이 바로 lodos의 핵심 아이디어예요. 당신의 AI는 당신의 작업을 보지만, 당신의 secret은 보지 않습니다. 전체 보안 아키텍처를 읽어보시거나, lodos를 다운로드해서 에이전트에게 키 대신 일을 맡겨보세요.