---
title: "xAI Grok Build CLI가 실제로 xAI에 보내는 데이터 분석"
published: 2026-07-12T01:09:50.000Z
canonical: https://jeff.news/article/4970
---
# xAI Grok Build CLI가 실제로 xAI에 보내는 데이터 분석

한 연구자가 xAI의 Grok Build CLI 0.2.93을 프록시로 분석해, 읽은 파일 내용과 저장소 스냅샷이 xAI 쪽으로 전송·저장되는 정황을 재현 가능하게 정리했다. 특히 .env 형태의 가짜 비밀값이 비가림 처리 없이 전송됐고, 읽지 말라고 한 파일까지 git bundle 형태의 전체 저장소 업로드에서 복원됐다는 점이 핵심이다.

## 결론부터 말하면, 이 분석은 “Grok가 학습에 썼다”가 아니라 “무엇이 전송·저장됐는가”를 증명하려는 글임

- 대상은 xAI 공식 Grok Build 코딩 CLI 0.2.93임
  - macOS Apple Silicon 환경에서 consumer login으로 테스트함
  - 바이너리 SHA-256, 버전, strings 출력, 캡처 로그, 재현 명령을 같이 제시함
  - 실제 비밀키가 아니라 `CANARY7F3A9` 같은 가짜 canary secret을 넣은 테스트 저장소를 사용함

- 핵심 주장은 세 가지임
  - Grok가 읽은 파일 내용이 xAI로 전송되고, `.env` 안의 가짜 비밀값도 비가림 처리 없이 포함됨
  - 별도로 저장소 전체가 업로드되며, 읽지 말라고 한 파일과 git 히스토리까지 복원 가능한 git bundle이 전송됨
  - 업로드 목적지는 `grok-code-session-traces`라는 구글 클라우드 스토리지(GCS) 버킷으로 보인다는 증거를 제시함

> [!WARNING]
> 이 글이 맞다면 “코딩 에이전트니까 필요한 파일만 보내겠지”라고 생각하면 위험함. 테스트에서는 모델이 읽은 파일뿐 아니라 저장소 스냅샷 채널로 tracked file과 git 히스토리까지 나간 정황이 제시됨.

## 첫 번째 채널: 모델 요청에 읽은 파일 내용이 그대로 들어감

- Grok가 파일을 읽으면 그 내용이 `/v1/responses` 요청 본문에 들어간 것으로 캡처됨
  - 48,070바이트짜리 POST 요청 body에서 `.env` 내용이 그대로 발견됨
  - 예시 canary 값인 `API_KEY=CANARY7F3A9-SECRET-should-not-leave`와 `DB_PASSWORD=CANARY7F3A9-DBPASS`가 복원됨
  - 요청 body 안에는 `model":"grok-4.5"`와 messages 구조도 들어 있어 모델 턴 요청으로 식별됨

- 같은 내용이 session_state 아카이브에도 들어간 것으로 제시됨
  - 테스트 중 `~/.grok/upload_queue/*`를 race-copy해서 압축을 풀었고, 그 안에서도 canary secret이 발견됨
  - 이 아카이브는 `/v1/storage`로 업로드되는 경로에 놓인 것으로 설명됨

- 다만 이 부분에는 범위 제한도 명확히 적혀 있음
  - 연구자는 “읽지 않은 파일이 `/v1/responses`에 들어갔다”는 주장은 하지 않음
  - 읽지 말라고 한 파일은 모델 턴 채널에서는 발견되지 않았다고 밝힘
  - 즉 모델 요청 채널은 “에이전트가 읽은 파일” 중심이고, 전체 저장소 업로드는 별도 채널이라는 구분이 중요함

## 두 번째 채널: 저장소 전체가 별도로 업로드됨

- 더 큰 이슈는 `/v1/storage` 쪽 저장소 스냅샷 업로드임
  - 12GB짜리 랜덤 파일 저장소 테스트에서 `/v1/storage` 요청만 총 5,476,228,005바이트, 약 5.10GiB가 캡처됨
  - 약 75MB 크기 chunk 73개가 모두 HTTP 200을 받았고, 캡처는 중간에 중단됨
  - 저장소 요청 실패는 0건으로 보고됨

