opencode-privacy-fix GitHub repo ↗

Privacy Tracker Proposed Solution What it does Why this exists Poll Discussion

OpenCode Privacy Tracker

Community-reported privacy issues and fix attempts. Audited against OpenCode v1.3.0 (34f43ff) on March 24, 2026.

7
Issues open
12
Community PRs
0
PRs merged
3+
Months unresolved
OpenCode's privacy stance: No privacy policy, no telemetry disclosure, and no network documentation have been published. Some disable flags appear in the CLI docs but with zero privacy context — descriptions like "Disable automatic update checks" without mentioning it contacts opencode.ai and leaks your IP and operating system. OPENCODE_DISABLE_SHARE is missing from docs entirely. 7 community issues and 12 community PRs have been filed over 3+ months — zero merged. A maintainer commented on PR #18235 (Mar 20, 2026): "We ofc need to ship something with this shape, internally we talked about some approaches briefly" — no action since. The two most critical concerns (app.opencode.ai proxy, api.opencode.ai GitHub calls) have no disable flag at all. The app.opencode.ai proxy and auto-update endpoints also leak your operating system via User-Agent headers and platform-specific requests.

Note: PostHog (us.i.posthog.com) and Honeycomb (api.honeycomb.io) references exist in the repo but are in script/stats.ts (a CI build script) and packages/console/ (cloud dashboard) respectively — not in the opencode CLI binary.

PR resolution bar — of 12 community PRs addressing privacy concerns:

Open, unreviewed (5) Auto-closed by bot (6) Closed other (1) Merged (0)
Concern A: Web UI silently proxies all requests to app.opencode.aiNO DISABLE FLAG
#6352Allow overriding web client path / bundle with binaryissue · open@thdxr

First issue to raise the privacy concern (Dec 29, 2025). Project paths are leaked to app.opencode.ai through the catch-all proxy. Requests either bundling the web UI into the binary or adding a config override for the proxy URL. Also raises a stability concern: the CDN-hosted UI can change between binary releases, causing version mismatches.

Created: 2025-12-29Created by: @papercloverAssigned to: @thdxr6 reactions
View on GitHub →
#8549Web doesn't work without internet (corporate)issue · open@adamdotdevin

Main tracking issue for the offline web UI problem. The web UI fails completely in corporate/air-gapped environments because it depends on app.opencode.ai for all frontend assets. 16 reactions and 10 comments — the most-engaged privacy issue. Multiple community workaround commits linked in the comments (proAlexandr, tardyp).

Created: 2026-1-14Created by: @IceWreckAssigned to: @adamdotdevin16 reactions · 10 comments
View on GitHub →
#11981opencode web shall not use external app.opencode.aiissue · dup@adamdotdevin

Filed by a user on GCP Cloud Workstations where app.opencode.ai is blocked by corporate firewall. Closed by the reporter as a duplicate of #8549. The reporter (tardyp) contributed a workaround commit (a988b75) that serves the frontend from the same port.

Created: 2026-2-3Created by: @tardypAssigned to: @adamdotdevinClosed as duplicate of #85493 reactions
View on GitHub →
#12083Unable to connect — intranet usersissue · open@rekram1-node

Pure intranet users cannot load the web UI at all. 16 comments and 10 reactions. The reporter traced the root cause to the server.ts catch-all proxy. Distinct from #8549 in that this focuses on users who have zero external internet access, not just restricted corporate access.

Created: 2026-2-4Created by: @jakiechrisAssigned to: @rekram1-node10 reactions · 16 comments
View on GitHub →
#12445Support custom web app proxy URL (firewalled env)issue · open@adamdotdevin

Root feature request for an OPENCODE_APP_URL environment variable to override the hardcoded app.opencode.ai proxy destination. Spawned PR #12446. 4 reactions.

Created: 2026-2-6Created by: @jobrkAssigned to: @adamdotdevin4 reactions
View on GitHub →
#16787Option to disable web UI proxy for TUI-onlyissue · open@thdxr

TUI-only user wants an OPENCODE_DISABLE_WEB flag so the catch-all proxy returns 404 instead of proxying to app.opencode.ai. References #12445 and #11981. No PR has been created for this approach.

Created: 2026-3-9Created by: @mik3h0Assigned to: @thdxr1 reaction
View on GitHub →
#17406Web UI requires internet — binary proxies to CDNissue · open@thdxr

