Why Gemini CLI keeps asking for permission, and what "Allow for this session" really means
Gemini CLI asks before a tool call when no rule covers it. The dialog looks like one decision, but four things decide the answer: folder trust, approval mode, a session rule, and any saved or administrator rule. Choosing "Allow for this session" adds one layer. It does not clear the others.
Run gemini --version first. This is for the stable v0.65.0 release, published on 20 October 2026.
Checked against Gemini CLI's documentation on 27 October 2026.
Status, 27 October 2026: project-level policy files in .gemini/policies/ are documented as non-functional (#18186, open, updated 13 October 2026). An open report says the session option can still miss shell commands that include a path (#16750, open, updated 11 May 2026). Unpaid-tier and Google One users were moved to Antigravity CLI on 18 June 2026, so this page applies to paid, API-key, Vertex AI and enterprise installs; the Gemini CLI hub has the details.
What has to agree before a prompt appears#
A prompt is what the CLI shows when its policy engine returns ask_user. The engine checks the call against ordered rules and takes the highest-priority match. These layers decide what it finds.
Folder trust. Gemini CLI treats an untrusted folder as hostile. It does not load project settings, hooks (the settings.json scripts that can block a tool call), MCP servers (the external tool servers listed under mcpServers), or project GEMINI.md, and it refuses Auto-Edit and YOLO. It also does not offer a session or saved approval; the allow option is "Allow once" (an edit dialog may also offer "Modify with external editor"). Check /permissions trust or ~/.gemini/trustedFolders.json.
Approval mode. The mode sets the session posture: Default asks for writes and shell commands, Auto-Edit approves edits, Plan is read-only, and YOLO auto-approves tool calls except the exceptions below. The mode decides which rules are active before any dialog appears.
The rule the dialog writes. "Allow once" writes nothing. "Allow for this session" writes an in-memory rule that lasts until the CLI exits. "Allow for all future sessions" writes a TOML rule to disk, but only when the setting that enables it is on.
What each choice actually stores#
| Choice | What Gemini CLI records | How long it lasts |
|---|---|---|
| Allow once | Nothing | That one call |
| Allow for this session (shell) | An allow rule for each command root. For npm test, the root is npm. | The session, in the current mode and more permissive ones |
| Allow for this session (edit) | A rule for that file, and the session moves to Auto-Edit | The session |
| Allow tool for this session (MCP) | That one MCP tool | The session |
| Allow all server tools for this session | Every tool from that MCP server | The session |
| Allow for all future sessions (when enabled) | A TOML rule in ~/.gemini/policies/auto-saved.toml | Until you edit or delete the file |
The shell rule is a prefix, not the exact command. It is built from the command root and matched at the start of the string (the command-prefix matcher). Approving npm test covers npm run build for the session; it does not cover node script.js, because the first word differs.
Mode scope matters too. An approval made in Default applies to Default, Auto-Edit, and YOLO, not Plan. An approval made in Plan applies to all four; trusting something while read-only is deliberate global trust. A session approval on an edit also switches the session to Auto-Edit, so later edits stop asking.
The saved option is hidden by default: security.enablePermanentToolApproval is false. A fresh install in a trusted folder offers "Allow once" and "Allow for this session", not "Allow for all future sessions". Turn it on in ~/.gemini/settings.json if you want the saved choice. If you see neither option, check security.disableAlwaysAllow or admin.secureModeEnabled; despite the name, disableAlwaysAllow removes the session option too.
Why the same command asks again#
You are in a new session, or you changed mode. Session rules are memory. Closing the CLI clears them. Switching to Plan also hides them, because a Default-mode approval does not apply to Plan. /policies list shows which rules are active in the current mode.
The rule is a prefix, not the exact string. A command that starts with something else needs its own approval. An inline assignment can miss: CI=true npm test does not start with npm, even though the CLI may name npm as the root. An open report describes the path variant (#16750, open, updated 11 May 2026).
Redirection adds a condition. The policy engine asks when it sees >, >>, <, <<, or <<<, even when a command rule matches. A rule can opt out with allowRedirection = true; a session approval only does that when the approved command already had redirection. A later npm test > log can therefore ask again.
A higher rule wins. Session approvals are stored as a low-priority rule, below your ~/.gemini/policies rules and any admin rules. If a user policy returns ask_user or deny for the same tool in the same mode, it wins over the button you clicked. tools.confirmationRequired does the same. /policies list prints priority and source, so you can see the winner.
The options are hidden. An untrusted folder has no session option, and Auto-Edit and YOLO are refused. Separately, security.disableAlwaysAllow or admin.secureModeEnabled removes the session option; the only allow option is "Allow once". Check /permissions trust first, then /settings.
YOLO still has exceptions. A shell command whose flags came from untrusted context, or a build or test command after build files were modified, forces a confirmation even in YOLO; those commands offer only "Allow once". The ask_user tool also still asks. YOLO cannot be entered in an untrusted folder.
Folder trust: the gate before the mode#
Folder trust decides whether a project may load its own configuration. The trusted-folders page says the feature is disabled by default. The v0.65.0 settings schema and the trust UI (trustedFolders.ts, useFolderTrust.ts) default security.folderTrust.enabled to true; the CLI config loader (config.ts) falls back to false for the core flag. They do not agree, so check /settings and /permissions trust rather than assuming one default. On a fresh install the UI path normally shows the trust dialog.
The dialog offers trust for this folder, its parent (covering every subdirectory), or no trust. The choice is stored in ~/.gemini/trustedFolders.json. /permissions trust opens the same dialog later. The CLI's untrusted message says project settings, hooks, MCP servers, and project GEMINI.md files will not be applied.
In CI, an untrusted folder with trust enabled throws a fatal error instead of showing the dialog. --skip-trust or GEMINI_CLI_TRUST_WORKSPACE=true trusts the workspace for that run. Those flags remove the gate for the whole run.
The sandbox is a second boundary#
The sandbox does not answer the permission question. It limits what an already-approved command can touch. It is off by default, enabled with -s or --sandbox, GEMINI_SANDBOX, or tools.sandbox in settings. YOLO turns it on by default: YOLO removes the approval prompts, not the process boundary.
Sandboxing adds its own dialog. When a command needs network access or a path outside the sandbox, Gemini CLI shows a "Sandbox Expansion Request" with the same allow-once, session, and future-session choices. Those choices are tied to the command root, so approving an expansion for npm test can also cover other subcommands under npm for the session. It is still a separate decision from approving the command. If a command fails with "Operation not permitted", the sandbox is the layer to inspect.
security.toolSandboxing is a different, per-tool setting: it defaults to false and needs a restart when changed. It does not replace tools.sandbox.
Plan mode changes the contract#
Plan mode is Gemini CLI's read-only mode. It is enabled by default. Enter it with Shift+Tab, /plan, or gemini --approval-mode=plan. In Plan mode the policy engine denies the catch-all and allows a short list: read tools, read-only MCP tools with confirmation, ask_user, web_fetch and activate_skill with confirmation, the built-in research subagents, and writes to .md files in the plan directory. Approving the plan exits the mode and starts implementation.
An approval made in Plan mode applies to all modes, because choosing it while read-only is treated as deliberate global trust. An approval made in Default or Auto-Edit does not apply to Plan. So a command you allowed earlier can ask again the moment you enter Plan mode. If you want a command allowed only while planning, scope the policy to modes = ["plan"]; to allow it during implementation but not planning, list the other modes explicitly, as in modes = ["default", "autoEdit", "yolo"].
Make it stop, deliberately#
If the same command should be allowed in every session, write the rule instead of clicking through the dialog. Put it in ~/.gemini/policies/; project .gemini/policies/ is ignored at v0.65.0.
# ~/.gemini/policies/npm.toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["npm test", "npm run build"]
decision = "allow"
priority = 100
# Keep the command out of Plan mode; add "plan" to allow it there.
modes = ["default", "autoEdit", "yolo"]Start a new session after adding it. The rule is in the user tier, so it outranks a session approval and survives restarts. Add a deny rule for commands that must never run; deny is the documented replacement for the old tools.exclude setting.
If you want the dialog to offer a saved choice, set security.enablePermanentToolApproval to true and use "Allow for all future sessions". The rule lands in ~/.gemini/policies/auto-saved.toml. If the option is missing, the setting is off, the folder is untrusted, or disableAlwaysAllow is on.
For a whole task, change the mode. Auto-Edit covers edits but still asks for shell commands. YOLO covers everything except the exceptions above, and turns on the sandbox by default. YOLO cannot be set as the default approval mode in settings; it is a launch flag (--approval-mode=yolo) or the Ctrl+Y toggle. The toggle does not survive the next launch.
Check the real state#
Do not ask the model whether a rule is active; it cannot see the in-memory list reliably. Use the CLI's own surfaces:
/policies listprints the active rules grouped by mode, with priority and source. A rule whose source isDynamic (Confirmed)came from the dialog, whether session or saved./permissions trustopens the folder-trust dialog.~/.gemini/trustedFolders.jsonis the saved answer.- The settings dialog (
/settings) shows Default Approval Mode, Disable Always Allow, Allow Permanent Tool Approval, and Folder Trust. cat ~/.gemini/policies/auto-saved.tomlshows saved approvals;ls ~/.gemini/policiesshows your own rules.
Where to go next#
- Gemini CLI guides — the rest of the set.
- Does Gemini CLI read AGENTS.md? — if the rule you expected to stop the command is in an instruction file, not a policy.
- Why your Gemini CLI hook doesn't fire — if you tried a
BeforeToolhook as the enforcement layer. - Gemini CLI says MCP is connected — if the prompt is for an MCP tool that should already be allowed.