fix(plugins): allowlist bundled provider discovery#77194
Conversation
|
Codex review: needs maintainer review before merge. Summary Reproducibility: yes. Source inspection on current main shows bundled provider setup discovery and compat helpers can widen restrictive plugin allowlists before activation, while the PR adds targeted regression coverage for the intended policy. Next step before merge Security Review detailsBest possible solution: Review and land this PR if maintainers approve the Do we have a high-confidence way to reproduce the issue? Yes. Source inspection on current main shows bundled provider setup discovery and compat helpers can widen restrictive plugin allowlists before activation, while the PR adds targeted regression coverage for the intended policy. Is this the best way to solve the issue? Yes, subject to maintainer policy approval. The latest diff keeps the change localized to provider discovery/compat helpers, schema/docs, doctor migration, and regression tests, and it addresses the prior alias-normalization and master-toggle edge cases. What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against f8e080386d8b. Re-review progress:
|
a4ee232 to
b705cf2
Compare
Addresses review feedback: adds bundledMode to the strict plugins zod object so the config option passes validation, and adds schema.help documentation for the field.
…llowlist When plugins.bundledMode is set to "respect-allow", runtime provider discovery paths honor plugins.allow for bundled plugins instead of force-loading all providers. Default "compat" preserves existing behavior. Closes #75575
d9dba65 to
9f41a7e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9f41a7e26c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const allowedPluginIds = new Set(allow.map((pluginId) => pluginId.trim()).filter(Boolean)); | ||
| return pluginIds.filter((pluginId) => allowedPluginIds.has(pluginId)); |
There was a problem hiding this comment.
Normalize allowlist aliases before filtering providers
When plugins.allow contains a supported legacy/provider alias such as google-gemini-cli or minimax-portal, this raw set does not match the actual bundled plugin id (google, minimax). The normal plugin config path already normalizes allowlist entries through the plugin-id resolver, but this new public-artifact filter runs before that, so allowlist-mode web search/fetch inventories can disappear on the fast path even though the same config is accepted elsewhere. Please normalize these allow entries with the same plugin-id rules before filtering.
Useful? React with 👍 / 👎.
| if (allowSet && !allowSet.has(pluginId)) { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
Avoid re-enabling plugins after allowlist rejection
When plugins.enabled is false and allowlist mode filters out every requested bundled provider here, changed remains false but the later forcePluginsEnabled branch still returns a config with plugins.enabled: true. Provider hook/runtime compat calls can hit this with a restrictive plugins.allow that omits bundled providers, which re-enables globally disabled plugin loading even though no compat plugin was admitted. Keep the original config when no allowed entries were added, or only force-enable after at least one requested plugin survives the allowlist.
Useful? React with 👍 / 👎.
|
Maintainer triage update:
Current blocker list matches the ClawSweeper review and is narrow:
After those are fixed, update the body from |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c6d811eb8f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const allowSet = | ||
| !useCompatDiscovery && Array.isArray(allow) && allow.length > 0 ? new Set(allow) : undefined; |
There was a problem hiding this comment.
Normalize allow aliases before gating compat enablement
When plugins.enabled is false and plugins.allow contains a supported legacy/provider alias such as google-gemini-cli or minimax-portal, this raw set does not match the bundled plugin id passed in pluginIds (google, minimax). The same commit normalizes allow entries in web-provider-public-artifacts.ts, and normalizePluginsConfig accepts these aliases elsewhere, but this gate treats the compat plugin as ineligible and leaves plugins globally disabled, so provider hook/runtime compat cannot load the allowed bundled provider.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2c92b0aa2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } else if (!params.shouldFilterBundledByAllowlist) { | ||
| return true; |
There was a problem hiding this comment.
Limit compat bypass to bundled providers
When plugins.bundledDiscovery is "compat", this branch returns true for every non-workspace provider plugin, including global and config origins from PluginOrigin. Migrated configs with a restrictive plugins.allow therefore still discover omitted third-party/global provider plugins even though the new mode is documented and named as a bundled-provider compatibility escape hatch; keep the bypass to plugin.origin === "bundled" and let other origins continue through the base allow/deny policy.
Useful? React with 👍 / 👎.
| const allowedPluginIds = new Set( | ||
| allow.map((pluginId) => normalizePluginId(pluginId)).filter(Boolean), | ||
| ); | ||
| return pluginIds.filter((pluginId) => allowedPluginIds.has(pluginId)); |
There was a problem hiding this comment.
Apply deny and disabled-entry policy to public artifacts
When a bundled web provider is present in plugins.allow but also explicitly disabled with plugins.entries.<id>.enabled = false or blocked by plugins.deny, this filter still returns it because it only checks the allowlist before the public-artifact fast path returns providers. The loader fallback goes through passesManifestOwnerBasePolicy and would block those entries, so web_search/web_fetch can expose a provider the operator explicitly disabled whenever public artifacts are available; apply the same deny/entry policy before accepting the candidate.
Useful? React with 👍 / 👎.
|
Landed via rebase onto
|
|
Replaced this with a squashed branch on current This PR's visible head ref was detached from the recreated branch, so GitHub would not let me update |
|
Correction: this had already merged while I was trying to rewrite the detached head ref. #77569 was opened as a fallback replacement, but I closed it as stale once I confirmed this PR is the canonical merged one. Canonical merge: |
Summary
plugins.allowby default for fresh/new configs; omitted bundled provider plugins no longer appear in setup/runtime/web-search inventory unless allowed.plugins.allowconfigs with no explicitplugins.bundledDiscoveryget stamped as"compat", preserving upgrade behavior until the operator opts into"allowlist".compatbehavior explicit across provider setup/runtime activation and public-artifact web provider fallback, while keeping empty allowlists open.Verification
pnpm test src/plugins/providers.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/plugins/web-search-providers.runtime.test.ts src/plugins/web-provider-public-artifacts.fallback.test.ts src/commands/doctor/shared/plugin-tool-allowlist-warnings.test.ts src/commands/doctor/shared/legacy-config-migrate.test.ts src/commands/doctor-config-flow.test.ts src/config/schema.help.quality.test.ts src/config/schema.base.generated.test.tspnpm config:schema:checkpnpm config:docs:checkpnpm format:docs:checkpnpm exec oxfmt --check --threads=1 src/plugins/activation-context.ts src/plugins/bundled-compat.ts src/plugins/providers.ts src/plugins/providers.test.ts src/plugins/web-provider-public-artifacts.ts src/plugins/web-search-providers.runtime.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/commands/doctor/shared/legacy-config-migrations.runtime.providers.ts src/commands/doctor/shared/legacy-config-migrate.test.ts src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts src/commands/doctor/shared/plugin-tool-allowlist-warnings.test.ts src/config/types.plugins.ts src/config/schema.help.ts src/config/schema.base.generated.tsgit diff --checkpnpm buildtbx_01kqtfemz7e4jz8b829j4z4pt1:pnpm check:changedFixes #75575.
Additional verification after PR rewrite on 2026-05-04
pnpm test src/plugins/web-provider-public-artifacts.fallback.test.ts src/plugins/web-search-providers.runtime.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/plugins/providers.test.tspnpm config:schema:checkpnpm config:docs:checkpnpm exec oxfmt --check --threads=1 src/plugins/web-provider-public-artifacts.ts src/plugins/web-provider-public-artifacts.fallback.test.ts src/plugins/bundled-compat.ts src/agents/models-config.providers.plugin-allowlist-compat.test.tsgit diff --checkAdditional verification after alias follow-up on 2026-05-04
pnpm test src/agents/models-config.providers.plugin-allowlist-compat.test.tspnpm test src/plugins/web-provider-public-artifacts.fallback.test.ts src/plugins/web-search-providers.runtime.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/plugins/providers.test.tspnpm exec oxfmt --check --threads=1 src/plugins/bundled-compat.ts src/agents/models-config.providers.plugin-allowlist-compat.test.tsgit diff --check