ZCode 저장소 업로드 사건은 하나의 코딩 도구를 넘어서는 문제입니다. 개발자가 프로젝트에 AI 에이전트의 액세스 권한을 부여하기 전에 점점 더 답해야 하는 보안 문제를 드러내기 때문입니다. “저장소 액세스”란 현재 파일, 작업 트리, 아니면 수년간의 Git 기록을 의미할까요?
이 구분이 중요한 이유는 .git에 현재 코드베이스에서는 더 이상 보이지 않는 정보가 포함될 수 있기 때문입니다. 여기에는 삭제된 비밀 정보, 이전 소스 버전, 리플로그, LFS 자산 및 로컬 브랜치 기록이 포함될 수 있습니다. ZCode는 영향을 받은 업로드 동작이 수정되었다고 밝혔지만, 이 사건은 중요한 교훈을 남겼습니다: AI 코딩 에이전트에는 단순히 “저장소에 액세스”할 권한만이 아니라 명시적인 데이터 경계가 필요합니다.
ZCode에서 실제로 무슨 일이 있었을까?
2026년 9월 18일, 개발자 ferstar는 애플리케이션의 로컬 데이터 디렉터리에서 예상보다 큰 파일을 발견한 후 ZCode 3.12.3에 대한 리버스 엔지니어링 조사 결과를 공개했습니다.
원 조사에 따르면, 클라이언트는 소스 파일뿐만 아니라 .git, Git LFS 객체, 리플로그 및 저장소 메타데이터도 포함할 수 있는 암호화된 워크스페이스 스냅샷을 생성했습니다. 또한 클라이언트에는 업로드 자격 증명을 확보하고 암호화된 아카이브를 Alibaba Cloud OSS로 전송하는 파이프라인도 포함되어 있었습니다.
ZCode는 이후 코드베이스 인덱싱 및 Repo Wiki와 관련된 저장소 데이터 업로드를 인정하고, 사과했으며, 해당 동작이 수정되었다고 밝혔습니다. 또한 오픈 소스 검토와 제3자 검토 계획을 발표했습니다. 당시 보도에서는 ZCode 대응의 주요 내용을 재현했습니다.
| 주장 | 증거 |
|---|---|
| 이전 버전의 ZCode는 광범위한 저장소 스냅샷을 생성했음 | 리버스 엔지니어링 및 로컬 스냅샷 증거로 뒷받침됨 |
| 업로드 파이프라인이 존재했음 | 리버스 엔지니어링한 클라이언트 동작으로 뒷받침됨 |
| 소규모 저장소가 서비스에 성공적으로 도달함 | 연구자의 후속 테스트로 확인됨 |
| 313MB 규모의 상용 저장소가 성공적으로 업로드되었습니다 | 아니요 - 해당 업로드는 실패했습니다 |
| 현재 ZCode도 여전히 동일한 파이프라인을 사용합니다 | 증거 없음; 연구자는 이전 경로가 삭제되었다고 보고함 |
이는 먼저 해소해야 할 중요한 정보의 공백입니다: 사건은 실제로 발생했지만, 일부 바이럴 요약은 성공적으로 전송된 내용을 과장했습니다.
313MB 규모의 비공개 저장소는 실제로 업로드되었을까?
아니요.
상용 프로젝트 스냅샷에는 약 42,000개의 파일이 포함되어 있었으며, 약 313MB의 암호화 아카이브가 생성되었습니다. 연구자가 9월 19일에 게시한 업데이트에 따르면, 이 아카이브는 로컬에 남아 있었습니다 대기 중 업로드 한도를 초과해 564번 시도가 실패한 후의 상태입니다. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))
별도의 더 작은 공개 저장소 하나는 실제로 서비스에 도달했습니다. 이 저장소에는 538개의 파일이 포함되어 있었고 훨씬 더 작은 암호화 페이로드가 생성되었습니다.
| 저장소 | 관찰된 결과 |
|---|---|
| 313MB 상용 저장소 | 로컬에서 패키징되고 반복적으로 업로드가 시도되었으나 업로드 실패 |
| 소규모 공개 저장소 | 원격 서비스에 성공적으로 수락됨 |
따라서 올바른 결론은 “모든 ZCode 저장소가 업로드되었다”가 아닙니다. 구 클라이언트에 실제 저장소 업로드 메커니즘이 포함되어 있었고, 실제 성공 여부는 스냅샷에 따라 달라졌다는 것입니다.
이 사건에서 `.git` 디렉터리가 가장 중요한 이유
연구자가 확보한 대용량 스냅샷에서 페이로드의 대부분은 현재 소스 코드가 아니었습니다.
| 스냅샷 콘텐츠 | 대략적인 비중 |
|---|---|
.git/lfs/ |
56.8% |
.git/objects/ |
29.6% |
.git/logs/ |
0.2% |
| 현재 소스 코드 및 문서 | 13.4% |
즉, 스냅샷의 약 86.6%가 .git에서 비롯되었습니다. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))
이로 인해 보안에 대한 해석이 완전히 달라집니다.
현재 소스 트리를 읽는 AI 에이전트는 개발자가 현재 의도적으로 유지하는 내용을 볼 수 있습니다. Git 기록에 액세스하면 개발자가 이미 제거했다고 생각했던 내용이 드러날 수 있습니다.
가능한 과거 노출 항목:
- 삭제된 소스 파일
- 오래된 API 키 또는 토큰
- 이전 내부 엔드포인트
- 중단된 기능
- 과거 구성
- 로컬 브랜치 활동
- reflog에만 존재하는 상태
- 대용량 과거 LFS 에셋
Git reflog 문서에서는 reflog가 로컬 참조의 이전 값을 기록한다고 설명합니다. 해당 기록은 관련 기록이 원격 저장소에 푸시된 적이 없는 경우에도 로컬에 존재할 수 있습니다.
이는 다음과 같은 유용한 보안 규칙을 제시합니다.
“내 프로젝트 읽기”와 “내 Git 기록 읽기”는 별도의 권한이어야 합니다.
코드에서 삭제한 시크릿이 여전히 존재할 수 있는 이유
최신 파일에서 자격 증명을 삭제해도 Git에서 해당 자격 증명이 반드시 삭제되는 것은 아닙니다.
개발자가 실수로 API 키를 커밋한 후 다음 커밋에서 제거하면 현재 파일이 완전히 깨끗해진 것을 확인할 수 있습니다. 하지만 이전 블롭은 저장소 기록을 통해 여전히 접근 가능한 상태로 남아 있을 수 있습니다.
GitHub의 민감한 데이터 제거 지침에서는 기록을 다시 작성하기 전에 노출된 자격 증명을 폐기하거나 교체할 것을 명시적으로 권장합니다.
순서가 중요합니다:
- 자격 증명을 무효화합니다.
- 필요한 경우 민감한 기록을 제거합니다.
- 시크릿이 다시 커밋되지 않도록 방지합니다.
AI 코딩 에이전트의 경우, 이는 기록을 인식하는 기능이 일반 편집기 화면에서는 더 이상 노출되지 않는 데이터에 액세스할 수 있음을 의미합니다.
이는 읽기 전용 에이전트가 자동으로 위험이 낮은 것은 아닌 이유도 설명합니다. 파일 시스템 범위가 지나치게 넓거나 검색된 콘텐츠가 원격 모델로 전송된다면, 읽기 전용 액세스만으로도 중요한 정보가 유출될 수 있습니다.
모델 컨텍스트, 텔레메트리, 학습 및 저장소 업로드는 서로 다릅니다
또 다른 중요한 교훈은 하나의 “개인정보 보호” 토글만으로는 AI 코딩 도구가 가질 수 있는 모든 유형의 데이터 흐름을 나타낼 수 없다는 것입니다.
| 데이터 흐름 | 일반적인 목적 |
|---|---|
| 추론 컨텍스트 | 현재 작업에 답하는 데 필요한 코드 전송 |
| 텔레메트리 | 충돌, 안정성 및 사용량 측정 |
| 모델 학습 데이터 | 향후 모델 또는 제품 동작 개선 |
| 저장소 인덱스 | 프로젝트를 더 효율적으로 검색하고 이해 |
| 클라우드 스냅샷 | 더 광범위한 워크스페이스 상태 보존 |
| 동기화 / 백업 | 세션 또는 기기 간 데이터 복원 |
영향을 받은 ZCode 버전이 중요한 이유는, 연구자가 최적화/학습 옵션을 비활성화해도 별도의 스냅샷 파이프라인은 비활성화되지 않았다고 보고했기 때문입니다. 또한 해당 버전에서는 Repo Snapshot Indexing 토글을 꺼도 패키징 및 업로드 시도를 막지 못했다고 보고서는 주장했습니다. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))
이로부터 ZCode를 훨씬 넘어 적용되는 원칙을 도출할 수 있습니다.
“내 데이터로 학습하지 마세요”는 “내 데이터를 전송하지 마세요”라는 뜻이 아닙니다.
클라우드 모델에도 추론 컨텍스트가 필요합니다. 텔레메트리가 다른 엔드포인트를 통해 전송될 수 있습니다. 동기화 과정에서 또 다른 사본이 보존될 수 있습니다. 저장소 인덱싱에는 자체 데이터 경로가 있을 수 있습니다.
ZCode와 마찬가지로 로컬 AI 에이전트가 클라우드 도구를 사용하는 경우에도, 개인정보 보호는 주 에이전트 프로세스가 어디에서 실행되는지가 아니라 경계를 넘어가는 정확한 데이터에 따라 달라집니다.
암호화만으로는 가장 중요한 개인정보 보호 질문에 답할 수 없습니다
영향을 받은 ZCode 스냅샷은 업로드 전에 암호화되었습니다.
리버스 엔지니어링 보고서에 따르면 아카이브에는 AES-256-CTR 암호화가, 대칭 키 래핑에는 RSA-OAEP-SHA256이 사용되었습니다. RSA 공개 키는 서비스에서 제공했지만, 이에 대응하는 개인 키는 로컬에 저장되지 않았습니다. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))
이는 사용자 제어 종단 간 암호화와는 다른 방식으로 데이터를 보호합니다.
| 보호 | 의미 |
|---|---|
| TLS / 전송 암호화 | 네트워크를 통과하는 동안 데이터를 보호합니다 |
| 클라우드 저장 데이터 암호화 | 일부 인프라 위협으로부터 저장된 바이트를 보호합니다 |
| 제공업체 제어 키 | 서비스가 복호화할 수 있는 기술적 능력을 보유할 수 있습니다 |
| 사용자 제어 종단 간 키 | 서비스에는 필요한 복호화 키가 없습니다 |
따라서 “저장소가 암호화되었다”는 말만으로는 불충분합니다.
더 중요한 질문은 다음과 같습니다.
누가 이를 복호화할 수 있나요?
이 동일한 원칙은 프라이빗 RAG, 클라우드 백업, AI 메모리, 그리고 데이터가 암호화되어 있다는 이유로 보호된다고 주장하는 모든 시스템에도 적용됩니다.
코딩 에이전트에 실제로 필요한 저장소 액세스 범위는 어느 정도인가?
코딩 에이전트는 기존의 자동 완성 기능보다 더 많은 컨텍스트를 필요로 하는 것이 정당합니다. 저장소 전체를 대상으로 하는 리팩터링에는 많은 파일이 필요할 수 있습니다. 디버깅 에이전트에는 테스트, 의존성 메타데이터, Git 상태 및 빌드 출력이 필요할 수 있습니다.
하지만 “에이전트에 광범위한 컨텍스트가 필요할 수 있다”는 말이 “모든 기능이 저장소의 모든 바이트를 받아야 한다”는 뜻은 아닙니다.
| 데이터 범위 | 합리적인 기본값 |
|---|---|
| 현재 파일 | 관련 작업에 허용 |
| 참조된 소스 파일 | 허용 |
| 전체 소스 트리 | 작업에 따라 다름 |
.gitignore-제외된 파일 |
제외 |
.env / 자격 증명 |
차단 |
.git 객체 |
명시적으로 필요한 경우를 제외하고 제외 |
| Reflog | 기본적으로 제외 |
| Git LFS 캐시 | 필요한 경우를 제외하고 제외 |
| SSH / 클라우드 자격 증명 | 차단 |
| 전체 원격 스냅샷 | 명시적 동의 |
이는 도구 실행 신뢰 경계에서 사용한 동일한 원칙의 데이터 액세스 버전입니다. 모델이 무언가를 요청할 수 있다고 해서 주변의 모든 항목에 액세스하거나 이를 내보낼 권한까지 자동으로 부여해서는 안 됩니다.
코딩 에이전트에는 서로 독립적인 두 가지 경계가 필요합니다.
- 행동 경계: 에이전트가 무엇을 변경하거나 실행할 수 있는가?
- 데이터 경계: 에이전트가 무엇을 읽거나 전송할 수 있는가?
쓰기 권한이 없는 에이전트라도 읽기 및 네트워크 권한이 제한되지 않으면 심각한 개인정보 노출을 일으킬 수 있습니다.
사건 이후 ZCode는 무엇을 변경했는가?
이 사건을 현재 ZCode 버전에도 동일한 동작이 존재하는 것으로 묘사해서는 안 됩니다.
ZCode 3.14.0을 후속 검사한 결과, 연구자는 이전 업로드 사이드카가 제거되었고 이전 자격 증명 엔드포인트가 404를 반환했다고 보고했습니다. 검사한 경로에는 로컬 체크포인트 기능은 남아 있었지만, 이전의 원격 업로드 메커니즘은 없었습니다. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))
현재 Repo Wiki 문서에서도 훨씬 더 좁은 데이터 경계를 설명합니다.
문서에는 Wiki 컨텍스트에서 다음 항목을 제외한다고 나와 있습니다.
.git- 의존성 디렉터리
- 빌드 출력
- 캐시
- 로컬 런타임 상태
- 지원됨
.gitignore제외 항목 - 민감한 설정 파일로 의심되는 파일
- 심볼릭 링크 대상
Repo Wiki 출력은 저장소에 다시 기록되는 콘텐츠가 아니라 로컬 애플리케이션 데이터로 문서화되어 있습니다.
이는 버전 3.12.3에서 보고된 스냅샷 동작과 본질적으로 다릅니다.
오픈 소스만으로 코딩 에이전트를 비공개로 유지할 수 있는가?
아니요.
오픈 소스는 클라이언트의 감사를 쉽게 만들 수 있지만, 오픈 소스 애플리케이션도 여전히 소스 코드를 클라우드 모델로 전송하거나, 텔레메트리를 업로드하거나, 상태를 동기화하거나, 제공업체가 관리하는 스토리지에 의존할 수 있습니다.
더 유용한 체크리스트는 다음과 같습니다.
| 질문 | 보안 속성 |
|---|---|
| 에이전트가 무엇을 읽을 수 있는가 | 로컬 데이터 범위 |
| 무엇이 컴퓨터 밖으로 나갈 수 있는가 | 외부 전송 경계 |
| 왜 전송되나요? | 목적 제한 |
| 얼마나 오래 보관되나요? | 지속성 |
| 암호화 키를 누가 제어하나요? | 복호화 권한 |
| 동작을 비활성화할 수 있나요? | 사용자 제어 |
| 외부인이 이를 검증할 수 있나요? | 감사 가능성 |
이 때문에 프라이빗 AI 아키텍처는 소프트웨어 라이선스가 오픈 소스인지보다 데이터 흐름에 의해 더 많이 정의됩니다.
개발자는 새로운 AI 코딩 에이전트를 어떻게 감사해야 할까요?
개발자가 모든 앱을 리버스 엔지니어링할 필요는 없지만, 새로운 에이전트에 민감한 상업용 저장소를 첫 번째 테스트 환경으로 제공해서는 안 됩니다.
- 데이터 처리 문서를 읽으세요. 추론, 텔레메트리, 학습, 인덱싱, 동기화 및 백업을 구분하세요.
-
제외 규칙을 확인하세요. 특히
.git,.env, 무시된 파일, 종속성, 자격 증명 및 심볼릭 링크를 확인하세요. - 폐기 가능한 저장소부터 시작하세요. 먼저 민감하지 않은 코드를 사용하세요.
- 로컬 앱 저장소를 점검하세요. 예기치 않게 큰 캐시나 스냅샷은 숨겨진 데이터 범위를 드러낼 수 있습니다.
- 외부로 나가는 트래픽을 관찰하세요. 방화벽, DNS, 프록시 또는 라우터 로그로 원격 서비스를 식별할 수 있습니다.
- 무해한 카나리아 파일을 사용하세요. 관련 없는 파일이 모델 또는 업로드 컨텍스트에 들어가는지 테스트하세요.
- 가장 제한적인 권한부터 부여하세요. 특정 작업에 필요할 때만 권한을 확대하세요.
이 지점에서도 최소 권한 에이전트 설계가 도움이 됩니다. 단, “읽기 전용”을 무제한 저장소 접근 권한이 아니라 제한된 경로 및 통제된 외부 전송 데이터와 결합해야 합니다.
로컬 우선 코딩 에이전트가 다르게 해야 할 일
로컬 우선이라고 해서 모든 작업을 오프라인으로 실행해야 한다는 뜻은 아닙니다.
이는 기본적으로 로컬 데이터가 로컬 신뢰 경계 안에 머물고, 외부 전송은 우발적이 아니라 의도적으로 이루어진다는 의미입니다.
| 로컬 우선 원칙 | 권장 동작 |
|---|---|
| 저장소 인덱싱 | 가능한 경우 심볼, 임베딩 및 메타데이터를 로컬에 유지 |
| 원격 모델 컨텍스트 | 작업과 관련된 코드만 전송 |
| Git 기록 | 작업에 기록이 명시적으로 필요한 경우가 아니라면 제외 |
| 비밀 정보 | 컨텍스트 구성 전에 필터링 |
| 원격 업로드 | 범위를 명시하고 명시적인 동의 요청 |
| 학습 동의 | 추론 권한과 분리 |
| 민감한 저장소 | 완전한 로컬 모델 및 인덱싱 경로 제공 |
| 네트워크 의존성 | 오프라인에서 작동하지 않는 항목을 문서화하세요 |
이 원칙은 코딩보다 더 포괄적입니다. 진정한 로컬 AI 워크플로는 중요한 데이터 경로를 처음부터 끝까지 로컬로 유지해야 합니다. 임베딩, 인덱싱, 인증 또는 파일 처리가 원격 서비스에 보이지 않게 의존한다면 모델을 로컬에 설치하는 것만으로는 충분하지 않습니다.
하이브리드 시스템에서는 비공개 파일을 로컬 서비스 뒤에 두고, 승인된 원격 도구에 필요한 최소한의 컨텍스트만 제공하는 방식이 더 강력합니다. 이는 전체 로컬 파일 시스템을 노출하지 않고 클라우드 서비스를 사용하는 에이전트를 설계할 때 사용하는 것과 동일한 접근 방식입니다.
더 큰 교훈: 저장소 액세스는 보안 권한입니다
ZCode에서 얻을 수 있는 지속적인 교훈은 “클라우드 코딩 에이전트를 절대 사용하지 말라”가 아닙니다. 저장소 액세스가 그 자체로 보안 권한이 되었다는 점입니다.
최신 코딩 에이전트는 다음 기능을 결합할 수 있습니다.
- 전체 프로젝트 읽기
- Git 인식
- 터미널 실행
- 브라우저 액세스
- 원격 모델
- 백그라운드 작업
- 장기 메모리
- 자율 파일 편집
이는 개발자가 에이전트가 실행할 수 있는 명령만 검토해서는 안 된다는 뜻입니다.
또한 다음과 같은 질문을 해야 합니다.
- 어떤 파일을 관찰할 수 있나요?
- 얼마나 과거의 기록까지 확인할 수 있나요?
- 그 데이터 중 어떤 것이 기기 밖으로 나가나요?
- 어떤 서비스가 이를 수신하나요?
- 얼마나 오래 보관되나요?
- 누가 이를 복호화할 수 있나요?
AI 코딩 에이전트에서 개인정보 보호는 더 이상 모델이 코드로 학습하는지 여부만의 문제가 아닙니다. 에이전트의 데이터 경계가 사용자가 실제로 요청한 작업과 일치하는지가 중요합니다.
ZCode 저장소 업로드 사건에 관한 자주 묻는 질문
ZCode가 제보자의 313MB 비공개 저장소 전체를 업로드했나요?
아니요. 제보자는 대규모 상용 프로젝트 스냅샷이 패키징되어 업로드 대기열에 반복적으로 추가되었지만, 용량 때문에 업로드에 실패했다고 보고했습니다. 별도의 소규모 공개 저장소는 서비스에서 성공적으로 수락되었습니다.
`.git`에 현재 코드에 더 이상 없는 비밀 정보가 포함될 수 있나요?
예. Git 객체와 과거 커밋에는 작업 트리에서 민감한 콘텐츠를 삭제한 후에도 파일의 이전 버전이 남아 있을 수 있습니다. 리플로그에는 원격으로 푸시되지 않았을 수도 있는 로컬 참조 기록이 포함될 수도 있습니다.
AI 학습을 비활성화하면 코딩 에이전트가 코드 업로드를 중단하나요?
반드시 그렇지는 않습니다. 학습, 추론, 저장소 인덱싱, 텔레메트리, 클라우드 동기화 및 백업은 서로 별개의 데이터 흐름입니다. 모델 학습 동의를 비활성화해도 다른 클라우드 기능에 필요한 데이터 전송이 자동으로 비활성화되지는 않습니다.
ZCode는 저장소 스냅샷 문제를 해결했나요?
ZCode는 이 문제가 해결되었다고 밝혔습니다. 최초 제보자는 이전 원격 업로드 경로가 버전 3.14.0에 없다고 보고했으며, 현재 Repo Wiki 문서에서는 명시적으로 제외한다고 설명합니다 .git, 종속성, 빌드 결과물, 캐시 및 여러 민감한 파일 범주를 Wiki 모델 컨텍스트에서 제외합니다.
오픈 소스 AI 코딩 에이전트는 자동으로 비공개인가요?
아니요. 오픈 소스는 감사 가능성을 높이지만, 개인정보 보호는 여전히 도구가 어떤 파일을 읽는지, 어떤 데이터가 기기 밖으로 나가는지, 어떤 클라우드 서비스가 이를 수신하는지, 얼마나 오래 보관되는지, 암호화 키를 누가 관리하는지에 따라 달라집니다.
기술 및 AI 허브
더 읽어보기

다국어 임베딩 지원은 2026년에 왜 개인용 홈 검색 기능을 개선할까요?
공유 공간이 언어 간 검색을 어떻게 가능하게 하는지, 학습 균형이 왜 중요한지, 그리고 정확한 용어와 저자원 언어가 여전히 어디에서 실패하는지 알아보세요.

2026년에 홈 AI에서 벡터 데이터베이스 압축이 더욱 중요해지는 이유는 무엇일까요?
양자화가 벡터를 어떻게 축소하는지, 메모리 지역성이 검색 성능을 향상시킬 수 있는 이유, 그리고 압축으로 인해 재현율이 낮아지거나 재구축 복잡성이 증가하는 지점을 알아보세요.

2026년 홈 AI 복구는 왜 모델과 인덱스를 함께 조정하는 체크포인트 방식으로 전환되고 있을까요?
백업으로 인해 AI 상태가 여러 버전으로 섞이는 이유, 조정된 체크포인트가 일관성을 복원하는 방법, 그리고 재구축이 더 나은 복구 경로가 되는 경우를 알아보세요.

