Repository navigation
Description
Question
Hi,
While reviewing the codebase, I noticed that when using the opencode provider (i.e., authenticating with an
opencode.ai token), all user prompts and complete AI responses are persisted to a Cloudflare R2 bucket — with no
opt-out mechanism and no documentation informing users about this.
Important note: This only applies when using the opencode provider with an opencode.ai authorization token. When
using your own API key with a direct provider (e.g., anthropic, openai), the CLI connects directly to the
provider's API (e.g., api.anthropic.com) and bypasses the Zen proxy entirely — no data is stored server-side in
that case. Additionally, the x-opencode-session header that triggers the storage is only sent when
providerID.startsWith("opencode") (packages/opencode/src/session/llm.ts, line 213), so even the header-level
condition would not be met.
Here is the exact code path I traced for the opencode provider:
- The CLI always sends session headers when using the opencode provider:
packages/opencode/src/session/llm.ts (lines 213–219) sets x-opencode-session, x-opencode-request, and
x-opencode-project headers on every request to https://opencode.ai/zen/v1/. - The server-side handler at packages/console/app/src/routes/zen/util/handler.ts (line 82) creates a dataDumper
instance using the session ID from the request header. - The full request body (containing all user messages, system prompts, and tool definitions) is passed to the
dumper at line 170: dataDumper?.provideRequest(reqBody). - The full response is also stored — either as a complete body (line 207) or accumulated from stream chunks (line
267). - The dataDumper (packages/console/app/src/routes/zen/util/dataDumper.ts) writes two JSON files to the Cloudflare
R2 bucket ZenDataNew (defined in infra/console.ts:174) on every request:
- data/{model}/{YYYY}/{MM}/{DD}/{HH}/{mm}/{ss}/{requestId}.json — full request + response
- meta/{model}/{sessionId}/{requestId}.json — metadata only - The guards are: Resource.App.stage === "production" (line 4), sessionId !== "" (line 5), and data.modelName
must be set via providerInfo.storeModel (line 19). Since the CLI always sends a session ID for the opencode
provider, and standard models have storeModel configured, this means every single prompt is stored in production
for normal usage.
My questions:
- Why is it necessary to store the complete content of every prompt and response?
- Is there a data retention policy? How long is this data kept?
- Are there plans to document this behavior and inform users?
- Could an opt-out mechanism be provided (e.g., a CLI flag or account setting to disable prompt logging)?
- Who has access to the stored data?
I understand that some level of logging may be needed for billing and abuse prevention, but storing full prompt
and response content goes significantly beyond what's needed for those purposes. Usage metadata (token counts,
model, timestamp, cost) would be sufficient for billing without retaining the actual conversation content.
Thank you for looking into this.
Activity
github-actions commentedon Feb 19, 2026
This issue might be a duplicate of existing issues. Please check:
Please review these issues to see if your concern is already being tracked, and consider adding your findings there if applicable.
thdxr commentedon Feb 19, 2026
this is only relevant for free models provided by opencode zen which is clearly documented in our docs
storeModel is only set for free models
github-actions commentedon Apr 21, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.