Skip to content

feat(execpolicy): add typed permission rules and config schema#1189

Closed
greyfreedom wants to merge 7 commits into
Hmbown:mainfrom
greyfreedom:feat/execpolicy-typed-rules
Closed

feat(execpolicy): add typed permission rules and config schema#1189
greyfreedom wants to merge 7 commits into
Hmbown:mainfrom
greyfreedom:feat/execpolicy-typed-rules

Conversation

@greyfreedom
Copy link
Copy Markdown
Contributor

@greyfreedom greyfreedom commented May 8, 2026

Summary

This PR adds the first slice of persistent permission rule support at the execpolicy and config layers.

It introduces typed permission rules scoped by tool name, optional command prefix, and optional workspace-relative path pattern, with allow, deny, and ask decisions.

This intentionally does not add TUI approval modal persistence yet. It provides the policy/config foundation for that follow-up work.

Changes

  • Added PermissionDecision:
    • allow
    • deny
    • ask
  • Added ToolPermissionRule with:
    • tool
    • decision
    • optional command
    • optional path
  • Extended Ruleset to carry typed permission rules.
  • Added ExecPolicyEngine::check_tool_permission.
  • Kept legacy auto_allow / auto_deny compatibility by converting them into exec_shell typed rules.
  • Reused existing bash arity matching for shell allow/ask rules.
  • Preserved deny-wins behavior.
  • Added workspace-relative path glob matching with . / .. normalization.
  • Added config support for:
auto_allow = ["git status"]
auto_deny = ["rm -rf"]

[[permissions.rules]]
tool = "exec_shell"
decision = "allow"
command = "cargo test"

[[permissions.rules]]
tool = "file_edit"
decision = "ask"
path = "src/**"
  • Wired app-server startup to build its exec policy engine from config.

Precedence

When multiple rules match, the engine resolves them by:

  1. decision precedence: deny > ask > allow
  2. ruleset layer
  3. rule specificity

This keeps deny rules conservative while allowing narrower ask rules to force approval over broader allow rules.

Compatibility

Existing auto_allow and auto_deny config entries continue to work. They are treated as legacy shell rules and mapped into typed exec_shell permission rules internally.

Tests

Added coverage for:

  • legacy auto_allow compatibility
  • bash arity behavior for legacy rules
  • deny winning over allow
  • ask winning over allow
  • ask forcing approval under OnFailure
  • workspace-relative path glob matching
  • path normalization for . / ..
  • tool-name-only rules for non-shell tools
  • config deserialization for permissions.rules
  • config-to-policy-engine construction

Verification

cargo fmt --all
cargo test -p deepseek-execpolicy -p deepseek-config -p deepseek-app-server -p deepseek-tui-cli
cargo clippy -p deepseek-execpolicy -p deepseek-config -p deepseek-app-server -p deepseek-tui-cli --all-targets -- -D warnings
git diff --check

Follow-up Work

  • Connect typed permission rules to the full TUI tool invocation approval path.
  • Add approval UI actions such as “always allow this pattern”.
  • Persist generated rules after user confirmation.
  • Add rule preview before saving broad patterns.

Related Issue

Part of #1186

This is the first PR in the proposed permission-rules implementation plan. It only adds the execpolicy/config typed rule model, matching behavior, precedence tests, and legacy auto_allow / auto_deny compatibility.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a granular tool permission system, replacing the legacy command allow-list with a more flexible ruleset. It adds support for typed permission rules (e.g., exec_shell, file_edit) with decisions including allow, deny, and ask. The ExecPolicyEngine has been refactored to support layered rulesets with priority and specificity matching for tool names, command prefixes, and workspace-relative path globs. Feedback highlights a bug in absolute path normalization and suggests using a standard crate for glob matching to improve security and maintainability.

Comment thread crates/execpolicy/src/lib.rs
Comment thread crates/execpolicy/src/lib.rs Outdated
@greyfreedom greyfreedom changed the title # feat(execpolicy): add typed permission rules and config schema feat(execpolicy): add typed permission rules and config schema May 8, 2026
@Hmbown
Copy link
Copy Markdown
Owner

Hmbown commented May 8, 2026

Thanks. I am not merging this as-is because the PR body says this is only the first slice and that TUI approval persistence is still follow-up work, but it also uses Fixes #1186.

That would close the issue before the user-facing permission workflow exists. Please change the closing keyword to Related/Part of, or split the issue so this PR closes only an execpolicy/config foundation issue. I would also want a closer pass on the config surface before this goes into a patch release, since permission rules affect tool execution policy.

@greyfreedom
Copy link
Copy Markdown
Contributor Author

Thanks. I am not merging this as-is because the PR body says this is only the first slice and that TUI approval persistence is still follow-up work, but it also uses Fixes #1186.

That would close the issue before the user-facing permission workflow exists. Please change the closing keyword to Related/Part of, or split the issue so this PR closes only an execpolicy/config foundation issue. I would also want a closer pass on the config surface before this goes into a patch release, since permission rules affect tool execution policy.

Thanks, that makes sense.

I updated the PR body to replace Fixes #1186 with Part of #1186.

I’m also happy to narrow or adjust the config surface before merge. The intended scope for this PR is only the typed rule model, config parsing, matching behavior, precedence, and legacy auto_allow / auto_deny compatibility. TUI approval persistence will stay as follow-up work.

@greyfreedom greyfreedom force-pushed the feat/execpolicy-typed-rules branch 4 times, most recently from a4a1c57 to a706ecd Compare May 11, 2026 02:10
@greyfreedom greyfreedom force-pushed the feat/execpolicy-typed-rules branch 3 times, most recently from c42082a to 4926d86 Compare May 14, 2026 02:41
@greyfreedom greyfreedom force-pushed the feat/execpolicy-typed-rules branch from ab0c80e to c9860bc Compare May 22, 2026 10:17
@Hmbown
Copy link
Copy Markdown
Owner

Hmbown commented May 23, 2026

This PR was opened before the v0.8.41 rebrand and is now stale. Feel free to rebase onto current main and reopen. 鲸鱼兄弟们等你 🐋

@greyfreedom
Copy link
Copy Markdown
Contributor Author

This PR was opened before the v0.8.41 rebrand and is now stale. Feel free to rebase onto current main and reopen. 鲸鱼兄弟们等你 🐋

Since I cannot reopen the current PR, I created a new PR #2046 .

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants