Skip to content

Comments

feat(policy): implement project-level policy support#18682

Merged
Abhijit-2592 merged 14 commits intomainfrom
abhijit-2592/read-proj-dir-policy-file
Feb 20, 2026
Merged

feat(policy): implement project-level policy support#18682
Abhijit-2592 merged 14 commits intomainfrom
abhijit-2592/read-proj-dir-policy-file

Conversation

@Abhijit-2592
Copy link
Contributor

@Abhijit-2592 Abhijit-2592 commented Feb 9, 2026

Summary

This PR implements support for project-level policies in the Gemini CLI. It allows users to define fine-grained tool execution rules within a project's configuration directory ($PROJECT_ROOT/.gemini/policies), filling the gap between user-wide preferences and system-wide admin enforcement.

Details

The policy engine now supports a new Project Tier (Base 2), creating the following hierarchy:

  1. Admin (Tier 4): System-wide enforcement (e.g., /etc/gemini-cli/policies). Always wins.
  2. User (Tier 3): Personal preferences (~/.gemini/policies). Overrides project settings.
  3. Project (Tier 2): Project-specific rules ($PROJECT_ROOT/.gemini/policies). Overrides default settings.
  4. Default (Tier 1): Built-in safety nets.

Key Changes:

  • Policy Integrity (New):

    • Implemented Policy Integrity Verification: To prevent malicious modifications, the CLI calculates a checksum (SHA-256) of the project policy directory (filenames + content).
    • Interactive Mode: If policies are new or changed, the user is prompted via a UI dialog to explicitely accept and load them.
    • Non-Interactive Mode: The CLI will warn and load the new policies
    • Storage: Checksums are securely stored in policy_integrity.json in the global config directory.
  • Core:

    • Updated PolicyEngineConfig to accept a projectPoliciesDir.
    • Introduced PROJECT_POLICY_TIER constant and updated priority calculation logic.
    • Updated TOML loader to handle the new tier.
    • Added PolicyIntegrityManager for hash calculation and verification.
  • Storage: Added getProjectPoliciesDir() and getPolicyIntegrityStoragePath() to the Storage class.

  • CLI:

    • Updated loadCliConfig to integrate integrity checks.
    • Security: Added a strict check to ensure project policies are only loaded if the workspace is trusted. Untrusted workspaces will ignore local policy files.
    • Added PolicyUpdateDialog for user confirmation.
  • Documentation: Updated docs/core/policy-engine.md to reflect the new hierarchy and configuration options.

Related Issues

Closes #18679

How to Validate

  1. Setup:

    • Checkout this branch.
    • Run npm run build:all.
    • Ensure your workspace is trusted (or use a trusted directory).
  2. Verify Hierarchy (User > Project):

    • Create a project policy (.gemini/policies/project.toml) that allows a command.
    • Create a user policy (~/.gemini/policies/user.toml) that denies the same command.
    • Run the command. It should be denied (User wins).
  3. Verify Integrity:

    • Modify a project policy file.
    • Run the CLI. You should see a dialog asking to accept the changes when project policies changes.
    • Run with --prompt "hi" (non-interactive). You should see a warning and policies should NOT load.
    • Run with --prompt "hi" --accept-changed-policies. You should see a warning (auto-accept) and policies SHOULD load.
  4. Verify Security (Untrusted Workspace):

    • Mark the current workspace as untrusted.
    • Create a project policy that allows a restricted tool.
    • Attempt to use the tool. The project policy should be ignored.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@Abhijit-2592 Abhijit-2592 requested review from a team as code owners February 9, 2026 21:57
@Abhijit-2592 Abhijit-2592 requested a review from jacob314 February 9, 2026 21:57
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Abhijit-2592, 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 Gemini CLI's policy engine by introducing support for project-level policies. This new tier provides a crucial layer of granular control, allowing developers to define specific tool execution rules within their project's configuration, bridging the gap between global user preferences and system-wide administrative mandates. A key security enhancement ensures these project policies are only applied in trusted workspaces, preventing potential malicious overrides.

