20여 개 코딩 에이전트의 기록을 한 로그로: Asymptote-Labs/agent-beacon의 세션 텔레메트리·CEL 위협 탐지·핸드오프·승인형 메모리 심층 해부와 박스 실측
Claude Code로 오전에 고친 버그를 오후에 Codex가 처음부터 다시 헤매는 일은 흔하다. 세션 기록은 하네스마다 다른 폴더, 다른 형식(JSONL, SQLite, OTLP)으로 흩어져 있고, 누가 어떤 명령을 실행했는지 보안팀이 볼 방법도 마땅치 않다. Asymptote-Labs/agent-beacon(이하 Beacon)은 이 두 문제를 한 바이너리로 묶는다. 20여 개 코딩 에이전트의 세션을 하나의 정규화된 JSONL 런타임 로그로 모으고, 그 위에서 위협 탐지 규칙(CEL), 토큰·비용 집계, 하네스 간 세션 이어받기(handoff), MCP로 검색, 그리고 리뷰를 거친 프로젝트 메모리를 제공한다. 오늘(2026-10-22) GitHub Trending Go 일간 3위(+443)에 올랐다.
Beacon 한눈에: Claude Code·Codex·Cursor 등 23종 코딩 에이전트의 세션 기록을 하나의 정규화된 runtime.jsonl로 모은다
README의 첫 문장은 “Self-improving memory for coding agents”지만, 바이너리를 직접 돌려 보면 무게중심은 엔드포인트 텔레메트리 에이전트 쪽에 있다. 명령 체계가 beacon endpoint …로 시작하고, 출력은 Wazuh 호환 JSON이며, Splunk·Datadog·Sentinel·CrowdStrike Falcon·S3로 보내는 포워더가 기본 탑재돼 있다. 이 글은 그래서 “메모리 도구”가 아니라 “에이전트 활동을 기록·감사하는 계층”으로 보고 구조와 타협점을 따진다. 박스(리눅스 x64 VM, 8코어)에서 v1.3.45 릴리스 바이너리를 SHA-256 검증 후 받아, 격리 HOME + unshare -rn(네트워크 차단) + API 키 없음 조건으로 설치·백필·규칙 스캔·훅·handoff·MCP·규모 테스트를 직접 돌렸다. 입력은 가짜 AWS 키·GitHub 토큰·프롬프트 인젝션 문구·curl | bash·강제 푸시를 일부러 넣은 합성 Claude Code/Codex 세션이다. 수치는 2026-10-22 17:30~17:40 KST 실측이거나 GitHub API·저장소 문서에서 확인한 값이다.
한눈에 보기: 오늘 기준 스냅숏
항목
값
저장소
github.com/Asymptote-Labs/agent-beacon (생성 2026-05-12 11:49 KST) · 문서 docs.beacon.sh
라이선스
MIT (Copyright 2026 Asymptote Labs). 클라우드(beacon.sh)·엔터프라이즈 강제(enforcement) 기능은 별도
버전
v1.3.45 (2026-10-20 15:02 KST). 같은 날 1.3.43·1.3.44·1.3.45가 연달아 나올 만큼 릴리스가 잦음
Go 약 28.4만 줄(테스트 파일 571개 포함), 플러그인 7종(OpenCode·Cline·Pi·OpenClaw 등) TS/JS, 브라우저 확장, Terraform, 커스텀 OTel Collector
배포물
tar.gz / deb / rpm / macOS pkg(서명 팀 ID 기재) / Windows msi / Homebrew. 리눅스 tar.gz 하나에 바이너리 4개
지원 하네스
Claude Code, Codex CLI, Cursor, OpenCode, Cline, GitHub Copilot CLI, Factory Droid, Grok Build, Hermes, Pi, Gemini, Qwen, Kiro, Devin, Goose, OpenHands 등 share --harness 기준 23종
무엇이 들어 있나: 다섯 개의 얼굴
Beacon을 처음 보면 기능이 너무 많아 무엇이 핵심인지 헷갈린다. 최상위 명령만 24개다. 역할별로 묶으면 다섯 덩어리가 된다.
축
명령
하는 일
네트워크
수집(Collect)
endpoint install, endpoint <harness>, ci exec, cloud
하네스 설정에 OTel 환경변수·훅을 넣고, 각 하네스의 로컬 세션 저장소를 폴링·백필해 정규화 JSONL로 기록
로컬 전용 가능
탐지(Detect)
scan, rules lint/add/pull
CEL로 쓴 위협 규칙을 런타임 로그에 적용. 기본 6개 내장 + 공개 룰팩 77개
읽기 전용, 네트워크 안 씀
회계(Account)
token-usage, pricing
모델·세션·저장소·CI run 별 토큰과 추정 비용
로컬
연속성(Continue)
handoff list/export/resume, git link, share
세션 요약 브리프 생성, 다른 하네스로 이어받기, 커밋↔세션 연결(git notes), 트레이스 공유
share만 업로드
기억(Remember)
memory evaluations/candidates/skills, mcp serve
트레이스를 외부 평가기(Jev/SubQ)로 채점 → 후보 → 사람이 승인 → Agent Skill로 설치. MCP 도구 7개로 검색
평가 단계는 외부 API
핵심 관찰. “스스로 개선되는 메모리”의 실제 흐름은 로그 → 외부 LLM 평가 → 후보 → 사람 승인 → 스킬 파일이다. 자동으로 에이전트 프롬프트에 섞여 들어가는 블랙박스가 아니라, 승인 게이트가 있는 파이프라인이라는 점이 claude-mem류 ‘자동 회상’ 도구와 가장 크게 다르다. 반대로 말하면 외부 평가기 API 키가 없으면 메모리 후보는 생기지 않는다(박스 실측: 후보 0건).
구조: OTLP 수신(beacon-otelcol)·훅(beacon-hooks)·세션 저장소 폴링 세 경로가 한 로그로 합쳐지고, 그 위에서 scan·token-usage·MCP·handoff·memory가 돈다
아키텍처: 바이너리 네 개와 로그 하나
리눅스 tar.gz(88.2MB)를 풀면 실행 파일 네 개가 나온다. 크기 차이가 설계를 그대로 보여 준다.
데이터 경로는 세 갈래가 한 파일로 합쳐진다. ① OTLP 경로: Claude Code·Codex처럼 OpenTelemetry를 내보내는 하네스는 환경변수로 로컬 컬렉터를 가리키게 한다. ② 훅 경로: PreToolUse·PostToolUse·SessionStart 같은 훅에서 beacon-hooks가 직접 로그에 쓴다. ③ 폴링/백필 경로: OTel도 훅도 없는 하네스(Cursor·Cline·OpenCode SQLite 등)는 세션 저장소를 직접 읽는다. 설치 시 지난 30일치를 한 번에 백필한다. 세 경로 모두 같은 스키마(schema_version 1.0, event.action, harness.name, session.id, trace.id)로 ~/.beacon/endpoint/logs/runtime.jsonl에 append되고, 이 파일이 스캔·집계·MCP·handoff의 단일 진실 원천이 된다.
event.action
의미
session.started
세션 시작, 작업 디렉터리·브랜치·하네스 버전
prompt.submitted
사용자 프롬프트(비밀 마스킹 후)
agent.message
모델 응답 텍스트
tool.invoked / command.executed
도구 호출과 셸 명령·출력
file.modified / file.read
파일 변경·읽기(하네스가 Read 도구로 읽었을 때만 file.read)
token.usage
입력·출력·캐시 읽기/생성 토큰
telemetry.enabled
엔드포인트 자체 상태 이벤트
이 설계의 장점은 분명하다. 하네스가 늘어도 탐지 규칙·대시보드·MCP는 그대로이고, 규칙은 “Claude냐 Codex냐”가 아니라 e.event.action == "command.executed" 같은 공통 필드만 본다. 단점은 정규화가 하네스가 무엇을 알려 주느냐에 묶인다는 것이다. 아래 실측에서 보듯 같은 ‘자격 증명 파일 읽기’라도 Read 도구로 읽으면 file.read, Bash cat으로 읽으면 command.executed가 되고, 규칙 매칭 결과가 달라진다.
설치가 실제로 바꾸는 것
엔드포인트 에이전트는 사용자 환경 설정을 직접 고친다. 도입 전 가장 먼저 확인해야 할 부분이라 격리 HOME에서 --dry-run과 실제 설치(--service none --no-start) 후 생성·변경 파일을 모두 뽑았다.
export HOME=$PWD/run/home DO_NOT_TRACK=1
unshare -rn ./beacon endpoint install --harness claude,codex \
--service none --no-start --no-browser --collector ./beacon-otelcol
# Claude Code hooks installed: ~/.claude/settings.json
# Codex CLI endpoint hooks installed: ~/.codex/hooks.json
# Session backfill: 485 events from the last 30 days (Claude Code 480, Codex CLI 5).
systemd/launchd 없으면 감독 프로세스(collector.pid). 인벤토리 하트비트는 스케줄러 없으면 미설치
컨테이너·CI에서 주의
프라이버시 체크포인트. 설치는 하네스의 프롬프트·도구 상세 로깅 플래그를 켠다. 기본 목적지는 로컬 파일이지만, 나중에 endpoint connect나 SIEM 포워딩을 켜면 같은 데이터가 밖으로 나간다. Beacon Cloud에는 ‘Metadata-only’ 모드가 있어 프롬프트·응답·도구 인자·diff를 빼고 보낼 수 있다. 회사 노트북에 깔 거라면 이 모드와 포워딩 대상부터 정책으로 정해 두는 편이 맞다.
박스 실측: 가짜 GitHub 토큰·AWS 키는 런타임 로그·평가 목록·브리프 본문에서 마스킹됐지만 handoff 브리프 제목 줄에는 원문이 남았다
박스 실측 ①: 비밀 마스킹과 탐지 규칙
합성 세션 20개(Claude Code) + 1개(Codex)를 만들었다. 각 Claude 세션은 첫 프롬프트에 가짜 GitHub 토큰(ghp_…)과 AWS 키(AKIA…EXAMPLE), “ignore previous instructions” 문구를 넣고, 도구 호출 5개(cat ~/.aws/credentials, curl … | bash, .env 편집, npm test, git push --force origin main)를 수행한다. 원본 세션 파일 합계 126,108바이트가 백필 후 런타임 로그 486줄·477,359바이트(약 3.8배)가 됐다.
이벤트
건수
이벤트
건수
agent.message
120
token.usage
120
tool.invoked
101
command.executed
81
prompt.submitted
21
session.started
21
file.modified
20
telemetry.enabled
1
출력물
결과
비고
런타임 로그(JSONL)
0건 원문 노출 (ghp·AKIA 모두 [REDACTED], 접두어만 남김)
프롬프트와 cat 출력 속 키 모두 마스킹
memory evaluations run --dry-run 목록
마스킹된 제목 표시
OK
handoff export 본문
프롬프트·명령 출력 마스킹
OK
handoff exportTitle 줄
토큰·키 원문 그대로 1건
세션 저장소에서 직접 뽑은 제목이 마스킹을 거치지 않음
handoff list TITLE 열
ghp_12345… 앞부분 원문
긴 제목 잘림 덕에 일부만 보임
발견 사항. 런타임 로그 경로의 마스킹은 견고했지만, handoff 브리프는 “런타임의 원래 세션 저장소”를 읽기 때문에 제목(첫 프롬프트)이 마스킹 없이 브리프 파일(권한 0600)에 들어갔다. 브리프는 다른 에이전트에게 넘기려고 만드는 파일이라, 프롬프트에 토큰을 붙여 넣는 습관이 있다면 이 경로가 유출 지점이 될 수 있다. v1.3.45 기준 동작이며, 합성 키로만 확인했다.
탐지는 내장 기본 규칙 6개만으로 먼저 돌리고, 공개 룰팩(77개, 카테고리 10종)을 rules lint로 검증한 뒤 스토어에 넣어 다시 돌렸다. 린트는 규칙마다 들어 있는 적합성 픽스처 544개를 0 실패로 통과했다(132ms).
위 2개 + git-force-push-to-protected(high) 20 · git-remote-tampering(high) 20
331ms
--fail-on high
종료 코드 1
CI 게이트로 바로 사용 가능
–
합성 행위
결과
이유
curl … | bash
탐지
명령 문자열 정규식
프롬프트 속 “ignore previous instructions”
탐지
프롬프트 인젝션 규칙
git push --force origin main
탐지(2개 규칙 중복)
보호 브랜치 강제 푸시 + remote-tampering 정규식이 push --force도 포함 → 같은 행위가 2건
Bash cat ~/.aws/credentials
미탐
credential-file-read는 file.read 이벤트만 봄. 셸 명령으로 읽으면 command.executed라 빠짐
.env 편집
미탐
sensitive-edit 규칙들은 .envrc·CI·IaC·의존성 매니페스트 등 대상. 일반 .env는 범위 밖
정리하면 규칙 엔진 자체(CEL + 픽스처 내장 + 린트)는 잘 만들어졌지만, 탐지 범위는 이벤트 정규화의 해상도를 넘지 못한다. 자격 증명 파일 읽기처럼 중요한 행위는 Read 도구 경로와 셸 경로 양쪽 규칙을 함께 두는 게 안전하고, 중복 발견은 세션·행위 단위로 묶어 보는 후처리가 필요하다.
박스 실측 ②: 훅 지연, 토큰 집계, MCP
PreToolUse 입력(Bash)
지연 ms(5회)
훅 응답
동작
ls -la
6–8
{}
기록
curl … | bash
5–6
{}
기록(차단 없음)
cat ~/.aws/credentials
5–6
{}
기록(차단 없음)
rm -rf / --no-preserve-root
5–7
{}
기록(차단 없음)
훅 한 번에 5–8ms로 체감 비용은 거의 없다. 대신 오픈소스 판 훅은 관찰 전용이다. 위험 명령에도 빈 JSON을 돌려주고 차단하지 않는다. 실행 전 차단은 endpoint enforcement(“enterprise edition” 표기)로 분리돼 있다. 즉 무료 판은 “사후 탐지 + 감사 로그”이고, 실시간 가드레일을 원하면 하네스 자체 권한 설정이나 다른 도구와 함께 써야 한다. 훅 입력 4종 × 5회 = 20줄이 로그에 추가됐다.
token-usage (합성 20세션)
값
입력 토큰
153,000
출력 토큰
9,100
캐시 읽기
1,090,000
캐시 생성
30,000
추정 비용
$1.035 (claude-sonnet-4-5 가격표 기준, 세션당 $0.05175)
집계 시간
약 70ms(20세션) / 197ms(약 530세션)
MCP 서버(beacon mcp serve, stdio)는 search_activity, summarize_activity, get_activity_event, list_activity_filters, search_memory, get_memory, get_memory_context 7개 도구를 노출했다. 모두 읽기 계열이지만 readOnlyHint 주석은 붙어 있지 않았다. 에이전트가 “지난주에 이 테스트 어떻게 고쳤지?”를 스스로 찾게 하는 통로가 이것이다.
1,000세션에서는 “Claude Code: stopped at the backfill size limit”가 뜨고 약 530세션(12,773 이벤트)에서 백필이 멈췄다. 나머지는 beacon endpoint claude sync로 따로 읽으라고 안내한다. 로그는 약 10MB에서 runtime.jsonl.1로 회전했고, 스캔은 회전 파일까지 읽어 발견 수가 세션 수에 비례했다(약 532×4=2,128). 스캔은 이벤트 수에 대략 선형이라 CI에서 세션 로그 하나 검사하는 용도에는 충분히 빠르지만, 수개월치 개발자 PC 로그 전체를 주기적으로 훑는 용도라면 SIEM 쪽 탐지로 넘기는 게 자연스럽다.
설계 타협점
선택
얻는 것
치르는 것
단일 JSONL 로그
단순·이식성·grep 가능, 어떤 SIEM에도 붙음
인덱스 없음 → 검색·스캔이 선형, 10MB 회전
3중 수집(OTLP·훅·폴링)
하네스가 무엇을 지원하든 최대한 모음
같은 행위가 경로마다 다른 action으로 기록, 중복·누락 관리 필요
관찰 전용 훅
5–8ms, 에이전트 동작 안 깨뜨림
차단 없음. 실시간 방어는 유료/외부
CEL 규칙 + 내장 픽스처
규칙이 데이터라 바이너리 안 커짐, 린트로 회귀 방지
규칙 품질이 정규화 해상도에 묶임(셸 cat 미탐)
승인 게이트형 메모리
엉뚱한 기억이 자동 주입되지 않음, 스킬 파일로 투명
외부 평가기 API·사람 리뷰 비용, 오프라인이면 후보 0
하네스 설정 직접 수정
한 명령으로 23종 대응
프롬프트 로깅 플래그를 켬, 하네스 업데이트와 충돌 가능
로컬 우선 + 클라우드 옵션
기본은 아무것도 업로드 안 함
share·connect·포워더를 켜면 정책 관리 필요
비슷한 도구와 위치
도구
초점
범위
맞는 사용자
Beacon
세션 텔레메트리 + 탐지 + handoff + 승인형 메모리
하네스 23종, 로컬 JSONL/SIEM
보안·플랫폼팀, 다중 하네스 팀
claude-mem 계열
세션 요약을 자동 회상
주로 단일 하네스
개인 개발자 연속성
context-mode / headroom 류
컨텍스트 압축·도구 출력 샌드박스
토큰 절감
비용·문맥 최적화
하네스 내장 OTel
각 벤더 텔레메트리
벤더별 형식
단일 도구 조직
도입 체크리스트
항목
확인 내용
포워딩 정책
로컬만 / Metadata-only / 전체 중 무엇인지 먼저 결정
프롬프트 로깅
설치가 켜는 OTEL_LOG_USER_PROMPTS·log_user_prompt를 조직 정책과 대조
handoff 브리프
제목 마스킹 이슈가 고쳐지기 전까지 브리프 공유 전 수동 확인
룰팩
rules lint 통과 후 add, CI에선 scan --fail-on high
셸 경로 보강
자격 증명·.env를 셸로 읽는 경우를 잡는 command.executed 규칙 추가
백필 한도
대량 세션 환경은 설치 후 endpoint claude sync
업데이트 확인
필요 시 BEACON_UPDATE_CHECK로 비활성화, 버전 고정
# 최소 로컬 감사 구성 예
beacon endpoint install --harness claude,codex --no-backfill
beacon rules lint ./rules && beacon rules add ./rules
beacon scan --min-severity medium
beacon token-usage --top 10
beacon handoff export <session-id> --print # 공유 전 제목 줄 확인
실측하지 않은 것
항목
상태
실제 에이전트 세션
합성 JSONL만 사용. 실제 Claude Code/Codex 실행·OTLP 실시간 수신은 미검증
메모리 평가기
Jev/SubQ API 키 없음 → dry-run(21 트레이스, 추정 $0.00735)까지만
Beacon은 “에이전트가 배운 걸 기억하게 한다”는 문구보다 “여러 에이전트가 이 컴퓨터에서 무엇을 했는지 한 형식으로 남긴다”에서 진가가 나온다. 23종 하네스를 한 스키마로 묶는 정규화, 픽스처가 딸린 CEL 규칙, 5–8ms짜리 훅, 마스킹된 로컬 로그는 플랫폼·보안팀이 바로 쓸 만한 수준이다. 반면 무료 판 훅은 막지 않고 기록만 하며, 탐지 범위는 이벤트가 얼마나 잘게 정규화되느냐에 묶이고, handoff 제목처럼 마스킹 경로 밖의 출력이 아직 남아 있다. 메모리는 외부 평가기와 사람 승인이 있어야 돈다. 여러 코딩 에이전트를 섞어 쓰는 팀이라면 먼저 로컬 전용 모드로 깔아 scan과 token-usage부터 써 보고, 포워딩과 메모리는 정책이 정해진 다음 켜는 순서를 권한다.