
CrowdStrike 충돌의 본질은 필드 수였다: 커널이 20개를 예상한 곳에 21개. 독립적인 검증 계층은 전무했다.
2024년 7월 19일, 단 한 건의 벤더 업데이트로 인해 90분도 채 되지 않아 수백만 대의 Windows 머신이 다운되었으며, 그 원인은 단 하나의 숫자였습니다. CrowdStrike의 'Rapid Response Content' 채널 파일이 배포된 커널 인터프리터가 20개를 예상하던 곳에 21개의 필드를 선언한 것입니다. 그 추가 필드로 인해 범위를 벗어난 메모리 읽기(out-of-bounds read)가 발생하여 즉각적인 블루스크린이 유발되었고, 부팅 극초기에 충돌이 발생했기 때문에 다운된 에이전트는 롤백 명령을 수신하기 위해 다시 살아날 수도 없었습니다. 복구는 곧 각 머신으로 직접 걸어가 안전 모드(Safe Mode)에서 수작업으로 수리해야 함을 의미했습니다.
저는 그해 8월에 발표된 CrowdStrike 자체의 근본 원인 분석 보고서를 마음에 걸리는 의문이 명확해질 때까지 몇 번이고 다시 읽었습니다. 이는 해킹이 아니었습니다. 결함이 있는 AI 모델 때문도 아니었습니다. 운영 환경에 도달하기 전까지 그 어떤 독립적인 계층도 검증하지 않은 채 페이로드에 자리 잡고 있던, 21 대 20이라는 판별 가능한 산술적 사실이었습니다. 벤더의 검증기는 이를 승인했습니다. 마비된 엔터프라이즈 기업들은 그 검증기를 소유하지 못했습니다. 기업들이 소유한 것은 오직 그 참담한 결과뿐이었습니다.
저는 그 격차를 해결하기 위해 지난 기간 동안 데모를 구축했습니다. 소프트웨어 벤더와 프로덕션 플릿 사이에 위치하여 벤더가 무엇을 배포할 수 있는지를 코드로 결정하는 Kestrel이라는 콘솔입니다. 작동 방식은 다음 링크에서 직접 확인하실 수 있습니다: veriprajna.com/demos/software-update-integrity. 구축 과정에서 저를 놀라게 한 것은 진정한 해결책이 존재하는 위치였습니다. 저는 처음엔 더 똑똑한 모델이 필요할 것이라 확신했지만, 충돌을 가장 먼저 포착해 낸 것은 단 몇 줄의 순수 Python 코드였습니다.
충돌을 재현하고 코드가 결정하게 만들다
저는 7월 19일의 장애 시그니처를 테스트 픽스처로 재구성하고 제 시스템을 이에 적용해 보았으며, 스스로의 리플레이에 실망하게 되지 않을까 반신반의하기도 했습니다. 패키지는 C-00000291로, 제가 SentinelEdge라 명명한 가상의 벤더가 Acme Financial이라는 8,500개 엔드포인트 규모의 가상 플릿으로 푸시한 Rapid Response Content 채널 파일입니다. 이들 중 실제 존재하는 기업은 없습니다. 하지만 장애 시그니처는 진짜입니다. 선언된 스키마 필드가 20개에서 21개로 증가했고, 카나리(canary) 계획 없이 단 한 번의 웨이브로 플릿의 100%에 배포된 것입니다.
게이트는 네 가지 검사를 동시에 수행하며, 각 검사는 재량적 판단이 아닌 명확한 산술 또는 단순 조회입니다. 스키마 diff는 인터프리터가 20개를 예상하는 곳에서 21개의 필드를 감지하여 범위 초과 읽기 오류를 표시합니다. 실제 Windows VM 팜이 아닌 프로필별 결정론적 결과 모델인 시뮬레이션 샌드박스는 재부팅 주기 전반에 걸쳐 6개 플릿 프로필 중 5개에서 부트 루프를 발생시킵니다. 또한 스키마 검사와 무관한 드라이버 호환성 신호로부터 이를 도출하므로, 두 결과는 단순한 반복이 아니라 상호 검증을 형성합니다. 데드 에이전트 감지기는 롤백 루프를 참(true)으로 표시합니다. 충돌하는 에이전트 자체가 롤백을 수신해야 할 주체인데 부팅 전에 이미 사망하기 때문입니다. 영향 반경(blast radius)은 5% 카나리 정책 대비 100%에 달합니다. 판정: BLOCK. 화면에는 '어떠한 프로덕션 엔드포인트도 재부팅되기 전에 차단됨'이라고 표시됩니다.

