Skip to content

Permission Modes

Controls whether CodeBuddy should automatically continue, ask the user, or directly deny before editing files, running commands, accessing the network, or invoking other high-risk tools. Permission modes determine the session pace, not the entire logic of the permission system.

First, Understand: Permission Mode Is Just One Layer of the Permission System

For each tool call, CodeBuddy does not only look at the current mode. It evaluates the following in order:

  1. Hooks / special handling for interactive tools
  2. deny rules
  3. Trusted allow rules
  4. Command safety checks (interactive only)
  5. ask rules
  6. bypassPermissions short-circuit
  7. Untrusted allow rules
  8. The current permission mode's own baseline strategy
  9. Non-interactive fallback and the final resolution of auto / dontAsk

Therefore:

  • deny is always stronger than the mode
  • allow / ask rules will change the actual effect of the mode
  • auto only takes over "actions that would still end up as ask"
  • dontAsk is not "more permissive" — it means "never prompt, directly deny unapproved actions"
  • bypassPermissions is also not unconditionally allowing everything: preceding deny / ask rules and interactive dangerous command checks may still block it

For the complete evaluation order of permission rules, see Permission Rules.

Available Modes

CodeBuddy Code provides the following permission modes. Most can be directly switched or specified in the CLI; some modes are for IDE integration and subagent scenarios.

Modes You Can Switch Manually

ModeWhat can run without askingUse case
defaultRead tool inside trusted directoriesDefault; suitable for sensitive work / getting started
acceptEditsRead + Edit-family tools inside trusted directoriesKeep writing, then review with git diff
autoActions that would otherwise prompt are sent to the classifier for allow / deny determinationWant to reduce interruptions while maintaining security boundaries
dontAskOnly pre-approved actions continue; everything else is denied without askingNon-interactive automation / fixed whitelist agents
planDelegates to the mode active before entering plan (default = default); additionally allows writing session plan filesExplore the code before deciding what to change
bypassPermissionsSkips most approvalsUse only in sandbox containers / VMs / offline dev containers
delegateCoordination tools only (such as Agent / TaskCreate / SendMessage / team management); implementation tools are blockedThe main agent only decomposes and delegates; execution goes to subagents

Programmatic / Integration Modes (Not in the Shift+Tab Cycle)

ModeWhen it appears
fullAccessPassed by an IDE client through the protocol; semantically close to the global allow-all of bypassPermissions
workPassed by an IDE client. Read is allowed directly (without checking trusted directories), Edit always asks, Bash allows only safe commands directly, others ask
ignoreOnly takes effect for subagents (subagent / teammate), meaning "use the main session's mode; do not let the subagent's own frontmatter override it"; main sessions do not use it

Note: From an implementation perspective, auto, dontAsk, plan, and bypassPermissions can all be specified via CLI or settings; delegate is primarily switched via Shift+Tab within a session.

How to Switch Permission Modes

Switch During a Session: Shift+Tab

In the CLI, press Shift+Tab to cycle through the following modes:

text
default → bypassPermissions → acceptEdits → auto (when available) → plan → delegate → default → ...

Notes:

  • auto only appears in the cycle when available in the current environment
  • dontAsk is not in the keyboard cycle; it can only be entered via CLI, settings, or SDK / IDE control signals
  • On Windows, both Shift+Tab and Alt+M can trigger this (Alt+M is a compatibility alias)
  • You can customize the shortcut via ~/.codebuddy/keybindings.json

Status Bar Indicator

After switching, the current mode is displayed below the input area:

ModeTextDescription
defaultNot shownDefault mode does not take up extra space
bypassPermissions⏵⏵ bypass permissions on (shift+tab to cycle)Can cycle back to other modes
acceptEdits⏵⏵ accept edits on (shift+tab to cycle)Can cycle back to other modes
auto⏵⏵ auto mode on (shift+tab to cycle)Only appears when available
dontAsk⏵⏵ don't ask onNot in the cycle, so no cycle hint
plan⏸ plan mode on (shift+tab to cycle)Indicates plan mode is active
plan + pre-mode⏸ plan + accept edits (shift+tab to cycle) etc.Shows the inherited baseline mode before plan
delegate⇢ delegate mode on (shift+tab to cycle)Main agent is coordinating only

Specify at Startup: --permission-mode

bash
codebuddy --permission-mode default
codebuddy --permission-mode acceptEdits
codebuddy --permission-mode auto
codebuddy --permission-mode dontAsk
codebuddy --permission-mode plan
codebuddy --permission-mode bypassPermissions

--permission-mode officially supports these 6 literals. Other modes (delegate / work / fullAccess / ignore) cannot be used as standard CLI startup arguments.

