Skip to content

fix(policy): allow loading policy files via symbolic links#20289

Closed
berzrPTH wants to merge 5 commits intogoogle-gemini:mainfrom
berzrPTH:fix-symbolic-linked-policy
Closed

fix(policy): allow loading policy files via symbolic links#20289
berzrPTH wants to merge 5 commits intogoogle-gemini:mainfrom
berzrPTH:fix-symbolic-linked-policy

Conversation

@berzrPTH
Copy link
Copy Markdown

@berzrPTH berzrPTH commented Feb 25, 2026

Summary

Policy files (*.toml) discovered via directory scanning were previously
filtered using strictly entry.isFile(), silently ignoring valid files
that were symlinks.

This commit updates the directory filter to include symbolic links.
Furthermore, it refactors the file reading loop inside readPolicyFiles
to return an object containing both successfully read files and any
accumulated read errors. This ensures that a single unreadable file
(e.g., a broken symlink or an unreadable directory ending in .toml)
gracefully reports its error instead of throwing an exception and
causing the entire policy directory to be skipped.

Details

Changes:

  • Allowed isSymbolicLink() in fs.readdir filter for policy files.
  • Added per-file try...catch to readPolicyFiles for robust loading.
  • Refactored readPolicyFiles return type to { files, errors } to pass
    errors without breaking the directory loading loop.
  • Updated calls to readPolicyFiles in toml-loader.ts and
    integrity.ts to accommodate the new signature.

Related Issues

#20281

How to Validate

Pass the test:
npm test -w @google/gemini-cli-core -- src/policy/toml-loader.test.ts

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

Misc.

I'm relatively new to the TypeScript and the change is developed by me and Gemini CLI. Any guidance would be greatly appreciated.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @berzrPTH, 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 enhances the policy loading mechanism by introducing support for symbolic links, ensuring that policy files referenced through symlinks are correctly discovered and processed. It also significantly improves the robustness of the file reading process by implementing per-file error handling, allowing the system to continue loading other valid policy files even if some are unreadable, and providing comprehensive error reporting.

Highlights

  • Symbolic Link Support: Policy file discovery now includes symbolic links, allowing .toml files referenced via symlinks to be loaded correctly.
  • Robust File Reading: The readPolicyFiles function was refactored to handle individual file read errors gracefully, preventing a single unreadable file from halting the entire policy directory loading process.
  • Enhanced Error Reporting: readPolicyFiles now returns an object containing both successfully read policy files and any encountered errors, providing more detailed feedback on loading issues.
  • Function Signature Update: The readPolicyFiles function signature was updated to include a tierName parameter and to return an object { files, errors }, requiring updates to its callers.
Changelog
  • packages/core/src/policy/integrity.ts
    • Updated the call to readPolicyFiles to destructure the new { files, errors } return object.
  • packages/core/src/policy/toml-loader.ts
    • Modified the readPolicyFiles function signature to accept a tierName and return an object containing files and errors.
    • Updated the directory entry filter to include symbolic links (entry.isSymbolicLink()) when discovering .toml files.
    • Implemented a try...catch block within the file reading loop to handle errors for individual policy files.
    • Changed the return type of readPolicyFiles from PolicyFile[] to { files: PolicyFile[]; errors: PolicyFileError[] }.
    • Updated calls to readPolicyFiles within loadPoliciesFromToml to handle the new return signature and accumulate errors.
Activity
  • The author, berzrPTH, created this pull request to address an issue where policy files via symbolic links were silently ignored.
  • The author indicated they are relatively new to TypeScript and welcomed guidance on the changes.
  • The pull request includes changes to support symbolic links and improve error handling during policy file loading.
  • The author has validated the changes on Linux using npm run.
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.

@berzrPTH berzrPTH marked this pull request as ready for review February 25, 2026 09:25
@berzrPTH berzrPTH requested a review from a team as a code owner February 25, 2026 09:25
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 support for symbolic links when loading policy files, which is a good feature enhancement. The refactoring of readPolicyFiles to gracefully handle file read errors by returning both successfully read files and a list of errors is a solid improvement for robustness.

My review includes two critical security-related points:

  1. In packages/core/src/policy/integrity.ts, file read errors are silently ignored during the integrity hash calculation. This could lead to a user unknowingly accepting a weaker set of policies if a file becomes unreadable. I've suggested logging these errors to make this situation visible, aligning with the rule to log detailed errors for debugging.
  2. In packages/core/src/policy/toml-loader.ts, following symbolic links without validation introduces a path traversal vulnerability. A malicious symlink could cause the application to read sensitive files from outside the intended policy directory. I've recommended adding a check to ensure symlinks point to files within the policy directory, which aligns with rules on resolving symbolic links and sanitizing file paths to prevent path traversal vulnerabilities.

@gemini-cli gemini-cli bot added the priority/p1 Important and should be addressed in the near term. label Feb 25, 2026
@berzrPTH berzrPTH force-pushed the fix-symbolic-linked-policy branch from cca29bc to 2bea4f4 Compare February 26, 2026 06:01
@berzrPTH berzrPTH marked this pull request as draft February 26, 2026 06:09
@berzrPTH berzrPTH marked this pull request as ready for review February 26, 2026 06:18
@berzrPTH
Copy link
Copy Markdown
Author

