Article

How to preserve OpenCode access rules after the policy change

OpenCode 2.2.3 changes blanket integration rules. Identify what converts automatically, preserve extension restrictions and check the deployed version.

Editorial illustration for How to preserve OpenCode access rules after the policy change: a document represents the research briefing. Not documentary evidence.

OpenCode’s October 30, 2026 release changes what existing access rules control. Administrators and team owners using blanket integration policies should review them before upgrading: a rule that once restricted extensions can now restrict model providers and accounts instead. The v2.2.3 release notes identify this as a breaking change.

The affected rules use the action integration.use. A blanket rule now governs integrations and their accounts; MCP servers, skills and plugins have separate actions. MCP servers connect the coding agent to external tools, skills supply reusable instructions, and plugins extend its behavior. The migration matters to people maintaining these policies, not every OpenCode user.

Find rules that need more than automatic conversion

Inventory the policy sources you manage and save a copy before editing. Check device or system configuration, Console-delivered policies, and user or project files. Look under both policies and the older experimental.policies key, which the policy guide says still merges into it.

The 2.2.3 policy schema translates resources beginning with mcp:, skill: or plugin:. It preserves the allow or deny effect and removes that first prefix. The bare wildcard is different:

Old resource under integration.use

Decoded action

Decoded resource

mcp:github

mcp.use

github

skill:team:review

skill.use

team:review

plugin:*

plugin.use

*

*

integration.use

*

Review other unprefixed patterns for their intended scope too; do not apply a blind text replacement. An automatically converted exception can survive while its old blanket rule stops governing the same category.

In the released enforcement code, integration rules filter providers and web search, while MCP servers and skills have their own checks. An unchanged wildcard deny can therefore remove provider access without directly preserving those extension restrictions. Other policies or withheld remote configuration may still restrict extensions; this does not mean every tool becomes available.

Replace the blanket rule and preserve its exceptions

Consider a policy intended to deny all three extension categories except an MCP server configured as github. This illustrative fragment assumes the exception follows the broad deny at the same policy authority, with no other matching rules. It follows the documented migration and tagged schema; it is not a tested deployment configuration.

Before:

{
  "policies": [
    {"action": "integration.use", "resource": "*", "effect": "deny"},
    {"action": "integration.use", "resource": "mcp:github", "effect": "allow"}
  ]
}

After:

{
  "policies": [
    {"action": "mcp.use", "resource": "*", "effect": "deny"},
    {"action": "skill.use", "resource": "*", "effect": "deny"},
    {"action": "plugin.use", "resource": "*", "effect": "deny"},
    {"action": "mcp.use", "resource": "github", "effect": "allow"}
  ]
}

Here the old blanket rule is replaced, not retained alongside the new ones. Keeping it would also impose an integration-level deny. Retain that restriction only if account control is a separate, intentional requirement.

The matching implementation uses the last matching statement and defaults to allow when none matches. Put the broad deny before its exception and preserve the policy’s authority. The GitHub exception could retain its legacy prefixed spelling because it converts automatically; spelling out the new action makes the intended category clearer.

For a blanket allow, preserve the intended allow effect and precedence instead of copying this deny example. Review the complete rule list: conversion of individual statements is not proof that the combined policy still expresses the same decision.

Verify the deployed version before relying on the rules

There is an unresolved version-label mismatch. As checked on October 30, the live policy guide names 2.3.0 as the minimum version, but the published 2.2.3 release and its tagged schema already contain the change. The 2.2.2 schema lacks the new action names. Do not assume that every installation below 2.3.0 behaves alike, or send new rules to an unverified older server.

For rollout, use these acceptance checks on the actual serving installation:

  • Record the server version and all policy sources. Keep organization or device restrictions at their existing authority: the documented precedence puts managed and Console policy above user and project files.

  • Check one expected allow and one expected deny for each category you use: providers or accounts, MCP servers, skills and plugins. Include the exceptions that matter to daily work.

  • Inspect server logs after loading the policy. The validation guidance says invalid statements are dropped with a warning while other rules continue to apply. Successful startup alone is not an acceptance result.

If you are also moving from V1, treat plugin and integration compatibility as a separate task; see RohitAI’s OpenCode 2 upgrade guide.

Keep account access and extension access separate

The integration-policy design distinguishes integration.connect—which integrations can be listed and connected—from integration.use—which integration-supplied resources can be used. An account-backed resource includes the integration and account identifiers; without account metadata it uses a bare integration identifier. Allowing sign-in is therefore not the same as authorizing every account.

For administrators, the practical decision is twofold: choose the permitted account or provider route, then decide which extensions are allowed. One does not substitute for the other. The maintainer’s stated aim is to prevent accidental use of the wrong account, not deliberate bypass. Treat these as application policy controls, not a sandbox.