Highlights

  • New Policy Tier: Introduced a new 'Project' policy tier (Tier 3) to allow project-specific policy definitions, providing more granular control over tool execution within a project's configuration directory.
  • Updated Policy Hierarchy: The policy hierarchy has been re-established to prioritize policies in the order: Admin (Tier 4) > Project (Tier 3) > User (Tier 2) > Default (Tier 1).
  • Security Enhancement: Implemented a critical security measure to ensure project-level policies are only loaded and applied if the workspace is explicitly trusted, preventing malicious configurations from untrusted repositories.
  • Core Policy Engine Updates: The core policy engine configuration and TOML loader have been updated to recognize, process, and correctly prioritize policies from the new project tier.
  • CLI Integration: The CLI's configuration loading mechanism now integrates project policies, dynamically determining their path and applying them based on workspace trust.
  • Documentation and Testing: Comprehensive documentation updates reflect the new policy tier and hierarchy, and new unit and integration tests have been added to validate the project policy functionality and security.
Changelog
  • docs/core/policy-engine.md
    • Updated the policy tier table to include 'Project' as Tier 3 and shifted 'Admin' to Tier 4.
    • Revised the policy override guarantees to reflect the new 'Project' tier's position in the hierarchy.
    • Added the '$PROJECT_ROOT/.gemini/policies/*.toml' location for project policies in the policy locations table.
    • Updated priority examples to include project policy calculations.
  • packages/cli/src/config/config.test.ts
    • Modified existing loadCliConfig test calls to accommodate the new projectPoliciesDir argument, passing undefined to maintain previous behavior.
  • packages/cli/src/config/config.ts
    • Imported the Storage class.
    • Added logic within loadCliConfig to determine projectPoliciesDir using Storage.getProjectPoliciesDir() only if the trustedFolder flag is true.
    • Passed the newly determined projectPoliciesDir to createPolicyEngineConfig.
  • packages/cli/src/config/policy.ts
    • Updated the createPolicyEngineConfig function signature to accept an optional projectPoliciesDir argument.
    • Modified the internal call to createCorePolicyEngineConfig to pass this new projectPoliciesDir argument.
  • packages/cli/src/config/project-policy-cli.test.ts
    • Added a new test file to verify the CLI's integration with project-level policies.
    • Includes tests for Storage.getProjectPoliciesDir existence, correct passing of projectPoliciesDir to the core policy engine when the workspace is trusted, and ensuring projectPoliciesDir is not passed when the workspace is untrusted.
  • packages/core/src/config/storage.ts
    • Introduced a new public method getProjectPoliciesDir() which returns the path to the project-level policies directory (.gemini/policies within the current working directory).
  • packages/core/src/policy/config.ts
    • Defined new constants PROJECT_POLICY_TIER = 3 and updated ADMIN_POLICY_TIER = 4.
    • Modified getPolicyDirectories to accept an optional projectPoliciesDir and include it in the list of directories if provided.
    • Updated getPolicyTier to correctly identify and return PROJECT_POLICY_TIER for the project policies directory.
    • Modified createPolicyEngineConfig to accept and pass projectPoliciesDir to getPolicyDirectories and getPolicyTier.
    • Updated comments explaining the priority bands to reflect the new Project tier.
  • packages/core/src/policy/project-policy.test.ts
    • Added a new test file to validate the core logic of project-level policies.
    • Tests include verifying that project policies are loaded with the correct Tier 3 priority, demonstrating the hierarchy (Admin > Project > User > Default), and confirming that project policies are ignored if projectPoliciesDir is not provided.
  • packages/core/src/policy/toml-loader.ts
    • Updated the tier type in the PolicyFileError interface to include 'project'.
    • Modified the getTierName function to correctly return 'project' for Tier 3 and 'admin' for Tier 4.
Activity
  • The author has updated relevant documentation to reflect the new policy changes.
  • New tests have been added to cover the implemented project policy functionality and security aspects.
  • The changes have been validated on MacOS.
  • This pull request addresses and closes issue feat: implement project-level policy support #18679.
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.

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Size Change: +13.3 kB (+0.05%)

Total Size: 24.6 MB

Filename Size Change
./bundle/gemini.js 24.5 MB +13.3 kB (+0.05%)
ℹ️ View Unchanged
Filename Size
./bundle/sandbox-macos-permissive-open.sb 890 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB
./bundle/sandbox-macos-strict-open.sb 4.82 kB
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB

compressed-size-action

