GitHub report: Codex memory sends chats cross-provider

A Codex user says the agent’s Memories feature took a conversation they had routed through a private local model provider and sent it to OpenAI. The user believes that is where an OpenAI account warning for “cyber abuse” came from. The evidence at the centre of the report filed on GitHub on August 30 is one captured frame: a 38,095-byte WebSocket response.create message to chatgpt.com/backend-api/codex/responses, tagged request_kind = "memory". It went out with analytics disabled and every OpenTelemetry exporter set to none.
The reporter ran the test on the stock Windows Codex desktop binary 0.150.0-alpha.12.2. The report gives the binary’s SHA-256 hash and names the public source tag it matches, rust-v0.150.0-alpha.12.2. Every input was synthetic. The test used a prior rollout, Codex’s stored record of a session, labeled with a provider called synthetic_source and seeded with canaries: unique marker strings that would turn up downstream if the content travelled. A later OpenAI-backed session triggered memory generation and picked that rollout up.
What left the machine
The captured request carried store = false, prompt_cache_retention = "24h" and three top-level input items: a developer item listing additional tools, a developer message with the memory instructions, and a user message holding the serialized source conversation. The instructions alone ran to 31,000 characters. The user wrapper was 3,817 bytes, of which 3,092 were the rendered conversation. The reporter notes that the store and cache-retention values are what the client put in its request.
Of the six model-visible items in the source rollout, five appeared in the memory request as exact structural matches. They were the full environment-context message (working directory, workspace, shell, date, timezone and filesystem-policy fields), the ordinary user message, the tool call with its name and arguments, the tool output with its runtime paths and policy-rejection text, and the assistant reply. The source developer message stayed behind, as did session, turn, event and world-state records. The rollout path and working directory went out separately, outside the boundary where redaction runs.
OpenAI’s side of the same WebSocket flow answered with response.created and then response.completed. The completion named the model gpt-5.6-luna and reported 7,337 input tokens, 983 output tokens and 8,320 in total. The generated memory, 3,405 characters long, repeated the user, assistant, tool, private-text and synthetic-email canaries several times. The reporter reads that as proof the material was processed remotely, beyond a mere connection attempt, because the reply depends on the content sent.
Three steps in the source
The report traces the crossover through three stages of the tagged source. First, the memory job calls the rollout selector with model_providers: None. It still applies other eligibility rules, covering memory mode, age, idle state, source type and claim state, but not which provider created the rollout (state/src/runtime/memories.rs, lines 218-234). Second, the memory worker builds its provider, including the ModelClient that makes the request, from config.model_provider, the provider of the session that triggered the job (memories/write/src/runtime.rs). Third, phase 1 loads the stored rollout, filters and serializes the retained items, puts them into a new user message and sends it through that memory client (memories/write/src/phase1.rs, lines 282-322).
The reporter’s conclusion: a real, eligible rollout from a local provider can be selected by a later OpenAI-backed memory session and routed to OpenAI, unless some other eligibility condition stops that particular rollout from being claimed. The report treats the question of intent as secondary:
Whether the transfer resulted from an intentional design or a bug does not change what crossed the boundary.
How much of a thread goes
The filter keeps a wide set of item classes, per the report: user and assistant messages, agent messages, local shell calls, function calls and outputs, tool-search calls and outputs, custom-tool calls and outputs, web-search calls, and converted inter-agent messages. It drops source developer messages, reasoning records, compaction records, some generated-media and tool declarations, and bookkeeping. Long inputs are cut from the middle at 70% of the model’s effective context window, with a 150,000-token fallback, so the start and end survive. For a short thread under that limit, the reporter says, this can come to essentially the whole conversation along with its tool arguments, results, errors, environment context and local paths.
Before sending, the serializer calls redact_secrets. The report says its patterns cover conventional sk- keys, AWS AKIA identifiers, long bearer tokens, and values assigned to names such as api_key, token, secret or password. In a separate loopback test, the filter removed a fake OpenAI-style key, a bearer-token shape and a named api_key assignment. It let through a key containing underscores, a cookie-like value, an email address, a phone number, a private-key header, private prose, a Windows path and all the ordinary canaries. The reporter calls it “a useful narrow secret-pattern filter” and says it is not a scrubber for personal data, privileged material or filesystem identity.
Which switch closes it?
Per the report, only the feature gate [features] memories = false closes this path. Analytics and OpenTelemetry settings govern other subsystems, and no setting keeps Memories on while blocking cross-provider sends. The user-facing memory documentation describes local storage and controls. The developer README says phase 1 filters each rollout and sends it to a model. The reporter says neither text clearly discloses that a rollout made under one provider can later go out through another. The report also points to a related earlier issue about the opposite direction, where OpenAI model IDs were sent to an active non-OpenAI provider.
The fix the reporter asks for: memory generation should use the source rollout’s own provider, or skip the rollout when that provider is unavailable. Any cross-provider processing should be opt-in and name the destination and content classes before anything is sent. The UI should show a receipt of which task went to which provider and when, and automated tests should check provider isolation both at candidate selection and at send time.
The “cyber abuse” warning
The investigation began with the account warning, the reporter writes. None of the chats directed at OpenAI contained anything that could explain it, and the activity in question existed only in chats deliberately routed through the private local provider. From that and the captured Memories channel, the reporter states a “strong evidence-backed belief” that OpenAI policed the account using chat content “it had no right to receive”. The capture itself used synthetic data. The link to the warning rests on the reporter’s account of which chats held the activity, and the reporter calls the transfer data exfiltration “in the ordinary meaning of that term”.
The reporter wants content obtained across a provider boundary kept out of moderation, strikes, warnings and restrictions. OpenAI is asked to audit past account actions for this dependency, reverse the affected ones, notify each user and publish aggregate findings. The report urges OpenAI to preserve logs, moderation records and backend flags “for possible future discovery”. It also warns that any negative action against the account following the disclosure “will be perceived as retaliatory action.” The questions to maintainers include whether the crossover is intended or a bug, which released versions are affected, and how many users have received a negative account action based in whole or in part on content from local or third-party-provider chats.
The reporter also demands an official public incident response and adds: “Quietly patching the provider selector is not an adequate response to users who may already have been penalized.”
Up next
Tens of thousands of Mac minis go into AI training
Per The Information, OpenAI has acquired tens of thousands of Apple Mac minis and Mac Studios for reinforcement learning and computer-use agent training, while Anthropic is said to be renting Mac minis through AWS.
Related stories
- A dependency wrote AGENTS.md and Codex hid the edit
- Forced rm detection tightened in Codex
- Three ways to embed the Codex agent loop in your app
- Embedded browsers in Codex and VS Code leak the whole disk
- Codex CLI 0.157.0 leaves a daemon running after you quit
- Codex Security Cloud reviews commits with the laptop closed
Comments
No comments yet. Be the first.
Join the conversation
Sign in to leave a comment. It appears after moderation.

