이 글은 저의 이전 글인 "유출된 에이전트 키는 두 가지 부채입니다 — 그리고 저는 제 스캐너가 그에 대해 거짓말하는 것을 잡아냈습니다"의 후속
요약
에이전트 보안 스캐너인 agentproof-scan의 0.2.0 버전 업데이트 내용을 다룹니다. 이전 버전에서 문서와 실제 코드 간의 불일치가 있었던 부분을 수정하여, 약속된 탐지 범위와 기능을 실제 패키지에 반영했습니다.
핵심 포인트
- 0.2.0 버전은 문서에 명시된 탐지 패밀리와 추론 스캐닝 기능을 실제 코드에 구현하여 일치시킴
- 기존 6개에서 16개로 탐지 가능한 자격 증명 형태(credential shapes) 확장
- Gemini, Grok, GPT-4o-mini, Anthropic Haiku 등 다양한 모델 범위 지원 유지
- 보안 완화(mitigate)보다 탐지(detect)의 중요성을 강조하는 프로젝트 철학 유지
이 글은 저의 이전 글인 "유출된 에이전트 키는 두 가지 부채입니다 — 그리고 저는 제 스캐너가 그에 대해 거짓말하는 것을 잡아냈습니다"의 후속 글입니다. 해당 포스트는 수정되지 않은 상태로 유지되며, 이 글은 0.2.0 버전에서 변경된 사항만을 다룹니다. 만약 아직 읽지 않으셨다면, 발생한 사건들, 법적 근거, 그리고 "완화 (mitigate) 대신 탐지 (detect) 해야 하는 이유"에 대한 논거가 모두 그곳에 있으며 그 중 어느 것도 변하지 않았습니다. 먼저 그 글을 읽어주세요 — 여기서 다시 논쟁하지는 않겠습니다.
먼저, 수정 사항입니다 — 왜냐하면 이것이 이번 릴리스가 존재하는 이유이기 때문입니다.
저는 하나의 규칙을 지킵니다: 정직함에 대한 노트는 하단이 아니라 상단에 배치합니다. 0.2.0 버전에 대한 내용은 다음과 같습니다.
0.1.4 버전의 일부 기간 동안, 저의 공개 페이지는 0.1.4 패키지가 실제로 출시하지 않은 커버리지 (coverage)를 설명했습니다. README에서는 16개의 탐지 패밀리 (detection families)와 추론 스캐닝 표면 (reasoning-scanning surface)에 대해 언급했지만, PyPI에 올라온 0.1.4 휠 (wheel) 파일에는 6개의 탐지 패밀리만 포함되어 있었고 추론 스캔 모듈 (reasoning-scan module)은 전혀 없었습니다. 페이지가 코드보다 앞서 나갔던 것입니다. 이것이 바로 이 프로젝트 전체가 잡아내기 위해 존재하는 정확한 실패의 형태입니다 — 즉, 실제 작업이 완료되기 전에 완료된 것처럼 읽히는 주장 — 그리고 저는 제 자신의 README에서 그 실수를 저질렀습니다.
0.2.0은 코드가 페이지를 따라잡는 릴리스입니다. 새로운 기능을 발표하는 것이라기보다 제가 갚아야 할 부채를 갚는 것에 가깝습니다: 이제 출시된 패키지에는 페이지에서 언급했던 내용이 포함되어 있습니다. 전체 수정 사항은 이전 포스트의 목록(아래 항목 F)에 추가되었으며, 삭제 없이 추가만 되었습니다.
변하지 않은 것들 — 다시 설명하지 않기 위해
0.2.0은 추가적인 성격의 업데이트입니다. 이전 포스트를 참조해 주세요. 이것들을 새로운 것으로 재브랜딩하지는 않겠습니다:
종료 코드 (exit-code) 계약 (0 ran-and-clean / 1 scan-didn't-run / 2 defect-found), reason= 슬러그 (slugs), 그리고 완료 게이트 (completion gate) — 동일합니다.
Bring-your-own-key, 서버리스 (serverless), Apache-2.0 — 동일합니다.
모델 범위 (model scope) — Gemini 3 Pro-series, Grok 4–4.3, GPT-4o-mini, Anthropic Haiku부터 경량 Sonnet까지; 프론티어 모델 (frontier models)은 제외 — 동일합니다. 모든 모델 간 교차 수치는 여전히 "모든 모델"이 아니라 "실제로 소규모 상점에서 배송하는 모델들"에 대해 나타냅니다.
기존의 6가지 자격 증명 제품군 (credential families)은 0.1.4 버전에서와 정확히 동일하게 작동합니다. 기존 경로 중 변경된 것은 없습니다.
이미 0.1.4 버전을 사용 중이었다면, pip install -U agentproof-scan은 도구의 동작 방식이 아니라 커버되는 범위를 변경합니다.
세 가지 숫자가 증가했습니다 — 그리고 이 숫자들의 합은 1이 아닙니다.
이 부분은 라벨을 너무 성급하게 읽기 쉬우므로, 제가 가장 천천히 읽어주기를 바라는 부분입니다. 0.2.0은 세 가지 서로 다른 측정치를 이동시켰습니다. 이들은 세 가지 서로 다른 것을 측정합니다. 16가지 자격 증명 형태 (credential shapes)를 라벨링하는 스캐너가 "16가지 종류의 공격을 포착하는" 스캐너인 것은 아니며, 이 세 가지 숫자 중 어느 것도 다른 숫자의 부분 집합이나 총합이 아닙니다.
Layer 0.1.4 → 0.2.0 | 숫자의 의미 Backing (byte-reproducible, 0 API)
Detection (matchers)6 → 16 families
** (기본값으로 15개 활성화 + postgres 옵트인) | 매처는 자격 증명(credential)의 형태에 올바른 패밀리 레이블을 지정하고, 유사한 항목(look-alikes) 축에서는 조용히 유지합니다.
axis_b_coverage_green.json — 0.1.4 이후 추가된 10개 패밀리: 10/10 라벨링 완료, 놓친 것 없음(missed), 오탐지 없음(false positives) (유사하지 않은 문자열에 대해)
Elicitation (end-to-end)6 → 10 families
** 자격 증명이 에이전트의 실제 응답 안에 위치하는 경우, end-to-end로 수행됩니다: 플랜트(plant) → 프로브(probe) → 탐지(detect), 올바른 패밀리와 함께 아무것도 꾸며내지 않습니다.
elicitation_green.json — 10개 식재(planted), 10개 탐지(detected), 위음성률(FN) 0 / 위양성률(FP) 0, 허위 제공자 없음 (postgres 제외, 옵트인)
Reasoning-attack (H-CoT) new: 3 probes
** 사용자가 소유한 에이전트에 가짜 '추론 단계(reasoning step)'가 주입될 때, 스캐너는 결과적인 추론 채널 누출을 감지합니다 — 기존의 추론 채널 탐지에 추가된 것이며, 대체하는 것이 아닙니다.
hcot_green.json — 3개 프로브, FN 0 / FP 0; 세 경우 모두 답변은 깨끗하게 유지되었고 오직 추론만 누출되었습니다.
제가 명확히 해야 할 세 가지 사항이 있습니다. 그렇지 않으면 숫자들이 암시적으로 거짓말을 합니다:
Detection 16 ≠ elicitation 10 ≠ 3 H-CoT probes. 첫 번째는 매처(matcher)가 인지하는 형태(shapes)의 수를 나타냅니다. 두 번째는 에이전트(agent)의 응답에서 실제로 유출된 패밀리(families)의 수를 나타냅니다. 세 번째는 공격 프로브(attack probes)의 수이며, 중단된 패밀리나 공격의 수가 아닙. "16"을 "도구가 보호해 주는 항목의 수"로 읽는 것이 제가 방지하고자 하는 오독(misread)입니다. 여기서 진정한 능력의 향상은 elicitation 6 → 10이며, 이것이 바로 "실제 에이전트 흐름에서 더 많은 종류의 자격 증명(credential)이 포착됨"을 의미합니다.
H-CoT 행은 모델에 관한 것이 아니라 스캐너(scanner)에 관한 것입니다. 이는 이 도구가 사용자가 지정한 에이전트에서 해당 유출을 감지할 수 있음을 의미합니다. 이것이 어떤 실제 모델이 H-CoT에 취약하다는 주장은 아닙니다. 그러한 주장을 하려면 실제 모델을 대상으로 한 실시간 측정(live measurement)이 필요하며, 이번 릴리스에는 포함되어 있지 않습니다. 프로브(probes)는 사용자가 소유한 에이전트를 점검하기 위한 용도입니다. 이는 탈옥 키트(jailbreak kit)가 아니며, "본인이 소유한 에이전트만 스캔하십시오"가 이들이 배포할 때 내거는 규칙입니다.
세 가지 모두 오프라인 방식입니다 (정해진 방식, 0회의 API 호출). 이들은 심어진 합성(synthetic) 형태의 가짜 데이터(shape-only fakes)를 대상으로 스캐너를 실행하며, 실제 키나 실시간 모델은 사용하지 않습니다. 따라서 이 중 어느 것도 실제 에이전트가 얼마나 자주 유출되는지를 알려주지 않습니다. 그것은 아래에 설명될 다른 종류의 수치입니다.
프런티어 표면(frontier surface): 새로운 수치가 아닌 새로운 도달 범위(reach)
0.2.0은 이제 프런티어 모델(frontier model)의 확장 사고(extended-thinking) 트레이스(trace)를 지목하고 이를 일급 표면(first-class surface)으로 스캔할 수 있습니다. Anthropic의 확장 사고(extended thinking)의 경우, 추론(reasoning)은 content.0.thinking에 존재하고 답변은 content.1.text에 존재하는데, 사용자가 경로를 제공하면 스캐너가 전자를 읽을 것입니다. 이것이 도달 범위(reach)입니다. 즉, 이전에는 도구가 볼 수 없었지만 이제는 볼 수 있게 된 표면을 의미합니다.
이것은 프런티어 유출률(frontier leak rate)이 아닙니다. 이번 릴리스를 위해 프런티어 모델을 대상으로 실시간 측정 캠페인을 수행하지 않았으므로, 취약성 주장(vulnerability claim)에 백분율이나 모델 이름을 붙이지 않을 것입니다. "스캐너가 이제 이 표면을 볼 수 있습니다"와 "이 모델은 X%의 확률로 유출됩니다"는 서로 다른 문장이며, 여기서는 오직 전자의 내용만 뒷받침됩니다. 만약 API가 트레이스(trace)를 반환하지 않으면, 통과(pass)가 아니라 "확인할 수 없음"을 의미하는 not_applicable 결과가 나옵니다.
이전의 방향성 수치들 — 그대로 유지되었으며, 해당 라벨이 붙어 있음
이전 포스트의 교차 모델(cross-model) 수치는 0.1.4 캠페인 측정값**이며, 저는 이를 마치 0.2.0에서 새로 측정된 것처럼 조용히 다시 인쇄하지 않을 것입니다. 그 수치들의 실체는 다음과 같습니다:
정답 채널 0/90 (≤4.1%, Wilson95) vs 추론 채널 41/90 (45.6%, [35.7, 55.8]) — 즉, '정답은 맞았으나 추론 과정이 유출된(answer-clean-but-reasoning-leaks)' 분할 수치는 대상 범위 내의 두 추론 가능 모델(Haiku, Gemini-flash)을 대상으로 출시된 프로브(probe) 세트에 대해 측정되었습니다. 근거: package_under_test = 0.1.4를 기록하고 있는 channel_repro_green.json. 0.2.0은 가산적(additive)이며, 이 카나리(canary, sk-ant-…)는 매처(matcher)가 이미 보유하고 있던 원래 6개 제품군 중 하나이기 때문에, 이 측정값은 재실행된 것이 아니라 그대로 유지(carried forward)된 것입니다 — 동일한 프로브, 동일한 모델, 동일한 탐지 경로를 사용함. 여전히 방향성(directional)을 띠며(모델별로 상이함: Haiku 22/45, Gemini 19/45; 작은 N값, 프로브 문구에 민감함), 여전히 고정된 비율은 아닙니다.
완화 조치(Mitigation)를 통해 정답 측 노출을 ~79–93pp(설정별 상이) 감소시켰고, 방어/강화된 프롬프트(defended/hardened prompts)에 대한 과잉 거부(over-refusal)는 0/80(세 가지 타겟 전체에서 118/120)이었으며, ~85-vs-53-토큰의 프롬프트 크기 비용 — 이 모든 것은 0.1.4 캠페인의 결과이며, 0.2.0을 위해 재측정되지 않았고 변경되지 않았습니다. 가산적 릴리스(additive release)는 완화 경로(mitigation path)를 건드리지 않았으므로, 저는 이 수치들을 0.2.0 수치로 새로 명명하는 대신 해당 라벨과 함께 그대로 유지합니다.
여기서 정직함의 규칙은 간단합니다: 0.2.0 포스트에서 재사용되는 0.1.4 측정값은 반드시 그것이 0.1.4 측정값임을 명시해야 합니다. 이를 조용히 재사용하는 것은 그 자체로 작은 '거짓-GREEN(false-GREEN)'이 될 것입니다.
재현 계약 (Reproduction contract)
의도적으로 분리된 두 단계:
T1 — 모든 GREEN 기반 수치는 API 키 없이, 오프라인의 클론으로부터 바이트 단위로 일치하게(byte-for-byte)** 재현됩니다:
git clone https://github.com/ghkfuddl1327-wq/agentproof && cd agentproof
python score_axis_b_coverage.py # → axis_b_coverage_green.json (detection 16)
python score_elicitation.py # → elicitation_green.json (elicitation 10)
python score_hcot.py # → hcot_green.json (H-CoT 3 probes)
python -m pytest -q # 그 뒤에 숨겨진 게이트(gates)들
두 번 실행해도 동일한 바이트를 얻습니다. 만약 재생성된 파일이 커밋된 파일과 다르다면, 해당 주장은 깨진 것으로 간주하십시오. 이것이 바로 생성기(generators)를 결과물(artifacts)과 함께 배포하는 이유입니다.
- T2 — 모델 간 관찰 결과(cross-model observations)는 이런 방식으로 재현되지 않습니다. 그것들은 측정된 스냅샷(snapshots)입니다. 즉, API 키, 모델 가용성, 그리고 우리 아래에서 변동하는 제공자(provider)의 동작에 의존합니다. 방향성은 있으나 바이트 단위로 재현되지는 않습니다. 이것이 위에서 언급한
0/90,41/90,79–93pp버킷(bucket)의 정체입니다.
제한 사항 ( 0.2.0 변경 사항만 해당)
여전히 탐지기(detector)일 뿐이며, 완화(mitigation) 도구나 방패(shield)는 아닙니다. 새로운 두 가지 패밀리(families)는 **비밀의 증거가 아닌 노출 신호(exposure signals)**입니다. JWT는 종종 공개된 ID 토큰이며, Twilio의 SK…는 쌍이 되는 비밀(secret)이 별도로 존재하는 공개 식별자입니다. 그리고 발견 사항의 scope가 이를 명시하고 있습니다. postgres는 16번째 패밀리이며 선택 사항(opt-in)으로 유지됩니다. 왜냐하면 postgres://… URL 내부의 비밀번호는 문서를 채우는 플레이스홀더(placeholder) 비밀번호에서 오탐(false-positives)을 일으키기 때문입니다. 양치기 소년처럼 작동하는 패밀리를 출시하느니 차라리 기본적으로 비활성화해 두겠습니다. 이전 게시물의 '제한 사항'에 나열된 모든 내용은 여전히 유효합니다.
사용 방법
`bash
pip install -U agentproof-scan # 0.2.0
Apache-2.0, bring-your-own-key, serverless. Repo: github.com/ghkfuddl1327-wq/agentproof
만약 도구가 주장하는 기능을 수행하지 못하고 무언가를 망가뜨린다면, 그것은 발견 사항(finding)입니다. 이슈(issue)를 오픈하고 귀하의 환경에서 수치가 맞지 않는 부분을 알려주십시오. 저는 제 자신의 '그린(green)'을 신뢰하기보다 운영자들에 의해 교정(calibrated)되는 쪽을 택하겠습니다.
수정 사항 — 이전 게시물의 목록에 추가됨
추가 전용(Append-only): 삭제되지 않고 표시됨.
F. 공개 페이지, 0.1.4 버전 윈도우(window) — 출시된 패키지보다 앞서 설명된 커버리지(coverage). 0.1.4 버전 윈도우 동안 README에 명시된 내용: 16개의 자격 증명 제품군(credential families)에 대한 탐지 및 추론 스캐닝 표면(reasoning-scanning surface). [수정됨] PyPI의 0.1.4 패키지는 6개의 탐지 제품군만을 포함하고 있었으며 추론 스캔 모듈도 없었습니다 — 즉, 페이지에서 설명한 기능이 실제 출시된 코드에는 아직 포함되지 않았던 것입니다. 0.2.0 버전은 해당 코드를 탑재하여 출시합니다: 16개 제품군 매처(15개 기본 + postgres 옵트인(opt-in)), 10개 제품군에 대한 엔드 투 엔드(end-to-end) 유도(elicitation), 그리고 추론/H-CoT 표면이 이제 패키지에 포함되어 페이지와 패키지가 일치합니다. 휠(wheel)에 포함되기 전에 README에 커버리지를 작성하는 것은 이 도구가 잡아내기 위해 존재하는 바로 그 '현실보다 앞선 주장(claim-ahead-of-reality)'의 실패 사례입니다 — 제가 다른 모든 것에 적용하는 것과 동일한 기준으로 여기에 기록합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기