Copy link
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 implements support for project-level policies, introducing a new 'Project' tier into the policy engine's hierarchy, allowing repositories to define tool execution rules. The changes are well-structured, with updates to the core policy logic, storage configuration, and CLI wiring, and the documentation has been updated. However, despite the inclusion of a workspace trust check to prevent loading policies from untrusted folders, the implementation is vulnerable to a trust bypass. If local workspace settings can disable the folder trust mechanism, a malicious repository could force itself to be trusted and load arbitrary policies, potentially leading to Remote Code Execution. This violates the rule that security-sensitive settings should not be overridden by less-trusted configuration scopes. It is recommended to perform the trust check using only verified, global settings before any local configuration is processed to mitigate this risk.

@gemini-cli gemini-cli bot added the area/enterprise Issues related to Telemetry, Policy, Quota / Licensing label Feb 9, 2026
@Abhijit-2592 Abhijit-2592 force-pushed the abhijit-2592/read-proj-dir-policy-file branch 4 times, most recently from e394e26 to ddf5a68 Compare February 12, 2026 20:52
@jacob314 jacob314 requested a review from galz10 February 12, 2026 20:53
@Abhijit-2592 Abhijit-2592 force-pushed the abhijit-2592/read-proj-dir-policy-file branch from ddf5a68 to 93e34ed Compare February 13, 2026 19:24
@gniumg-source gniumg-source mentioned this pull request Feb 13, 2026
@Abhijit-2592 Abhijit-2592 force-pushed the abhijit-2592/read-proj-dir-policy-file branch from e0504e8 to 719bb0d Compare February 14, 2026 00:53
Copy link
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

UI portion looks good once these comments are addressed.

@Abhijit-2592 Abhijit-2592 force-pushed the abhijit-2592/read-proj-dir-policy-file branch 3 times, most recently from a9753ed to 5d0ffb7 Compare February 19, 2026 22:48
Copy link
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

lgtm

@Abhijit-2592
Copy link
Contributor Author

Documentation: Safety Checker Tier Alignment

I have updated the SafetyCheckerRule logic in toml-loader.ts to align with the tiered precedence system used by the rest of the policy engine. Here is the technical rationale for these changes:

  1. Tier Precedence Alignment: Previously, safety checkers used raw integer priorities. This meant a 'Default' checker (Tier 1) with priority 500 would incorrectly execute before a 'User' checker (Tier 3) with priority 10. By applying transformPriority, we ensure that User and Workspace checkers correctly override/precede Default ones (e.g., Tier 3 becomes 3.010 vs Tier 1 1.500).

  2. Fix for Selective Reloading: The removeCheckersByTier(tier) method relies on Math.floor(priority) to identify which checkers belong to which tier (1, 2, or 3). Without transformation, raw priorities (like 100) would never match the tier number, making clean policy reloading and 'hot-swapping' impossible.

  3. Attribution and Debugging: The source field was added to allow the engine to report exactly which file (e.g., 'Workspace: project.toml') restricted a tool call. This is critical for users to troubleshoot denied actions in a multi-file configuration.

I have also added unit tests to toml-loader.test.ts to verify that these tiered priorities are correctly assigned.

@Abhijit-2592 Abhijit-2592 force-pushed the abhijit-2592/read-proj-dir-policy-file branch from 5d0ffb7 to 831f7bd Compare February 19, 2026 23:57
Introduces a new 'Project' tier (Tier 3) for policies, allowing users to define
project-specific rules in `$PROJECT_ROOT/.gemini/policies`.

Key Changes:
- **Core**: Added `PROJECT_POLICY_TIER` (3) and bumped `ADMIN_POLICY_TIER` to 4.
  Updated `getPolicyDirectories`, `getPolicyTier`, and `createPolicyEngineConfig` to handle
  project-level policy directories.
- **Storage**: Added `getProjectPoliciesDir()` to the `Storage` class.
- **CLI**: Updated `loadCliConfig` to securely load project policies.
  Crucially, project policies are **only loaded if the workspace is trusted**.
- **Tests**: Added comprehensive tests for both core policy logic and CLI integration,
  verifying priority hierarchy (Admin > Project > User > Default) and trust checks.

This hierarchy ensures that project-specific rules override user defaults but are still
subject to system-wide admin enforcement.
Adds the 'Project' tier (Base 3) to the policy engine documentation.
Updates the priority hierarchy, location table, and formula examples
to reflect the new Project -> User precedence.
…efault

Updates the policy engine to prioritize User policies over Project-specific policies.
This change is a security measure to ensure that users maintain control over their
environment and are not inadvertently compromised by policies defined in a cloned
repository.