berzrPTH commented Feb 26, 2026

fix(policy): allow symlinked policy files with tier-aware security

Enable the loading of `.toml` policy files via symbolic links across
all policy tiers. This change includes architectural improvements to
error handling and security hardening:

1. **Discovery**: Updated `readPolicyFiles` to recognize symlinks
  using `entry.isSymbolicLink()`.
2. **Robustness**: Refactored the loader to use value-based error
  reporting (`{ files, errors }`), ensuring that individual broken
  files do not prevent the rest of the directory from loading.
3. **Security**: Implemented path traversal protection for the
  `workspace` tier. Symlinks in project-local directories are now
  restricted to resolve within the policy folder, while global user
  policies remain unrestricted.
4. **Observability**: Updated `PolicyIntegrityManager` to be tier-aware
  and added explicit logging for unreadable policy files to assist
  with debugging integrity mismatches.

This ensures that users can manage policies via symlinks while
protecting against malicious repository-based path traversal attacks.

@gemini-code-assist Please review.

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 support for symbolic links in policy file loading and enhances error handling, including a valuable path traversal check for workspace policies. However, it introduces two high-severity security issues: a prototype property access bypass and a Time-of-Check to Time-of-Use (TOCTOU) race condition in the symlink validation. Furthermore, a pre-existing critical vulnerability in the policy integrity hashing logic, allowing hash collisions via a null-byte separator, needs urgent attention. There's also an opportunity to improve performance and error handling within the file reading loop. Addressing these security and performance concerns is crucial.

@berzrPTH berzrPTH force-pushed the fix-symbolic-linked-policy branch from 2bea4f4 to ec3af46 Compare February 26, 2026 06:43
@berzrPTH
Copy link
Copy Markdown
Author

@gemini-code-assist Please review.

@berzrPTH berzrPTH force-pushed the fix-symbolic-linked-policy branch from ec3af46 to ded335e Compare February 26, 2026 06:48
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 enhances policy file discovery by adding support for symbolic links. However, it introduces a high-severity path traversal vulnerability because the crucial security check to prevent symlinks from pointing outside the policy directory is only applied to 'workspace' policies. This check must be extended to all policy tiers to prevent attackers from reading arbitrary files. Additionally, while the implementation includes a security check for workspace policies and improves robustness by gracefully handling file read errors, there's a performance optimization needed for fs.realpath(baseDir) to avoid repeated asynchronous I/O operations.

@berzrPTH
Copy link
Copy Markdown
Author

Open for discussion and review. The PR is now ready for review.

@berzrPTH berzrPTH force-pushed the fix-symbolic-linked-policy branch from ca55508 to 1ce06aa Compare March 11, 2026 16:47
@berzrPTH
Copy link
Copy Markdown
Author

@kschaab PTAL. Rebased and fixed the test.

Update readPolicyFiles to include symbolic links in the directory scan
by checking `entry.isSymbolicLink()`. Add defensive error handling
within the file-reading loop to prevent a single unreadable file from
crashing the entire directory load.
…ding

Refactor `readPolicyFiles` to return a result object containing both
successfully read files and a list of errors. This enables the policy
engine to load all valid rules while explicitly tracking and reporting
failures (e.g., broken symlinks) instead of silently skipping them or
aborting the entire tier load. Update callers in `toml-loader.ts` and
`integrity.ts` to handle the new return signature.
Harden security by verifying that symbolic links in the 'workspace' tier
resolve to paths within the intended policy directory. This mitigates
potential data exfiltration risks from malicious repositories while
maintaining flexibility for user-owned global policies.
Update the PolicyIntegrityManager to pass the policy scope down to the
loader, ensuring that the correct security rules (like symlink
restrictions) apply during hashing. Implement a clean lookup mapping for
scopes and add explicit logging for any unreadable policy files
discovered during the integrity check to improve debuggability.
…ment

The change is required following the introduction of path traversal
protection in readPolicyFiles, which uses fs.realpath to resolve policy
paths.
@berzrPTH berzrPTH force-pushed the fix-symbolic-linked-policy branch from 1ce06aa to e781e7b Compare March 11, 2026 16:51
@gemini-cli
Copy link
Copy Markdown
Contributor

gemini-cli bot commented Mar 15, 2026

Hi there! Thank you for your interest in contributing to Gemini CLI.

To ensure we maintain high code quality and focus on our prioritized roadmap, we have updated our contribution policy (see Discussion #17383).

We only guarantee review and consideration of pull requests for issues that are explicitly labeled as 'help wanted'. All other community pull requests are subject to closure after 14 days if they do not align with our current focus areas. For this reason, we strongly recommend that contributors only submit pull requests against issues explicitly labeled as 'help-wanted'.

This pull request is being closed as it has been open for 14 days without a 'help wanted' designation. We encourage you to find and contribute to existing 'help wanted' issues in our backlog! Thank you for your understanding and for being part of our community!

@gemini-cli gemini-cli bot closed this Mar 15, 2026
@berzrPTH
Copy link
Copy Markdown
Author

Since the commit was automatically closed. I may just keep the branch as is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants