Skip to content

Conversation

@wendytang
Copy link

@wendytang wendytang commented Mar 5, 2025

  • Stores tool permissions in ~/.config/goose/tool_permissions.json
  • Acts as a cache - tool calls that are an exact match and have been approved will not require confirmation again
{"permissions: {
    "developer__text_editor:b871f8fe6d390dac8d27b78210d2078815b3d57e57149d2b5ec2562859d116c7": [
      {
        "tool_name": "developer__text_editor",
        "allowed": false,
        "context_hash": "b871f8fe6d390dac8d27b78210d2078815b3d57e57149d2b5ec2562859d116c7",
        "readable_context": "Tool: developer__text_editor, Args: {\n  \"command\": \"write\",\n  \"file_text\": \"hey!\",\n  \"path\": \"/tmp/hello.txt\"\n}",
        "timestamp": 1741308946,
        "expiry": null
      },
      {
        "tool_name": "developer__text_editor",
        "allowed": true,
        "context_hash": "b871f8fe6d390dac8d27b78210d2078815b3d57e57149d2b5ec2562859d116c7",
        "readable_context": "Tool: developer__text_editor, Args: {\n  \"command\": \"write\",\n  \"file_text\": \"hey!\",\n  \"path\": \"/tmp/hello.txt\"\n}",
        "timestamp": 1741309005,
        "expiry": null
      }
]}

@wendytang wendytang changed the title [draft] feat: implement a tool permission store feat: implement a tool permission store Mar 7, 2025
@wendytang wendytang marked this pull request as ready for review March 7, 2025 01:06
@wendytang wendytang requested a review from yingjiehe-xyz March 7, 2025 01:06

let file = File::open(file_path)?;
let mut permissions: ToolPermissionStore = serde_json::from_reader(file)?;
permissions.permissions_dir = store.permissions_dir;
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need to clean up the expired entries?

Copy link
Author

Choose a reason for hiding this comment

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

yes, good call

if let Ok(tool_call) = request.tool_call.clone() {
if let Some(allowed) = store.check_permission(request) {
if allowed {
let output = capabilities.dispatch_tool_call(tool_call).await;
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need to output something to let users know the permission is skipped due to cache?

Copy link
Author

Choose a reason for hiding this comment

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

possibly, it could be a bit noisy imo

// This helps identify when the same tool is being used in a different context
let mut hasher = Hasher::new();
hasher.update(
serde_json::to_string(&tool_request.tool_call.as_ref().unwrap().arguments)
Copy link
Contributor

@yingjiehe-xyz yingjiehe-xyz Mar 7, 2025

Choose a reason for hiding this comment

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

do we want to hash on some argument params? I am wondering whether we will have low hit rate if we hash all, including argument param and value, like write file, the name can be different, but they are super similar

Copy link
Author

Choose a reason for hiding this comment

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

Similar thought - I was thinking to hash by tool name only at first, but this would lump all bash commands in one hash.

Any ideas about how to do the hash at the right level of granularity?

Copy link
Contributor

@yingjiehe-xyz yingjiehe-xyz Mar 7, 2025

Choose a reason for hiding this comment

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

yeah, kind of tricky, introducing some cosine similarity check may be overkilled. I am wondering whether we can have a set of normalized keys? for example in bash case, we have "command":write, "file_path": xxx, and we maintain a set containing "file_path", if it is in the normalized key set, like "file_path", we replace the value with "normalized_value" before hashing. Even with such case, we cannot handle all argument keys, we can just start with bash? how do you think?

@yingjiehe-xyz
Copy link
Contributor

Overall, lgtm, thanks for the improvment

@wendytang wendytang merged commit c4f571a into main Mar 7, 2025
6 checks passed
@wendytang wendytang deleted the wtang/permission_store branch March 7, 2025 18:54
michaelneale added a commit that referenced this pull request Mar 9, 2025
* main:
  feat: parallel processing in approve mode (#1575)
  Feat: support auto-including dirs in binary/bench-work-dir (#1576)
  refactor models component (#1535)
  docs: Add running Goose in CI tutorial (#1426)
  chore: remove logging of oauth config, just log where we output (#1573)
  feat: implement a tool permission store (#1516)
  minor typo (#1569)
  fix: open new session in working dir when hotkey is pressed (#1570)
  feat: store working directory for sessions  (#1559)
  docs: extension timeout (#1567)
  fix: update openrouter referer website to point to github page site (#1566)
  feat(cli): add --debug flag to goose session / run (#1564)
alicehau pushed a commit that referenced this pull request Mar 10, 2025
ahau-square pushed a commit that referenced this pull request May 2, 2025
cbruyndoncx pushed a commit to cbruyndoncx/goose that referenced this pull request Jul 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants