
An independent wire-level analysis of Grok Build CLI 0.2.93 found two materially different data paths leaving a developer’s machine.
The first path looked like the expected behavior of a cloud coding agent: files that the agent opened were serialized into model requests. The second path was different. Grok Build packaged a Git repository into a bundle and sent it through a storage endpoint, including a tracked file the agent had been explicitly told not to read and the repository’s commit history.
That distinction is the center of the incident.
The evidence does not prove that xAI trained on private source code. It does not prove that employees viewed the uploaded repositories, that every account received the same configuration, or that every file on a developer’s computer was collected. It does show that, in the tested configuration, a full Git repository crossed the network independently of the files required for the model’s immediate task. The server accepted the upload with an HTTP 200 response, and the captured bundle could be cloned with standard Git tooling. (Gist)
After the findings became public, the researcher tested the same Grok Build 0.2.93 client again and reported that the server returned a new disable_codebase_upload: true flag. The previous repository-storage requests were no longer observed. That is meaningful evidence of a server-side mitigation, but it is not the same as a published security advisory, a global rollout guarantee, or confirmation that previously uploaded data was deleted. (X (formerly Twitter))
The incident matters because AI coding agents sit directly on a high-value trust boundary. They can read source code, inspect configuration, invoke shells, load repository-defined instructions, contact cloud services, and preserve session state. A small difference between “send the file needed for this question” and “upload the whole repository and history” can change the exposure from a limited model request into a source-code disclosure event.
What Happened
xAI introduced Grok Build as an early-beta terminal coding agent for professional software engineering. Its official launch material described a command-line tool available to SuperGrok and X Premium Plus subscribers, with capabilities including project planning, file changes, review, plugins, hooks, skills, MCP integrations, subagents, and Git worktrees. (SpaceXAI)
Cereblab later tested Grok Build CLI 0.2.93 on an Apple Silicon Mac using a consumer login. The researcher recorded the client version, the executable’s SHA-256 hash, the hosts contacted, request methods, URL paths, response codes, byte counts, and selected request bodies. The traffic belonged to the researcher’s own machine and account, and the repositories contained synthetic canary strings rather than real credentials. (Gist)
The analysis produced three major findings.
First, when Grok Build read a tracked secrets file, synthetic values assigned to API_KEY e DB_PASSWORD appeared verbatim in the request sent to the model endpoint. The same canary strings were also present in a staged session-state archive associated with the storage path. (Gist)
Second, the client uploaded a Git bundle through /v1/storage. The bundle contained a tracked canary file that the agent had been explicitly instructed not to open. Cloning the captured bundle recovered both that file and the Git history. The behavior was repeated with a second, unrelated repository. (Gist)
Third, a large-repository test showed that this was not merely a small metadata exchange. During a run involving approximately 12 GB of incompressible test data, the capture recorded at least 5.10 GiB of accepted storage traffic before the researcher stopped the test. Model requests during the same session totaled about 192 KB. The roughly 27,800-to-one difference showed that the large transfer could not be explained by the amount of source code placed in the model context. (Gist)
The researcher subsequently reported that the behavior changed without changing the 0.2.93 client. A server-provided setting disabled codebase upload, and later runs did not reproduce the original storage requests. (X (formerly Twitter))
As of July 13, 2026, xAI’s public changelog listed Grok Build 0.2.98, but the visible release notes did not describe the repository-upload finding, the new server flag, the scope of the mitigation, or the handling of earlier data. The public xAI status page also showed no active declared incident. Those public pages do not establish that xAI has made no statement through any other channel, but they do mean the normal changelog and service-status mechanisms did not provide a formal incident explanation at that point. (SpaceXAI)
The Timeline
| Date | Event | What it establishes |
|---|---|---|
| May 25, 2026 | xAI publicly introduces Grok Build as an early-beta terminal coding agent | Establishes the official product context and intended cloud-agent workflow |
| July 2026 | Cereblab tests Grok Build CLI 0.2.93 on macOS with a consumer account | Defines the affected test environment, not every possible deployment |
| Initial wire capture | Read file contents appear in /v1/responses and staged session data | Shows actual file contents can leave the machine when the agent reads them |
| Repository test | A never-read tracked file is recovered from a captured Git bundle accepted through /v1/storage | Proves repository content beyond the active model context was transmitted |
| Second repository test | The same result is reproduced on an unrelated codebase | Reduces the likelihood that the result was unique to one repository |
| Large-repository test | At least 5.10 GiB is accepted through storage requests before the test is stopped | Demonstrates multi-gigabyte transfer, but not completion of the full 12 GB run |
| July 13 update | The same client receives disable_codebase_upload: true, and the original storage behavior is not observed in repeat runs | Supports a server-side mitigation for the tested account |
| July 13 public status | Changelog and service status contain no detailed incident entry | Leaves remediation scope and historical-data treatment publicly unresolved |
The most important temporal detail is that the client binary did not need to change for the observed behavior to stop. That makes a version number alone an incomplete security signal. A team could run the same binary on two different days and receive materially different data-handling behavior because of server-side configuration.
Normal Cloud Inference Versus Full Repository Upload
A cloud AI coding agent cannot analyze code that never reaches its inference environment. If a developer asks an agent to explain auth.ts, debug a stack trace, or refactor a package, some relevant source code will normally be transmitted to the provider or another configured model endpoint.
That fact does not make every form of repository collection equivalent.
A model request should be bounded by the task, the agent’s file-access decisions, the user’s permissions, and the product’s disclosed context behavior. A repository backup, session snapshot, training trace, debugging archive, or remote-restore artifact has a different purpose and a different data lifecycle.
| Pergunta | Task-scoped model context | Full repository or trace upload |
|---|---|---|
| What triggers it | Agent needs content to answer or act | Product-level storage, synchronization, tracing, backup, or telemetry logic |
| Typical scope | Selected files, excerpts, diffs, command output | Potentially all tracked files and reachable Git history |
| Relation to current task | Direct | May be independent of what the model reads |
| Expected size | Usually bounded by context and task | May approach repository size |
| User expectation | Code needed for the requested operation is processed remotely | Entire project may be copied to a separate storage path |
| Retention question | Model-request and provider retention policy | Storage-object, trace, backup, and deletion policy |
| Appropriate control | File permissions, context review, model policy | Explicit repository-upload control, storage policy, retention control, and egress monitoring |
| Main security concern | Sensitive data in selected context | Source-code and history disclosure beyond task necessity |
The Grok Build CLI repository upload finding concerned the second column. The never-read canary did not appear in the model-turn channel, which is consistent with the agent not opening it for inference. It did appear in the Git bundle sent through storage. (Gist)
This matters for consent. A developer may reasonably understand that asking a cloud service to inspect a file sends that file to the service. The same developer may not expect an independent background mechanism to package every tracked file and its history, especially after asking the agent not to read anything.
The Two Data Channels
The captured behavior becomes easier to understand when the traffic is separated into two channels.
Channel A, model inference
The first channel used the model-response path:
POST cli-chat-proxy.grok.com/v1/responses
The captured request body contained conversation data, model information, and content from files the agent had opened. In the researcher’s synthetic secrets test, a tracked .env ou secrets.env file contained values similar to:
API_KEY=CANARY7F3A9-SECRET-should-not-leave
DB_PASSWORD=CANARY7F3A9-DBPASS
Those values appeared verbatim in a decrypted request body sent to /v1/responses. All of the test repository’s file markers that the agent read could be recovered from those model requests. (Gist)
A control run used a file the agent was told not to open. Its marker did not appear in Channel A. This narrows the finding: the model-request path carried files the agent read, rather than indiscriminately placing the entire repository into every inference request. (Gist)
The synthetic values were not real vendor-formatted tokens. The test therefore proves that those particular values, inside API_KEY e DB_PASSWORD fields, were transmitted without redaction. It does not prove that Grok Build has no secret-detection logic for any recognizable credential format.
Channel B, repository and session storage
The second channel used storage paths such as:
POST cli-chat-proxy.grok.com/v1/storage
The decisive artifact was a captured Git bundle. The request received HTTP 200, and the preserved request body could be cloned as a repository. The resulting clone contained a unique tracked file whose marker was not present in the model-request channel and which the agent had been instructed not to read. The clone also exposed the repository’s commit history. (Gist)
The researcher found first-party binary strings referring to an xAI data-collector component, repository-state collection, workspace collection, storage coordination, storage.googleapis.com, and a bucket named grok-code-session-traces. A staged metadata file contained object identifiers beginning with gs://grok-code-session-traces/. These artifacts support the conclusion that the storage process was an intentional software component rather than an accidental reuse of the model request. (Gist)
A simplified representation of the observed architecture looks like this:
Developer repository
|
| agent opens selected files
v
File and tool context
|
v
/v1/responses
|
v
Cloud model inference
Developer repository
|
| repository-state collection
v
Local upload queue and Git bundle
|
v
/v1/storage
|
v
Cloud storage path
The two arrows represent different security decisions. Channel A answers, “What information does the model need for this turn?” Channel B answers, “What project or session state does the product preserve elsewhere?”
Those decisions should not share an implicit consent model.

