Permissions & Safety
Permissions are the most common early blocker when setting up ACT. This page helps you choose the right permission strategy and configure it.
What permissions does ACT need?
Section titled “What permissions does ACT need?”ACT commands use several tools that require explicit permission:
| Tool | Used by | Why |
|---|---|---|
Bash | Git commands, Flutter CLI, project scaffolding | Runs shell commands for builds, tests, and git operations |
Read | All workflow commands | Reads specs, plans, source files |
Write | Spec, plan, work commands | Creates spec files, plan files, and source code |
Edit | Work, refine-spec commands | Modifies existing files |
Glob / Grep | Spec, plan, refine-spec commands | Searches codebase for patterns and conventions |
Both Claude Code and OpenCode gate these tools behind a permission system — the configuration differs, but the strategies below apply to both.
Which strategy should I choose?
Section titled “Which strategy should I choose?”AI coding agents run shell commands, read and write files, and search your codebase on your behalf. That’s what makes them powerful — but it also means you need to decide how much autonomy to give them and what boundaries to put in place.
The key tradeoffs to consider are:
- Safety vs friction: Tighter permissions mean more manual approvals. Looser permissions mean fewer interruptions but more trust in the agent.
- Local access: If you need to run apps on iOS Simulator, Android emulators, or physical devices, you need a strategy that runs natively on your machine — not inside a container.
- Prompt injection risk: When an agent browses the web or reads untrusted input, malicious content could try to hijack its behavior. Stronger isolation (containers, non-sudo accounts) limits the blast radius if this happens.
With that in mind, here are three approaches — from most conservative to most permissive:
| Strategy | CLI support | Safety | Setup effort | Simulators / emulators | Friction |
|---|---|---|---|---|---|
| Permission rules | Both | High | Low | Full access | Some prompts initially |
| DSP + non-sudo account | Claude Code | Medium | Medium | Full access | None |
| Docker container | Both | Highest | High | Limited | None |
Strategy 1: Permission rules
Section titled “Strategy 1: Permission rules”The most common approach. You pre-configure which tools your AI CLI is allowed to use, and it runs without prompting for those tools.
Add tool permissions to your project’s .claude/settings.json:
{ "permissions": { "allow": [ "Bash(git *)", "Bash(flutter *)", "Bash(dart *)", "Bash(node *)", "Bash(gh *)", "Read", "Write", "Edit", "Glob", "Grep" ] }}Add tool permissions to your project’s opencode.json:
{ "$schema": "https://opencode.ai/config.json", "permission": { "bash": { "git *": "allow", "flutter *": "allow", "dart *": "allow", "node *": "allow", "gh *": "allow" }, "read": "allow", "edit": "allow", "glob": "allow", "grep": "allow" }}This allows ACT to run its full workflow without interruption while still blocking unexpected shell commands.
Project-level vs global permissions
Section titled “Project-level vs global permissions”The examples above show project-level configuration. Both CLIs also support a global (user-level) config file that applies to all projects:
| Project config | Global config | |
|---|---|---|
| Claude Code | .claude/settings.json | ~/.claude/settings.json |
| OpenCode | opencode.json | ~/.config/opencode/opencode.json |
Project-level settings override global settings when they conflict. A good pattern is to set your ACT permissions globally so they apply everywhere, then tighten per-project if needed.
Advantages:
- Easy to set up — one config file (or global for all projects)
- Full access to local simulators and emulators
- Granular control over which commands are allowed
Disadvantages:
- You may still get occasional prompts for commands not in your allow list
- Requires maintaining the allow list as your workflow grows
Learn more here:
Strategy 2: DSP mode on a non-sudo account
Section titled “Strategy 2: DSP mode on a non-sudo account”Dangerously Skip Permissions (DSP) mode disables all permission checks, giving Claude Code full autonomy. To mitigate the risk, you run it under a dedicated non-sudo user account that has no access to sensitive data.
claude --dangerously-skip-permissionsThis is ideal for developers who want zero-friction AI development with full access to native tooling (iOS Simulator, Android emulators, etc.).
Advantages:
- Zero permission friction — Claude Code runs completely autonomously
- Full local dev setup with simulators and emulators
- Ideal for AI-assisted development and manual testing side by side
Disadvantages:
- Requires setting up a separate user account on your machine
- Some residual risk from prompt injection — if Claude Code performs web searches, malicious content on websites could attempt to hijack the session. The non-sudo boundary limits the blast radius, but doesn’t eliminate it entirely.
Strategy 3: Docker container
Section titled “Strategy 3: Docker container”Run your AI CLI inside a Docker container or devcontainer for maximum isolation. Any prompt injection or unintended commands can only affect the container — your host machine stays safe.
Resources:
Inside the container, you can safely use DSP mode (Claude Code) or pre-configure permission rules (OpenCode) since the container itself is the security boundary:
claude --dangerously-skip-permissionsAdvantages:
- Strongest isolation — prompt injection attacks can only affect the container, not your host machine
- Safe to use DSP mode inside the container
- Reproducible, shareable environment
Disadvantages:
- iOS Simulator: Not available (requires macOS host)
- Android Emulator: Requires additional setup for hardware acceleration passthrough
- Visual testing: You can’t easily see the app UI running inside the container
- Higher setup effort compared to local strategies
Troubleshooting
Section titled “Troubleshooting”Repeated permission prompts
Section titled “Repeated permission prompts”If you keep getting prompted for the same tools every time you start a new session, your permissions likely aren’t persisted to your config file.
- Claude Code: Accepting a permission interactively writes it to
.claude/settings.json, so it persists across sessions. If you’re still being prompted, check that the file exists in your project root and that the tools appear inpermissions.allow(notpermissions.deny). - OpenCode: Selecting “Always Allow” only lasts for the current session — it is not written to disk. To persist permissions, you must manually add them to
opencode.jsonas shown in Strategy 1 above.
The fix in both cases is the same: add the permissions you need to your config file (project-level or global) so they’re loaded automatically at startup. See the Strategy 1 examples above for the full recommended configuration.