Skip to content

feat: Persistent "Always Allow" policies with granular shell & MCP support#14737

Merged
allenhutchison merged 22 commits intomainfrom
feature/always-allow-policy-persistence
Dec 12, 2025
Merged

feat: Persistent "Always Allow" policies with granular shell & MCP support#14737
allenhutchison merged 22 commits intomainfrom
feature/always-allow-policy-persistence

Conversation

@allenhutchison
Copy link
Copy Markdown
Contributor

@allenhutchison allenhutchison commented Dec 8, 2025

Description

This PR introduces the ability for users to persist "Always Allow" decisions for tools, streamlining the user experience by reducing repetitive confirmations. It includes granular control for shell commands and full support for MCP tools.

Changes

  • "Always Allow" Persistence: Users can now choose to always allow a tool execution, which saves a policy to the configuration.
  • Granular Shell Control: Added commandPrefix and argsPattern to policy configuration. This allows users to whitelist specific shell commands (e.g., git status) without granting blanket access to the shell tool.
  • MCP Tool Support: Implemented mcpName in policy configuration to distinguish tools from different MCP servers.
  • UI Enhancements: Updated the ToolConfirmationMessage UI to include the "Always allow" option.
  • Testing: Added new tests in packages/core/src/policy/persistence.test.ts to verify policy persistence and matching logic.

Commits

  • feat: implement always allow and save to policy option
  • feat: Add commandPrefix and argsPattern to policies for granular tool control and persistence.
  • feat: implement mcpName in policy updates and configuration for multi-cloud platform tools.

Fixes: #12898

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @allenhutchison, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the tool interaction experience by introducing persistent 'Always Allow' policies. It allows users to save their approval decisions, reducing friction for frequently used tools. The changes also bring granular control over shell commands and full support for Multi-Cloud Platform tools, ensuring that policy management is both flexible and robust.

Highlights

  • Always Allow Policy Persistence: Users can now choose to persist 'Always Allow' decisions for tools, saving these policies to the configuration to avoid repetitive confirmations.
  • Granular Shell Control: Policy configurations now support commandPrefix and argsPattern, enabling users to whitelist specific shell commands (e.g., 'git status') without granting broad access.
  • Multi-Cloud Platform (MCP) Tool Support: The policy configuration has been extended with mcpName to correctly distinguish and manage tools originating from different MCP servers.
  • UI Enhancements: The ToolConfirmationMessage UI has been updated to include the new 'Always allow and save to policy' option, providing a clear user choice for persistence.
  • New Policy Persistence Tests: New tests have been added in packages/core/src/policy/persistence.test.ts to thoroughly verify the functionality of policy persistence and its matching logic.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable feature for persisting "Always Allow" decisions, which will improve the user experience by reducing repetitive confirmations. The implementation of granular controls for shell commands using commandPrefix and argsPattern, as well as support for MCP tools via mcpName, is well-thought-out. The changes are logically structured, and the addition of persistence tests is a great step towards ensuring the reliability of this new functionality.

I've found one critical issue related to how policy data is persisted, which could lead to configuration file corruption. My specific comment addresses this with a suggested fix. Once that is addressed, this PR will be in excellent shape.

Comment thread packages/core/src/policy/config.ts
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Dec 8, 2025

Size Change: +5.1 kB (+0.02%)

Total Size: 21.6 MB

Filename Size Change
./bundle/gemini.js 21.6 MB +5.1 kB (+0.02%)
ℹ️ View Unchanged
Filename Size
./bundle/sandbox-macos-permissive-closed.sb 1.03 kB
./bundle/sandbox-macos-permissive-open.sb 890 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-closed.sb 3.29 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB

compressed-size-action

allenhutchison and others added 7 commits December 8, 2025 14:03
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit addresses all instances of the `@typescript-eslint/no-floating-promises` linting error.

Promises returned by `messageBus.publish` and other asynchronous operations within tool callbacks and tests are now properly awaited or explicitly marked with `void` (where appropriate, but `await` was preferred in these cases).

This ensures that asynchronous operations complete before subsequent logic executes and resolves linting warnings, improving code reliability and maintainability.
This change updates the `scripts/lint.js` to:
1. Upgrade `pip` in the virtual environment before installing `yamllint`. This resolves compatibility issues with newer Python versions (e.g. 3.14).
2. Explicitly use `https://pypi.org/simple` as the index URL for `yamllint` installation to avoid potential authentication issues with private registries.
Corrected the `yamllint` installer in `scripts/lint.js` to properly use `path.join` for constructing the cross-platform Python executable path.

Previously, `path.join` was incorrectly placed directly within the shell command string, leading to a `no-undef` ESLint error during pre-commit checks.
This change extracts the path construction into a JavaScript variable, ensuring it's evaluated correctly before being used in the shell command.

This fully addresses the review comment on PR #14746 regarding cross-platform compatibility.
Corrected formatting for the `argsPattern` escape string in `packages/core/src/policy/config.ts`.

This change aligns the string escaping with code style guidelines, splitting a long line for better readability.
@allenhutchison allenhutchison marked this pull request as ready for review December 9, 2025 00:42
@allenhutchison allenhutchison requested a review from a team as a code owner December 9, 2025 00:42
@gemini-cli gemini-cli Bot added size/l A large sized PR review/involved PRs that may take a lot of work to review labels Dec 9, 2025
Copy link
Copy Markdown
Contributor

@abhipatel12 abhipatel12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a few questions! Lmk what you think!

Comment thread packages/core/src/policy/config.ts
Comment thread packages/core/src/tools/tools.ts
Comment thread packages/core/src/policy/config.ts
Comment thread packages/core/src/policy/config.ts
Comment thread packages/core/src/ide/detect-ide.test.ts

if (message.persist) {
try {
const userPoliciesDir = Storage.getUserPoliciesDir();
Copy link
Copy Markdown
Contributor

@StoyanD StoyanD Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this will cause a security issue. The default behavior should be to persist the policies for a project, not the user.
Example scenario:

  1. i grant a bunch of shell permissions when working in my project
  2. i clone a random project from github and now gemini launches in that project with all the permissions I already allowed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something like this

 getProjectPolicies(): string {
    const policiesPath = path.join(this.getGeminiDir(), 'policies.json');
    if (!fs.existsSync(policiesPath)) {
      fs.mkdirSync(path.dirname(policiesPath), { recursive: true });
      fs.writeFileSync(policiesPath, '{}');
    }
    return policiesPath;
  }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't currently support policy at the project level only at the user and admin level.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't currently support policy at the project level only at the user and admin level.

but wont this cause a security issue once tool use permissions is persisted? if someone enables a sensitive permission for one project they dont expect that to translate to every project

Copy link
Copy Markdown
Contributor

@abhipatel12 abhipatel12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit about a comment but LGTM otherwise!

Comment thread packages/core/src/policy/config.ts
Comment thread packages/core/src/policy/config.ts Outdated
Comment thread packages/core/src/policy/config.ts
@allenhutchison allenhutchison added this pull request to the merge queue Dec 12, 2025
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Dec 12, 2025
@allenhutchison allenhutchison added this pull request to the merge queue Dec 12, 2025
Merged via the queue into main with commit 5f298c1 Dec 12, 2025
20 of 21 checks passed
@allenhutchison allenhutchison deleted the feature/always-allow-policy-persistence branch December 12, 2025 21:56
thacio added a commit to thacio/auditaria that referenced this pull request Dec 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review/involved PRs that may take a lot of work to review size/l A large sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add session persistence to calls that are always allowed

3 participants