단 한 건의 업데이트로 방지된 예상 다운타임은 5,000,000달러로 표시되며, 저는 이 숫자의 성격을 명확히 하고자 합니다. 이는 데모 고유의 모델로, 영향을 받는 비율에 시간당 500만 달러 입력값과 1시간의 최소 복구 시간을 곱한 것이며 공식은 화면에 표시됩니다. 고객이 실제로 절감한 금액이 아닙니다. 7월 19일의 실제 복구에는 1시간이 아니라 수일이 걸렸으므로, 최소 복구 기준은 의도적으로 보수적으로 설정되었습니다.
초록색 결과는 빨간색 결과보다 나를 더 불안하게 만들었다
저는 빨간색 사례보다 초록색 사례에 더 신경을 곤두세웠습니다. 위험한 업데이트를 막으면서 안전한 업데이트까지 질식시키는 거버넌스 계층은 스스로 예약한 서비스 중단에 불과하기 때문입니다. 동일한 가상 벤더가 무해한 탐지 시그니처 업데이트인 RRC-7741(선언 스키마 20 대 20, 1.2% 단계적 카나리 계획 포함)을 푸시합니다. 에이전트 팀이 실행되고, 스키마가 일치하며, 6개 프로필 중 5개가 재부팅 주기를 통과하고, 데드 에이전트 루프는 거짓이며, 영향 반경은 정책 내에 머뭅니다. 판정: APPROVE ROLLOUT. 102개 엔드포인트의 카나리 링으로 릴리스되었습니다. 안전하고, 신속하며, 평온한 결과입니다.

세트 내 6개의 무해한 업데이트 전체에서 게이트는 단 한 건의 오탐 차단(false block)도 발생시키지 않았습니다. 제가 분모를 명시하여 말하는 이유는 6개는 6개일 뿐이며, 이를 귀하의 플릿에 대한 일반화된 약속으로 부풀려 표현하지 않기 위함입니다. ALLOW 사례의 가치는 단순한 백분율보다 더 좁고 훨씬 중요합니다. 게이트는 일상적인 트래픽에서는 보이지 않고, 플릿을 무너뜨릴 수 있는 단 한 번의 위기에서 결코 흔들리지 않을 때에만 신뢰를 얻을 수 있습니다.
판정 권한을 모델에서 떼어낸 이유
저는 처음에 추론이 가장 어려운 부분이며, 더 정교한 모델이나 영리한 비평 에이전트가 잘못된 업데이트를 잡아낼 것이라 가정하고 구축을 시작했습니다. 그러나 이는 인정하기까지 시간이 좀 걸렸던 명백한 오판이었습니다. Kestrel 내부에는 LLM 팀이 존재합니다: 정규화기, 샌드박스 인터프리터, 그리고 업데이트가 안전하다고 주장하는 쪽과 충돌할 것이라 주장하는 대립되는 두 비평 에이전트입니다. 이 적대적 쌍은 결정이 내려지기 전에 양방향에서 판정을 레드팀 검증하므로 그 역할을 충실히 수행합니다. 하지만 이 에이전트들 중 어느 누구도 최종 판정을 내리지 않습니다.
최종 판정은 두 개의 순수 Python 파일인 verifier.py 및 gate.py에 의해 결정되며, 이들은 에이전트 프레임워크 외부에 완전히 독립적으로 존재합니다. 에이전트 팀은 기본 모델인 claude-opus-4-8과 함께 Pydantic AI 기반으로 구동되며, 시스템 전체는 API 키 없이 결정론적 자문 대체 메커니즘을 통해 오프라인에서도 작동합니다. 이 모든 모드에서 게이트는 동일하며 동일한 결정을 반환합니다. 결정은 추론이 아니라 산술이기 때문입니다. 에이전트는 자문하고 코드가 결정합니다. '허용' 쪽으로 기우는 자문 에이전트라 할지라도 중대한 결정론적 발견을 번복할 수 없으며, 이는 취향의 문제가 아닙니다.
벤더를 검증하기 위해 구축된 계층이 안전에 관해 벤더의 말을 그대로 믿을 수는 없습니다. 자체 모델의 말을 그대로 믿어서도 안 됩니다.
그 한 문장이 바로 아키텍처가 현재와 같은 구조를 갖추게 된 이유입니다. 벤더가 배포하는 것을 통제하는 유일한 임무를 가진 제품에 대한 신뢰는, 설득당해 '예'라고 답할 수 있는 구성 요소를 거쳐서는 절대 안 됩니다.
감사관에게 전달할 자료
저는 증거 기록을 구축하는 동안 보조 모니터에 EU 사이버 복원력 법(CRA)을 열어 두었습니다. 그 기록이야말로 제가 실제로 방어해야 할 결과물이기 때문입니다. 모든 결정은 SHA-256 콘텐츠 해시, 판정, 결정론적 증명, 프로필별 샌드박스 결과, 모델 ID가 포함된 자문 에이전트 판정, 트리거된 정책 규칙, 그리고 각 단계의 레이턴시를 담은 단계별 평가 추적을 포함하는 불변 HTML 파일과 서명된 JSON 파일로 내보내집니다.

추적은 제가 개별 단계를 직접 클릭해 보기 전까지 과소평가했던 부분이었습니다. 한 이벤트는 '서명된 벤더 매니페스트 정규화, 184ms 만에 완료'라고 표시되며, 감사 검토를 위해 결정 출력과 함께 보존됩니다. 모든 단계는 재현 가능합니다. 규제 당국은 제 대시보드를 맹신할 필요가 없습니다. 산술을 다시 실행하여 동일한 결과를 얻을 수 있습니다.

저는 서명이 무엇이고 무엇이 아닌지에 대해 신중을 기합니다. 이는 로컬 SHA-256이며 기업용 PKI가 아닙니다. 벤더 업데이트 피드와 그 배후의 ITSM 티켓은 테스트 스텁이며 라이브 커넥터가 아닙니다. 이 기록은 규제 요건에 부합하도록 설계되었습니다: CRA의 단기 인시던트 보고, SEC의 중대 사이버 보안 인시던트에 대한 4영업일 내 공시, 2025년 풀턴 카운티에서 제기된 Delta 대 CrowdStrike 소송에서 제기된 벤더 책임 문제 등입니다. '부합하도록 설계되었다'는 뜻이지, 누구도 인증하지 않으며 법적 자문도 아닙니다. 규정 준수를 보장한다는 감사 로그를 판매하려는 자가 있다면 그는 단지 물건을 팔려는 사람일 뿐입니다.
제가 자랑스럽게 생각하는 또 하나의 결정이 있으며, 그것은 바로 '거부'입니다. 픽스처 XX-0000은 게이트가 파싱할 수 없는 암호화된 독점 콘텐츠 바이너리(blob)이므로 게이트는 추측하지 않습니다. ABSTAIN(기권)을 반환하고 사람에게 전달합니다. 읽을 수 없는 항목을 승인하는 게이트는 게이트가 전혀 없는 것보다 더 나쁘기 때문입니다. 샌드박스가 모델링할 수 없는 레거시 호스트는 플래그가 지정되어 제외되며 결코 안전하다고 간주되지 않습니다. 어휘는 ALLOW, HOLD, BLOCK, ABSTAIN 네 단어로 구성되며, 마지막 단어야말로 제가 가장 확고히 지키고자 하는 단어입니다.
12개 중 12개가 의미할 수 있는 진정한 범위
여기서 속도를 늦추어야 합니다. 바로 이 시점에서 창업자가 편리하게 숫자를 부풀리기 시작하기 때문이며, 저는 회사 이름을 참된 지혜를 뜻하는 Veriprajna로 지었으므로 수치 부풀리기는 용납될 수 없습니다. 고정되고 라벨이 지정된 12개 업데이트 세트에서 게이트는 12개 모두에 대해 올바른 결정을 내립니다. 그중 6개는 무해하며 단 한 건도 차단하지 않습니다. 하나는 솔직한 ABSTAIN입니다. 전광판에는 12/12 검증된 결정, 0/6 오탐 차단, 세트 전체에 걸쳐 약 1,330만 달러의 예상 방지 다운타임이 기록되며, 이 중 500만 달러는 단 한 건의 CrowdStrike급 차단에서 비롯됩니다.

