Skip to content

Globally configurable allowed tools #179

Description

@timtatt

Describe the feature or problem you'd like to solve

Globally allowed tools within config.json

Proposed solution

Similar to Claude Code, allowing permitted tools to be configurable at the global level.

eg. from Claude ~/.claude/settings.json

{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test:*)",
      "Read(~/.zshrc)"
    ],
    "deny": [
      "Bash(curl:*)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

This configuration will be used by every instance of Copilot CLI started

Example prompts or workflows

I may want to make certain CLI commands available in every session (without needing to specify with CLI flags) eg.

npm:*
go:*
git:diff:*
git:log:*

Additional context

No response

Activity

added theissue type on Oct 2, 2025
changed the title [-]Globally Allowed Tools[/-] [+]Globally configurable allowed tools[/+] on Oct 2, 2025

laeubi commented on Nov 17, 2025

@laeubi

Yes it would be great, as it works for directories already to allow copilot to (permanently) add a directory it should be possible to allow it permanently to run a given tool!

TWiStErRob commented on Jan 15, 2026

@TWiStErRob

It's hack time:

alias copilot="copilot --allow-tool 'shell(npm:*)' --allow-tool 'shell(go:*)' --allow-tool 'shell(git:diff:*)' --allow-tool 'shell(git:log:*)'"
added
area:permissionsTool approval, security boundaries, sandbox mode, and directory restrictions
area:configurationConfig files, instruction files, settings, and environment variables
and removed on Apr 16, 2026

antonech commented on Jun 30, 2026

@antonech

+1. The per-launch --allow-tool flag and the per-location permissions-config.json both fall short for a common case: a self-hosted MCP server whose tools I trust in every repo.

With todays options I either:

  • repeat --allow-tool 'my-mcp()' on every launch (only persists via a shell alias/wrapper), or
  • duplicate the same tool_approvals block under each repo key in permissions-config.json (keyed by exact repo root, no wildcard, so it never covers a new repo).

A persisted, location-independent allow list would solve this. The existing --allow-tool grammar already expresses it cleanly, so the config could reuse it, e.g.:

// ~/.copilot/settings.json
{
  "permissions": {
    "allow": ["my-mcp()", "my-mcp(some_tool)", "shell(git:diff:*)"],
    "deny":  ["shell(curl:*)"]
  }
}

where my-mcp() = all tools of that MCP server (mirroring <mcp-server-name>(tool-name?) from copilot help permissions). Denials should keep precedence, as they do for the flags today.

kvnloo commented on Sep 27, 2026

@kvnloo

I think the important part here is defining the permission lattice before adding another config surface.

A predictable precedence could be:

deny > repo deny > global deny > explicit session allow > repo allow > global allow > ask

Whatever ordering is chosen, it should be deterministic and visible through something like /permissions explain <tool-call>.

I would also normalize MCP permissions on stable (server, tool) identity rather than display name, so reconnects or renamed UI labels cannot change authority accidentally.

A small table-driven test covering conflicting global/repo/session rules would probably prevent a lot of future permission drift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:configurationConfig files, instruction files, settings, and environment variablesarea:permissionsTool approval, security boundaries, sandbox mode, and directory restrictions

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions