Permissions and unattended runs
Verified against Claude Code 2.1.263, Codex CLI 0.153.4
Unattended means nobody is there to click Allow. If the agent can prompt, the job hangs. If you skip every prompt, the agent can push to main, exfiltrate secrets, or wipe the runner. I want the middle: write the repo, run the tests, stop.
The pattern I use is restricted autonomy. The agent edits files. A deterministic step commits, opens the PR, and talks to the network. Permission denylists sit in front of the agent. Cost caps sit next to it.
In Claude Code
Permission rules are deny, then ask, then allow. A matching deny wins even if a narrower allow exists. Modes I opened on the permissions page:
default/manual: prompt on first use of a toolacceptEdits: write files and common filesystem commands without a promptplan: read-only explorationauto: a classifier reviews actionsdontAsk: deny anything not pre-allowed. Tools that need a person (AskUserQuestion, MCP tools markedrequiresUserInteraction) are denied even when an allow rule matchesbypassPermissions: skip prompts, including writes to.gitand.claude. Isolated VMs only
For -p (non-interactive), the built-in starting mode is Manual. You must pass the mode you want.
claude --bare -p "Run the test suite and fix failures" \
--permission-mode dontAsk \
--permission-prompts none \
--allowedTools "Read,Edit,Bash(npm test *),Bash(npm run build *)" \
--max-budget-usd 5
--bare skips auto-discovery of hooks, skills, custom commands, subagents, plugins, MCP servers, auto memory, and CLAUDE.md. Use it in CI so a teammate’s ~/.claude does not change the job. --permission-prompts none (v2.1.259+) denies anything that would wait on a host. --max-budget-usd is compared to the same session cost figure /usage shows.
Auth in bare mode does not read the keychain. Set ANTHROPIC_API_KEY.
Do not use bypassPermissions on a shared GitHub runner. dontAsk plus an allowlist is the minimum I would check in.
In Codex
The CLI reference names codex exec (alias codex e) for scripted runs. Sandbox values: read-only, workspace-write, danger-full-access. Approval values: untrusted, on-request, never. --full-auto still exists and prints a deprecation warning. Prefer --sandbox workspace-write.
codex exec --sandbox workspace-write --ask-for-approval never --ignore-user-config \
"Run the test suite and fix failures. Do not commit or push."
--ignore-user-config skips $CODEX_HOME/config.toml. Auth still uses CODEX_HOME. --ignore-rules skips user and project execpolicy .rules files. Do not pass --dangerously-bypass-approvals-and-sandbox on a shared runner.
Permission profiles (:read-only, :workspace, :danger-full-access) are a separate system. The permissions page says not to mix profiles with sandbox_mode / --sandbox in one session.
In Cursor
Headless CLI:
export CURSOR_API_KEY=...
agent -p --force "Apply the lint fixes and stop"
-p / --print is non-interactive. Without --force (alias --yolo) the agent proposes edits and does not apply them. Output formats: text, json, stream-json.
Cloud agents load project hooks from .cursor/hooks.json. They do not load ~/.cursor/hooks.json. User-level hooks stay on your laptop. Put the build gate in the repo or it will not run in the cloud.
Minimum safe CI config
- Isolated runner. One job, one checkout, no shared workspace credentials beyond
GITHUB_TOKEN. - Allowlist the tools the agent needs. Deny everything else.
- Agent writes files. A later step with a fixed script runs
git commit,gh pr create, and any network install. - A cost cap (
--max-budget-usdfor Claude Code). Fail the job when it trips. - A verify command after the agent exits. The hook or the workflow, not the model, decides if the PR opens.
If you cannot write the allowlist, you are not ready for unattended. Stay interactive.
Sources
- https://code.claude.com/docs/en/permissions
- https://code.claude.com/docs/en/headless
- https://code.claude.com/docs/en/iam
- https://code.claude.com/docs/en/costs
- https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md
- https://developers.openai.com/codex/permissions
- https://developers.openai.com/codex/cli/reference
- https://cursor.com/docs/cli/headless
- https://cursor.com/docs/agent/hooks