- 모델 턴 채널과 저장소 업로드 채널의 크기 차이가 결정적 근거로 쓰임
  - 같은 12GB 세션에서 `/v1/responses` 전체 요청량은 196,705바이트, 약 192KB였음
  - `/v1/storage`는 5.10GiB였으니 약 27,800배 차이임
  - 모델이 파일을 대량으로 읽은 게 아니라, 별도 저장소 스냅샷이 나갔다고 보는 이유임

- “읽지 말라”고 한 파일이 실제 업로드 bundle에서 복원됐다는 점이 가장 세게 박힘
  - SuperGrok 계정으로 quota를 풀고, `Reply with exactly: OK. Do not read or open any files.`라는 프롬프트를 사용함
  - `src/_probe/never_read_canary.txt`에 고유 문자열 `CANARY-XR47P2-NEVERREAD-UNIQUE`를 심어둠
  - 캡처된 `uploaded_repo.bundle`을 `git clone`했더니 해당 파일과 marker가 그대로 복원됨
  - bundle에는 전체 git 히스토리도 포함돼 있었다고 함

- 동일한 패턴을 두 번째 저장소에서도 재현했다고 밝힘
  - 별도 Cloudflare Worker 저장소에서도 git bundle 업로드가 캡처됨
  - clone 결과 `CANARY-AUTH-4T8K2-NEVERREAD` marker가 복원됨
  - 즉 단일 저장소에서 우연히 나온 결과가 아니라는 쪽으로 증거를 보강함

## 목적지는 GCS의 grok-code-session-traces로 보임

- 바이너리 문자열에서 관련 단서가 나옴
  - `crates/codegen/xai-data-collector/src/gcs.rs`
  - `crates/codegen/xai-grok-shell/src/upload/{gcs,turn,trace,manifest}.rs`
  - `grok-code-session-traces`
  - `storage.googleapis.com`
  - `Uploading bytes to GCS via proxy`

- staged metadata에도 버킷명이 그대로 등장함
  - 파일별 `fileId`가 `gs://grok-code-session-traces/repo_changes_dedup/v2/.../sha256_...` 형태였다고 함
  - 연구자는 AWS S3가 아니라 GCS 쪽 목적지라고 정리함

- 서드파티 텔레메트리도 별도로 관측됨
  - `api.mixpanel.com/track`, `/engage` 요청이 200 응답을 받음
  - `grok.com/_data/v1/events` 요청도 언급됨

## “Improve the model”을 꺼도 업로드는 계속됐다는 대목이 꽤 중요함

- xAI의 소비자 정책은 모델 개선을 위한 데이터 사용과 opt-out을 설명함
  - 연구자도 이 부분은 인정함
  - 다만 정책상 학습 여부와 CLI의 저장소 업로드 동작은 별개라고 선을 그음

- 테스트에서는 모델 개선 설정을 꺼도 저장소 업로드가 중단되지 않았다고 함
  - `/v1/settings` 응답에서 `trace_upload_enabled: true`, `upload_enabled: true`, `session_registry_enabled: true`가 남아 있었다고 밝힘
  - `max_upload_file_bytes`는 1,073,741,824바이트, 즉 파일당 1GiB로 보고됨
  - 연구자 해석은 “opt-out은 학습 사용에 대한 것이지, 코드 업로드 자체를 멈추는 설정은 아니었다”는 쪽임

> [!IMPORTANT]
> 기업 보안 관점에서는 학습에 썼는지보다 “내 저장소가 어디까지 외부 저장소에 남는가”가 먼저임. 특히 git 히스토리에는 지운 줄 알았던 비밀값이나 내부 URL이 남아 있을 수 있음.

## 연구자가 스스로 못 박은 한계도 있음

- xAI가 이 데이터를 학습에 사용했다는 증거는 제시하지 않음
  - 전송과 저장은 관찰했지만, 학습 사용 여부는 정책과 내부 처리의 문제라고 분리함

