Документация доступна только на английском языке.
Permissions
Permission modes, permission rules, protected paths, auto mode and the audit trail.
Before any tool runs, Nib decides whether it may run without asking you. PreToolUse hooks run first. Then, in order: deny rules, the checks that always need you (protected paths, secret stores, outward actions, sandbox escapes), ask rules, allow rules, and the session's permission mode, which in auto mode consults a classifier model. If none of them allows the call, Nib asks you; in auto mode, a call the classifier blocks, and most of those checks, are held back instead (see Auto mode).
Permission modes
A mode decides only which of the agent's calls need your approval. The agent works the same way in every mode: it finishes what you asked, makes routine choices itself and tells you which, and never takes an outward or hard-to-undo action you didn't ask for.
| Mode | What runs without asking | Switch to it |
|---|---|---|
default | Read-only actions inside the workspace: reading and searching files, read-only shell commands such as ls or git status | The default |
acceptEdits | The above, plus file edits inside the workspace | Shift+Tab, /mode acceptEdits |
plan | Read-only exploration only. Edits and mutating commands are denied until you approve a plan | Shift+Tab, /plan |
auto | Low-risk actions, as judged by a fast classifier model. Risky ones are held back without asking, and you can allow one by saying so | Shift+Tab, /mode auto |
bypass | Everything, except deny rules, your organization's ask rules (managed settings; your own ask rules, from your settings, the command line or this session, pause while Bypass is on, and a repository's never ask), a PreToolUse hook of your organization's that asks (your own hooks' asks pause too), and raising a spend cap or budget. Shell commands run outside the sandbox unless your settings keep it on | --permission-mode bypassPermissions at start, or /mode bypass. The first time, a screen says what bypass does; accepting is remembered, and it doesn't ask again |
In the CLI, Shift+Tab cycles through default, acceptEdits, plan and auto. Bypass joins the cycle while the session is in it, or when the CLI started in it or with --allow-dangerously-skip-permissions.
There is also dontAsk, for unattended runs: anything that would have prompted is denied instead. Headless nib -p runs behave this way unless you pre-approve tools.
Plan mode
In plan mode the agent explores, then calls ExitPlanMode with a plan. You approve it (and pick the mode to continue in) or send it back with feedback. While planning, the agent may write its own plan file and the folders the session owns outright: the working folders of its artifacts, its memory folder and its scratch folder. Nothing else is writable. The agent enters plan mode itself with EnterPlanMode only when you ask it for a plan first.
Auto mode
Auto mode hands the "should I ask?" question to a separate, fast model (the provider's small model). The classifier sees only your own recent messages and the proposed action. It never sees the agent's reasoning or tool output, so text injected into a web page or file can't argue it into approving something.
When the classifier blocks an action, auto mode doesn't ask you. The call is denied, and the agent goes on with other work and tells you in one line what it held back. To allow it, say so in the chat (for example "allow the push"), or use Allow this under the held call:
- Allow this lets exactly that action (the same command, or the same file) run once, the next time the agent tries it. Anything different is judged again.
- A message you type is read by the classifier. If it approves exactly the action that was held back, the agent's next try of it runs once.
- Nothing is saved to your settings. For a command you want to run every time, add an allow rule.
The checks that always need you never go to the classifier. In auto mode most of them hold the action back the same way, even if you asked for it earlier: publishing, outward actions, printing a credential, reading a secret store, commands nothing local can undo, and writes to git's own data in .git. The held line names the exact command or file, and only Allow this, or a message after it that clearly approves that exact action, lets it run. A message that doesn't say which action it approves leaves it held. A few checks still ask you, as the table shows: running outside the sandbox, writes that can make code run, CI workflow changes that widen access, commands Nib can't check, and a crew member's spending.
The classifier fails closed. If it's unavailable, errors, or answers ambiguously, Nib asks you. After 3 consecutive blocks, or 20 in one session, auto mode pauses and asks you instead, so a confused agent can't grind against it. Only a person can answer, and approving resumes auto mode. Apart from these, auto mode asks only for the checks that still ask, ask rules, a hook that asks, and requests only you can approve, such as running an untrusted workspace's workflow script, raising a spending cap or making an artifact public. Archiving a session or adopting a race's lane goes to the classifier like any other action, and deleting a race is held back like a command nothing local can undo. Broad allow rules such as Bash(*) are ignored in auto mode, because they would bypass the classifier entirely.
Auto mode is available by default. Only your organization's managed settings can turn it off (disableAutoMode), and a project's settings can't make it the starting mode.
Rules
Rules let you pre-approve, always ask, or always deny specific actions. The syntax is Tool or Tool(specifier), the format existing settings.json rules already use.
{
"permissions": {
"allow": [
"Bash(npm run test *)",
"Bash(git log *)",
"Edit(src/**)",
"WebFetch(domain:docs.python.org)",
"mcp__github__get_issue"
],
"ask": ["Bash(git push *)"],
"deny": ["Read(.env)", "Read(**/*.pem)", "Bash(curl *)", "WebSearch"]
}
}Evaluation order
- Deny rules win over everything. A deny matches in every mode, including bypass.
- The checks that always need you come next, in every mode but bypass. An ordinary allow rule doesn't skip them.
- Ask rules force a prompt even if an allow rule also matches.
- Allow rules approve the call.
- If no rule matches, the mode decides.
Rules from every settings file are combined: managed, command line, local, project and user. See Configuration for where they live.
Rule reference
| Rule | Applies to | Specifier |
|---|---|---|
Bash(…) | Bash, RunTests, Monitor, and shell commands run through Terminal and Process | A command pattern |
Read(…) | Read, Grep, Glob, and the other tools that read files: RepoMap, LSP, Diagnostics | A path pattern |
Edit(…) | Edit, Write, ApplyPatch, EditLines, NotebookEdit, RenameSymbol | A path pattern |
WebFetch(domain:…) | WebFetch | A host name, *.example.com for its subdomains, or *, as in the sandbox's domain lists |
WebSearch(…) | WebSearch | A query glob |
Agent(…) (alias Task) | Agent | A subagent type, such as Agent(Explore) |
Skill(…) | Skill | A skill name: Skill(deploy), Skill(deploy *), Skill(ops:*) |
History(…) | History reading another session or the whole project | session:<id> or project |
mcp__server, mcp__server__tool, mcp__server__* | MCP tools, and ReadMcpResourceTool reading that server's resources | — |
| Any other tool name | That tool | — |
A Read(…) deny rule also blocks edits there. An Edit(…) rule covers edits only: allowing edits to a path doesn't allow reading it.
Command patterns
| Pattern | Matches |
|---|---|
Bash(npm test) | Exactly npm test |
Bash(npm run test *) | npm run test and npm run test --watch, but not npm run test:unit. A rule ending in :* (the prefix form), such as Bash(npm run test:*), is read the same way |
Bash(git log *) | git log and git log --oneline, but not git logx |
Bash(ls*) | ls, lsof, anything starting with ls |
Nib parses shell commands properly before matching. A compound command such as npm test && git push is split, and each part has to be allowed on its own. Command substitutions, heredocs, pipes and wrappers such as env, timeout or xargs are understood, so timeout 60 rm -rf build is treated as rm -rf build.
If you write Bash(git * main), Nib warns that the wildcard before the subcommand matches far more than you probably intended.
A line the agent submits in a Terminal is checked as the whole line, even when it typed it over several calls. When it recalled, completed or edited the line with keys (history, Tab, cursor keys), Nib checks what was typed of it. If that part is a risky command (one that touches credentials, spends money, destroys data, publishes, or reaches people outside), no rule approves it: default and acceptEdits ask, dontAsk denies it, auto mode leaves it to the classifier, and bypass runs it. Plan mode never runs such a line.
Path patterns
Path patterns follow gitignore conventions:
| Pattern | Meaning |
|---|---|
src/** or ./src/** | Relative to the working directory |
/docs/** | Relative to the root of the settings file's project (for user settings, ~/.nib) |
~/notes/** | Relative to your home directory |
//etc/hosts | An absolute path |
.env, *.pem | A bare name matches at any depth |
!pattern | In a Read(…) or Edit(…) rule in a deny or ask list: carves an exception out of the earlier rules of the same kind in that list from the same settings layer (user, project, local…), not only the same file. In an allow list Nib warns and ignores it |
* matches within a path segment, ** across segments, and a pattern that names a directory covers everything below it.
Protected paths
Some files are how a prompt injection would persist or escalate: agent configuration, git internals, shell startup files and tool configs that execute code. Writes to them always need you, auto mode included: auto mode asks about the ones that can make code run, and holds back a write to git's own data in .git (its objects, refs, logs, index and info/exclude) until you allow it. Only bypass, where you've chosen to answer for everything, skips the question. In dontAsk and headless runs they are denied.
Protected directories, at any depth: .git, .nib, .claude, .codex, .cursor, .gemini, .vscode, .idea, .husky, .cargo, .devcontainer, .yarn, .mvn, .ssh, .gnupg, .aws.
Protected files, at any depth, include .gitconfig, .gitmodules, shell startup files (.bashrc, .zshrc, .profile and friends), .envrc, .npmrc, .yarnrc, bunfig.toml, .pre-commit-config.yaml, lefthook configs, .mcp.json, .claude.json and .nib.json.
A few locations inside protected directories are exempt because agents legitimately write there, such as .nib/worktrees and .nib/agent-memory.
Nib also refuses to run obviously destructive shell commands against critical paths, such as removing your home directory or the filesystem root, until you approve them (in auto mode, with Allow this), except in bypass mode.
Checks that always need you
Some calls need you in every mode but bypass, whatever the classifier would say. The other modes ask. Auto mode either asks or holds the call back until you allow it, as the table says, and what you said before the call doesn't count. In dontAsk mode and headless runs, where nobody can answer, they are denied.
| Check | What it catches | In auto mode | What can pre-approve it |
|---|---|---|---|
| Protected paths | Writes to the protected paths | Asks; a write to git's own data in .git is held back | Nothing. A folder the agent writes in without asking, such as auto memory, doesn't cover a protected path inside it |
| Secret stores | Reading a secret store in your home directory, such as ~/.ssh, ~/.aws or CLI tokens (the full list is under Sandbox) | Held back, naming the file | For the Read tool, a Read allow rule naming the exact file, without wildcards, in your user settings or managed settings. Shell commands that read one always need you |
| Outward actions | Commands that publish to a registry, deploy to production or change deployed infrastructure, change a repository's visibility or settings, write deployment secrets, or force-push or delete a remote default branch | Held back | An allow rule for the exact command, without wildcards, in your user settings or managed settings |
| Credential printers | Commands that fetch a live credential and print it | Held back | Same as outward actions |
| CI workflow permissions | Edits to a CI workflow that widen its token's permissions:, or that run pull requests from forks with the workflow's secrets (pull_request_target) | Asks | Same as outward actions |
| Sandbox escapes | A command the agent asks to run outside the sandbox (dangerouslyDisableSandbox) | Asks | Nothing |
| Commands Nib can't check | A shell command too long to check, or one Nib can't parse | Asks; a Terminal line the agent recalled or edited with keys is left to the classifier | Nothing |
When one call meets several checks, or an ask rule too, auto mode asks if any of them asks.
For outward actions, credential printers and CI workflow permissions, a rule from a project or local settings file, a session rule, or a rule an agent proposed never pre-approves the call, so an agent can't widen its own reach. That's why "allow": ["Bash(npm publish)"] in a project's settings still asks before publishing.
Answering a prompt
When Nib asks, you can choose:
| Choice | Effect |
|---|---|
| Allow | This call only |
| Allow for this session | Adds a session rule, so similar calls run without asking until the session ends |
| Always allow | Writes a rule to .nib/settings.local.json, which is not meant to be committed |
| Deny | The call fails and the agent is told it was denied |
| Send back with a note | The call fails and the agent receives your note, so it can change course. It needs the note: without one, Deny is the answer |
In the app, Allow and Deny are the prompt's buttons. Allow for this session and Always allow are in Allow's menu, and Send back with a note in Deny's. Each says in words what it lets through, for example "commands starting with “npm run lint”", and Always allow lets you edit the rule before it's saved.
Nib suggests a rule for "always" that is as narrow as is useful, for example Bash(npm run lint *) rather than Bash(npm *).
Hooks and permissions
PreToolUse hooks run before the permission engine and can return allow, deny, ask or defer. A hook's deny holds in every mode. A hook's ask holds in every mode too, but in bypass only your own hooks and your organization's can ask (from your user settings, managed settings, the command line, or the program embedding Nib); bypass ignores an ask from a repository's hook (its project or local settings), a plugin's, a skill's or an agent's. A hook's allow skips a routine prompt, never one that needs you: one of the checks that always need you, auto mode's pause after repeated blocks, or a classifier that can't decide. A PermissionRequest hook runs when a prompt would be shown and can answer it for you, with the same limit on approving; denying has none. See Hooks.
Workspace trust
When you open a folder you haven't trusted, Nib asks whether you trust it: the app and VS Code ask about the folder you're working in, and the terminal asks when the folder's own settings would turn something on. Each asks once per start, and only on the computer the folder is on. Not now leaves the folder untrusted until you quit; once you trust it, that's remembered. Until you do, the project's own settings files can only narrow permissions. They can't add allow rules, hooks, environment variables, additional directories, sandbox network hosts, an API key helper or a status line command.
Independently of trust, project and local settings can never set the default mode to auto or bypass, and can't override sensitive environment variables such as HOME, TMPDIR or XDG_*. Nor can they define MCP servers, approve the project's own servers or switch plugins: a repository's servers go in .mcp.json, where each asks for your approval.
Audit
Every decision is written to the session's audit file, and every one that isn't a trivial allow (a read-only call the mode allows) is also a permission.decision event in the session log, with the tool, the outcome, what decided it (a rule, the mode, the classifier, a protected path, a hook, or you) and the matching rule. You can review any session's decisions after the fact.
Command-line flags
nib --permission-mode acceptEdits
nib --allowedTools "Bash(git log *)" Edit
nib --disallowedTools "Bash(rm *)" WebFetch
nib --dangerously-skip-permissions # same as --permission-mode bypassPermissionsThe flag, or accepting bypass once in any Nib client, is your choice. In the terminal UI, --dangerously-skip-permissions shows the same screen until you've accepted bypass. Where nothing can show it (-p, including a background run with --bg, ACP, mcp serve), the flag is your choice and nothing asks. An editor's mode picker offers bypass once you've accepted it, when the run started in it, or with --allow-dangerously-skip-permissions. A program in SDK mode can switch a run to bypass later only if the run started in it or was given --allow-dangerously-skip-permissions (the Agent SDK's allowDangerouslySkipPermissions). In every case your organization's policy can turn bypass off, deny rules apply, and bypass doesn't run as root outside a container.
Bypass also doesn't run as root, unless Nib runs in a container: run it as a non-root user, or in a container. A session asked to start in bypass as root uses Default mode and says why.
--allowedTools and --disallowedTools accept comma- or space-separated lists and never split inside parentheses. They apply to the session only.
Sessions
A session is an append-only log of events, which is what makes resume, fork, rewind and worktree isolation possible.
Sandbox
Shell commands the agent runs are contained by the operating system sandbox — Seatbelt on macOS, bubblewrap on Linux — with workspace-only writes, no credential reads, and network access through a filtering proxy.