Also works in non-interactive mode:

bash
codebuddy -p --permission-mode dontAsk "only allow whitelisted actions, deny everything else"
codebuddy -p --permission-mode auto "try to automatically fix lint errors"

Additional shortcuts:

  • -y / --dangerously-skip-permissions: equivalent to --permission-mode bypassPermissions

Persistent Default: permissions.defaultMode

Configure in ~/.codebuddy/settings.json or project settings:

json
{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}

Priority order:

  1. Current session value
  2. CLI --permission-mode
  3. permissions.defaultMode
  4. default

defaultMode: "auto" has additional restrictions:

  • Only user settings and CLI-injected settings can grant auto
  • defaultMode: "auto" in .codebuddy/settings.json and .codebuddy/settings.local.json will be ignored and fall back to default
  • If auto is disabled or currently unavailable, it will also fall back to default

plan Remembers the Pre-Entry Mode

When entering plan, CodeBuddy records the "permission mode before entering plan"; it restores that mode on exit. This means:

  • If you switch into plan from acceptEdits, during plan regular Read / Bash / non-plan-file Edit still follows acceptEdits baseline
  • The only thing plan mode additionally allows is writing to the current session's plan file
  • Exiting plan returns to the previous mode, not forcibly to default

Detailed Mode Semantics

default (Default)

The most conservative and stable mode.

Tool typeBehavior
ReadPath is inside trusted directories (cwd + permissions.additionalDirectories + user-added addDir) → allow; otherwise ask
EditAsk
BashAsk
OtherAsk

Suitable for:

  • First time in an unfamiliar repository
  • Changes involving sensitive directories, production scripts, external services
  • When you want every high-risk action to be visible

acceptEdits (Auto-Approve File Edits)

Auto-allows Edit-family tools, but not Bash.

Tool typeBehavior
ReadAllow inside trusted directories; ask outside
EditAuto-allow
BashAsk
OtherAsk

Edit-family tools mainly include:

  • Edit
  • Write
  • MultiEdit
  • NotebookEdit

Notes:

  • acceptEdits only affects Edit-family tools, not Bash — Bash always follows a separate safety classification
  • "Trusted directories" are based on the workspace root + user-configured permissions.additionalDirectories + startup --add-dir
  • Reads/writes to protected files still ask according to the original mode and do not use automatic allow
  • If an operation is first matched by a deny / ask rule, the rule still takes priority

Suitable for:

  • When you want CodeBuddy to continuously edit files but don't want it to run commands on its own
  • When you prefer to review changes uniformly through git diff

auto (Classifier Auto-Determination)

auto is not "fully automatic allow" — it sends actions that would otherwise ask to the classifier for a second judgment.

When Does auto Take Over?

The classifier only runs when all of the following conditions are met:

  1. The tool call was not denied by a deny rule
  2. It was not pre-allowed by an allow rule
  3. It did not match an explicit ask rule
  4. The regular permission chain still resulted in an ask
  5. The current mode is auto

So auto only takes over "the final unresolved ask" — it does not replace the entire permission system.

What Situations Won't Enter the Classifier?

The following situations will not go through the auto classifier:

  • Tool calls that have already matched allow / deny rules
  • Tool calls that matched an explicit ask rule
  • AskUserQuestion
  • ExitPlanMode

In other words, ask rules under auto still mean "mandatory manual approval".

What Results Can the Classifier Give?

The classifier has only two outcomes: allow (proceed) or deny (reject). There is no intermediate state like "partial approval".

What Happens When the Classifier Cannot Determine?

  • Classifier error / unavailable: For safety, the action is directly denied (fail-closed), and the model is prompted to use other natural tools to achieve the goal or stop and explain to the user; consecutive failures will automatically exit auto and fall back to default.
  • Conversation too long, exceeding classifier capacity: Interactive sessions fall back to normal approval prompts; -p / stream-json and other headless modes abort the current run.
  • Too many rejections (repeated rejections by classifier in a short time): auto pauses — interactive sessions fall back to normal prompts, headless mode aborts the run, avoiding repeated idle spinning.

These are all automatic behaviors that require no configuration.

Notes on Allow Rules Under auto

To prevent allow rules from bypassing the classifier entirely, under auto mode CodeBuddy temporarily ignores "overly broad / dangerous" allow rules (filtered from memory only for this check, without modifying your settings). Mainly ignored are:

  • Catch-all shell rules: Bash, Bash(*), PowerShell, PowerShell(*)
  • Dangerous command / cmdlet prefixes: such as Bash(sudo *), Bash(eval *), PowerShell(iex *)
  • Any Agent / Task rules: such as Agent(*) — to prevent using subagents to bypass the classifier

Narrow and specific safe rules remain effective, such as Bash(npm test), Bash(git status), PowerShell(Get-Content foo.txt), Read, Edit(src/foo.ts).

If you do need certain actions to be exempt from review under auto, the correct approach is to configure autoMode rules (see below), not to write broad allow rules.

auto Configuration and Self-Check Commands

The trusted boundary and allow / block rules for the auto classifier are controlled by top-level autoMode settings (environment / allow / soft_deny / hard_deny). See Settings Configuration for details.

3 local commands help you view and validate configuration:

bash
codebuddy auto-mode defaults   # View built-in default rules
codebuddy auto-mode config     # View currently effective rules ($defaults expanded)
codebuddy auto-mode critique   # Have the model check your custom rules for ambiguity, redundancy, or false positives

Suitable for:

  • When you want to reduce daily confirmation prompts
  • But don't want to go directly into bypassPermissions
  • And are willing to explicitly configure trusted boundaries for internal org repos / domains / buckets

dontAsk (No Prompts, Directly Deny Unapproved Actions)

The core semantics of dontAsk: any action that would normally prompt for approval does not prompt — it is directly denied.

It is not an alias for bypassPermissions; quite the opposite, it is stricter.

Tool typeBaseline behavior
ReadOnly read-only operations inside trusted directories continue; reads outside trusted directories are denied
EditDenied, unless pre-approved by an allow rule
BashDenied, unless pre-approved by an allow rule
OtherDenied, unless pre-approved by an allow rule

Important details:

  • dontAsk only overrides the final ask result; actions already allowed / denied are not affected
  • Explicit ask rules under dontAsk will not prompt — they are directly converted to deny
  • AskUserQuestion and ExitPlanMode are also denied under dontAsk (no prompts / no entering plan approval) — the intent of dontAsk is "never interrupt the user", so even these interactive tools are no exception
  • When denied, the model receives a prompt: it can try other natural tools to achieve the goal, or stop and explain to the user if the capability is truly needed
  • Combining allowedTools / permissions.allow with dontAsk creates a "fixed whitelist agent"

Suitable for:

  • CI / batch processing / background agents
  • When you explicitly want "do it if you can, fail immediately if you can't"
  • When you need a stable, predictable tool surface rather than runtime ad-hoc approvals

plan (Explore Before Changing)

The goal of plan mode: explore first, write a plan, get confirmation, rather than immediately applying source code changes.

CodeBuddy's plan is not an independent "fully read-only mode" — it delegates to the mode active before entering plan:

  • Read: delegates to the pre-plan mode
  • Bash: delegates to the pre-plan mode
  • Edit: if the target is the current session's plan file, allows directly; otherwise delegates to the pre-plan mode

This means:

  • Entering plan from default, ordinary Edit / Bash still asks
  • Entering plan from acceptEdits, non-plan-file Edit still auto-allows per acceptEdits baseline
  • What plan truly additionally allows is only "writing to the current session's plan file"

Entry / exit methods:

  • Enter: Shift+Tab or EnterPlanMode
  • Exit: Shift+Tab again or ExitPlanMode

Start directly in plan:

bash
codebuddy --permission-mode plan

bypassPermissions (Skip Most Approvals)

bypassPermissions skips most of the normal approval flow, suitable for isolated containers / VMs / dev containers, sandboxes without external network, or scripted scenarios where you fully understand the consequences.

But it is not "all preceding rules become ineffective". More precisely:

  • Tools not blocked by preceding rules will be allowed directly at the bypass stage
  • But before that, deny / ask rules are still evaluated first
  • In interactive sessions, dangerous Bash commands may still require explicit confirmation
  • If permissions.disableBypassPermissionsMode: "disable", this mode degrades back to default baseline

In other words, the following claims are inaccurate:

  • "Once bypass is enabled, ask rules become ineffective"
  • "Once bypass is enabled, dangerous commands will unconditionally pass"

Startup methods:

bash
codebuddy --permission-mode bypassPermissions
# Equivalent
codebuddy -y
codebuddy --dangerously-skip-permissions

Disable Channel (Administrators)

To disable this mode:

json
{
  "permissions": {
    "disableBypassPermissionsMode": "disable"
  }
}

Suitable for:

  • Isolated containers / sandboxes / dev containers
  • Environments without external network or shared state
  • When you explicitly accept the consequences of fully automated execution

delegate (Multi-Agent Coordination Mode)

In delegate mode, the main agent only coordinates and does not directly execute implementation tools.

Behavior:

  • The main agent retains only coordination tools (such as Agent, TaskCreate, SendMessage)
  • Implementation tools (such as Read, Write, Edit, Bash) are not exposed to the main agent
  • Actual read/write and execution work is delegated to subagents

