Kill Switch, Circuit Breaker, Canary Token
킬 스위치(Kill Switch)는 에이전트의 수정 가능 표면(edit surface) 밖에 존재하는 불리언 값입니다. Redis 키(key), 기능 플래그(feature flag), 서명된 설정(signed config)처럼 에이전트가 손댈 수 없는 자리에서 에이전트를 완전히 비활성화하는 역할을 합니다. 회로 차단기(Circuit Breaker)는 그보다 더 세밀한 통제 장치입니다. 같은 도구 호출(tool call)이 다섯 번 연속 발생하는 식의 특정 패턴(pattern)이 감지되면 작동(trip)해 해당 경로(path)를 일시 정지하고, 사람에게 보고(escalate)합니다. 카나리 토큰(Canary Token)은 고전적인 기만 기법(deception)의 연장선에 있습니다. 에이전트가 정당하게 만질 이유가 없는 가짜 자격 증명(fake credential)이나 허니팟(honeypot) 레코드를 일부러 심어 두고, 접근이 발생하는 순간 경보(alert)를 발생시키는 방식입니다. eBPF 기반 데이터 경로(datapath), 예를 들어 Cilium은 격리된 파드(pod)의 송신(egress)을 커널 계층(kernel layer)에서 포렌식 허니팟(forensic honeypot)으로 재작성(rewrite)할 수 있습니다. 공개된 Cilium 벤치마크는 부하 상황에서 1 밀리초(ms) 이하의 P99 데이터 경로 지연(datapath latency)을 보고합니다. 다만 전파 시간(propagation budget)은 데이터 경로 자체가 아니라 정책 업데이트(policy update)가 노드(node)까지 도달하는 방식에 좌우됩니다. 움직이는 기준선(baseline)에 적응하는 통계적 탐지기(statistical detector)인 EWMA, CUSUM은 드리프트(drift)를 조용히 받아들일 수 있으므로, 절대 휘지 않는 엄격한 헌법적 한계(hard constitutional limit)와 함께 계층화해서 사용해야 합니다.
유형: Learn
언어: Python(표준 라이브러리, 킬 스위치/회로 차단기/카나리 세 가지 탐지기 시뮬레이터)
선수 지식: Phase 15 · 13(비용 거버너; Cost governors), Phase 15 · 10(권한 모드; Permission modes)
예상 시간: 약 60분
문제
비용 거버너(Lesson 13)는 에이전트가 얼마를 쓸 수 있는지를 제한합니다. 그러나 정해진 예산(budget) 안에서 무엇을 할 수 있는지는 제한하지 않습니다. 시간당 50달러의 속도 제한(velocity limit)이 걸려 있어도, 에이전트는 비밀 정보를 유출(exfiltrate)하거나, 잘못된 게시물을 공개(publish)하거나, 리소스를 삭제할 수 있습니다. 토큰 사용량 관점에서 비싼 행동이 실제 영향에서는 가장 값싸 보이는 경우가 흔합니다.
이 강의는 비용 계층(cost layer) 옆에 함께 놓여야 하는 세 가지 탐지기(detector)를 다룹니다.
- 킬 스위치(Kill Switch): 에이전트가 닿을 수 없는 곳에 있는 불리언 형태의 차단 버튼입니다.
- 회로 차단기(Circuit Breaker): 특정 경로를 멈추는 행동 패턴(action-pattern) 탐지기입니다.
- 카나리 토큰(Canary Token): 정당한 이유로 만질 일이 없는 미끼(bait)로, 에이전트가 이것을 건드리는 순간 의도를 스스로 드러냅니다.
세 가지 모두 LLM 이전 시대부터 존재해 온 공학 기법입니다. 고전적인 기만 기법, 비율 제한 기반 차단기(rate-limit breaker), 기능 플래그 기반 차단(feature-flag kill)은 자율 에이전트보다 훨씬 오래된 패턴입니다. 새로워진 부분은 공격 표면(attack surface)입니다. 에이전트는 신뢰할 수 없는 외부 콘텐츠를 읽고(Lesson 11), 자기 메모리(memory)를 수정하며, 안전해 보이는 여러 행동을 조합해 안전하지 않은 하나의 결과를 만들어 낼 수 있습니다. 여기서 다루는 탐지기들이 의미를 가지는 이유는 에이전트의 자기 보고(self-report)를 신뢰하지 않기 때문입니다.
개념
킬 스위치(Kill Switch)
킬 스위치는 에이전트가 읽을 수는 있지만 쓸 수는 없는 불리언 값입니다. 구현 선택지는 다음과 같습니다.
- 관리형 서비스의 기능 플래그. LaunchDarkly, Statsig, Unleash 같은 서비스를 사용합니다. 변경 사항이 수 초 안에 전파됩니다.
- 에이전트가 폴링(polling)하는 Redis 키. 구조가 단순합니다. 에이전트 프로세스가 매 턴(turn)마다 확인해야 합니다.
- 오브젝트 스토리지(object storage) 안의 서명된 설정. 에이전트는 부팅 시 서명(signature)을 검증하고, 서명되지 않은 상태는 거절합니다.
- 운영체제 수준 신호(OS-level signal) 또는 컨테이너 라이프사이클 종료. Docker
kill, Kubernetes kubectl delete pod, systemd stop 같은 방식입니다.
올바른 킬 스위치가 갖추어야 할 속성은 다음과 같습니다.
- 에이전트가 그 값을
off로 바꿀 수 없어야 합니다. 즉, 에이전트의 자격 증명(credential)이 쓰기 권한을 갖지 못하는 시스템 안에 두어야 합니다.
- 시작 시점에만 확인하는 것이 아니라, 결과를 동반하는 모든 행동(consequential action)마다 확인해야 합니다.
- 꺼져 있을 때는 에이전트가 접근할 수 있는 로깅(logging) 시스템에 기록을 남기는 것까지 포함해, 외부에서 관찰 가능한 어떤 일도 하지 않아야 합니다.
- 다시 켜는 작업(re-enable)은 자동 타임아웃이 아니라 사람의 명시적인 행동으로만 이루어져야 합니다.
회로 차단기(Circuit Breaker)
회로 차단기는 에이전트 전체가 아니라 특정 패턴만 일시 정지시킵니다. 2007년 마이클 나이가드(Michael Nygard)의 책에서 정리된 고전적인 형태가 지금도 그대로 통용됩니다.
- Closed(닫힘): 해당 행동이 허용됩니다.
- Open(열림): 해당 행동이 차단됩니다.
- Half-open(반열림): 쿨다운(cool-down) 이후 1~3회의 시험 호출(probe attempt)이 허용됩니다(기본값 1회). 성공하면 차단기가 다시 닫히고, 남은 시도 중 하나라도 실패하면 다시 열립니다.
에이전트 환경에서 의미가 있는 작동 조건(trigger)은 다음과 같습니다.
- 동일한 도구 호출이 다섯 번 연속 발생(반복 루프; repetitive loop).
- 같은 도구에 서로 다른 입력으로 다섯 번 연속 실패(시스템적 실패; systemic failure).
- 도구 호출 속도(tool call rate)가 기준치(threshold)를 초과(Lesson 13의 속도 한계).
- 신뢰할 수 없는 콘텐츠 읽기(out-of-trust content read) 이후 특정 도구가 호출되는 경우. 예:
file.delete(Lesson 11).
카나리 토큰(Canary Token)
카나리 토큰은 허니토큰(honeytoken)이라고도 부르며, 에이전트가 절대로 만져서는 안 되는 입력을 의미합니다. 접근하는 행위 자체가 경보가 됩니다.
에이전트를 위한 예시는 다음과 같습니다.
- 실제 권한이 없는 가짜
AWS_SECRET_ACCESS_KEY를 환경 변수(environment)에 둡니다. 유출 시도가 발생하면 즉시 주체를 특정(attribution)할 수 있습니다.
- 알려진 센티넬 값(sentinel value)이 붙어 있는 가짜 데이터베이스 레코드를 둡니다. 이 레코드를 읽거나 갱신(update)하면 경보가 발생합니다.
- 작업 공간(workspace) 안에 가짜 파일을 둡니다. 이 파일을 읽거나 편집하면 의심스러운 행동으로 분류됩니다.
- 세션 시작 시점에 주입한 가짜 메모리 항목을 둡니다. 이후 출력에 이 항목이 등장하면 메모리가 유출된 것입니다.
카나리 설계는 워크플로(workflow)마다 다르게 맞춰야 합니다. 에이전트가 정당하게 접근할 이유가 있는 카나리는 잡음(noise)에 지나지 않습니다.
통계적 한계와 엄격한 한계를 함께 두는 이유
통계적 탐지기(EWMA, CUSUM, 도구 호출 비율에 대한 z-score)는 움직이는 기준선에 적응합니다. 이는 정상적인 드리프트(legitimate drift)에 대해서는 장점이지만, 의도적인 적대적 드리프트(adversarial drift)에는 단점이 됩니다. 인내심 있는 공격자는 알람이 울리지 않을 정도로 천천히 기준선을 옮겨 갈 수 있습니다.
엄격한 헌법적 한계(Lesson 17)는 휘지 않습니다. "secrets@ 주소로는 절대 이메일을 보내지 않는다" 같은 헌법적 규칙은 단순하고, 감사가 가능하며, 느린 드리프트로는 우회할 수 없습니다. 계층화 패턴은 이런 모양입니다. 통계적 탐지기가 대부분의 잡음을 걸러 내고, 엄격한 한계가 그 탐지기를 통과해 들어온 공격을 막아 냅니다.
eBPF 데이터 경로 재지정을 통한 격리(quarantine)
Cilium의 eBPF 기반 네트워크 정책(network policy)은 격리된 파드의 송신을 커널 계층에서 포렌식 허니팟으로 재작성할 수 있습니다. Cilium의 공개 벤치마크는 TCP_RR 조건에서 1 밀리초 미만의 P99 데이터 경로 지연을 보고합니다. 실제 운영 클러스터에서 격리를 작동시키는 데 걸리는 실시간 예산(wall-clock budget)은 데이터 경로 자체가 아니라, 제어 평면(control plane)에서 노드까지 정책 업데이트가 전파되는 방식에 의해 결정됩니다. 오퍼레이터(operator)가 미리 로드되어 있는 Kubernetes 환경에서는 수백 밀리초가 현실적인 범위이며, 꼬리 지연(tail latency)은 클러스터 규모와 재조정(reconcile) 주기에 따라 달라집니다. 이 구성은 두 가지를 제공합니다. 첫째, 에이전트는 실제로는 아무것도 외부로 빼낼 수 없게 됩니다. 둘째, 허니팟 안에서 보이는 에이전트의 행동은 전면적으로 관찰됩니다. 카나리 토큰과 동일한 패턴을 다른 계층에서 적용하는 셈입니다. 격리된 환경 안에서 무엇을 시도하는지를 통해 에이전트가 의도를 스스로 드러내게 만듭니다.
어떤 탐지기도 잡지 못하는 것
- 허용된 기본 동작(primitive)을 조합해 만드는 의미론적 공격(semantic attack). 개별 행동은 모든 탐지기를 통과합니다. 문제는 그 조합 자체에 있습니다. 이는 Lesson 10에서 다룬 자동 모드(Auto Mode) 복합 실패와 같은 종류의 문제입니다.
- 탐지기 자체를 페이로드(payload)의 일부로 포함하는 공격. 에이전트가 "행동하기 전에 카나리를 비활성화하라"라고 적힌 페이지를 읽고, 실제로 그렇게 할 수 있는 권한이 있다면, 탐지기는 그 자체가 침해당한(compromised) 상태가 됩니다. 따라서 카나리 토큰은 반드시 에이전트가 수정할 수 없는 시스템에 두어야 합니다.
사용해보기
code/main.py는 짧은 에이전트 궤적(trajectory)을 세 가지 탐지기에 차례로 통과시켜 시뮬레이션합니다. 외부 딕셔너리(dict)에 보관된 킬 스위치, 동일한 도구 호출이 다섯 번 발생하면 작동하는 회로 차단기, 그리고 읽기 시 경보를 발생시키는 카나리 파일이 함께 동작합니다. 합성된 궤적에는 정상적인 행동, 반복 루프, 카나리 탐색(canary probe), 킬 스위치가 켜진 시나리오가 포함되어 있으며, 킬 스위치가 켜졌을 때 에이전트의 행동이 어떻게 중단되는지 보여 줍니다.
산출물 만들기
outputs/skill-tripwire-design.md는 에이전트 배포를 위한 탐지기 스택(detector stack)을 검토하고 빈틈을 표시합니다. 누락된 킬 스위치, 누락된 카나리, 너무 느슨하게 잡힌 회로 차단기 기준치 등이 점검 대상입니다.
연습문제
-
(쉬움) code/main.py를 실행해 보세요. 회로 차단기가 5번째 턴(다섯 번째 동일 호출)에서 작동하고, 카나리가 9번째 턴(가짜 키 읽기)에서 작동하는지 확인하세요.
-
(중간) 통계적 탐지기를 추가해 보세요. 도구 호출 비율(tool-call rate)에 대한 EWMA z-score 방식을 사용합니다. 천천히 드리프트하는 궤적을 입력하고, 이 탐지기는 끝까지 작동하지 않는다는 사실을 보여 주세요. 그런 다음 엄격한 한계(10분에 도구 호출 50회 이하)를 추가하고, 동일한 궤적에서 이 엄격한 한계가 작동하는지 보이세요.
-
(중간) 브라우저 에이전트(Lesson 11)를 위한 카나리 토큰 묶음을 설계하세요. 최소 세 개의 카나리를 나열하고, 각각이 무엇을 탐지하는지 설명하세요.
-
(어려움) Cilium의 네트워크 정책 문서를 읽어 보세요. 송신 재지정(egress-redirect) 격리 흐름을 구체적으로 설명하세요. 어떤 정책 선택자(policy selector), 어떤 파드, 어떤 송신 재작성, 어떤 경보를 사용합니까? "격리하기로 결정"한 순간부터 "첫 재지정 패킷"까지의 실시간 지연을 결정짓는 요인은 무엇입니까?
-
(어려움) 킬 스위치가 작동된 에이전트의 재활성화 절차(re-enable procedure)를 정의하세요. 누가 다시 켤 수 있습니까? 어떤 내용을 문서화해야 합니까? 다시 켜기 전에 에이전트에서 무엇이 달라져 있어야 합니까?
핵심 용어
| 용어 | 흔한 설명 | 실제 의미 |
|---|
| 킬 스위치(Kill Switch) | "Off button" | 에이전트의 수정 표면 밖에 있는 불리언. 결과를 동반하는 모든 행동에서 확인됨 |
| 회로 차단기(Circuit Breaker) | "Pattern pause" | 반복, 실패율, 비율 제한에 따라 행동별로 작동 |
| 카나리 토큰(Canary Token) | "Honeytoken" | 에이전트가 정당하게 만질 이유가 없는 미끼. 접근하면 경보 발생 |
| 허니팟(Honeypot) | "Forensic sandbox" | 격리된 에이전트가 관찰되는 재지정 트래픽 또는 작업 공간 |
| EWMA | "Moving average" | 지수 가중 이동 평균. 드리프트에 적응함(장점이자 단점) |
| CUSUM | "Cumulative sum" | 기준선에서의 지속적인 이동을 감지 |
| 엄격한 한계(Hard limit) | "Constitutional rule" | 적응하지 않음. 이력과 무관하게 항상 일정 |
| 헌법적 한계(Constitutional limit) | "Always-true rule" | Lesson 17의 헌법(constitution)과 연결됨. 에이전트가 수정할 수 없음 |
더 읽을거리