Kousigan A

Coding agent permissions: five boundaries a prompt can't set

Least privilege for AI coding agents: scope files, commands, network, secrets and actions, see what six agents document, and audit access with one prompt.

Last verified against official docs on

An AI coding agent can reach whatever its environment can reach: your files, the credentials on the machine and the network. Least privilege gives the agent enough access to finish its task and no more, and the tool enforces that limit, because a prompt can’t. More access makes an agent’s mistakes more expensive without making it any smarter.

The guide covers five boundaries to set, what six coding agents say they enforce, an access audit prompt and a security checklist.

This is part 6 of the series. Part 2 put control before execution, with a plan you approve. Part 4 collected evidence after execution. This part puts boundaries around execution.

Claude Code is the worked example. The tool behaviour below comes from each tool’s official docs, last verified on 11 October 2026; none of it was tested for this post.

The agent can reach whatever its environment can reach

An agent runs with the access of the place you start it in. OpenAI’s sandbox security guide says it in one line: “Agent-generated code can access the files, credentials, and network available to its environment.”

So your agent’s permissions are part of your architecture. If the agent runs on your main machine with your SSH keys and your cloud login, both are inside its reach.

“I trust the agent” is the wrong security model. The better question is: what can the agent do if it makes a mistake? A good model can still misread a task or run the wrong command. Trust the boundaries to limit the damage when something goes wrong.

That doesn’t mean “never give AI access”. An agent with no tools is a chat window. The engineering problem is controlled autonomy: give the agent the access the task needs, and design the environment so the rest isn’t there to use.

Every coding agent has five boundaries to set:

Boundary The question to ask
Files What can it read and write?
Commands What can it execute?
Network Where can it connect?
Credentials Which identities can it use?
Actions What can it change outside the project?

Least privilege: permission follows the task

Least privilege for a coding agent is a ladder. Each step adds a new kind of risk, so climb only as far as the task needs:

Read → Write → Execute → Network → External systems → Production

Don’t jump straight to the bottom. A documentation task needs to read the repository and write docs. It probably needs no production credentials, no database access and no deployment rights.

A local feature needs to read and write project files, run the tests and run local commands. There is still no reason for production access.

Contain the blast radius

Where the agent runs matters as much as what it may do. The risky setup takes no effort at all:

Agent → your main machine → everything you own

The safer setup puts layers in between:

Agent → isolated environment → project → limited tools → limited credentials

OpenAI’s sandbox security guide gives the same advice: “Run workloads in isolated compute, such as virtual machines. Use separate environments for users or workloads that must not share data.” A container or a separate user account counts too.

Whether an agent can make a mistake is only half the question. Ask how far the mistake can travel:

Blast radius Example
Low A wrong local test
Medium A broken pull request
High A published package
Very high The production database, a production deployment, an exposed credential

The higher the blast radius, the stronger the boundary and the approval should be.

Set the five boundaries

Files: scope what it can read and write

Filesystem access is the boundary people remember, and it still has gaps. In several agents, a blocked path is blocked only for the agent’s own file tools.

Claude Code is a clear example. Its permissions docs say a Read(./.env) deny rule blocks its file tools and the file commands it recognises in Bash, such as cat. The same docs say the rules don’t apply to “arbitrary subprocesses that read or write files indirectly, like a Python or Node script that opens files itself”. For a block that covers every process, they point you to the sandbox.

Keep sensitive directories out of reach, and deny the paths the agent has no reason to read. Where you start the agent matters too. GitHub’s Copilot CLI docs say “Typically, you should not launch Copilot CLI from your home directory.”

Commands: allow a short list, ask for the rest

Shell access is where the agent can do almost anything you can. A safer setup is a short list of commands that run without asking, such as tests, lint, the build and git diff. Everything else gets a prompt or a block.

Be careful about what a command rule really matches. Claude Code’s Bash rule docs say a Bash deny or ask rule “covers the invocation Claude usually produces and isn’t a security boundary around the program”. A rule matches the command text, so the same program called another way can slip past it. For limits that don’t depend on the text, the docs point to sandboxing, which the operating system enforces.

Network access is a permission too

People lock down files and forget the network. But where can the agent connect? These destinations are not equal:

localhost · package registry · GitHub · documentation · internal API · production API

