Weir
AI 에이전트가 API 키를 유출하는 것을 포착하세요. 에이전트 프레임워크는 추적(traces)과 로그에 키를 복사할 수 있으며, 코딩 에이전트는 이를 모델의 컨텍스트로 읽어 들일 수 있습니다. Weir는 각 키를 정확한 값으로 찾아내고, 어디로 갔는지 이름을 지정하며, 절대 출력하지 않습니다.
- 사용자가 구축하는 에이전트: 가짜 키를 심어 실제 키가 존재하는 곳을 식별하고, 에이전트 자체의 플로우를 실행하여 스팬(spans), 로그, 콘솔 출력, 모델, 다른 서비스 등 도달한 모든 위치에 대한 판정 결과를 얻습니다. 유출되었는지, 정리되었는지 또는 불완전한지 확인합니다. MLflow에서 [GHSA-j7qq-vr8c-xvw3]를 발견했습니다.
- 사용하는 코딩 에이전트: Claude Code에서는 상태 표시줄을 통해 실제 키 중 어떤 것이 세션에 진입했거나 도구 호출로 나갔는지 보여주며, 선택적 후크(hook)는 모델이 읽기 전에 알려진 키를 도구 결과에서 제거합니다.
CI PyPI License: Apache-2.0
Weir plants fake keys in your agent, lets its telemetry flow, and checks every span, log and metric for those exact values: leak, clean or incomplete.
10초 만에 사용해 보세요
pip install weir-scan
weir canary judge --sample
Terminal recording: weir canary judge --sample prints a LEAK line naming the planted fake key and the span it reached, then "result: leak", and exits 1.
사용하는 두 가지 방법
1. CI 환경 또는 노트북에서 에이전트 테스트하기
weir-run은 실제 키가 존재할 곳에 고유한 가짜 키를 심고, 로컬의 가짜 모델을 대상으로 에이전트 자체 플로우를 실행하여 에이전트가 내보내는 모든 것을 포착합니다. 이후 weir canary judge는 이 모든 내용을 검색하여 해당 정확한 값을 찾아냅니다.
pip install weir-scan weir-run
weir-run run --config canary.toml
[[placement]]
id = "env.OPENAI_API_KEY"
kind = "env"
...
풀 리퀘스트(pull request)에서는 한 단계가 이를 실행하고 댓글로 판정 결과를 게시합니다:
- uses: IdoGol24/weir@<ref>
설정, pytest fixture 및 전체 워크플로우는 weir-run README · action README를 참고하세요.
2. 사용자의 Claude Code 세션 모니터링하기
상태 표시줄 세그먼트(status-line segment)는 사용자가 입력한 실제 자격 증명(credentials) 중 몇 개가 현재 세션의 컨텍스트에 포함되었는지, 그리고 그중 몇 개가 도구 호출(tool call)을 통해 외부로 전송되었는지를 계산합니다. /weir를 사용하면 각 항목이 어디서 왔는지, 어떤 턴에서 이동했는지, 현재 어디에 위치하는지, 그리고 무엇을 해야 하는지 설명해 줍니다. 이 기능은 절대 실제 값을 보여주지는 않습니다.
설정(Setup) 시 마스킹 후크(redaction hook)를 추가할 수도 있습니다. Read, Bash, Grep, Glob 또는 WebFetch 결과가 등록된 키(keys) 전체 값을 포함하고 있으며, 이것이 weir audit 형식과 일치하는 경우, 이 후크는 모델이 인식하기 전에 해당 값을 [weir: NAME removed]로 대체합니다. 이때 상태 표시줄은 이를 제외된 것으로 계산합니다. Claude Code의 훅 참조에 따르면 이러한 대체는 "클로드가 보는 것만 변경"한다고 합니다. Bash 출력과 같이 30,000자 이상의 대용량 출력이 발생하는 경우에도, Claude Code는 전체 출력을 세션 폴더의 파일로 저장하고 클로드에게 해당 경로를 제공합니다(도구 참조). 이렇게 저장된 사본은 후크가 실행되기 전에 작성된 원본 출력을 담고 있으므로, 후크는 이 또한 소유자 전용으로 동일하게 재작성합니다. 만약 후크가 실패하면, 상태 표시줄에는 "가능성이 낮게 마스킹됨(possibly not redacted)"이라고 표시됩니다.
The weir segment beside an existing status line: a green check and "no known key seen", then a warning sign with "2 entered" in amber and "1 sent" in red.
uv tool install weir-scan
weir statusline setup
weir statusline undo를 사용하면 이 기능을 제거할 수 있습니다. Linux 및 macOS에서 사용할 수 있습니다. 자세한 내용은 docs/statusline.md을 참고하세요.
차별점(Why it's different)
- 추측하지 않습니다. 원본이든 인코딩되었든 심어둔 정확한 값을 찾기 때문에, 탐지된 것은 실제 유출입니다.
- 모든 출구 경로를 확인합니다: 스팬(spans), 로그(logs), 메트릭(metrics), 콘솔 출력(console output), 모델로 전송된 프롬프트(prompts), 그리고 다른 서비스에 대한 요청(requests)까지 포함됩니다. 비특권 사용자 네임스페이스(unprivileged user namespaces)가 허용되는 Linux 환경에서는 에이전트가 외부 네트워크 없이 실행되므로, 직접적인 연결도 포착됩니다.
- 테스트 장치에서 오탐지된 '모든 것이 안전함' 상태는 없습니다.
weir-run 테스트에서 필수라고 표시한 항목이 실행되지 않았다면, 결과는 절대 "깨끗함(clean)"이 아닌 "불완전함(incomplete)"입니다. 종료 코드: 0은 깨끗함(clean), 1은 유출(leak), 2는 사용 불가능한 입력(unusable input), 3은 불완전함(incomplete)입니다.
- 오프라인이며 결정론적입니다 (deterministic). 어떤 AI 모델도 아무것도 결정하지 않으며, Weir 자체도 어디로 아무것도 전송하지 않습니다. 테스트가 이 두 가지를 강제합니다.
Weir로 발견된 취약점: GHSA-j7qq-vr8c-xvw3, MLflow 권고 사항이며 3.17.0에서 수정되었습니다.
제한 사항 (Limits)
- 해시되거나, 분할되거나, 잘린 값(truncated ones)이 아닌 전체 값만 찾습니다.
- 테스트가 실행되는 동안 에이전트가 전송하는 것만 볼 수 있습니다.
- 네트워크 격리(Network isolation)는 Linux에서만 가능하며 비특권 사용자 네임스페이스를 필요로 합니다. 다른 환경에서는 보고서에 네트워크가 격리되지 않았다고 명시됩니다.
- 가짜 모델은 OpenAI와 Anthropic의 Messages API와 호환되는 방식을 사용합니다.
- 상태 표시줄(status line)은 인벤토리(inventory) 내의 키만, 전체 값으로 알고 있습니다. 파일 내부나 변수 이름으로 나가는 키는 감지하지 못합니다.
- 인벤토리는 한 번에 하나의 프로젝트만을 다룹니다.
전체 목록은 docs/canary.md와 docs/statusline.md에 있습니다.
마스킹 훅(redaction hook):
- 모델은 도구 호출(tool call) 후에 모델이 읽는 내용만 변경합니다. 이미 실행된 명령을 되돌리거나 채팅에 붙여넣은 키를 가로챌 수는 없습니다.
- 인벤토리화된 키(inventoried keys)는 전체 값으로만 일치시킵니다. 다른 텍스트에 붙어 있는 키나 PDF 안에 있는 키는 제거되지 않습니다.
- 후크(hook)가 완료되지 않거나 도구 호출이 실패하면, Claude Code는 원래 출력을 그대로 전달합니다. 이 경우 상태 표시줄은 녹색이 아닌 "possibly not redacted" 또는 "entered"를 표시합니다.
전체 목록: docs/statusline.md#the-redaction-hook
박스에 포함된 기능
weir scan: 이미 가지고 있는 추적 경로(traces)를 따라 민감한 데이터가 이동하는 것을 추적합니다. 예를 들어 신뢰할 수 없는 도구 출력에서 나가는 이메일까지입니다.
weir inventory: 에이전트가 접근할 수 있는 자격 증명(credentials)을 이름만으로 나열합니다.
weir audit: 저장된 에이전트 세션과 사용자의 실제 자격 증명(credentials)을 오프라인 상태에서 확인합니다.
FAQ
실제 키가 필요한가요? 아니요. 테스트는 가짜 값만 사용합니다. 상태 표시줄의 경우, Weir는 실제 키 자체를 저장하는 것이 아니라 키화된 지문(keyed fingerprints)만 저장합니다.
gitleaks나 trufflehog와 어떻게 다른가요? 이들은 코드에서 비밀처럼 보이는 문자열을 찾습니다. Weir는 특정 값이 실제로 에이전트를 통해 빠져나갔는지 증명합니다. 둘 다 사용하세요.
어딘가로 데이터를 전송하나요? 아니요. 가짜 모델은 127.0.0.1에서만 수신하고 아무것도 전달하지 않으며, 스캐너는 네트워크 연결을 열지 않습니다. 테스트가 이 두 가지를 강제합니다.
라이선스
Apache-2.0, 전부 영구적으로. 숨기는 것 없고, 제한하는 것 없고, 집으로 전화하는 것도 없습니다.
왜 "weir"인가요?
<p align="center">
<img src="https://raw.githubusercontent.com/IdoGol24/weir/main/docs/assets/weir.jpg" alt="A weir: a low dam across a river, with water flowing evenly over its crest" width="560">
<br>
<em>Weir는 강물의 흐름을 측정하는 낮은 댐입니다. 물은 계속 움직이지만, 측정은 어쨌든 이루어집니다.</em>
<br>
<sub>Damhead Weir, Water of Leith. Photo by 501ghost, Wikimedia Commons, CC0.</sub>
</p>