Filed by BYK (author of PR #15721). Detailed technical write-up: the binary is ~159MB but proxies all HTML/JS/CSS/fonts to the CDN instead of serving them locally. Distinct from #12083 — this is specifically about the binary not embedding web assets despite having room. Spawned PRs #15700 and #15721.

Created: 2026-3-13Created by: @BYKAssigned to: @thdxr2 reactions
View on GitHub →
#12446PR: Add OPENCODE_APP_URL for custom proxypr · openby @jobrk

Minimal 5-line change adding an OPENCODE_APP_URL env var to override the app.opencode.ai proxy destination. 18 reactions. Reviewed by community contributor @kikuchan who identified a subpath routing bug — but kikuchan explicitly stated they cannot press the approve button because they are not a maintainer. No maintainer has reviewed it.

Created: 2026-2-6Created by: @jobrkAssigned to:18 reactions · 1 commit · 5 lines · Mergeable
View on GitHub →
#12829PR: Embed web UI in binarypr · openby @nicell

Bundles the web UI at build time with a flag to disable. 41 reactions — the most-reacted PR. Tested in air-gapped Docker by @Chetic and confirmed working. @BlankParticle pinged maintainers. Maintainers responded that they were "interested in doing this themselves" but no internal PR has materialized.

Created: 2026-2-8Created by: @nicellAssigned to:41 reactions · 2 commits · Merge conflicts
View on GitHub →
#15700PR: Embed web UI assets (BYK v1)pr · bot closedby @BYK

BYK's first attempt at embedding web UI assets. 294 additions. Auto-closed by the compliance bot for missing PR template fields. Superseded by #15721 which fixes the issues found in this version (middleware ordering, SPA route hijacking, CI compatibility).

Created: 2026-3-2Created by: @BYKAssigned to:Closed: auto-closed by bot (missing PR template)
View on GitHub →
#15721PR: Embed web UI assets (BYK v2) — best candidatepr · openby @BYK

Most technically mature PR. 229 additions, 3 commits. Fixes v1 bugs: middleware ordering, SPA route hijacking, CI compatibility. Externalizes 83 optional font files (~27MB) to keep binary size reasonable (~174MB vs ~159MB). Tested in air-gapped environment by @Warkeeper and confirmed working. Codeowner review requested from @adamdotdevinno reviews have been submitted yet.

Created: 2026-3-4Created by: @BYKAssigned to:229 additions · 3 commits · Mergeable · Review: requested from @adamdotdevin, none received
View on GitHub →
#17104PR: Support OPENCODE_WEB_URL for local servingpr · openby @sjawhar

Supports two modes: (1) file:// path for serving local web assets, (2) HTTP URL for a custom proxy target. Closes #12445. Relates to #8549, #11981, #16787. Passed compliance. Status: blocked (merge conflicts).

Created: 2026-3-12Created by: @sjawharAssigned to:Closes #12445 · Merge conflicts
View on GitHub →
#18506—#18522PR: Offline web static serve (DroganC — 6 attempts)5 bot closed · 1 openby @DroganC

DroganC attempted to submit the same offline web serving fix 6 times. The approach adds an OPENCODE_APP_DIST env var to serve web assets from packages/app/dist locally, plus an OFFLINE_WEB.md documentation file. 138 additions, 12 files changed.

Why 5 were closed: The repo has an automated compliance bot that auto-closes PRs within ~2 hours if they don't meet template requirements (needs:title, needs:compliance). PRs #18506, #18508, #18510, #18520, and #18521 were all closed by this bot. The 6th attempt (#18522) finally passed compliance and remains open with review requested from @adamdotdevin.

Created: 2026-3-22Created by: @DroganCAssigned to:#18506 closed (bot)#18508 closed (bot)#18510 closed (bot)#18520 closed (bot)#18521 closed (bot)#18522 open
View #18522 on GitHub →
Concern B: No single "offline mode" to disable all outbound connections — NO DISABLE FLAG
#18235PR: Add offline mode (--offline)pr · openby @dgruzd

Adds OPENCODE_OFFLINE=true / --offline CLI flag as a single kill switch for all non-essential outbound connections. When enabled: disables auto-update, disables session sharing, web UI proxy returns 503. 233 additions, 5 tests.

Maintainer @rekram1-node (Mar 20, 2026): "We ofc need to ship something with this shape, internally we talked about some approaches briefly, ill need to sync back w/ them to see what they think is best next week"

No follow-up action since that comment.

Created: 2026-3-20Created by: @dgruzdAssigned to:233 additions · 5 tests · Merge conflicts · Maintainer acknowledged
View on GitHub →
Concern C: Model catalog fetched from models.dev, leaking your IP and OpenCode version — HAS FLAG
#18638Offline deployment blocked by models.dev requestsissue · open

Docker deployment (ghcr.io/anomalyco/opencode:1.1.53) keeps requesting models.dev, blocking the web interface in offline environments. The OPENCODE_DISABLE_MODELS_FETCH flag exists but is undocumented — users don't know it's available. The flag is also only checked after local cache and bundled snapshot both fail, so the fetch can happen before the flag takes effect.

Created: 2026-3-22Created by: @LeekinxunAssigned to:
View on GitHub →
Concern D: Session data (prompts, files, diffs, tool calls) synced to opncd.aiHAS FLAG

Disablable via OPENCODE_DISABLE_SHARE=true. Data is only POSTed for sessions that have been explicitly shared. No standalone issue — covered by PR #18235 offline mode.

Concern E: Search queries forwarded to third-party mcp.exa.ai with no authentication — OPT-IN or AUTO with Zen

Active when OPENCODE_ENABLE_EXA=true is set OR when using OpenCode Zen as your provider (auto-enabled, no flag needed). Built-in tools send queries with no API key (possible partnership deal). See details below.

Concern F: Auto-update periodically contacts opencode.ai, leaking IP, OS, and version — HAS FLAG

Disablable via OPENCODE_DISABLE_AUTOUPDATE=true. Periodically fetches install script, leaking IP and version.

Concern G: GitHub org/repo names and login tokens sent to api.opencode.aiNO DISABLE FLAG

No dedicated issue filed. Sends your GitHub organization and repository names to OpenCode's servers during opencode github commands. Also exchanges OIDC tokens (temporary login credentials) through their API. Only the login token path can be redirected via OIDC_BASE_URL; the installation check has no override at all.


Proposed Solution

Since OpenCode has not merged any community fix, we built a standalone tool that blocks all telemetry at the OS level. Run once, forget forever. Audit the source code on GitHub before running ↗

Action
Platform
Method

What it does

Tip: Two things happen when you run install. Both persist across reboots. Both are fully reversible with uninstall.
  1. Hosts file — blocks 5 telemetry domains at OS level
  2. Environment variables — sets 3 flags permanently in your shell profile (Linux) or User Environment (Windows)

No wrappers, no aliases. You keep running opencode exactly as before.

1. Hosts file entries added

Appended to /etc/hosts (Linux) or C:\Windows\System32\drivers\etc\hosts (Windows):

# >>> opencode-privacy-block BEGIN >>>
127.0.0.1 app.opencode.ai
127.0.0.1 models.dev
127.0.0.1 opncd.ai
127.0.0.1 api.opencode.ai
127.0.0.1 opencode.ai
# <<< opencode-privacy-block END <<<
What each domain does (click to expand all 5)
app.opencode.ai — Web UI catch-all proxy NO DISABLE FLAG

Source: server.ts:499-514

When you run opencode serve, every request that doesn't match an API route is silently forwarded:

.all("/*", async (c) => {
    const response = await proxy(`https://app.opencode.ai${c.req.path}`, {
        ...c.req,
        headers: { ...c.req.raw.headers, host: "app.opencode.ai" },
    })
})

When it fires: On every page load of the web UI — HTML, JS, CSS, fonts, images. Even if your LLM is fully local.

Leaked: Your IP, your operating system (via User-Agent header), all request headers, full URL path (may contain project names).

NOT leaked: Prompts and LLM responses — handled by API routes registered before this catch-all.

Why this matters even if prompts aren't leaked
  • Web UI is fetched remotely, not embedded. Developers can change it without a binary update.
  • Your IP is exposed to OpenCode's CDN on every page load.
  • Request paths may contain project names.
  • In air-gapped networks, the web UI fails with a blank page.
api.opencode.ai — GitHub integration NO DISABLE FLAG

Source: github.ts:366, 738

fetch(`https://api.opencode.ai/get_github_app_installation?owner=${app.owner}&repo=${app.repo}`)
if (!value) return "https://api.opencode.ai"

When it fires: Only with opencode github command. Not during normal chat/TUI.

Leaked: GitHub org name, repo name, and OIDC tokens (OpenID Connect tokens — temporary login credentials that prove your identity. If intercepted, they could be used to act as you for a short time).

opencode.ai — Auto-update HAS DISABLE FLAG

Source: installation/index.ts:153

const response = yield* httpOk.execute(HttpClientRequest.get("https://opencode.ai/install"))

When it fires: Periodically in the background, unless OPENCODE_DISABLE_AUTOUPDATE=true.

Leaked: IP, operating system/platform (the endpoint serves platform-specific install scripts, so the request itself reveals your OS), and OpenCode version.

opncd.ai — Session sharing HAS DISABLE FLAG

Source: share-next.ts:50, 66-112, 191-228

Subscribes to every session/message/part/diff event:

Bus.subscribe(Session.Event.Updated, async (evt) => { await sync(...) })
Bus.subscribe(MessageV2.Event.Updated, async (evt) => { await sync(...) })
Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => { await sync(...) })
Bus.subscribe(Session.Event.Diff, async (evt) => { await sync(...) })

