Skip to content

fix(security): default to ask when no permission rule matches (#886)#981

Merged
aeppling merged 2 commits intodevelopfrom
fix/permission-default-ask
Apr 2, 2026
Merged

fix(security): default to ask when no permission rule matches (#886)#981
aeppling merged 2 commits intodevelopfrom
fix/permission-default-ask

Conversation

@pszymkowiak
Copy link
Copy Markdown
Collaborator

@pszymkowiak pszymkowiak commented Apr 2, 2026

Summary

Problem

Two related issues:

#886: RTK's PreToolUse hook auto-allowed every rewritten command that wasn't explicitly in a deny/ask list. This bypassed Claude Code's least-privilege default where unlisted commands should prompt for confirmation.

#893: In bypassPermissions mode, Claude Code discards updatedInput when permissionDecision is present. RTK rewrites were silently ignored.

Fix

Permission precedence is now: Deny > Ask > Allow (explicit) > Default (ask)

For Allow verdict, permissionDecision is omitted from hook output. This is equivalent to allow by default, AND fixes bypassPermissions mode where updatedInput was discarded.

Verdict When Hook output
Deny deny rule matched passthrough (no JSON)
Ask ask rule matched permissionDecision: "ask" + updatedInput
Allow explicit allow rule matched updatedInput only (no permissionDecision)
Default no rule matched permissionDecision: "ask" + updatedInput

Per-tool support

Tool ask support Behavior on Default
Claude Code Yes permissionDecision: "ask" — user prompted
Copilot VS Code Yes permissionDecision: "ask" — user prompted
Gemini CLI No (allow/deny only) allow (limitation — no ask mode)

Files changed

  • src/hooks/permissions.rs — load allow rules, add Default variant, 7 new tests
  • src/hooks/rewrite_cmd.rs — treat Default same as Ask (exit 3)
  • src/hooks/hook_cmd.rs — permission checks for Copilot VS Code + Gemini deny + omit permissionDecision on Allow
  • src/hooks/README.md — document permission precedence model
  • .claude/hooks/rtk-rewrite.sh — omit permissionDecision on Allow, add "ask" on exit 3

Test plan

  • cargo fmt --all — clean
  • cargo clippy --all-targets — no new warnings
  • cargo test permissions — 30 tests passed (7 new)
  • cargo test hook_cmd — 14 tests passed

Fixes #886
Fixes #893

Previously, commands not in any deny/ask list were auto-allowed. This
bypassed Claude Code's least-privilege default where unlisted commands
should prompt the user for confirmation.

Permission precedence is now: Deny > Ask > Allow (explicit) > Default (ask).

Changes:
- permissions.rs: load allow rules from settings.json, add Default variant
- rewrite_cmd.rs: treat Default same as Ask (exit 3)
- hook_cmd.rs: add permission checks to Copilot VS Code hook (ask/allow/deny),
  add deny check to Gemini hook (no ask mode available in Gemini CLI)

Gemini CLI limitation: only supports allow/deny, no ask mode. Codex: ask
is parsed but fails open. These tools document the limitation.

Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
@aeppling
Copy link
Copy Markdown
Contributor

aeppling commented Apr 2, 2026

Hey,

Fix is correct and ready to go, just one thing, for the flow documentation (deny->allow->ask) , this should be documented in the root README.md of the hook folder.

This is to be conform with how we document code, in the incoming coding practice, comment will only be used to specify edge case or issue fix, for the core documentation it goes in respective README.md of affected feature.

Once this is done we can merge

Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
@aeppling
Copy link
Copy Markdown
Contributor

aeppling commented Apr 2, 2026

go

@aeppling aeppling merged commit 158c745 into develop Apr 2, 2026
10 checks passed
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.

2 participants