Permissions and safety
Changing the rules
Turn a hard block into a prompt, grant an exception for a session or forever, and see what is currently granted — without disarming the built-in guards.
The defaults are strict because the wrong default is expensive. When they are too strict for what you actually do, here is how to move them.
See what is granted right now
> /permissions # active grants — list and revoke
snaga permissions # the long-term policy file and the audit log
The slash command shows grants held in memory for this session; the CLI subcommand shows the persistent policy and what has been decided over time.
Turn hard blocks into prompts
By default a privileged command — sudo, and its kin — is blocked outright.
To be asked instead of refused, opt in through .snaga/trust.toml:
[shell]
enable_escalation = true
Now a privileged match produces an interactive consent prompt rather than a
block. self_destructive patterns are not affected: a fork bomb is still
blocked with escalation on. The setting moves one class, not both.
Answering a prompt
The prompt offers a scope, and the scope decides how long your answer lasts:
| Answer | Lasts |
|---|---|
| Once | this command only |
| Session | until you quit |
| Project | saved for this project |
| User | saved for you, everywhere |
| No | denied |
Project and User write the approved pattern into the policy file, preserving
the comments already in it. Session keeps it in memory only.
Your rules are added on top of the built-ins, not instead of them
This is the part worth reading twice, because the intuitive assumption is wrong and the wrong assumption is dangerous.
Writing your own rules does not replace the default rule set. Your rules are placed ahead of the defaults — first match wins, so yours take priority — and every default that does not collide with one of yours is kept.
So this, on its own:
[[rule]]
pattern = "cargo build"
class = "safe"
...allows cargo build --release, and leaves sudo gated and a fork bomb
hard-blocked. Before rules were merged this way, that single entry would have
replaced the entire default set — one line of convenience silently disarming
every guard.
The property is pinned by a test named for it,
user_rules_do_not_disarm_default_guards, which asserts all three outcomes
together: the custom rule allows what it names, the fork bomb is still blocked,
and sudo is still gated.
Deliberate overrides still work. Declaring the same pattern as a default replaces it — your classification wins and the duplicate is dropped. Declaring a broader one that downgrades a guard is honoured too, because it is an explicit choice on your own machine. What is prevented is the accidental case, not the intentional one.
How a decision is reached
In order:
- An operator-approved prefix from a previous "Project" or "User" answer → allow.
- The first rule whose pattern appears in the command:
safe→ allow;self_destructive→ block;privileged→ block when escalation is off; resolve against the non-interactive default when there is nobody to ask; otherwise prompt.
- No rule matched → allow.
Step 1 short-circuits, which is why a persistent allow you granted earlier does not have to fight the rule set every time — and why it is worth granting at the narrowest scope that works.
The design position behind all of this
Snaga's stated contract is that users own their systems and accept the risks on them. That is why a broad override on your own machine is honoured rather than second-guessed. The guards exist to stop accidents and to make dangerous things visible — not to overrule you about your own computer.