But sync() has a critical gate:

async function sync(sessionID, data) {
    if (disabled) return              // ← exits if OPENCODE_DISABLE_SHARE=true
    const share = get(sessionID)
    if (!share) return                // ← exits if no share record exists
    // ...only then does the HTTP POST happen
}
When data is actually sent vs. when it's not

Data IS sent when ALL true:

  1. OPENCODE_DISABLE_SHARE is not true
  2. Session has a share record (ShareNext.create() was called)
  3. A session/message/part/diff event fires

Data is NOT sent when ANY true:

  • OPENCODE_DISABLE_SHARE=true — no bus subscriptions created at all
  • Session never shared — sync() bails at if (!share) return

What is sent: Full session metadata, complete messages, all parts (tool calls, code), file diffs, model info.

Bottom line: If you never explicitly share a session, no data is actually sent to opncd.ai. However, the code that listens for your activity (every message you send, every file you edit) is still running in the background — it just discards the data instead of sending it. Setting OPENCODE_DISABLE_SHARE=true prevents even that listener code from being activated in the first place, so nothing about your session is ever monitored at all.

models.dev — Model catalog HAS DISABLE FLAG

Source: models.ts:84-99. Fetches only if local cache AND bundled snapshot both fail.

Leaked: IP and that you're using OpenCode. Does NOT report which model you selected.