Why the Never-Read Canary Matters
A large outbound request alone would not be enough to prove a full repository upload. It might contain logs, embeddings, encrypted cache data, generated artifacts, or repeated model context. A local archive alone would also be insufficient because software may create temporary files and delete them without transmitting them.
The never-read canary closed those evidentiary gaps.
The researcher placed a unique marker in a tracked repository file and gave Grok Build a narrow instruction:
Reply with exactly: OK. Do not read or open any files.
The test then established four separate facts:
- The canary did not appear in the captured model-turn content.
- A Git bundle left the machine through
/v1/storage. - The storage request received HTTP 200.
- Cloning the captured bundle recovered the never-read marker and Git history.
That sequence rules out several weaker explanations.
It was not merely a filename list, because the file contents were recoverable. It was not merely a content hash, because the marker appeared verbatim after cloning. It was not solely a local cache, because the artifact was taken from an accepted network request. It was not ordinary task context, because the model channel did not contain the canary and the agent had been instructed not to read files. (Gist)
The second-repository reproduction matters as well. The same procedure on an unrelated codebase produced another accepted Git bundle containing that project’s own never-read marker. Repetition does not prove universality, but it makes a one-off repository corruption or test-fixture mistake less plausible. (Gist)
This is the point at which “Grok Build might be uploading metadata” became “the tested Grok Build configuration uploaded repository contents and history.”
What the 12 GB Test Proved
The large-repository experiment addressed a different objection: perhaps the Git bundle behavior applied only to small repositories, or perhaps the storage endpoint rejected large content before meaningful data left the machine.
The researcher built a repository containing approximately 12 GB of random test data. Random data was useful because it could not be compressed into a tiny archive that merely looked large before packaging.
The preserved capture recorded:
- 82 content POST requests to
/v1/storage - 73 chunks of approximately 75 MB
- 5,476,083,317 bytes in the large chunks
- 5,476,228,005 total request bytes across the storage paths
- HTTP 200 for every storage request
- 196,705 bytes across five
/v1/responsesmodel requests
The test was manually stopped while another large chunk was still being sent. It therefore proves that at least 5.10 GiB was transferred successfully and that the upload was still progressing. It does not prove that all 12 GB completed or remained stored indefinitely. (Gist)
The model path was about 192 KB. Even allowing for encoding and protocol overhead, 192 KB cannot carry more than five gigabytes of repository content. The storage transfer was therefore structurally independent from the source material placed in the model context.
The approximately 27,800-fold size difference is useful because it does not depend on interpreting internal function names. It is a physical constraint: the data observed on one channel could not have originated solely from the data observed on the other.
The report also notes that model requests began returning usage-related 402 and 429 responses while storage uploads continued to receive HTTP 200. That indicates the repository-storage activity did not require the model to complete a useful answer. (Gist)
A responsible description of the result is:
During the tested 12 GB run, Grok Build CLI 0.2.93 successfully transmitted at least 5.10 GiB through its storage path before the researcher stopped the capture.
An irresponsible description would be:
xAI stored a complete 12 GB private repository.
The second statement adds completion and retention claims that the available evidence does not establish.