- 일부 캡처는 관찰했지만 보존하지 못했다고 밝힘
  - 3GB 테스트에서 `storage.googleapis.com/grok-code-session-traces` 직접 PUT 라인을 봤지만 로그는 보존하지 못함
  - 64MB, 600MB, 3GB sweep 일부도 live 관찰만 있고 저장된 로그는 없다고 함
  - 보존된 핵심 로그는 12GB 테스트의 `/v1/storage` 200 응답들과 git bundle 증거임

- 문서화 여부 주장도 제한적으로 표현함
  - xAI 전체 문서를 다 뒤진 건 아니고, CLI 설치 스크립트와 quickstart 자료에서 이 메커니즘을 찾지 못했다는 주장임
  - 그래서 방어 가능한 표현은 “CLI 자체 설정 자료에 명확히 드러나지 않았다”에 가까움

## 개발팀이 바로 챙겨야 할 포인트

- 클라우드 코딩 에이전트를 회사 저장소에서 쓸 때는 “모델에게 보낸 프롬프트”만 보면 안 됨
  - 별도 trace, session_state, repo_state, upload queue 같은 채널이 있을 수 있음
  - 읽지 말라고 한 파일도 저장소 스냅샷에 들어갈 수 있는지 확인해야 함

- `.env`나 secrets 파일이 tracked 상태라면 특히 위험함
  - 이 테스트의 `.env`는 git-tracked였고, gitignored 파일까지 같은지 별도 검증은 없었음
  - 그래도 tracked secret이 그대로 전송된 것만으로도 충분히 큰 경고임

- 도구 도입 전에 확인할 질문이 꽤 명확해짐
  - 저장소 전체나 git 히스토리를 업로드하는가
  - 업로드된 데이터가 어느 리전에 얼마나 오래 저장되는가
  - 모델 개선 opt-out과 telemetry·trace 업로드 opt-out이 분리돼 있는가
  - 조직 관리자 설정으로 업로드 범위를 제한할 수 있는가

---

## 기술 맥락

- 이 분석의 핵심은 코딩 에이전트가 서버로 코드를 보내는 것 자체가 아니에요. 클라우드 기반 에이전트라면 모델 추론을 위해 일부 컨텍스트를 보내야 하거든요. 문제는 그 범위가 “읽은 파일”을 넘어 “저장소 전체와 히스토리”까지 확장되는지예요.

- git bundle 증거가 강한 이유는 파일 내용과 git 히스토리를 실제로 복원할 수 있기 때문이에요. 단순히 파일명이 manifest에 있었다거나 해시가 보였다는 수준이면 반박 여지가 남지만, clone해서 never-read marker를 읽었다면 업로드된 내용의 범위가 훨씬 명확해져요.

- `/v1/responses`와 `/v1/storage`를 분리해서 본 것도 중요해요. 모델 요청 채널은 에이전트가 읽은 파일 중심이고, 저장소 채널은 별도로 대량 데이터를 보낼 수 있어요. 그래서 프롬프트에 “파일 열지 마”라고 쓰는 것만으로 저장소 업로드를 막았다고 볼 수 없어요.

- 조직에서 이런 도구를 평가할 때는 개인정보 처리방침만 읽고 끝내면 부족해요. 실제 CLI가 어떤 auxiliary upload를 하는지, trace와 session_state가 어디에 저장되는지, opt-out이 학습에만 적용되는지 업로드 자체에도 적용되는지까지 봐야 해요.

## 핵심 포인트

- Grok Build CLI는 읽은 파일 내용을 /v1/responses 요청과 session_state 업로드에 포함해 보냄
- git bundle 형태의 전체 저장소 업로드에서 읽지 말라고 한 파일과 git 히스토리까지 복원됨
- 12GB 저장소 테스트에서 /v1/storage로 최소 5.10GiB가 200 응답과 함께 업로드됨
- Improve the model 설정을 꺼도 trace_upload_enabled와 upload_enabled가 true로 남았고 저장소 업로드는 계속됨

## 인사이트

클라우드 코딩 에이전트가 코드를 서버로 보내는 건 피할 수 없는 면이 있지만, 이 글의 포인트는 범위와 투명성임. 특히 저장소 전체와 히스토리까지 업로드되는 동작이 기본값이고, 모델 개선 opt-out과 별개로 계속된다면 기업 환경에서는 바로 보안 검토 대상임.
