feat(policy): support auto-add to policy by default and scoped persistence#20361
feat(policy): support auto-add to policy by default and scoped persistence#20361spencer426 merged 9 commits intomainfrom
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
|
Size Change: +6.46 kB (+0.02%) Total Size: 26.2 MB
ℹ️ View Unchanged
|
2bbda31 to
07bea4f
Compare
5c02895 to
1dbe1de
Compare
9095519 to
f904a4b
Compare
This comment was marked as outdated.
This comment was marked as outdated.
99b4d9d to
72a9ad3
Compare
jacob314
left a comment
There was a problem hiding this comment.
LGTM once we back out the functionality making approve all the default which needs to be an opt in only setting or removed.
18b6f51 to
c70ca89
Compare
…rity consistency, and narrowing enforcement
- Set autoAddToPolicyByDefault to false (opt-in only) per Jacob's request. - Refactored regex pattern builders in utils.ts to be safer and avoid brittle slicing. - Updated documentation and JSON schema to reflect the new default value. - Restored and cleaned up priority constants and helpers in config.ts. - Improved test robustness by using escapeRegex in assertions. - Narrowed permanent approval label for file edits to be more specific.
c70ca89 to
45d9c5c
Compare
60bfdc0 to
014a13a
Compare
| // and wraps it in double quotes. We simply prepend the key name and escape | ||
| // the entire sequence for Regex matching without any slicing. | ||
| const encodedPath = JSON.stringify(filePath); | ||
| return escapeRegex(`"file_path":${encodedPath}`); |
There was a problem hiding this comment.
why are we calling escapeRegex here and line 116? That seems unneeded.
There was a problem hiding this comment.
gemini tells me without this we are insecure? i blocked the follow on pr just to verify...
Review and Manual Test Results
- Intent of the PR: The author intended to remove the escapeRegex wrapping from buildFilePathArgsPattern and buildPatternArgsPattern in packages/core/src/policy/utils.ts, claiming that JSON.stringify already safely escapes paths and patterns.
- Identified Bug: Both the static review and the manual script execution identified a critical flaw in this logic. While JSON.stringify safely escapes strings for valid JSON syntax (e.g., quotes and newlines), it does not escape Regular Expression control
characters (such as ., +, ?, [, ], (, ), etc.). - Manual Execution Findings: A test script verified that without escapeRegex, any file path or pattern containing regex special characters (like src/foo[bar].ts) fails to match its literal string counterpart because the characters are interpreted as regex operators
rather than literal characters.
Final Recommendation
Reject the PR.
The changes introduce a critical bug that compromises the security, accuracy, and core logic of the policy engine. The removal of escapeRegex breaks literal string matching for any file path or pattern containing regex special characters.
The assessment recommends leaving a comment on the PR explaining the difference between JSON escaping and Regex escaping, and requesting that the author restore the escapeRegex calls around JSON.stringify.
There was a problem hiding this comment.
Sorry my mistake. I think the correct order of operations is
JSON.stringify(escapeRegex(filePath))
Calling escapeRegex after the JSON.stringify doesn't make sense but calling it before is reasonable if the pattern we are trying to match is the filePath as an escaped regexp.
- Reverted the removal of `escapeRegex` around `JSON.stringify()` in `buildFilePathArgsPattern` and `buildPatternArgsPattern`. As pointed out in PR review #20361, `escapeRegex` is required to prevent Regular Expression control characters (like `.` or `+` in filenames) from acting as regex wildcards, which could allow overly broad policy matches (e.g. `foo.ts` matching `fooXts`). - Removed the old comment documenting LLM generation. - Added explanatory comments explaining exactly why `escapeRegex` is necessary for safety when matching literal stringified arguments.

Summary
This PR implements the "auto-add to policy by default" feature (#17148) as an opt-in setting, streamlining the tool approval process in trusted workspaces while enhancing security through rule narrowing for edit/exec tools and workspace-scoped persistence.
Details
security.autoAddToPolicyByDefault(default:false) allows users to make "Allow for all future sessions" the default choice for tools in trusted workspaces.edittools (e.g.,write_file) andexectools are now strictly narrowed to the specific file or root command using relative paths..gemini/policies/auto-saved.toml) when the folder is trusted.utils.tsto use safeJSON.stringifylogic, avoiding brittle slicing.getAlwaysAllowPriorityFractionandALWAYS_ALLOW_PRIORITY_FRACTION.advanceTimersByTimeAsyncandescapeRegexfor assertions.EditToolpath correction was interfering with policy matching.Related Issues
Closes #17148
How to Validate
"security.autoAddToPolicyByDefault": trueand"security.enablePermanentToolApproval": truein your settings.editorwrite_file..gemini/policies/auto-saved.toml(if workspace policies are enabled) or the global auto-saved policy.Pre-Merge Checklist