You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
/connect shows providers that are disabled in the config #54145
In v1, if enabled_providers was set to a restricted list, /connect only showed providers that were actually enabled.
In v2, /connect now shows all providers, even if enabled_providers is set to a restricted list.
This makes it hard for a company to prevent users from using unapproved providers. (In our case, like in #2853, we want to lock down to only a custom provider.)
Plugins
None
OpenCode version
2.0.26
Steps to reproduce
Configure a custom provider, then set enabled_providers to only its ID.
Start OpenCode and run /connect.
Observe that providers outside the allowlist still appear.
Screenshot and/or share link
No response
Operating System
Ubuntu 26.04 (in a Docker container, running inside Ubuntu 26.04 on WSL on Windows 11).
Terminal
No response
Reacted by dr0bz, Morten (MOQ), rshibanov and Dennis Rutjes
Thanks for the clear report. I could reproduce this on 2.0.26, and it still happens on the latest v2 branch (5cfe3b4).
What I did:
Configured a single custom provider (mycompany, via @ai-sdk/openai-compatible) and set enabled_providers: ["mycompany"].
Started OpenCode. The custom model was selected, so the config was loaded.
Ran /connect.
The Connect an integration dialog still listed OpenCode Console, openai, github-copilot, amazon-bedrock, azure, the Cloudflare providers, digitalocean, gitlab and others, and searching "openai" found it. The recording and screenshots below show it, and the script below reproduces it.
It looks like enabled_providers is applied to the provider list but not to the list of integrations that /connect shows. I didn't check whether connecting a provider outside the allowlist makes its models usable.
Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.
I traced where the two lists diverge, and the gap matches your report exactly.
enabled_providers is normalized into experimental.policies as provider.use allow/deny entries (packages/core/src/config/normalize.ts), and those are then applied in packages/core/src/config/plugin/policy.ts:
That transform only visits the provider catalog. The /connect dialog is fed by a different registry — Integration.Service.list() via server.integrationintegration.list — and nothing applies the policy to it, so every integration keeps showing up regardless of enabled_providers.
The two registries already line up by id: packages/core/src/config/plugin/provider.ts treats a configured provider's id as its integration id (const integrationID = id) and calls ctx.integration.transform(...), so the same plugin context can also trim the integration registry. The plan is to extend the policy plugin to remove denied integrations the same way it removes denied providers, so a restricted allowlist shows only allowlisted integrations in /connect.
I have a checkout of v2 at the commit the bot tested, so I can verify the dialog and add a test on the config policy path. If you would rather the integration registry stay untouched and the filtering happen at the server endpoint instead, say so and I will follow that.
The fix applies provider policy to the integration registry as well: a provider.use deny now removes that provider's integration from the registry /connect reads, and the integration catalog reloads when config or organization-managed policy changes. Integrations registered under their own id — the OAuth integration a remote MCP server registers, for example — are left to integration.use, so a provider allowlist does not hide them from the dialog.
Covered by three tests in packages/core/test/config/policy.test.ts: removal under a wildcard deny with one allow, restoration when the deny is lifted, and the reload path. The change also updates specs/v2/provider-policy.md, which documents the hosted:<integration ID> resource of integration.use that nothing implements yet — worth deciding whether that should be the surface for this instead.
Reproduces on 2.1.0 (current npm latest), so this is still present after the latest release.
Setup: config uses the v2 policies surface (provider.use deny *, allow llama-local and opencode). opencode models correctly lists only the allowed providers, but /connect →
"Connect an integration" still lists every integration (OpenAI, GitHub Copilot, Bedrock, Azure,
Cloudflare, DigitalOcean, GitLab, Console, ...). So the provider catalog is filtered, while the
integration registry behind /api/integration is not.
The fix for this is already written and verified: #54186 by @argszero. It was closed on 2026-10-20
for a non-technical reason — GitHub's limit of 3 open PRs for contributors without write access.
The author wrote: "Closing this to stay within GitHub's 3-open-pull-request limit ... The branch
remains on my fork, so I can reopen it on request."
Could a maintainer reopen and merge it (or take over the branch)? The change applies the same provider.use statements to the integration registry that /connect reads, and leaves
integrations registered under their own id (e.g. remote MCP OAuth) governed by integration.use.
Environment: OpenCode 2.1.0, Ubuntu 24.04 on WSL2.
Still reproduces on 2.1.4 (managed /etc/opencode/opencode.json, Linux).
Setup: provider.use deny * + allow ai-gateway (a custom AISDK provider, file:///opt/ai-gateway-provider). /connect still lists every integration.
The "Popular" group should also disappear when only custom providers are allowed. Today it keeps showing "OpenCode Console" (and the other popular providers) even though policy denies them. The Popular category is hard-coded in the TUI (opencode-go, opencode, openai, github-copilot, anthropic, google), so it is not affected by enabled_providers, disabled_providers or provider.use policies. An organisation that locks users to one gateway cannot hide it through config.
Workaround we use to get most of the way there: negate the built-in plugins individually (-opencode.models.dev, -opencode.websearch.* and 32 -opencode.provider.* entries). Caveats:
-opencode.provider.* also disables opencode.provider.dynamic, which breaks custom AISDK providers (No AISDK provider plugin returned an SDK), so every plugin has to be listed by name.
"OpenCode Console" stays visible anyway. disabled_providers: ["opencode"] and enabled_providers: ["ai-gateway"] don't hide it, and a plugin calling store.remove("opencode") on the integration store seemed to break the session (Model unavailable).
Questions:
Is there a supported config option to hide the OpenCode Console / Popular entries?
Activity
opencode-agent commentedon Oct 9, 2026
Thanks for the clear report. I could reproduce this on 2.0.26, and it still happens on the latest
v2branch (5cfe3b4).What I did:
mycompany, via@ai-sdk/openai-compatible) and setenabled_providers: ["mycompany"]./connect.The Connect an integration dialog still listed OpenCode Console, openai, github-copilot, amazon-bedrock, azure, the Cloudflare providers, digitalocean, gitlab and others, and searching "openai" found it. The recording and screenshots below show it, and the script below reproduces it.
It looks like
enabled_providersis applied to the provider list but not to the list of integrations that/connectshows. I didn't check whether connecting a provider outside the allowlist makes its models usable.Related:
enabled_providerslist are not being respected #36819: v2/modelsshowing providers outsideenabled_providers(closed after 60 days of inactivity)experimental.policiesnot enforced for model selection or LLM execution #34971:experimental.policiesnot enforced for model listing or use (closed after 60 days of inactivity)recording.mp4
Reproduction script (drive.ts)
Run it with opencode-drive:
opencode-drive run ./drive.ts. It drivesopencodefrom yourPATH; setOC_DEVto the path of an OpenCode checkout to run that from source instead.argszero commentedon Oct 9, 2026
I'd like to work on this.
I traced where the two lists diverge, and the gap matches your report exactly.
enabled_providersis normalized intoexperimental.policiesasprovider.useallow/deny entries (packages/core/src/config/normalize.ts), and those are then applied inpackages/core/src/config/plugin/policy.ts:That transform only visits the provider catalog. The
/connectdialog is fed by a different registry —Integration.Service.list()viaserver.integrationintegration.list— and nothing applies the policy to it, so every integration keeps showing up regardless ofenabled_providers.The two registries already line up by id:
packages/core/src/config/plugin/provider.tstreats a configured provider's id as its integration id (const integrationID = id) and callsctx.integration.transform(...), so the same plugin context can also trim the integration registry. The plan is to extend the policy plugin to remove denied integrations the same way it removes denied providers, so a restricted allowlist shows only allowlisted integrations in/connect.I have a checkout of
v2at the commit the bot tested, so I can verify the dialog and add a test on the config policy path. If you would rather the integration registry stay untouched and the filtering happen at the server endpoint instead, say so and I will follow that.argszero commentedon Oct 9, 2026
Opened #54186 for this.
The fix applies provider policy to the integration registry as well: a
provider.usedeny now removes that provider's integration from the registry/connectreads, and the integration catalog reloads when config or organization-managed policy changes. Integrations registered under their own id — the OAuth integration a remote MCP server registers, for example — are left tointegration.use, so a provider allowlist does not hide them from the dialog.Covered by three tests in
packages/core/test/config/policy.test.ts: removal under a wildcard deny with one allow, restoration when the deny is lifted, and the reload path. The change also updatesspecs/v2/provider-policy.md, which documents thehosted:<integration ID>resource ofintegration.usethat nothing implements yet — worth deciding whether that should be the surface for this instead.rshibanov commentedon Oct 20, 2026
Reproduces on 2.1.0 (current npm
latest), so this is still present after the latest release.Setup: config uses the v2
policiessurface (provider.usedeny*, allowllama-localandopencode).opencode modelscorrectly lists only the allowed providers, but/connect→"Connect an integration" still lists every integration (OpenAI, GitHub Copilot, Bedrock, Azure,
Cloudflare, DigitalOcean, GitLab, Console, ...). So the provider catalog is filtered, while the
integration registry behind
/api/integrationis not.The fix for this is already written and verified: #54186 by @argszero. It was closed on 2026-10-20
for a non-technical reason — GitHub's limit of 3 open PRs for contributors without write access.
The author wrote: "Closing this to stay within GitHub's 3-open-pull-request limit ... The branch
remains on my fork, so I can reopen it on request."
Could a maintainer reopen and merge it (or take over the branch)? The change applies the same
provider.usestatements to the integration registry that/connectreads, and leavesintegrations registered under their own id (e.g. remote MCP OAuth) governed by
integration.use.Environment: OpenCode 2.1.0, Ubuntu 24.04 on WSL2.
dennisrutjes-1 commentedon Oct 26, 2026
Still reproduces on 2.1.4 (managed
/etc/opencode/opencode.json, Linux).Setup:
provider.usedeny*+ allowai-gateway(a custom AISDK provider,file:///opt/ai-gateway-provider)./connectstill lists every integration.The "Popular" group should also disappear when only custom providers are allowed. Today it keeps showing "OpenCode Console" (and the other popular providers) even though policy denies them. The
Popularcategory is hard-coded in the TUI (opencode-go,opencode,openai,github-copilot,anthropic,google), so it is not affected byenabled_providers,disabled_providersorprovider.usepolicies. An organisation that locks users to one gateway cannot hide it through config.Workaround we use to get most of the way there: negate the built-in plugins individually (
-opencode.models.dev,-opencode.websearch.*and 32-opencode.provider.*entries). Caveats:-opencode.provider.*also disablesopencode.provider.dynamic, which breaks custom AISDK providers (No AISDK provider plugin returned an SDK), so every plugin has to be listed by name.disabled_providers: ["opencode"]andenabled_providers: ["ai-gateway"]don't hide it, and a plugin callingstore.remove("opencode")on the integration store seemed to break the session (Model unavailable).Questions:
/connect.DocMAX commentedon Oct 31, 2026
Let AI fix it, what are you waiting for?!