A safer pattern sends the agent only to allowed destinations, through an approved network path. OpenAI’s sandbox security guide says “Allow outbound traffic only to approved endpoints”. GitHub’s firewall docs explain why it limits the Copilot cloud agent’s internet access: “Unexpected behavior from Copilot, or malicious instructions, could lead to code or other sensitive information being leaked to remote locations.”

Secrets: if the agent doesn’t need the credential, don’t expose it

Secrets should never sit where agent-generated code can freely read them:

  • .env files
  • production API keys
  • cloud admin tokens
  • database passwords
  • personal access tokens

The better pattern keeps the credential behind a boundary the agent can’t open:

Agent → approved operation → credential boundary → external system

An environment variable is still inside the boundary. OpenAI’s guide warns that “Injecting a stored secret into the environment still exposes it to agent-generated code.” Claude Code’s sandbox docs say the same: sandboxed commands inherit its environment, “including any secrets in its environment”. Claude Code has a sandbox.credentials setting to deny or mask them, but “There is no built-in credential deny list, so only the files and variables you list are restricted.”

Here is an example .claude/settings.json for a local feature task. It denies reads of the env file and a secrets folder, asks before any push, and turns on the sandbox with two allowed domains:

.claude/settings.json
{
  "permissions": {
    "deny": ["Read(./.env)", "Read(./secrets/**)"],
    "ask": ["Bash(git push *)"]
  },
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "network": {
      "allowedDomains": ["github.com", "*.npmjs.org"]
    },
    "credentials": {
      "files": [{ "path": "~/.aws/credentials", "mode": "deny" }],
      "envVars": [{ "name": "GITHUB_TOKEN", "mode": "deny" }]
    }
  }
}

allowUnsandboxedCommands: false turns off the retry that lets Claude ask to run a failed command outside the sandbox. The sandbox runs on macOS, Linux and WSL2; on native Windows, the sandboxing docs say commands run unsandboxed.

MCP servers and Git: every tool is more access

Every MCP server you connect adds tools, and each tool can reach a system outside your project. Review them like a dependency: what can each tool read, what can it change, and whose credentials does it use? Part 3 covers when MCP is worth adding at all.

Check, too, whether your sandbox covers MCP. In Claude Code, local MCP servers run outside the sandbox “with your full access” (sandboxing docs). In GitHub Copilot CLI, local MCP servers run inside it by default (local sandboxing docs).

Git permissions follow the same rule. Committing to a local branch is cheap to undo. Force pushing, pushing to the main branch or merging is not.

GitHub’s risks and mitigations page shows what scoped Git access looks like for its cloud agent. The agent “only has the ability to push to a single branch”. It “cannot directly run git push or other Git commands”, and it “cannot approve or merge a pull request”.

Some actions deserve a human at the boundary

Some actions are not like npm install, npm test or git diff:

  • deleting data or dropping a database
  • force pushing
  • deploying to production
  • rotating credentials
  • changing infrastructure
  • sending external messages
  • changing security settings

For these, a better pattern is:

Agent proposes → policy checks → human approval → action → audit

OpenAI’s guardrails guide has the same rule in its section on cybersecurity actions. “Pause ambiguous or high-risk actions for explicit human approval before the tool runs.” The same list asks you to “fail closed if review times out or becomes unavailable”. A gate that quietly lets the action through when nobody answers is not a gate.

Keep production out of the development loop

A development agent belongs with development resources:

Development → local resources → test data → sandbox

Not this:

Development agent → production database → production credentials → production deployment

If an agent genuinely needs production, give it scoped, auditable, narrowly authorised access, such as a read-only role for one task. A blanket credential is the thing to avoid.

Approval is not enforcement

A prompt that says “ask before doing X” isn’t a security boundary. “Please don’t access production” is a request. “The agent has no production credentials and no network route to production” is a boundary. Instruction, permission and enforcement are three different things.

Part 2 made this point about plans: a STOP in your prompt is not a plan mode. Security works the same way. Claude Code’s permissions docs say “Permission rules are enforced by Claude Code, not by the model. Instructions in your prompt or CLAUDE.md shape what Claude tries to do, but they don’t change what Claude Code allows.”

Even a real approval step can be weaker than it looks. GitHub’s note on approvals for Copilot automations that change issues says: “Approvals are a workflow convenience, not a security control. They don’t enforce a server-side boundary”. It goes on: “Use repository and agent permissions, not approvals, to control what an automation is allowed to do.”

Ask two questions of every tool: does it ask before acting, and what can the action reach once it runs?

Claude Code’s permission modes page separates them: modes “decide whether Claude asks before an action”, while the sandbox and outer isolation “decide what an action can reach once it runs”. Codex’s permissions page makes the same split: “Changing who reviews a request doesn’t expand the sandbox.”

Permissions, sandboxes and secret files in six coding agents

Agent Approvals and rules Sandbox Network Secret files
Claude Code (permissions, modes, sandbox) Modes from default (Manual) to bypassPermissions; auto mode, where a classifier reviews actions, is the starting mode in the terminal and VS Code from v2.1.283. allow, ask and deny rules; deny wins in every mode Off by default; /sandbox or sandbox.enabled. OS-enforced for shell commands and their child processes, on macOS, Linux and WSL2 Sandboxed commands reach only sandbox.network.allowedDomains, which start empty; WebFetch(domain:...) rules for the fetch tool Read(./.env) deny rules; sandbox.credentials to deny or mask files and environment variables
OpenAI Codex (approvals and security, permissions) approval_policy (on-request, never or granular); the Auto preset is workspace-write with on-request in a version-controlled folder OS-enforced sandbox_mode: read-only, workspace-write or danger-full-access; .git, .agents and .codex stay read-only Off by default in workspace-write; sandbox_workspace_write.network_access = true turns it on, and features.network_proxy limits it to allowed domains A permission profile entry such as "**/*.env" = "deny" makes matching files unreadable
Gemini CLI (policy engine, sandbox, ignore file) Approval modes default, autoEdit, plan and yolo; policy rules decide allow, deny or ask_user. Project-level policies currently have no effect, so use user or admin policies -s, GEMINI_SANDBOX or "tools": {"sandbox": true}; Seatbelt on macOS, Docker or Podman, a Windows native sandbox, gVisor on Linux The default macOS profile, permissive-open, allows network; the -proxied profiles send it through a proxy .geminiignore hides paths from the tools that support it
Cursor (run modes, agent security, ignore file) Terminal commands need approval by default. Run Modes: Allowlist, or Auto-review, which runs allowlisted calls, sandboxes other shell commands when it can and sends the rest to a classifier. Each MCP tool call needs approval unless you allowlist it Shell commands; Seatbelt on macOS, a native sandbox on Linux; set paths in sandbox.json. .git/config and .git/hooks are protected Blocked by default in the sandbox, opened by your network mode and sandbox.json .cursorignore blocks Agent, Tab, Inline Edit and @ mentions; .env* is on the default ignore list
Windsurf, now documented as Devin Desktop (terminal, ignore file) Four auto-execution levels: Disabled, Allowlist Only, Auto and Turbo; an allow list and a deny list. Admins on Teams and Enterprise can cap the level Not covered in the Desktop docs checked Not covered in the Desktop docs checked .devinignore paths “cannot be viewed, edited, or created by Devin”; a global .codeiumignore for enterprise
GitHub Copilot (CLI, local sandbox, firewall, content exclusion) The CLI asks the first time it needs a tool that can change or run files; --allow-tool and --deny-tool, and deny wins. --allow-all-tools gives it “the same access as you do” CLI: /sandbox enable, deny-by-default for files. The cloud agent runs in the GitHub Actions environment Cloud agent: a firewall is on by default, with a recommended allowlist for package registries Content exclusion on Business and Enterprise plans, but it is “currently not supported in Edit and Agent modes” in VS Code and other editors

Every row comes from the linked docs, last verified on 11 October 2026; none was tested for this post. Windsurf’s docs now redirect to Devin Desktop’s.

Gemini CLI’s docs also note that for unpaid tier and Google One users, Gemini CLI was replaced by Antigravity CLI on 18 June 2026.

Each of these docs has a line that says where the protection stops. Claude Code’s sandbox wraps shell commands only; its own file tools and hooks run outside it. Copilot’s firewall covers processes the cloud agent starts through its Bash tool, and MCP server processes fall outside it. GitHub says the firewall “should not be considered a comprehensive security solution”.