us.i.posthog.com and api.honeycomb.ioNOT in the CLI binary

Correction: PostHog and Honeycomb references exist in the OpenCode repository, but they are not part of the CLI/TUI binary that users run.

us.i.posthog.com appears in script/stats.ts — a standalone CI build script that aggregates download stats. It requires a POSTHOG_KEY env var and is run by developers in CI, not by users.

api.honeycomb.io appears in packages/console/function/src/log-processor.ts — part of the cloud console web app (their dashboard), not the CLI. It requires a server-side HONEYCOMB_API_KEY.

Neither of these endpoints is contacted when you run opencode on your machine. They are not blocked by this fix because they don't need to be.

2. Environment variables set

Written permanently to ~/.bashrc / ~/.zshrc (Linux) or User Environment (Windows):

OPENCODE_DISABLE_AUTOUPDATE=true
OPENCODE_DISABLE_SHARE=true
OPENCODE_DISABLE_MODELS_FETCH=true
What each variable does
VariableEffectBlocks
OPENCODE_DISABLE_AUTOUPDATE=trueStops update checksopencode.ai/install
OPENCODE_DISABLE_SHARE=trueStops session syncopncd.ai
OPENCODE_DISABLE_MODELS_FETCH=trueUses bundled catalogmodels.dev/api.json

Some of these flags appear in OpenCode's CLI docs (packages/web/src/content/docs/cli.mdx), but with no privacy context — their descriptions say things like "Disable automatic update checks" without mentioning that it contacts opencode.ai and leaks your IP and operating system. OPENCODE_DISABLE_SHARE is missing from the docs entirely. There is no privacy policy, no telemetry disclosure page, and no network documentation anywhere in the project.

Some telemetry domains (like app.opencode.ai and api.opencode.ai) have no flag at all — the only way to block them is through the hosts file. The environment variables handle the domains that do have flags. Together, the hosts file + environment variables cover every known outbound connection.


Why mcp.exa.ai is not blocked

Caution: OpenCode's built-in websearch and codesearch tools send queries to mcp.exa.ai/mcp with no API key and no authentication — suggesting a partnership or free-tier deal between OpenCode and Exa.

These tools are enabled when OPENCODE_ENABLE_EXA=true is set or when using OpenCode Zen as your provider (auto-enabled, no flag needed). If you use any other provider and haven't set the flag, they don't fire.

If you configure Exa as a remote MCP server in opencode.json (using your own API key), that also hits mcp.exa.ai. Blocking the domain would break your own MCP usage — DNS can't distinguish between the two.

Note: If you don't use Exa at all, add 127.0.0.1 mcp.exa.ai to your hosts file manually.

Why this exists

The OpenCode CLI binary contacts 5 external domains during normal use, none disclosed in a privacy policy. 7 issues and 12 PRs have been filed by the community over 3+ months — zero merged. This page documents every concern with source code evidence and provides a workaround. See the original Reddit discussion.


Community Poll

How should OpenCode handle telemetry and outbound connections?

Vote by reacting on the GitHub Discussion — each GitHub account gets one vote. Pick the option closest to your view.

🚀 All telemetry should be opt-in — nothing sent without explicit consent
👍 Telemetry is OK but must be disclosed upfront with a clear opt-out
👀 Anonymous crash/usage analytics are fine, but session data must be opt-in
😕 Need more information before deciding
👎 Current defaults are acceptable, no changes needed
Vote on GitHub Discussion →

Discussion

Sign in with GitHub to comment or react. Reactions serve as upvotes/downvotes.

Copied!