runok is a command permission tool for LLM coding agents.
📖 Documentation · 🚀 Quick Start · 🔧 Configuration · 📋 Recipes
Even with allow rules configured, Claude Code asks for confirmation in cases like these:
# Claude adds a comment before the command -- no longer matches your allow rule
⏺ Bash(# check logs
git log --oneline -5)
⎿ Running…
Command contains newlines that could separate multiple commands
Do you want to proceed?
❯ 1. Yes
2. No# Claude chains commands with && -- same problem
⏺ Bash(git log --oneline -5 && echo "---" && git status)
⎿ Running…
Command contains quoted characters in flag names
Do you want to proceed?
❯ 1. Yes
2. Norunok parses commands with tree-sitter-bash, so comments, compound commands (&&, |, ;), and wrapper commands (sudo, bash -c, xargs) are all handled correctly. Each sub-command is evaluated independently against your rules.
Flexible command parsing
tree-sitter-bashAST parsing -- comments, pipes,&&,;are understood, not treated as opaque stringssudo,bash -c,xargsare recursively unwrapped so rules apply to the inner command
Flexible rule configuration
- Wildcards, flag alternation (
-f|--force), optional groups, argument-order-independent matching - Conditional
whenclauses with CEL expressions for environment-aware decisions - OS-level sandboxing (macOS Seatbelt / Linux Landlock) for file and network restrictions
And more -- preset sharing, denial feedback, extension protocol, Claude Code plugin for natural-language configuration assistance
cargo install --git https://github.com/fohte/runok.gitPre-built binaries are also available on GitHub Releases. See Installation for details.
The fastest way to get started is with the interactive setup wizard:
runok initThis creates a runok.yml, and if you have Claude Code configured, migrates your Bash permissions to runok rules and registers the PreToolUse hook automatically.
You can also configure manually. Create ~/.config/runok/runok.yml:
rules:
- allow: 'git status'
- allow: 'git diff *'
- allow: 'git log *'
- ask: 'git push *'
- deny: 'git push -f|--force *'
message: 'Force push is not allowed'
defaults:
action: askAnd add runok as a PreToolUse hook in .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": ["runok check --input-format claude-code-hook"]
}
]
}
}See Claude Code Integration for sandbox setup and advanced configuration.
runok check -- git status # => allow
runok check -- git push -f main # => deny
runok check -- git push main # => askSee runok.fohte.net
Feature requests and bug reports are welcome on GitHub Issues.