Cursor’s ignore file doesn’t reach the terminal or MCP tools, and its run modes docs call Auto-review “not a security boundary”. Windsurf’s deny list makes the agent “always ask for permission” before a listed command. Read that line before you rely on any setting.

The autonomy ladder: raise it only when the boundaries hold

The autonomy ladder below is a mental model, not a universal standard. Each level gives the agent more freedom and a bigger blast radius:

Level The agent can
0 Read only
1 Suggest changes
2 Edit files
3 Run local checks
4 Create a branch or pull request
5 Take external actions
6 Make production changes

The evidence from Part 4 is what tells you the work at one level is good enough to try the next.

Audit your agent’s access: a prompt and a checklist

Prompt: map the agent’s access before you restrict it

Use this prompt before you change any permission setting: it asks the agent to map what it can reach first, and then wait.

Prompt: map the agent's access before you restrict it
Workflow to assess: <describe how you use the agent in this repository>

Analyse this repository and the current AI-assisted
development workflow.

Do not change anything.

Create an access and autonomy assessment covering:

1. Filesystem access
2. Shell/command execution
3. Network access
4. MCP/tools/integrations
5. Git permissions
6. Credentials and secrets
7. External services
8. Production/deployment access
9. Destructive operations
10. Human approval points

For each capability, classify it as:

- Required
- Useful but optional
- Unnecessary
- High risk

For every high-risk capability, explain:

- What could go wrong
- What the agent actually needs
- What can be removed or restricted
- Whether isolation would help
- Whether human approval is appropriate
- What deterministic enforcement could be added

Never print, expose or commit secret values.

Do not commit, push, deploy, run destructive commands
or make external changes unless I explicitly authorise it.

Do not modify configuration yet.

If two reasonable attempts to inspect something fail,
stop and report the failure rather than repeatedly guessing.

Return a proposed least-privilege setup and wait for approval.

The prompt needs no tool-specific feature, but a plan or read-only mode, if your agent has one, enforces “Do not change anything” too.

A security checklist for coding agents

AI agent security check
AI AGENT SECURITY CHECK

□ Agent runs in an appropriate environment
□ Filesystem access is scoped
□ Sensitive directories are excluded
□ Shell access is controlled
□ Network access is restricted where possible
□ Production credentials are not exposed
□ Secrets are not printed or committed
□ MCP tools are reviewed
□ External actions require appropriate authorisation
□ Destructive commands have safeguards
□ Git permissions are scoped
□ Production access is separated
□ High-risk actions have approval gates
□ Agent activity is auditable
□ Tests and verification run before consequential changes
□ Failure and timeout behaviour is defined
□ Human review exists where the risk warrants it

Quick answers

What is least privilege for an AI coding agent?

Least privilege for an AI coding agent means it gets only the access its task needs: the files, commands, network and credentials for that job. Everything else stays out of its environment, so a mistake cannot reach it.

Is a prompt instruction enough to stop a coding agent from doing something?

A prompt instruction such as “don’t touch production” guides a coding agent but enforces nothing. Claude Code’s docs say Claude Code enforces its permission rules, while prompt instructions only shape what the model tries. A real limit comes from permission rules, a sandbox or missing credentials.

Should a coding agent have network access?

A coding agent should reach only the network destinations its task needs, such as a package registry. Codex keeps command network access off by default in its workspace sandbox, and the Copilot cloud agent runs behind a firewall allowlist.

How do you keep .env files away from a coding agent?

Keep .env files out of reach with your agent’s deny rules or ignore file, such as Read(./.env) in Claude Code or .cursorignore in Cursor. Check what the rule covers: several agents say their file blocks don’t apply to terminal commands or scripts.

What is the difference between sandboxing and permissions?

Permissions decide whether a coding agent asks before an action, runs it, or is refused. A sandbox decides what the action can reach once it runs, such as which folders and network domains, and the operating system enforces it.

More on AI coding is in the AI category.

Cartoon of Kousigan making a heart with his hands

Kousigan A

Build with AI. Ship with care.

Software engineer building real products with AI assistants. I write down what works: prompts, rules, skills and agents, and how to ship safely.