Suitable for:

  • When the main agent focuses on task decomposition, dispatch, and result convergence
  • When using Team / Swarm style collaborative execution

work (IDE Integration)

work is only passed by the IDE client through the protocol; CLI users generally do not use it directly.

Tool typeBehavior
ReadAllow directly, without checking trusted directories
EditAsk
BashSafe commands allowed directly; others ask
OtherAllow

fullAccess (IDE Integration)

Only set by IDE clients through the protocol; semantically close to bypassPermissions.

ignore (Subagent Only)

ignore is only used for subagent configuration, meaning:

  • Do not adopt the mode from the subagent's own frontmatter
  • Use the parent session's current mode

Main sessions will not have this value.

Protected Critical Files

Write operations to the following paths retain special handling even under acceptEdits / bypassPermissions:

  • Repository itself: .git, .gitconfig, .gitmodules
  • Shell config: .bashrc / .bash_profile / .zshrc / .zprofile / .envrc, etc.
  • Package management: .npmrc / .yarnrc / .pnpmfile.cjs / bunfig.toml, etc.
  • IDE / tools: .vscode / .idea / .husky / .devcontainer / .cargo / .yarn / .mvn
  • CodeBuddy itself: .codebuddy (except .codebuddy/worktrees)
  • MCP / config: .mcp.json / .codebuddy.json

Permission Mode Inheritance for Subagents

By default, subagents (Agent tool calls, Agent Teams members) inherit the main session's permission mode, but the actual priority is more nuanced than "simple inheritance".

To force override the default subagent mode at the team / project layer:

json
{
  "permissions": {
    "subagentPermissionMode": "bypassPermissions"
  }
}

Subagent Permission Mode Priority

When the main session is not auto / dontAsk, the subagent mode resolves in the following order:

  1. mode explicitly passed in the Agent tool call
  2. permissionMode in the subagent's frontmatter / product config (writing ignore uses the parent session's mode)
  3. CLI --subagent-permission-mode
  4. Environment variable CODEBUDDY_SUBAGENT_PERMISSION_MODE
  5. Settings permissions.subagentPermissionMode
  6. Code-level inheritance mapping
  7. Otherwise directly inherits the main session's current mode

The only special inheritance mapping currently is:

  • Main session delegate → subagent defaults to default

The reason is simple: the main agent is restricted to "coordination only", but subagents must be able to actually work.

auto / dontAsk Parent Session Ceiling

If the main session is currently auto or dontAsk, a permission ceiling is triggered first:

  • Subagents are directly clamped to the same mode as the parent session
  • Even if the Agent tool explicitly passes a more permissive mode, it will not take effect
  • The purpose is to prevent subagents from bypassing the parent session's security boundary

This ceiling also affects the "auto direct-approve" short-circuit in the interruption layer for background subagents / team members; when the parent session is auto / dontAsk, these short-circuits are disabled and must go through the normal permission check flow.

Non-Interactive / Automation Scenarios

If you are working in -p, stream-json, background agents, or other environments where approval prompts cannot be shown, here's how to understand each mode:

ModeTypical result in non-interactive mode
default / acceptEdits / planAny action that still requires ask at the end will be denied
autoActions that would ask go through the classifier; classifier unavailable → fail-closed; transcript too long → abort run
dontAskUnapproved actions are directly denied without waiting for manual confirmation
bypassPermissionsMost actions continue executing directly

Therefore:

  • For "fixed whitelist automation" → dontAsk + allow rules
  • For "as automatic as possible while maintaining classifier safety boundary" → auto
  • For "don't block almost anything" → bypassPermissions

Working with Permission Rules

A common misconception is treating mode as the sole permission source.

The recommended understanding is:

  • Mode defines the baseline
  • allow / ask / deny define exceptions

Standard rule layering example:

json
{
  "permissions": {
    "defaultMode": "default",
    "allow": ["Bash(npm test)", "Read(/etc/hosts)"],
    "ask": ["WebFetch"],
    "deny": ["Bash(rm -rf *)", "Edit(.git/**)"]
  }
}

Fixed whitelist automation example:

json
{
  "permissions": {
    "defaultMode": "dontAsk",
    "allow": [
      "Read",
      "Grep",
      "Glob",
      "Bash(npm test:*)"
    ],
    "deny": [
      "Bash(git push:*)"
    ]
  }
}

The effect of the second configuration is:

  • Read / Grep / Glob pass automatically
  • npm test ... passes automatically
  • git push ... is always denied
  • Other unlisted actions are directly denied under dontAsk

This is the most common approach for "giving an agent only a small set of explicit capabilities".