Why a Git Bundle Changes the Risk
A Git bundle is not a screenshot of the current directory. Git’s official documentation describes a bundle as an archive containing references and Git objects that can be consumed by commands such as git clone, git fetche git pull. A self-contained bundle can reconstruct the history reachable from the references included in it. (Git SCM)
That makes a Git bundle valuable for backup and disconnected repository transfer. It also makes it more sensitive than the visible files in the latest checkout.
Consider a credential that was committed in January and removed in February:
January commit:
config/production.env
DB_PASSWORD=real-production-password
February commit:
delete config/production.env
rotate documentation
The current directory may look clean. A secret scanner that checks only the checked-out files may report nothing. But the January blob can remain reachable through commit history. A bundle carrying that history may preserve the deleted value.
A Git bundle can also reveal:
- Previous implementations of authentication logic
- Internal hostnames removed from current configuration
- Security bugs fixed before public release
- Customer identifiers or test fixtures deleted from the main branch
- Old deployment scripts
- Abandoned features
- Commit authors and timestamps
- Tags and branch history included in the bundle
- Secrets that were deleted but never revoked
A bundle does not automatically include every form of local Git state. Git’s documentation states that a full bundle of refs does not include the working tree, index, stash, per-repository configuration, or hooks merely because those items exist locally. Uncommitted files that were never added to a reachable Git object are outside a normal history-based bundle. (Git SCM)
| Local data type | Normally represented in a history-bearing Git bundle | Security implication |
|---|---|---|
| Current tracked files | Sim | Current source code can be reconstructed |
| Prior committed versions | Yes, when reachable from bundled refs | Deleted code and secrets may survive |
| Committed file later deleted | Yes, through earlier commits | Deletion from the latest branch is not remediation |
| Never-committed untracked file | Não | A Git bundle alone does not normally capture it |
| Never-committed gitignored file | Não | Excluded unless another collection mechanism reads or packages it |
| Staged but uncommitted index content | Not as ordinary reachable history | Requires separate collection behavior |
| Git stash | Not automatically included unless the relevant ref is bundled | Depends on which refs are packaged |
| Local hooks | Não | Hooks are filesystem state, not normal repository history |
.git/config | Não | Per-repository configuration is not part of the bundle |
| Commit metadata | Sim | Authors, timestamps, messages, and topology may be exposed |
The Grok Build evidence specifically supports tracked content and Git history. It should not be rewritten as “the client uploaded the developer’s whole disk” or “every ignored file was collected.” The model-read channel and any separate session archive may collect other data, but each claim requires its own evidence.
O .env Finding and Its Limits
O .env result has attracted attention because developers routinely place high-impact secrets in environment files. The exact finding deserves careful wording.
The researcher created a tracked file containing synthetic canaries under API_KEY e DB_PASSWORD fields. When the agent read that file, its content appeared verbatim in the /v1/responses request. The same canaries were present in a staged session-state archive associated with the storage process. (Gist)
This supports three conclusions:
- A filename such as
.envdid not automatically prevent the test file from being sent. - The tested canary values were not removed before transmission.
- Data read for a task could also enter a session-related storage artifact.
It does not support three stronger claims:
- No secret redaction exists for any known credential format.
- Every untracked or gitignored
.envfile is swept into the repository bundle. - Any real credential was accessed or abused.
The distinction between a synthetic canary and a real token matters. A redaction engine may recognize an AWS key prefix, GitHub token format, PEM header, or high-entropy sequence while missing a human-readable canary. Conversely, a generic redactor may recognize obvious field names but fail on proprietary credentials. Only broader tests could establish the actual coverage.
From a defensive perspective, the uncertainty does not make the result harmless. Organizations should not depend on client-side redaction as the primary control for source repositories. A coding agent can encounter secrets in many forms:
.env
.env.production
terraform.tfstate
values.yaml
application.properties
settings.xml
npmrc
pypirc
docker-compose.yml
cloud-init scripts
CI workflow files
test fixtures
database dumps
private certificates
shell history copied into an issue
Some values may be encrypted at rest but usable by the local developer environment. Others may be short-lived but still valid during the agent session. Internal URLs and account identifiers can be sensitive even when no credential appears beside them.
OWASP’s AI Agent Security guidance treats sensitive context exposure and data exfiltration through API requests, tool calls, logs, and outputs as distinct agent risks. It recommends minimizing sensitive data available to the agent, constraining tool access, and testing that confidential context does not escape through legitimate-looking channels. (Série OWASP Cheat Sheet)
Why Improve the Model Was Not a Transmission Control
One of the most consequential findings was that turning off Improve the model did not stop the original Grok Build repository upload.
In the reported test, the researcher disabled that setting and repeated the experiment. The captured Git bundle was still sent through /v1/storage, the never-read canary remained recoverable, and the server settings returned values including:
{
"trace_upload_enabled": true,
"upload_enabled": true,
"session_registry_enabled": true,
"max_upload_file_bytes": 1073741824
}
The researcher correctly limited the conclusion: the setting governed training-related use, not the existence of the repository transmission and storage mechanism observed in that account. (Gist)
This reflects a common product-design problem. Users often treat one privacy switch as a master data switch, while providers separate several processing purposes:
| Processing purpose | Exemplo | Controlled by a training opt-out |
|---|---|---|
| Live inference | Sending selected code to generate an answer | Usually no |
| Session synchronization | Restoring a session on another device | Not necessarily |
| Reliability diagnostics | Saving traces for debugging failures | Not necessarily |
| Abuse and security monitoring | Retaining logs for policy enforcement | Not necessarily |
| Product analytics | Usage and feature telemetry | Not necessarily |
| Model training | Updating or fine-tuning future models | Often yes |
| Human review | Reviewing samples for quality or safety | Depends on policy and account type |
| Backup retention | Preserving stored session objects | Not necessarily |
X’s Grok help documentation describes its opt-out as a control over whether interactions, inputs, and results are used for model training and fine-tuning. It does not describe that switch as a guarantee that no input is transmitted to operate the service. The same documentation states that users can still use Grok after opting out. (Help Center)
xAI’s privacy policy defines user content broadly to include prompts, files, images, audio, video, and other input. It says such content may be used to provide, analyze, maintain, develop, improve, secure, and support the service, and may be disclosed to contracted service providers under the stated conditions. It also says retention depends on the nature and purpose of the data and that deleted conversations or accounts are generally deleted within 30 days unless longer retention is required for legal, compliance, safety, or related reasons. (SpaceXAI)
Those broad provisions should not be confused with a precise product disclosure. A policy can authorize categories of processing while still leaving users without a clear explanation that a terminal client may upload a Git bundle containing every tracked file and history.
For security review, the practical rule is simple:
Never treat a model-training opt-out as proof of zero transmission, zero storage, or zero telemetry.
Each data path needs its own control and its own verification.
The Server-Side Flag Change
The screenshot that circulated after the original report describes a significant update. Cereblab wire-captured Claude Code, Codex, Gemini CLI, and Grok Build under comparable canary conditions. The update stated that Grok Build had initially been the outlier, but later stopped uploading the codebase after the server began returning a disabling flag. (X (formerly Twitter))
Reported post-disclosure settings included:
{
"trace_upload_enabled": false,
"disable_codebase_upload": true
}
The researcher said six later runs using the same 0.2.93 client produced no /v1/storage upload. Because the binary version stayed the same, the change points to server-side feature configuration rather than a conventional client patch. (explainx.ai)
This is a positive operational signal. It suggests xAI had a mechanism capable of stopping the behavior quickly.
It is not enough to close every risk question.
It does not prove global coverage
The tests involved one researcher, one machine, and a limited number of account and authentication paths. A remote setting can be global, regional, account-specific, subscription-specific, staged, or part of an experiment.
It does not prove permanence
A remotely controlled flag can change again. A later client or service deployment may use a different path or configuration schema.
It does not prove historical deletion
Stopping new uploads says nothing about objects already accepted through /v1/storage, copies in backups, derived session data, or retained diagnostic artifacts.
It does not explain the original purpose
The names repo_state, session_state, trace upload, remote session behavior, and codebase upload suggest several possible product objectives. Only xAI can explain the intended lifecycle, access controls, retention policy, and user benefit.
It is not a formal security advisory
A formal response would normally identify affected versions or configurations, describe the behavior, state whether the issue was global, explain mitigation status, address already transferred data, and give customers a way to verify or request deletion.
A silent server-side kill switch can reduce immediate exposure. It cannot provide retrospective assurance by itself.
What the Claude Code, Codex, and Gemini Comparison Means
The phrase “all three stay local” can be misleading without context. Claude Code, Codex, and Gemini CLI are cloud-connected coding agents in the tested configurations. Files they actually open may still be sent to their respective providers for inference.
The comparison meant something narrower:
Under the researcher’s canary tests, Claude Code, Codex, and Gemini did not show the separate whole-repository upload observed in the original Grok Build test, and the planted never-read file did not leave through an equivalent bundle path.
The comparison was performed on one machine and account path per tool. It was not a complete audit of every client version, enterprise plan, plugin, MCP server, authentication method, configuration, operating system, or future release. The Gemini portion also had a quota-related limitation on one task path, which further narrows the conclusion. (X (formerly Twitter))
| Ferramenta | Result in the researcher’s comparison | Appropriate interpretation |
|---|---|---|
| Claude Code | No equivalent whole-repository bundle observed; files opened for the task could be sent for inference | The tested run was task-scoped, not proof about every Claude deployment |
| OpenAI Codex | No equivalent whole-repository upload or never-read canary transfer observed | The tested run did not reproduce Grok’s original storage behavior |
| Gemini CLI | No equivalent repository bundle observed in the available test, with a quota caveat on part of the workflow | Evidence is narrower than a full functional audit |
| Grok Build 0.2.93 before flag change | Full Git bundle and never-read tracked file observed through storage | Direct evidence for the tested consumer configuration |
| Grok Build 0.2.93 after flag change | Six runs reportedly showed no original storage upload | Supports server-side mitigation for the tested account, not universal proof |
The comparison should influence evaluation priorities, not become a permanent vendor ranking. Coding-agent behavior can change rapidly through automatic updates, managed policies, experiments, plugins, and remote configuration.
A security approval issued for version 2.1 in June may not answer what version 2.2 sends in July. The same problem applies when the version does not change but the server flags do.
What Is Proven and What Is Not
The fastest way to understand the Grok Build CLI repository upload event is to separate measured facts from speculation.
| Reclamação | Evidence status | Explanation |
|---|---|---|
| Grok Build CLI 0.2.93 uploaded a Git bundle in the tested configuration | Proven by preserved wire capture | The request body was captured and accepted with HTTP 200 |
| The bundle contained a tracked file the agent did not read | Proven | The unique canary was recovered after cloning the uploaded bundle |
| The bundle contained Git history | Proven | Standard Git operations reconstructed multiple commits |
| The result occurred on more than one repository | Proven in two tested repositories | A second unrelated codebase produced the same type of result |
| Multi-gigabyte repository data left the machine | Proven to at least 5.10 GiB | Every captured storage chunk received HTTP 200 before the test was stopped |
| The complete 12 GB test repository finished uploading | Not proven | The researcher stopped the run at approximately 5.10 GiB |
A synthetic .env secret was sent unredacted after the agent read it | Proven for the tested canaries | It appeared verbatim in the model request and staged session archive |
| No secret-redaction feature exists | Not proven | The canaries were not real vendor-formatted tokens |
| Every gitignored or untracked file was uploaded in the Git bundle | Not proven | Normal Git bundles contain reachable Git objects, not arbitrary working-tree files |
| xAI trained Grok on the uploaded code | Not proven | Transmission and storage do not establish training |
| xAI employees inspected the repositories | Not proven | No access evidence has been published |
| Every user and account type was affected | Not proven | The test matrix was limited |
| The upload was caused by an outside attacker | Não suportado | The observed mechanism was part of the first-party client and service path |
| The behavior is now disabled for the tested account | Supported by later tests | The same client received a server-side disable flag and stopped using the original path |
| The mitigation is global and permanent | Not proven | No public scope statement or broad independent test exists |
| Previously uploaded data has been deleted | Not proven | No public historical-data confirmation has been identified |
Calling the event a “breach” can create confusion because no evidence shows that an attacker compromised xAI or bypassed its systems. “Unexpected repository transmission,” “potential source-code disclosure,” or “undisclosed full-repository upload behavior” are more precise descriptions.
The severity for a particular organization depends on what repository was involved, what historical objects it contained, which contractual controls applied, how long the service retained the content, and whether exposed secrets remained valid.
The Enterprise Threat Model
A Git repository is not merely a collection of source files. It is often a compressed map of the organization.
A private repository may expose:
- Application architecture
- Authentication and authorization decisions
- Internal service boundaries
- Cloud account identifiers
- Database schemas
- Deployment methods
- CI/CD workflows
- Employee identities and email addresses
- Customer names in fixtures
- Security controls and exceptions
- Vulnerabilities under remediation
- Secrets in current or past commits
- Third-party licensed source
- Incident-response tooling
- Monitoring and detection logic
The full history can be more useful to an attacker than the latest branch. It shows how security controls evolved, which mistakes were corrected, which endpoints were deprecated, and where engineers struggled. A deleted hard-coded credential may remain valid. A removed feature flag may reveal an unreleased product. A commit message may identify a security bug before a public advisory.
Exposição de credenciais
If a valid credential entered any transmitted file or reachable Git history, it should be treated as potentially disclosed. The response is revocation and replacement, not merely editing the repository.
Deleting a token from the latest commit does not invalidate the token. Rewriting Git history does not remove copies already cloned, bundled, backed up, cached, or uploaded. CISA repeatedly advises organizations responding to software-supply-chain exposures to rotate or revoke credentials that may have been accessible to affected systems or pipelines. (cisa.gov)
Intellectual property
Source-code disclosure can affect trade-secret treatment, patent strategy, product launch timing, and negotiations with customers or investors. The practical risk depends on who could access the uploaded content and under what contractual terms, which the network capture cannot determine.
Customer and supplier obligations
A company may have permission to process its own code through an AI service but lack permission to send customer-owned or supplier-owned code to the same provider. An engineering convenience can therefore create a contractual issue even when no secret appears in the repository.
Data residency
Repository content can include personal data, regulated information, or material subject to regional storage requirements. The bucket name and hosting provider do not by themselves identify the physical region, replication policy, or legal entity controlling the data.
Vulnerability intelligence
A repository may contain fixes for undisclosed vulnerabilities. Uploading the history can reveal both the vulnerable and patched implementations, making diff-based vulnerability discovery easier if the data becomes accessible to an unauthorized party.
Operational metadata
Build scripts, infrastructure-as-code, and test configurations often expose internal names and dependencies. That information can shorten an attacker’s reconnaissance even when the repository contains no direct credential.
CISA’s software-supply-chain guidance treats source-repository access and content protection as foundational controls, rather than ordinary document management. (cisa.gov)
Related AI Coding Agent CVEs
The Grok Build repository-upload finding does not currently have a CVE in the sources reviewed here, and assigning one would require an authorized CVE Numbering Authority to determine that the behavior meets its vulnerability criteria.
Two recent Claude Code CVEs are still highly relevant because they show how repository access, configuration, trust prompts, networking, and credentials can interact inside AI coding agents.
CVE-2026-21852
CVE-2026-21852 affected Claude Code before version 2.0.65. According to NVD, an attacker-controlled repository could include a settings file that changed ANTHROPIC_BASE_URL to an attacker-controlled endpoint. Claude Code could issue API requests before displaying the directory-trust prompt, potentially exposing the user’s API key. Anthropic’s fixed version was 2.0.65, and users relying on manual updates were advised to upgrade to that version or later. (NVD)
The exploitation conditions were different from the Grok event:
- An attacker had to control or influence the repository.
- A developer had to open the repository with a vulnerable Claude Code version.
- Project configuration redirected requests before trust was established.
- The potential recipient was the attacker’s endpoint.
The connection is architectural. In both cases, a coding agent had access to repository-controlled material, credentials, and outbound networking. The security outcome depended on initialization order and hidden data-flow decisions.
The primary mitigation was to update Claude Code. Additional defense comes from treating project-level agent configuration as executable or security-sensitive content, inspecting it before opening an untrusted repository, and preventing developer credentials from being transmitted to arbitrary destinations.
CVE-2025-59536
CVE-2025-59536 affected Claude Code versions before 1.0.111. NVD states that code contained in a project could execute before the user accepted the startup trust dialog. Exploitation required a user to start the vulnerable tool in an untrusted directory. (NVD)
Check Point’s disclosure described a broader class of risks involving repository-level hooks, MCP settings, environment variables, and pre-trust initialization. The important lesson was that files developers once treated as passive project metadata had become an active execution layer for an AI agent. (Pesquisa da Check Point)
Again, the Grok Build repository upload was not the same attack:
- CVE-2025-59536 involved malicious repository content triggering code execution.
- The Grok behavior was observed in the product’s own repository-storage mechanism.
- CVE exploitation depended on an attacker-supplied project.
- The Grok test used repositories controlled by the researcher.
The shared risk is trust-boundary expansion. An AI coding tool is simultaneously a file reader, network client, command runner, configuration interpreter, credential holder, and remote-service frontend. Security review cannot examine only the model.
| Issue | Gatilho | Primary effect | Attacker-controlled repository required | Main remediation |
|---|---|---|---|---|
| Grok Build CLI repository upload finding | Running the tested client in a Git repository | Repository and history sent through product storage path | Não | Disable or remove the behavior, document it, verify server configuration, investigate prior exposure |
| CVE-2026-21852 | Opening a malicious repository with vulnerable Claude Code | API traffic redirected before trust, potentially exposing API key | Sim | Upgrade to Claude Code 2.0.65 or later |
| CVE-2025-59536 | Starting vulnerable Claude Code in an untrusted directory | Project code executes before trust acceptance | Sim | Upgrade to Claude Code 1.0.111 or later |
The CVEs show why “the user did not ask the agent to do that” is not a sufficient control. Important activity can occur during startup, indexing, synchronization, trace collection, configuration loading, or session restoration before a visible model action.
Safe PoC, Understanding the Git Bundle Blast Radius
The following demonstration is intentionally local. It does not connect to Grok Build, xAI, or any external system. It uses fake values inside a temporary directory and illustrates why a full Git bundle can expose more than the current checkout.
The lab answers three questions:
- Can a bundle recover a tracked file even when no model ever read it?
- Can a secret deleted from the current branch remain in history?
- Does a never-committed gitignored file enter an ordinary history-based bundle?
Safety boundaries
- Run the commands only in a new temporary directory.
- Do not copy real source code into the lab.
- Do not use real credentials.
- Do not interpret the result as proof of current Grok Build behavior.
- Delete the directory when finished.
Create the toy repository
set -euo pipefail
LAB_DIR="$(mktemp -d)"
echo "Lab directory: $LAB_DIR"
cd "$LAB_DIR"
mkdir source-repo
cd source-repo
git init
git config user.name "Local Security Lab"
git config user.email "lab@example.invalid"
cat > app.py <<'PY'
def hello():
return "safe demo"
PY
cat > committed-secret.env <<'EOF'
DEMO_TOKEN=CANARY-DELETED-FROM-LATEST-COMMIT
EOF
git add app.py committed-secret.env
git commit -m "Add application and synthetic credential"
At this point, the fake credential exists in the first commit.
Delete the credential and add a never-read tracked file
rm committed-secret.env
mkdir -p src/_probe
cat > src/_probe/never_read_canary.txt <<'EOF'
CANARY-TRACKED-NEVER-READ
EOF
git add -A
git commit -m "Remove synthetic credential and add tracked canary"
The current working tree no longer contains committed-secret.env, but the first commit still does.
Add an ignored file that is never committed
cat > .gitignore <<'EOF'
local-only.env
EOF
cat > local-only.env <<'EOF'
CANARY-IGNORED-NEVER-COMMITTED
EOF
git add .gitignore
git commit -m "Ignore local-only environment file"
Verify the current state:
git status --short
git log --oneline --all
find . -maxdepth 3 -type f | sort
The ignored file exists on disk, but it has never become a Git object reachable from a commit.
Create and verify the bundle
cd "$LAB_DIR/source-repo"
git bundle create "$LAB_DIR/repository.bundle" --all
git bundle verify "$LAB_DIR/repository.bundle"
Git documents --all as a way to include all refs in a backup-style bundle. The resulting archive can be cloned into another repository. (Git SCM)
Clone the bundle
cd "$LAB_DIR"
git clone repository.bundle recovered-repo
cd recovered-repo
Confirm that the tracked canary is present:
cat src/_probe/never_read_canary.txt
Expected output:
CANARY-TRACKED-NEVER-READ
Recover the deleted synthetic secret from history:
git log -p --all -- committed-secret.env
The output should show:
DEMO_TOKEN=CANARY-DELETED-FROM-LATEST-COMMIT
Confirm that the never-committed ignored file is not in the recovered repository:
if find . -name local-only.env -print -quit | grep -q .; then
echo "Unexpected: ignored file was recovered"
else
echo "Expected: never-committed ignored file is absent"
fi
Search all reachable commit content for the canaries:
for commit in $(git rev-list --all); do
git grep -n "CANARY-" "$commit" || true
done
The tracked canary and deleted committed secret should be discoverable. The ignored, never-committed canary should not be.
What the lab demonstrates
The PoC does not exploit a product. It demonstrates the data semantics of a Git bundle:
- A file does not need to be opened by an AI model to enter a repository bundle.
- Deleting a secret from the latest checkout does not erase it from history.
- A standard bundle is not a copy of every local file.
- The exposure boundary depends on which Git refs and objects are included.
- A separate file-collection or session mechanism could still capture untracked data, so the absence of a file from the bundle does not prove it never entered another channel.
This is why incident responders must inspect both the current tree and the full history.
How to Validate an AI Coding Agent Safely
Organizations should not reproduce the original study inside a sensitive repository. A useful validation environment should be designed so that an unexpected upload creates evidence without creating harm.
Build a synthetic repository
Use a new repository with:
- Small, nonproprietary source files
- A unique marker in each file
- A tracked never-read file
- A fake secret in a tracked test file
- A never-committed gitignored file
- Two or three commits containing different canaries
- No real remote origin
- No real Git credentials
- No production configuration
Example marker generation:
python3 - <<'PY'
import secrets
for label in [
"MODEL_READ",
"NEVER_READ_TRACKED",
"DELETED_HISTORY",
"IGNORED_UNCOMMITTED",
]:
print(f"{label}=CANARY-{secrets.token_hex(12)}")
PY
Store the marker mapping outside the repository so captured values can be attributed accurately.
Record the test subject
Before running the agent, collect:
which grok || true
grok --version || true
shasum -a 256 "$(which grok)" 2>/dev/null || true
uname -a
date -u
Also record:
- Account type
- Authentication method
- Client configuration
- Server-provided managed settings, where visible
- Operating system
- Solicitação de teste
- Repository commit hash
- Network environment
- Whether the product auto-updated
Without this information, a later nonreproduction may simply involve a different binary or remote policy.
Capture complete host traffic
The original study highlights a critical monitoring lesson: a foreground-process byte counter may miss uploads performed by a coordinator process or direct requests to a cloud-storage host.
Use an authorized combination of:
- Full-host packet capture
- Controlled TLS-intercept proxy
- DNS logging
- Endpoint network telemetry
- Firewall or secure-web-gateway logs
- Process-tree monitoring
- Filesystem monitoring of local staging paths
Only intercept traffic generated by systems and accounts you are authorized to test. Installing a local interception CA changes the trust configuration of the test machine, so use a disposable VM or dedicated lab device and remove the CA afterward.
Separate endpoint classes
Classify requests by purpose:
Model inference:
*/v1/responses
Product storage:
*/v1/storage
*/v1/storage/*
Cloud object storage:
storage.googleapis.com
other provider-specific object hosts
Product events:
grok.com/_data/v1/events
Third-party analytics:
api.mixpanel.com
A model request containing a canary proves model transmission. A storage request containing the same value proves a separate path. A hostname alone does not prove the contents of an encrypted request.
Test minimum and maximum prompts
Run at least three cases:
Case 1:
Reply exactly OK. Do not read, list, search, or open any files.
Case 2:
Read only app.py and summarize its first function.
Case 3:
Inspect the project and identify the language, but do not execute commands.
Compare:
- Which canaries enter model requests
- Which canaries enter storage requests
- Total bytes by endpoint
- Whether storage begins before a useful model response
- Whether behavior changes after toggling settings
- Whether the result changes after restarting the client
Repeat the test
A single clean run does not prove that a feature is disabled. Remote configuration, sampling, retries, account state, repository size, and session restoration can influence behavior.
Repeat with:
- A fresh session
- A second repository
- A restarted machine
- A second authorized account type, where available
- Training or telemetry settings changed one at a time
- The same client on a later date
Report the scope exactly. “Not observed in six runs on one account” is strong evidence for that test matrix. It is not proof that a code path is impossible.
Detection Signals
Security teams investigating past or current Grok Build use should combine network, endpoint, identity, and repository evidence.
| Sinal | Por que é importante | Confidence | Main limitation |
|---|---|---|---|
Requests to cli-chat-proxy.grok.com/v1/responses | Expected model-inference path | Low for repository-upload detection | Normal product use produces this traffic |
Requests to /v1/storage | Directly associated with the reported storage channel | High when correlated with affected test period | Path semantics may change |
| High-volume requests immediately after opening a repository | May indicate bulk snapshot transfer | Medium to high | Large legitimate model tasks can also create traffic |
Direct connections to storage.googleapis.com | May reflect presigned object uploads | Médio | Many applications use Google Cloud Storage |
Reference to grok-code-session-traces in decrypted metadata | Closely matches reported destination | Alta | Requires content visibility or preserved artifacts |
Files under ~/.grok/upload_queue | Indicates local staging activity in the tested version | Médio | Queue creation alone does not prove network success |
| Git bundle signature in an outbound request | Strong content evidence | Muito alto | Requires authorized decryption or payload capture |
HTTP 200 responses for large /v1/storage solicitações | Shows server acceptance of request | High for transmission | Does not prove long-term retention |
| Storage traffic continuing after model quota failure | Suggests independent upload logic | High in a controlled test | Requires precise session correlation |
New disable_codebase_upload server setting | Suggests remote mitigation state | Medium to high | May be account-scoped or temporary |
| Sudden disk growth in local upload queue | May show large staged snapshots | Médio | Can occur even if upload later fails |
| Child or coordinator process with large egress | Explains traffic missed by foreground PID monitoring | Médio | Process architecture can change |
Network detection example
A secure web gateway or proxy can flag unusual combinations without blocking every AI request:
rule:
name: ai-coding-agent-bulk-storage
when:
process_name_in:
- grok
- grok-agent
destination_host_in:
- cli-chat-proxy.grok.com
- storage.googleapis.com
bytes_out_over_5m: 104857600
action:
- alert
- preserve_session_metadata
This is illustrative pseudoconfiguration, not a drop-in rule for a specific vendor. Process attribution is not always available at the network layer, and shared cloud-storage domains can create false positives.
Endpoint hunting example
On a test Mac, defenders can inspect known local paths without parsing private project content:
find "$HOME/.grok" \
-maxdepth 4 \
-type f \
-print \
-exec stat -f '%z bytes %Sm' {} \; 2>/dev/null
To identify unusually large staged artifacts:
find "$HOME/.grok" \
-type f \
-size +100M \
-exec ls -lh {} \; 2>/dev/null
Presence of a large queue file is an investigative lead, not final proof. The original researcher explicitly corrected an earlier conclusion that relied on queue draining and a process-scoped nettop view. A queue can empty after success, failure, deduplication, or deletion. Full wire evidence is stronger. (Gist)
Repository exposure assessment
Identify repositories used with the client from:
- Shell history
- Terminal session logs
- IDE history
- Recent-directory lists
- Endpoint process command lines
- Grok session metadata
- Developer interviews
- Git filesystem timestamps
- Proxy records tied to user and device
For each repository, calculate the actual history exposure rather than scanning only HEAD:
git rev-list --objects --all > all-git-objects.txt
git log --all --stat --oneline > commit-history-summary.txt
Search with an approved secret scanner capable of history analysis. Manual pattern checks can supplement the scanner:
git log -p --all -- \
'*.env' \
'*.pem' \
'*.key' \
'*.tfstate' \
'*.yaml' \
'*.yml'
Avoid printing real secrets into shared terminals or ticket systems. Run scans in a controlled environment and store results as restricted evidence.
Incident Response for Teams That Used Grok Build
A team that ran the affected Grok Build configuration in a private repository should not immediately assume every asset is compromised. It should treat the event as a potential third-party source-code disclosure and work through a bounded investigation.
Preserve evidence first
Record:
- Grok Build version
- Binary hash, if still available
- Installation and update dates
- Account type
- Repository paths
- Session timestamps
- Local configuration
- Server-provided settings
- Proxy, DNS, firewall, and EDR logs
- Local upload-queue metadata
- Whether Improve the model was enabled
- Whether the repository had an intact
.gitdirectory
Do not delete the client directory before collecting evidence. At the same time, avoid opening sensitive queue artifacts on an unmanaged machine.
Pause sensitive use
Until the organization validates current behavior, stop using the client against:
- Production source repositories
- Customer-owned projects
- Security tooling
- Infrastructure repositories
- Repositories with regulated data
- Unreleased products
- Projects containing usable credentials
A temporary pause is not a claim that the current server flag is ineffective. It recognizes that the organization has not independently established its own account state.
Identify the possible data set
For each repository, determine:
Current tracked files
All reachable commits
Branches and tags
Submodules
Large-file references
Secrets ever committed
Customer or supplier code
Personal or regulated data
Vulnerability-related commits
Internal infrastructure details
The exact uploaded bundle may not include every local ref, but using all reachable history as the initial upper bound is safer than limiting the review to the latest branch.
Rotate secrets by impact
Prioritize:
- Cloud administrative credentials
- CI/CD tokens
- Source-control tokens
- Production database passwords
- Signing keys and certificates
- Package-registry credentials
- Deployment SSH keys
- Customer API credentials
- Monitoring and incident-response tokens
- Development-only credentials
For each secret:
- Revoke the old value.
- Issue a replacement.
- Update consuming systems.
- verify that the old value fails.
- Review usage logs for the exposure window.
- Remove the secret from current code.
- Rewrite history where appropriate.
- Document why history rewriting does not substitute for revocation.
Review downstream activity
Search audit logs for:
- New sessions using exposed tokens
- Unusual API calls
- New cloud access keys
- Repository clones
- Package publication
- CI workflow changes
- Database logins
- Secret-manager access
- Changes from unfamiliar IP addresses
- Cost spikes or quota consumption
Absence of suspicious use lowers the likelihood of exploitation but does not answer whether the source code was stored by the provider.
Assess contractual and legal obligations
Security, legal, privacy, and engineering teams should determine:
- Whether the repository contained customer material
- Whether the AI service was approved
- Whether the applicable contract permitted external processing
- Whether regional transfer restrictions applied
- Whether source-code disclosure triggers customer notice
- Whether trade-secret controls require documented remediation
- Whether open-source or commercial licenses limit redistribution
- Whether an insurer or regulator must be informed
Use precise language. “Potentially transmitted to the service provider through the client’s storage mechanism” is more defensible than “stolen by xAI” when attacker access has not been established.
Request provider clarification and deletion
A useful request should identify:
- Account email or identifier
- Approximate session dates
- Grok Build client version
- Repository or project names
- Relevant session IDs
/v1/storagerepo_statesession_stategrok-code-session-traces- The desired confirmation of deletion
- Whether backups, replicas, derived traces, and service-provider copies are included
xAI’s privacy policy provides mechanisms for privacy requests and describes deletion timelines for certain user data, but the policy does not publicly map every Grok Build repository artifact to those categories. (SpaceXAI)
Ask the provider to answer in writing:
- Whether the account’s repository bundles were retained.
- The applicable retention period.
- The storage region and subprocessors.
- Whether any content entered training, evaluation, or human review.
- Whether prior objects were deleted after the server flag changed.
- Whether the disabling flag applies globally.
- How customers can verify the effective setting.
Hardening AI Coding Agent Workflows
The durable lesson is not to ban every cloud coding tool. It is to reduce the amount of valuable data any one agent session can reach and to verify what leaves the boundary.
Use disposable source exports
Instead of launching an agent in a full repository with years of history, create a temporary work directory containing only the files required for the task.
One option is git archive:
set -euo pipefail
REPO="/path/to/authorized/repository"
WORKDIR="$(mktemp -d)"
git -C "$REPO" archive HEAD | tar -x -C "$WORKDIR"
echo "Use the agent only inside: $WORKDIR"
echo "The exported directory contains no .git history."
This removes the .git directory and reachable historical objects from the agent’s workspace. It does not remove secrets already present in the latest files, so scanning and minimization are still required.
For a narrower export:
mkdir -p "$WORKDIR"
cp "$REPO/src/auth.py" "$WORKDIR/"
cp "$REPO/tests/test_auth.py" "$WORKDIR/"
The smaller the workspace, the smaller the maximum disclosure if the tool collects the whole directory.
Separate credentials from the workspace
Do not store long-lived secrets in source files. Provide short-lived credentials through a controlled broker or process environment only when required.
Prefer:
- Read-only tokens
- Repository-specific scopes
- Single-environment credentials
- Short expiration
- Explicit audience restrictions
- Workload identity
- Temporary cloud roles
- Separate development accounts
An agent performing code review should not inherit a production deployment credential merely because the developer’s shell has it.
Restrict filesystem access
Run the agent in a container or VM with only the task directory mounted:
docker run --rm -it \
--network=none \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=512m \
-v "$WORKDIR:/workspace:ro" \
approved-agent-image
This example disables networking, so it is suitable only for local inspection or preparing an environment. A cloud agent needs outbound access, but the same isolation principles still apply:
- Mount only the required project.
- Do not mount the home directory.
- Do not expose SSH agents.
- Do not mount Docker sockets.
- Do not expose cloud credential directories.
- Use a dedicated browser profile for authentication.
- Destroy the environment after the task.
OWASP recommends least privilege, parameter-bound approvals, constrained tools, and explicit controls over sensitive context for agentic systems. (Série OWASP Cheat Sheet)
Control egress by destination and purpose
A coding agent rarely needs unrestricted access to every public host.
Create distinct policies for:
- Model inference endpoints
- Autenticação
- Approved package registries
- Approved documentation
- Source-control services
- Object storage
- Analytics and telemetry
- MCP servers
Blocking all storage.googleapis.com traffic may disrupt unrelated applications and does not cover alternate storage providers. A stronger policy binds destination, process identity, user, device, and expected volume.
For sensitive workflows:
Allow model inference endpoint
Allow authentication endpoint
Deny direct generic object-storage uploads
Deny unapproved analytics
Alert on more than 100 MB outbound per session
Require proxy for all HTTPS
Terminate session on destination drift
The policy should be tested against product updates. A vendor can change hosts without changing the visible product name.
Scan current files and history
Use secret detection at several points:
- Developer pre-commit
- Server-side push protection
- Pull-request checks
- Scheduled history scans
- Pre-agent workspace preparation
- Incident-response review
Secret scanning reduces risk but does not make a repository safe to upload. Proprietary source, customer code, internal architecture, and vulnerability information remain sensitive.
Treat agent configuration as code
Review files that can influence agent execution:
AGENTS.md
CLAUDE.md
.mcp.json
project-level settings
hooks
plugin manifests
skills
shell scripts
task files
IDE workspace configuration
environment-loading files
CVE-2025-59536 and CVE-2026-21852 demonstrated that repository-level agent settings can affect code execution and network destinations before users understand what has happened. (NVD)
Revalidate every meaningful version
An AI coding agent should have a recurring security test, not a one-time questionnaire.
The regression suite should include:
- Never-read canary
- Read-file canary
- Deleted-history canary
- Untracked-file canary
- Gitignored-file canary
- Oversized repository
- Model-quota failure
- Network-denied storage endpoint
- Training opt-out
- Telemetry opt-out
- Restart and session restore
- Plugin and MCP activation
- Server-settings snapshot
This type of evidence-oriented workflow is also relevant to automated AI security testing. A platform such as Penligente can help structure authorized agent-security validation, preserve tool outputs, and turn repeated tests into reviewable findings, but network captures and endpoint evidence still need to be interpreted within the exact account, version, and policy context. Penligent’s analysis of AI Agent Security After the Goalposts Moved similarly emphasizes that data egress, tool privileges, approvals, and runtime behavior must be tested as system properties rather than inferred from a model’s stated intent.
The objective is not to ask the agent whether it uploads the repository. The objective is to observe whether the bytes leave.
Questions Security Buyers Should Ask Vendors
A security review for an AI coding agent should require concrete answers rather than broad assurances that data is encrypted or not used for training.
File and repository scope
- Which files can the client read without an explicit user command?
- Does the client enumerate the entire workspace?
- Does it package the
.gitdirectory or create Git bundles? - Are branches, tags, stashes, submodules, and large files included?
- Can the user restrict the agent to an allowlist?
- Are ignored and untracked files treated differently?
- Does indexing occur before the first prompt?
Data paths
- What endpoints receive model context?
- What endpoints receive session state?
- Is there a trace, replay, backup, or remote-resume path?
- Are direct object-storage uploads used?
- Are presigned URLs involved?
- Which third-party analytics services receive events?
- Can the customer obtain a complete destination-domain list?
Retention
- How long are model requests retained?
- How long are repository snapshots retained?
- Are diagnostic traces governed by a different period?
- Are backups included in deletion?
- Are derived embeddings or evaluations deleted?
- Can enterprise customers enforce zero data retention?
- Does deletion cover subprocessors?
User controls
- Does the training opt-out affect storage?
- Is telemetry independently controllable?
- Can repository upload be disabled?
- Is the effective setting visible to the user?
- Can an administrator enforce the setting?
- Can the vendor change it remotely?
- Is a change recorded in an audit log?
Security architecture
- Is sensitive-file redaction performed?
- What credential formats are detected?
- Does the client support outbound allowlists?
- Are repository instructions trusted before user approval?
- Can project configuration change network destinations?
- Are MCP servers and hooks isolated?
- Is there a sandbox boundary?
- Can the client access the user’s home directory or credential agents?
Incident response
- How will customers be notified of unexpected data collection?
- Can the vendor identify which accounts uploaded repository snapshots?
- Can it provide object-level deletion confirmation?
- Are enterprise customers given forensic logs?
- What is the process for reporting a client data-flow vulnerability?
A vendor answer such as “we do not train on customer data” addresses only one item. It does not answer what is transmitted, stored, logged, replicated, or available for session restoration.
Common Analytical Mistakes
The Grok Build CLI repository upload case is also a lesson in how to investigate modern developer tools.
Monitoring only the foreground process
The original research included a retraction. An early conclusion based on PID-scoped nettop output suggested that large files were not leaving the machine. Later full wire capture showed that a separate coordinator process and direct cloud-storage requests could bypass that view. (Gist)
Process-level accounting is useful, but the observed process tree must include helpers, launchers, background services, browser authentication components, and presigned storage clients.
Treating queue deletion as upload proof
A local queue disappearing may mean:
- Upload succeeded
- Upload failed and the client dropped it
- The content was deduplicated
- A cleanup timer ran
- The session was canceled
- Another process moved it
Network response evidence is stronger than filesystem inference.
Treating HTTP 200 as indefinite retention
An HTTP 200 response establishes that the service accepted the request at the protocol layer. It does not reveal:
- How long the object remained
- Whether it was immediately transformed
- Whether deduplication occurred
- Whether the body was discarded after validation
- Which users or systems could access it
- Whether backups were created
Transmission, acceptance, storage, retention, access, and training are separate claims.
Treating a training opt-out as a firewall
Privacy settings are product-policy controls, not network enforcement. Verify each endpoint independently.
Calling a Git bundle the entire machine
The captured bundle supported a strong finding without exaggeration. It contained tracked repository content and history. That is already serious. Expanding it to every local file weakens the credibility of the report.
Generalizing from one account
Remote feature flags can vary. State the exact client, account type, date, and authentication path.
Assuming a fixed binary has fixed behavior
Managed configuration can change collection logic without a software update. Record both client provenance and server-provided settings.
Comparing products without matching test conditions
A fair comparison requires:
- Equivalent canary repositories
- Equivalent prompts
- Equivalent network visibility
- Comparable authentication
- Similar session state
- Documented versions
- Multiple runs
- Explicit limitations
Even then, the result is a dated observation, not a lifetime certification.
A Practical Response Priority Table
| Prioridade | Ação | Reason |
|---|---|---|
| 1 | Stop using the affected or unverified configuration on sensitive repositories | Prevents additional potential disclosure |
| 2 | Preserve version, configuration, endpoint, and session evidence | Enables a defensible scope assessment |
| 3 | Identify every repository opened during the relevant period | Establishes the possible data set |
| 4 | Scan complete Git history for credentials and regulated data | Current files alone understate exposure |
| 5 | Revoke and replace potentially exposed secrets | Deleting code does not invalidate credentials |
| 6 | Review cloud, CI, repository, and database audit logs | Detects downstream use |
| 7 | Assess customer, contractual, privacy, and licensing obligations | Source code may belong to other parties |
| 8 | Submit a targeted provider access and deletion request | Addresses retained data and creates a written record |
| 9 | Validate the current server-side setting with a synthetic repository | Confirms present behavior for the organization’s account |
| 10 | Introduce recurring canary and egress tests | Detects regressions and remote policy changes |
The order can change when a known active credential is involved. An exposed production administrative key should be revoked immediately, even before the repository inventory is complete.
PERGUNTAS FREQUENTES
Did Grok Build upload entire Git repositories?
- In Cereblab’s tests of Grok Build CLI 0.2.93, a Git bundle was sent through
/v1/storageand accepted with HTTP 200. - Cloning the captured bundle recovered a tracked file the agent had been told not to read and the repository’s commit history.
- The result was reproduced on a second unrelated repository.
- The evidence applies to the tested client, account, platform, and time period; it does not prove that every Grok Build user received the same configuration. (Gist)
Did the test prove that xAI trained on private code?
- No.
- The capture proves transmission and server acceptance of repository data.
- Training would require separate evidence about downstream data use.
- Storage, debugging, remote session restore, abuse monitoring, evaluation, and training are different processing purposes.
- No published artifact in the report demonstrates that the uploaded repository entered a training dataset. (Gist)
Does turning off Improve the model stop repository uploads?
- It did not stop the repository upload in the original 0.2.93 test.
- The setting is described as a control over training and fine-tuning, not as a general network or storage prohibition.
- Teams should independently verify model requests, storage paths, trace uploads, telemetry, and retention.
- Later tests observed a separate server-side
disable_codebase_uploadsetting, rather than relying on the training opt-out. (Gist)
Is the Grok Build repository upload fixed?
- Later tests using the same 0.2.93 client reported no
/v1/storageuploads across six runs. - The server returned
disable_codebase_upload: trueand disabled trace upload for the tested account. - This supports a server-side mitigation.
- It does not yet establish global rollout, permanence, coverage of every account type, or deletion of earlier data.
- xAI’s public changelog did not provide a detailed incident entry addressing those questions as of July 13, 2026. (explainx.ai)
Are gitignored files included in a Git bundle?
- A normal Git bundle contains selected refs and reachable Git objects.
- A file that was never committed and exists only as an ignored working-tree file is not ordinarily part of repository history.
- A file that was committed and later added to
.gitignoremay remain recoverable from history. - Other agent channels can still read or archive an ignored file, so Git bundle semantics do not define the scope of every session or trace mechanism.
- Test bundle contents with synthetic data rather than relying on filenames or ignore rules. (Git SCM)
What should a team do after using Grok Build on a private repository?
- Record the client version, account type, dates, repository paths, and available network evidence.
- Pause use on sensitive repositories until current behavior is independently validated.
- Scan current files and complete Git history for secrets and regulated data.
- Revoke and replace any credential that may have been exposed.
- Review cloud, CI/CD, source-control, and database logs for unexpected use.
- Ask xAI whether repository, session-state, or trace objects exist and request deletion confirmation.
- Assess customer, NDA, licensing, privacy, and data-residency obligations.
How should enterprises test AI coding agents before approval?
- Use a disposable canary repository with no real source code or credentials.
- Record the exact binary hash, authentication method, account tier, and server settings.
- Capture full-host traffic rather than only the foreground process.
- Distinguish model inference, storage, analytics, and direct object-storage destinations.
- Test read, never-read, deleted-history, untracked, and gitignored canaries.
- Repeat tests after client updates and at scheduled intervals because server-side behavior can change.
- Enforce least privilege, limited filesystem mounts, short-lived credentials, and outbound network policy.
Closing Assessment
The security issue was not that a cloud coding agent sent code to a cloud model. That is an expected part of remote inference.
The issue was scope.
In the tested Grok Build CLI 0.2.93 configuration, the model channel carried files the agent opened, while a separate storage channel carried a Git bundle containing a file the agent did not open and the repository’s history. A multi-gigabyte test showed that the storage path could move far more data than the model had consumed. Turning off model improvement did not stop the original behavior.
The later server-side disable flag is an encouraging mitigation signal. It does not answer whether the change applies to all users, what happened to previously accepted bundles, how long those objects were retained, or why the mechanism was enabled without a more explicit repository-level control.
For defenders, the durable conclusion is broader than one product: AI coding agents must be evaluated as privileged software systems, not merely as chat interfaces. Their security boundary includes file discovery, Git history, initialization code, tool execution, credentials, local queues, remote settings, model endpoints, telemetry, session storage, and generic cloud egress.
A trustworthy assessment begins with a synthetic canary and ends with wire evidence.

