diff --git a/services/www/src/docs/content/config.mdx b/services/www/src/docs/content/config.mdx index 54c1896dbbe..749218a592e 100644 --- a/services/www/src/docs/content/config.mdx +++ b/services/www/src/docs/content/config.mdx @@ -218,8 +218,9 @@ See the [permissions guide](/permissions) for rule matching and available action ### Policies -Allow or deny use of a provider, or hard-deny a permission check, with ordered -statements that broader configuration can override. +Allow or deny use of a provider, hard-deny a permission check, or block an MCP +server, skill, or plugin, with ordered statements that broader configuration can +override. ```jsonc { @@ -227,7 +228,7 @@ statements that broader configuration can override. "policies": [ { "action": "provider.use", "resource": "*", "effect": "deny" }, { "action": "provider.use", "resource": "anthropic", "effect": "allow" }, - { "action": "permission", "resource": "shell:git push *", "effect": "deny" }, + { "action": "tool.use", "resource": "shell:git push *", "effect": "deny" }, ], }, } diff --git a/services/www/src/docs/content/permissions.mdx b/services/www/src/docs/content/permissions.mdx index a8e540213c3..a91ed74689e 100644 --- a/services/www/src/docs/content/permissions.mdx +++ b/services/www/src/docs/content/permissions.mdx @@ -286,7 +286,7 @@ approvals run. It turns `allow` or `ask` into `deny` and never grants access. ```jsonc { "experimental": { - "policies": [{ "action": "permission", "resource": "shell:sudo *", "effect": "deny" }], + "policies": [{ "action": "tool.use", "resource": "shell:sudo *", "effect": "deny" }], }, } ``` diff --git a/services/www/src/docs/content/policies.mdx b/services/www/src/docs/content/policies.mdx index 571d810d577..d76272381ce 100644 --- a/services/www/src/docs/content/policies.mdx +++ b/services/www/src/docs/content/policies.mdx @@ -31,11 +31,11 @@ valid credentials. Each statement has three fields: -| Field | Values | Meaning | -| ---------- | ---------------------------- | ---------------------------------------------------- | -| `action` | `provider.use`, `permission` | The operation being controlled | -| `resource` | string or wildcard pattern | What the statement applies to; depends on the action | -| `effect` | `allow`, `deny` | The decision when this statement matches | +| Field | Values | Meaning | +| ---------- | --------------------------------------------- | ---------------------------------------------------- | +| `action` | `provider.use`, `tool.use`, `integration.use` | The operation being controlled | +| `resource` | string or wildcard pattern | What the statement applies to; depends on the action | +| `effect` | `allow`, `deny` | The decision when this statement matches | Statements that fail validation are dropped with a warning in the server log and the rest of the list still applies. Check the log after editing a `deny`. @@ -106,18 +106,18 @@ Use `provider.use` instead of the V1 `enabled_providers` and `disabled_providers lists. V1 files still load; see [Migrate from V1](/migrate-v1#supported-fields-without-direct-native-equivalents). -## Permissions +## Tools -`permission` statements hard-deny a [permission](/permissions) check. The resource is +`tool.use` statements hard-deny a [permission](/permissions) check. The resource is `:`, matched against every resource the tool checks. ```jsonc { "experimental": { "policies": [ - { "action": "permission", "resource": "shell:git push *", "effect": "deny" }, - { "action": "permission", "resource": "edit:*.env", "effect": "deny" }, - { "action": "permission", "resource": "webfetch:*", "effect": "deny" }, + { "action": "tool.use", "resource": "shell:git push *", "effect": "deny" }, + { "action": "tool.use", "resource": "edit:*.env", "effect": "deny" }, + { "action": "tool.use", "resource": "webfetch:*", "effect": "deny" }, ], }, } @@ -136,15 +136,15 @@ applies after agent rules and saved approvals, so it overrides an `ask` and an | `github_delete_repository:*` | One MCP tool | | `*` | Everything not already denied | -A `permission` statement with `allow` never grants access. It only lifts an earlier +A `tool.use` statement with `allow` never grants access. It only lifts an earlier broader `deny`, after which the agent's own rules decide. ```jsonc { "experimental": { "policies": [ - { "action": "permission", "resource": "shell:*", "effect": "deny" }, - { "action": "permission", "resource": "shell:git status *", "effect": "allow" }, + { "action": "tool.use", "resource": "shell:*", "effect": "deny" }, + { "action": "tool.use", "resource": "shell:git status *", "effect": "allow" }, ], }, } @@ -152,6 +152,32 @@ broader `deny`, after which the agent's own rules decide. `git status` falls back to the agent's `shell` rule; every other command is blocked. +## Integrations + +`integration.use` controls whether an MCP server, skill, or plugin is loaded. The +resource is the integration kind and its ID: + +| Resource | Applies to | +| ----------------- | ----------------------------------------------------------------- | +| `mcp:` | An [MCP server](/mcp-servers) by its configured name | +| `skill:` | A [skill](/skills) by its ID | +| `plugin:` | A [plugin](/plugins) by unversioned package name or absolute path | + +```jsonc +{ + "experimental": { + "policies": [ + { "action": "integration.use", "resource": "mcp:*", "effect": "deny" }, + { "action": "integration.use", "resource": "mcp:github", "effect": "allow" }, + { "action": "integration.use", "resource": "plugin:opencode-acme-cli", "effect": "deny" }, + ], + }, +} +``` + +A denied MCP server or skill is removed, and a denied plugin is not loaded, however +it was configured. + ## Precedence Ordinary settings let the nearest configuration win. Policies reverse that: statements