Skip to content

Filesystem-scoped permission authority and centrally managed repository rules #12226

Description

@VorlMaldor

What would you like to be added?

Add filesystem-scoped permission authority and centrally managed per-repository permission rules.

Permission configuration should be evaluated by the filesystem scope it governs. A repository-local .qwen configuration may govern only that repository directory and its descendants. It must not affect a parent directory, a sibling repository, or any other path outside its authority root.

Support centrally managed repository rules at both system and user scope. A system administrator should be able to assign policy to a specific repository from the system configuration. A user should be able to assign policy to a repository inside that user's home directory from user configuration.

Use this precedence order:

  1. Enforced system policy.
  2. System policy explicitly assigned to the repository.
  3. User policy explicitly assigned to the repository, only when the repository is inside that user's home directory.
  4. Repository-local or nested .qwen policy, constrained to that directory tree.
  5. User-wide policy, constrained to the user's home directory.
  6. General system defaults.
  7. Built-in defaults.

The first applicable scope owns the decision. Within the same authority and scope, keep the existing deny > ask > allow resolution.

System defaults should remain overridable. Enforced system policy and system policy explicitly assigned to a repository must not be overridable by user or repository configuration.

One possible central representation is:

{
  "permissions": {
    "repo": {
      "/workspace/project-a": {
        "allow": ["Edit(/**)", "Shell(git status)", "Shell(rg *)"]
      },
      "/workspace/project-b": {
        "ask": ["Edit(/**)", "Shell(*)"]
      }
    }
  }
}

Paths must be canonicalized before scope evaluation, including symlinks and ... Permission paths beginning with / should resolve relative to the configuration's authority root, not the host filesystem root. Repository-scoped ~/ expressions must not escape the repository authority root.

The /permissions output should show the winning rule, its source file, its authority root, and whether it is enforced.

For noninteractive execution, allow should execute, deny should refuse, and ask should refuse when no prompt can be shown.

Why is this needed?

The current flat merge rule makes a broader user-level ask override a repository-local allow, even when the local rule governs a narrower filesystem scope. That prevents a repository from declaring bounded automation permissions for its own tree and makes unattended repository workflows fail despite an explicit local policy.

At the same time, simply allowing every repository-local rule to override user or system policy would create a real trust problem. Filesystem-scoped authority resolves both concerns: local rules can control only their own subtree, while administrators and users retain central control through explicit repository assignments and enforced policy.

This also gives operators one managed location for repository policy without allowing repository configuration to affect upstream or unrelated paths.

Additional context

This supersedes #12223. The earlier proposal asked only for project-local rules to override broader user rules. This version incorporates the maintainers' concern about trust and makes the authority boundary explicit.

Compatibility proposal: treat existing system configuration as general system defaults unless a rule is explicitly marked enforced or explicitly assigned to a repository. Existing same-scope conflict behavior can remain deny > ask > allow.

Example outcome:

  • A user-wide ask: Edit(/**) applies generally inside the user's home.
  • A repository-local allow: Edit(/**) permits edits inside that repository only.
  • It grants no authority over the repository's parent, sibling repositories, or unrelated paths.
  • An enforced system denial still wins everywhere in its declared scope.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions