nah: A context-aware permission guard for Claude Code (and LLM agents)
Technical Positioning
A safer, more scalable, and context-aware alternative to basic allow-or-deny permission systems for LLM agents, preventing dangerous actions without nuking untracked files or exfiltrating keys.
SaaS Insight & Market Implications
The "nah" project addresses a critical and emerging pain point in the rapidly evolving landscape of AI agent development, specifically concerning the security and control of autonomous LLM-powered tools like Claude Code. As LLMs transition from conversational interfaces to active agents capable of executing code and interacting with system resources, the need for robust, context-aware permission systems becomes paramount. Current approaches, often limited to simple allow-or-deny lists per tool, are proving unscalable and insufficient, leading to a dilemma where developers either risk dangerous actions or severely cripple agent capabilities. "nah" represents a significant step forward by introducing a "PreToolUse hook" that deterministically classifies agent actions into granular "action types" (e.g., filesystem_read, git_history_rewrite). This allows for the application of sophisticated, context-dependent policies (allow, context, ask, block), moving beyond the "fool's errand" of maintaining static deny lists. Developers care deeply about this because it directly tackles the inherent tension between agent autonomy and system security. It enables them to deploy powerful AI agents with confidence, mitigating risks like data exfiltration or malware installation, while still allowing for necessary operations under controlled conditions. This tool signifies a broader trend towards "agent safety" and "AI guardrails" as a distinct and crucial layer in the AI development stack. It highlights the market's demand for specialized tooling that bridges the gap between LLM capabilities and enterprise-grade security requirements. The shift from coarse-grained, static permissions to dynamic, context-aware policy enforcement is a key innovation, reflecting a maturing understanding of how to build reliable and trustworthy autonomous systems. "nah" positions itself as an essential component for any organization building or deploying LLM agents, ensuring operational safety without sacrificing the agent's utility.
Proprietary Technical Taxonomy
context-aware permission guardPreToolUse hookdeterministic classifierallow-or-deny per toolaction typesgit_history_rewrite
Raw Developer Origin & Technical Request
Hacker News
Mar 13, 2026
Show HN: A context-aware permission guard for Claude Code
We needed something like --dangerously-skip-permissions that doesn’t nuke your untracked files, exfiltrate your keys, or install malware.Claude Code's permission system is allow-or-deny per tool, but that doesn’t really scale. Deleting some files is fine sometimes. And git checkout is sometimes not fine. Even when you curate permissions, 200 IQ Opus can find a way around it. Maintaining a deny list is a fool's errand.nah is a PreToolUse hook that classifies every tool call by what it actually does, using a deterministic classifier that runs in milliseconds. It maps commands to action types like filesystem_read, package_run, db_write, git_history_rewrite, and applies policies: allow, context (depends on the target), ask, or block.Not everything can be classified, so you can optionally escalate ambiguous stuff to an LLM, but that’s not required. Anything unresolved you can approve, and configure the taxonomy so you don’t get asked again.It works out of the box with sane defaults, no config needed. But you can customize it fully if you want to.No dependencies, stdlib Python, MIT.pip install nah && nah installgithub.com/manuelschipper/na...
The deny list problem is real but I think the harder issue is that context matters so much. Deleting a temp file and deleting a config file look the same to a classifier.We've been approaching it from the policy side, define what the agent is allowed to do upfront and evaluate each action before it runs. Human approval for anything that falls outside the policy. Different tradeoffs but same underlying frustration.
dns_snek
• Mar 12, 2026
This is not criticism of your project specifically, but a question for all tools in this space: What's stopping your agent from overwriting an arbitrary source file (e.g. index.js) with arbitrary code and running it?A rogue agent doesn't need to run `rm -rf /`, it just needs to include a sneaky `runInShell('rm -rf /')` in ANY of your source code files and get it to run using `npm test`. Both of those actions will be allowed on the vast majority of developer machines without further confirmation. You need to review every line of code changed before the agent is allowed to execute it for this to work and that's clearly not how most people work with agents.I can see value in projects like this to protect against accidental oopsies and making a mess by accident, but I think that marketing tools like this as security tools is irresponsible - you need real isolation using containers or VMs.Here's one more example showing you why blacklisting doesn't work, it doesn't matter how fancy you try to make it because you're fighting a battle that you can't win - there are effectively an infinite number of programs, flags, environment variables and config files that can be combined in a way to execute arbitrary commands: bash> nah test "PAGER='/bin/sh -c \"touch ~/OOPS\"' git help config" Command: PAGER='/bin/sh -c "touch ~/OOPS"' git help config Stages: [1] git help config → git_safe → allow → allow (git_safe → allow) Decision: ALLOW Reason: git_safe → allow Alternatively: bash> nah test "git difftool -y -x 'touch ~/OOPS2' --no-index /etc/hostname /etc/hosts" Command: git difftool -y -x 'touch ~/OOPS2' --no-index /etc/hostname /etc/hosts Stages: [1] git difftool -y -x touch ~/OOPS2 --no-index /etc/hostname /etc/hosts → git_safe → allow → allow (git_safe → allow) Decision: ALLOW Reason: git_safe → allow
felix9527
• Mar 12, 2026
Interesting approach to the PreToolUse side. I've been building on the other end — PostToolUse hooks that commit every tool call to an append-only Merkle tree (RFC 6962 transparency log style). The two concerns are complementary: "nah" answers "should this action be allowed?" while a transparency log answers "can we prove what actually happened, after the fact?" For the adversarial cases people are raising (obfuscated commands, indirect execution) — even if a classifier misses something at pre-execution time, an append-only log with inclusion proofs means the action is still cryptographically recorded. You can't quietly delete the embarrassing entries later. The hooks ecosystem is becoming genuinely useful. PreToolUse for policy enforcement, PostToolUse for audit trail, SessionStart/End for lifecycle tracking. Would be great to see these compose — a guard that also commits its allow/deny decisions to a verifiable log.
netcoyote
• Mar 12, 2026
As binwiederhier mentioned, we're all solving the same problems in different ways. There are now enough AI sandboxing projects (including mine: sandvault and clodpod) that I started a list: https://github.com/webcoyote/awesome-AI-sandbox
visarga
• Mar 12, 2026
It helps but a LLM could still code a destructive command (like inlined python -c scripts) you can't parse by rules and regex, or a gatekeeper LLM be able to understand its implication reliably. My solution is sandbox + git, where the .git folder is write protected in the sandbox as well as any outside files being r/o too.My personal anecdata is that both cases when Claude destroyed work it was data inside the project being worked on, and not matching any of the generic rules. Both could have been prevented by keeping git clean, which I didn't.
bryanlarsen
• Mar 12, 2026
How do people install stuff like this? So many tools these days use `npm install` or `pip install`. I certainly have npm and pip installed but they're sandboxed to specific projects using a tool like devbox, nix-devshell, docker or vagrant (in order of age). And they'll be wildly different versions. To be pedantic `pip` is available globally but it throws the sensible `error: externally-managed-environment`I'm sure there's a way to give this tool it's own virtualenv or similar. But there are a lot of those things and I haven't done much Python for 20 years. Which tool should I use?
binwiederhier
• Mar 12, 2026
I love how everyone is trying to solve the same problems, and how different the solutions are.I made this little Dockerfile and script that lets me run Claude in a Docker container. It only has access to the workspace that I'm in, as well as the GitHub and JIRA CLI tool. It can do whatever it wants in the workspace (it's in git and backed up), so I can run it with --dangerously-skip-permissions. It works well for me. I bet there are better ways, and I bet it's not as safe as it could be. I'd love to learn about other ways that people do this.https://github.com/binwiederhier/sandclaude
ramoz
• Mar 12, 2026
The deterministic context system is intuitive and well-designed. That said, there's more to consider, particularly around user intent and broader information flow.I created the hooks feature request while building something similar[1] (deterministic rails + LLM-as-a-judge, using runtime "signals," essentially your context). Through implementation, I found the management overhead of policy DSLs (in my case, OPA) was hard to justify over straightforward scripting- and for any enterprise use, a gateway scales better. Unfortunately, there's no true protection against malicious activity; `Bash()` is inherently non-deterministic.For comprehensive protection, a sandbox is what you actually need locally if willing to put in any level of effort. Otherwise, developers just move on without guardrails (which is what I do today).[1] https://github.com/eqtylab/cupcake
m4r71n
• Mar 12, 2026
The entire permissions system feels like it's ripe for a DSL of some kind. Looking at the context implementation in src/nah/context.py and the way it hardcodes a ton of assumptions makes me think it will just be a maintenance nightmare to account for _all_ possible contexts and known commands. It would be nice to be able to express that __pycache__/ is not an important directory and can be deleted at will without having to encode that specific directory name (not that this projects hardcodes it, it's just an example to get to the point).
benzible
• Mar 12, 2026
FYI, claude code “auto” mode may launch as soon as tomorrow: https://awesomeagents.ai/news/claude-code-auto-mode-research...
Engagement Signals
124
Upvotes
90
Comments
Cross-Market Term Frequency
Quantifies the cross-market adoption of foundational terms like context-aware permission guard and PreToolUse hook by tracking occurrence frequency across active SaaS architectures and enterprise developer debates.