Skip to content

Warn when a Bash(rtk:*) allow rule is present #4649

Open

Description

@KuSh

Summary

A Bash(rtk:*) (or Bash(rtk *)) allow rule in a Claude Code settings file allows every command rtk can run, which is far more than it reads like. rtk init and rtk verify should warn when one is present.

What the rule grants

Agents that write the rtk prefix themselves get a prompt for every such command, and Bash(rtk:*) is the obvious way to silence those prompts. Once #3970 is fixed, the rule keeps granting rtk's own commands (rtk gain, rtk discover) and every command rtk filters, while deny and ask rules for the command behind the prefix still apply. Even so, a filtered command that no ask rule names, such as rtk git push, runs without a prompt, even though the user never allowed git push.

Proposal

When a loaded settings file holds a Bash(...) allow rule that matches every rtk … command, rtk init (install and upgrade) and rtk verify print a warning naming the file and the rule, for example:

warning: Bash(rtk:*) in ~/.claude/settings.json allows every command rtk filters, including `rtk git push`.
         Deny and ask rules for those tools still apply. Consider narrower rules such as Bash(rtk git status:*).

The hook itself stays silent: its stdout is the protocol with the host, and a warning on every call would be noise.

Related

Activity

  1. rtk-wshm-sync-bot commented on Oct 18, 2026

    @rtk-wshm-sync-bot

    wshm · Automated triage by AI

    🔍 Automated Triage

    ✨ Category feature
    🟡 Priority medium
    🎯 Confidence 82%

    Summary

    Request to warn on overly broad Bash(rtk:*) allow rules in rtk init/verify, since they silently grant all rtk-filtered commands despite deny/ask rules intending to restrict them.

    📁 Relevant files
    • src/init/mod.rs
    • src/hook/verify.rs
    • src/discover/registry.rs

    Suggested Actions

    1. Coordinate with Permission verdict is computed on a command that is not the one that runs — a model-authored rtk prefix escapes the host allowlist #3970 (rtk-prefix verdict) and fix(hooks): honor permission rules for already-rtk-prefixed commands #3195 (fix under review) before implementing the warning
    2. Reuse settings-file parsing from fix(uninstall): strip stale rtk permission rules from settings.json #4128 (uninstall cleanup of Bash(rtk …) rules) for detecting the rule
    3. Define the exact match logic for 'allow rule matches every rtk … command' across Bash(rtk:*) and Bash(rtk *) syntaxes
    4. Add warning output to both rtk init (install/upgrade) and rtk verify per the proposed message format

    Triaged automatically by wshm · This is an automated analysis, not a human review.

  2. xiaozou-second commented on Oct 21, 2026

    @xiaozou-second

    I'd like to take this one.

    Plan. rtk init (install and upgrade) and rtk verify print a one-line stderr warning naming the rule and the settings file whenever a loaded Bash(...) allow rule reduces to the bare command name — Bash(rtk:*), Bash(rtk *), Bash(rtk), Bash(*rtk*). The hook path (rtk hook <agent>, rtk rewrite) stays silent, as you ask. --dry-run and init --show stay silent too; the warning is an advisory at the point the user can act on it.

    Two readings I'd like settled before opening the PR, since the issue says "matches every rtk … command":

    • Bash(*) — grants every command rtk filters, but it isn't rtk-specific, and "consider narrower rules such as Bash(rtk git status:*)" is misleading advice for someone who deliberately allowed everything. I lean towards not flagging it.
    • Bash(rtk git:*) — covers rtk git push but not rtk cargo test. The literal wording says it does not match every rtk command, so I lean towards not flagging it either. Flagging it would catch the headline risk but the message would overstate what the rule grants.

    A prefix test on the pattern (strip Bash(, ), then */:/whitespace, compare to rtk) gets both readings without a glob matcher, and keeps Bash(rtk git push) — the example the warning itself names — out of the warning.

    On the premise: #3970 and #3195 are both still open, so the warning's wording describes the exposure as it stands today rather than after a fix. Happy to hedge the text if you'd rather it read that way.

    ~80 lines including unit tests for both spellings. Will link the PR here once it's up.

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