이제 제가 요약을 거부하는 부분입니다. 이는 12개의 라벨링된 항목에 대한 결과일 뿐이며, 귀하의 플릿에 도착할 다음 업데이트에 대한 보증이 아닙니다. 무해한 6개 항목은 엄밀히 6개일 뿐입니다. 이는 '불량 업데이트를 100% 차단한다'는 뜻이 아니며 결코 그렇게 될 수도 없습니다. 만약 제가 그런 문장을 쓰는 것을 보신다면 제 글을 읽는 것을 멈추셔야 합니다. 제가 보증하는 숫자는 다른 종류의 것입니다: 판정에 모델 온도가 포함되지 않으므로 매 실행마다 동일한 입력에 대해 동일한 결정을 내립니다. 내일 픽스처 세트를 다시 실행해도 바이트 단위로 동일한 결과가 반환되며, 이는 확률론적 계층에서는 불가능한 방식으로 결정론적 계층을 감사할 수 있게 해 줍니다.
내게 남겨진 질문
이번 개발을 통해 제게 깊이 남은 것은 그 실패가 얼마나 평범한 것이었는가 하는 점입니다. 20개가 예상되던 자리에 21개의 필드가 존재했다는 사실. 벤더와 플릿 사이에 독립적인 검증자가 자리 잡고 있었다면, 단 한 대의 머신이 재부팅되기 전에 어떤 독립 검증자라도 단순 산술을 통해 잡아낼 수 있었던 숫자였습니다. 하지만 그런 검증자는 없었습니다. 그리고 오늘날에도 여전히 거의 존재하지 않습니다.
모든 기업은 자신이 제어할 수 없는 벤더로부터 커널 권한을 가진 에이전트를 8개에서 12개씩 실행하고 있으며, 이들 각각은 파일을 링 0(ring 0)으로 직접 밀어 넣을 수 있습니다. SBOM 도구는 오픈 소스 종속성을 감시합니다. ID 관리는 접근을 감시합니다. 하지만 벤더의 독점 업데이트가 인입될 때 이를 읽고 안전성을 입증하는 주체는 아무도 없습니다. Kestrel은 EDR이 아니며 커널을 결코 건드리지 않습니다. 이러한 에이전트 위에 자리 잡고 그들이 배포할 수 있는 것을 통제합니다. 그것이 바로 제가 구축하고자 했던 계층이며, 전체 분석은 다음 위치에서 확인할 수 있습니다: veriprajna.com/demos/software-update-integrity.
제 설명을 글로 읽기보다 직접 작동하는 모습을 보고 싶으시다면, 전체 시스템이 엔드투엔드로 실행되는 모습을 여기에서 확인하실 수 있습니다.
그러므로 제가 이제 모든 플릿을 볼 때마다 던지는 질문은 이것입니다: 다음 벤더 업데이트가 도착했을 때, 그 파일과 운영 환경 사이에 무엇이 자리 잡고 있으며 그 검증 과정을 입증할 수 있는가? 만약 그 답이 벤더를 맹목적으로 신뢰하는 변경 자문 위원회(CAB)라면, 수백만 대의 머신을 마비시킨 그 산술적 오류는 여전히 통제되지 않은 채 작동하고 있는 것입니다. 그것은 결코 스스로를 예고하지 않습니다. 재부팅되는 그 순간까지, 이전에 도착했던 모든 정상 업데이트와 완전히 똑같은 모습을 하고 있을 것입니다.