Key Changes:
- Swapped Tier 2 (now Project) and Tier 3 (now User).
- Updated documentation to reflect the new hierarchy.
- Updated all built-in policy TOML files with correct tier information.
- Adjusted all tests and integration test expectations to match new priority values.
Adds a security mechanism to detect and prompt for confirmation when project-level policies are added or modified. This prevents unauthorized policy changes from being applied silently.

- PolicyIntegrityManager calculates and persists policy directory hashes.
- Config integrates integrity checks during startup.
- PolicyUpdateDialog prompts users in interactive mode.
- --accept-changed-policies flag supports non-interactive workflows.
- toml-loader refactored to expose file reading logic.
…tegration tests

- Refactored `PolicyUpdateDialog` to remove side effects (`process.exit`, `relaunchApp`) and delegate logic to parent.
- Updated `AppContainer` to handle relaunch logic.
- Added comprehensive unit tests for `PolicyUpdateDialog`.
- Fixed `project-policy-cli.test.ts` to correctly mock `PolicyIntegrityManager`.
- Fixed typo in `packages/core/src/policy/config.ts`.
Updates config.test.ts to fix createPolicyEngineConfig mock expectations and expands project-policy-cli.test.ts to cover integrity check scenarios (NEW, MISMATCH) and interactive confirmation flows.
Updates the terminology and configuration for the intermediate policy tier
from "Project" to "Workspace" to better align with the Gemini CLI ecosystem.

Key changes:
- Renamed `PROJECT_POLICY_TIER` to `WORKSPACE_POLICY_TIER`.
- Renamed `getProjectPoliciesDir` to `getWorkspacePoliciesDir`.
- Updated integrity scope from `project` to `workspace`.
- Updated UI dialogs and documentation.
- Renamed related test files.
This change eliminates the need for a CLI restart when a user accepts new or
changed project-level policies. Workspace rules are now dynamically injected
into the active PolicyEngine instance.

Key improvements:
- Added Config.loadWorkspacePolicies() to handle mid-session rule injection.
- Fully encapsulated acceptance and integrity logic within PolicyUpdateDialog.
- Integrated centralized keybindings (Command.ESCAPE) for dialog dismissal.
- Refactored PolicyIntegrityManager tests to use a real temporary directory
  instead of filesystem mocks for improved reliability.
- Updated copyright headers to 2026 across affected files.
- Added UI snapshot tests for the policy update dialog.

Addresses review feedback from PR #18682.
Simplified createPolicyEngineConfig signature by moving workspacePoliciesDir into the PolicySettings interface. Updated all core and CLI call sites and tests to align with the consolidated settings structure.
Centralized the workspace policy discovery and integrity verification
logic into a new 'resolveWorkspacePolicyState' helper in the policy
module. This significantly simplifies 'loadCliConfig' in config.ts,
reducing its imperative bloat and removing low-level core dependencies
from the main configuration flow.

- Moved workspace integrity check and directory discovery to policy.ts
- Refactored loadCliConfig to use the new declarative resolver
- Added comprehensive unit tests for the resolver using real temp dirs
- Cleaned up redundant function arguments in core and CLI calls
- Verified project integrity with 'npm run preflight'
…y reliability

Addressed PR review feedback by refining policy lifecycle management,
improving TypeScript strictness, and streamlining CLI arguments.

- Removed redundant '--accept-changed-policies' flag.
- Updated non-interactive mode to automatically load changed policies with a warning.
- Replaced unsafe 'as NodeJS.ErrnoException' casts with 'isNodeError(e)'.
- Implemented safer TOML/JSON parsing with better validation and type guards.
- Added 'removeRulesByTier' and 'removeCheckersByTier' to PolicyEngine for clean policy reloading.
- Integrated a concurrency guard in PolicyUpdateDialog to prevent interleaved calls.
- Updated CLI and SDK tests to align with new logic and improved type safety.
@Abhijit-2592 Abhijit-2592 force-pushed the abhijit-2592/read-proj-dir-policy-file branch from 831f7bd to ed6a20d Compare February 20, 2026 00:04
@Abhijit-2592 Abhijit-2592 added this pull request to the merge queue Feb 20, 2026
Merged via the queue into main with commit d8b24e6 Feb 20, 2026
26 of 27 checks passed
@Abhijit-2592 Abhijit-2592 deleted the abhijit-2592/read-proj-dir-policy-file branch February 20, 2026 00:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/enterprise Issues related to Telemetry, Policy, Quota / Licensing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: implement project-level policy support

3 participants