Overview
The permission system intercepts every tool call an agent makes and produces one of three decisions: allow the tool to execute, deny it, or ask the user for confirmation. The system combines static configuration with dynamic runtime analysis. Three components drive the decision together:- Rules — explicit allow/deny/ask patterns per tool and command, evaluated with highest priority. Rules have two sources: statically pre-configured in
PermissionContext, or dynamically added when the user accepts a suggested rule during an ASK prompt. Suggestions are auto-generated from the current tool call, so accepting one means future identical calls are handled automatically without prompting again. - Mode — a static global policy set at configuration time; determines default behavior for all calls that match no rules (e.g.,
EXPLOREmakes the agent read-only;DONT_ASKsilently denies unmatched calls). - Built-in checks — dynamic runtime analysis performed by the tools themselves against actual call inputs: read-only command detection (parsing the bash command at call time) and dangerous path protection (checking the real file path or command target). Tools can mark a safety ASK as bypass-immune via
PermissionDecision.bypass_immune=True; the engine then honors it acrossDEFAULT,ACCEPT_EDITS, andDONT_ASK(allow rules cannot silence it).BYPASSmode is the one exception — it explicitly opts out of all safety ASKs by design.
- DEFAULT
- EXPLORE
- ACCEPT_EDITS
- BYPASS
- DONT_ASK
Deny rules and explicit ask rules are always honored, in every mode (including
BYPASS).Tool-emitted safety ASKs (bypass_immune=True) are honored in DEFAULT, ACCEPT_EDITS, and DONT_ASK — they cannot be silenced by allow rules. In BYPASS mode they are skipped on purpose: BYPASS’s contract is “the user has opted out of safety prompts; only deny/ask rules remain as guardrails.”Permission Mode
AgentScope supports the following modes, each suited to a different deployment scenario.| Mode | Behavior | Use Case |
|---|---|---|
DEFAULT | All ops require explicit rules or user confirmation. The only built-in auto-allow is Bash recognizing read-only commands (ls, git status, cat, …) and returning ALLOW. Read / Glob / Grep return PASSTHROUGH and still ASK unless an allow rule matches | Most secure, recommended default |
ACCEPT_EDITS | Auto-allow file ops in working directories; auto-allow Bash filesystem commands (mkdir/touch/rm/cp/mv/sed) only when every target path resolves inside a working directory | Active development with user present |
EXPLORE | Read-only: allow read-only tools and read-only Bash commands (ls, git status, cat, …); deny modifications. User-configured DENY/ASK rules take precedence over the read-only auto-allow | Code exploration, planning |
BYPASS | Skip all permission checks except deny/ask rules and tool DENY. Tool safety ASKs are NOT enforced (rm -rf /, writes to ~/.bashrc, command injection, etc. all pass through). Use deny rules to protect specific paths | Sandboxed environments or fully trusted runs |
DONT_ASK | Convert every ASK (default, ASK rules, and safety ASKs) to DENY; safe-by-default for non-interactive runs | Unattended / scheduled execution |
AgentState.permission_context when creating the agent, or update it at runtime.
Permission Rules
APermissionRule maps a specific tool and call pattern to one of three behaviors: ALLOW, DENY, or ASK.
Each rule consists of the following fields. When the permission engine evaluates a rule, it calls the tool’s match_rule() method with rule_content and the actual call input to determine whether the rule applies.
Tool this rule applies to:
"Bash", "Read", "Write", "Edit", or any custom tool name.Match pattern — semantics depend on
tool_name:- Bash: wildcard prefix pattern (
npm run:*matchesnpm run build,npm run test) - Read / Write / Edit: glob pattern (
src/**/*.pymatches any.pyundersrc/) - Other tools: exact JSON-serialized parameter match
ALLOW, DENY, or ASKOrigin of the rule:
"userSettings", "projectSettings", "session", etc.Pattern Examples
rule_content is consumed by each tool’s match_rule() method and auto-generated by ToolBase.generate_suggestions(). Because both methods are part of the tool interface, each tool can define its own pattern syntax and matching logic independently.
For AgentScope’s built-in tools, the patterns are as follows:
- Bash
- File Tools (Read / Write / Edit)
Matches against the
command parameter. Pattern format is COMMAND_PREFIX:* — the prefix is the leading token of the command, and * matches any arguments that follow.| Pattern | Matches | Does Not Match |
|---|---|---|
npm run:* | npm run build, npm run test | npm install |
git commit:* | git commit -m "fix" | git push |
rm:* | rm file.txt, rm -rf /tmp/x | ls |
Configuring Rules
At initialization — pass rules intoPermissionContext when creating the agent:
UserConfirmResultEvent.rules; the agent adds them to the engine automatically:
Built-in Checks
Each tool implements acheck_permissions() method that runs against the actual call inputs at runtime. AgentScope’s built-in tools cover three areas:
- Dangerous path protection —
Write,Edit, andBashcheck whether the target file or command touches sensitive paths. Returns a bypass-immune safety ASK that is honored inDEFAULT/ACCEPT_EDITS/DONT_ASK(allow rules cannot silence it).BYPASSmode skips it on purpose. - Read-only command detection —
Bashparses the command string to detect read-only operations and auto-allows them in every mode (includingDEFAULT). For input-dependent tools likeBash, this is exposed via thecheck_read_only()method (see below). - ACCEPT_EDITS mode —
WriteandEditauto-allow operations on files within configured working directories.Bashadditionally requires that every target path of a filesystem command (mkdir/touch/rm/cp/mv/sed, …) resolves inside a working directory.
Custom tools
A custom tool implementscheck_permissions() to add tool-specific permission logic. Tools whose read-only status depends on the input (like Bash — ls is read-only, rm is not) should also override check_read_only().
Safety check contract
A safety check is a tool-emitted ASK that the tool considers too dangerous to be silently overridden — e.g.Write to ~/.bashrc, Bash with rm -rf /. Setting bypass_immune=True on the decision asks the engine to surface the ASK to the user even when an allow rule matches or the mode would otherwise auto-allow.
Use it whenever a wrong call would cause damage the user almost certainly didn’t intend. Example: a custom DeployTool returns bypass_immune=True when the target is prod-*, so a blanket allow_rules["DeployTool"] = ["*"] configured for staging cannot accidentally authorize a production deploy.
The exact handling per mode:
| Mode | bypass_immune=True ASK is… |
|---|---|
DEFAULT | honored — allow rules cannot override it |
ACCEPT_EDITS | honored — same as DEFAULT |
EXPLORE | not applicable (the engine does not call check_permissions in EXPLORE; the read-only verdict is final) |
BYPASS | ignored — BYPASS skips all safety ASKs by design |
DONT_ASK | converted to DENY (no user available to answer) |
bypass_immune=False, the default) can be overridden by a matching allow rule in DEFAULT/ACCEPT_EDITS, and is silently allowed by BYPASS’s fallback.
Read-Only Commands
Common read-only bash commands are auto-allowed without any rules, in every mode (includingDEFAULT). A compound command (&&, ||, ;, |) is read-only only if all subcommands are read-only. Output redirections (>, >>) always make a command non-read-only.
Full read-only command list
Full read-only command list
| Category | Commands |
|---|---|
| Git | git status, git log, git diff, git show, git branch, git blame, git grep, git reflog, git config --list |
| Files | ls, cat, head, tail, grep, rg, find, tree, stat, wc, pwd, which |
| Docker | docker ps, docker images, docker logs, docker inspect, docker info |
| GitHub CLI | gh repo view, gh issue list, gh pr list, gh status |
| Package managers | npm list, pip list, pip show, node --version, python --version |
Dangerous Path Protection
| Category | Paths |
|---|---|
| Shell configs | .bashrc, .zshrc, .bash_profile, .profile |
| Git configs | .gitconfig, .gitmodules |
| SSH | .ssh/config, .ssh/authorized_keys, id_rsa, id_ed25519 |
| Credentials | .env, .env.local, .npmrc, .pypirc, .aws/credentials |
| Directories | .git/, .ssh/, .claude/, .vscode/, .aws/, .kube/ |
Common Recipes
The following examples show how to configureAgentState.permission_context for common deployment scenarios. Each recipe combines a mode with rules to match a specific use case.