Skip to content

Conversation

@stanislavHamara
Copy link
Contributor

This PR introduces granular per-tool permission settings at the session level, complementing the existing pattern-based Allow/Deny rules.

Summary

  • Add Tools map to PermissionsConfig for per-tool control
  • Each tool can have enabled (true/false) and mode ("ask" / "always_allow")
  • Per-tool settings take priority over pattern-based rules
  • Fully backward compatible with existing Allow/Deny patterns

Permission Evaluation Order

  1. Session-level permissions (if configured)
    • Per-tool settings (Tools map) — most specific, checked first
    • Pattern-based Allow/Deny — broader rules, fallback
  2. Team-level permissions config
  3. YOLO mode (--yolo flag / ToolsApproved)
  4. Read-only hint (auto-approve read-only tools)
  5. Default: ask for user confirmation

API Examples

Enable YOLO mode for a session

curl -X POST http://localhost:8080/api/sessions/{id}/tools/toggle

Configure per-tool permissions

curl -X PATCH http://localhost:8080/api/sessions/{id}/permissions \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": {
      "tools": {
        "think":      { "enabled": true },
        "shell":      { "enabled": true, "mode": "ask" },
        "filesystem": { "enabled": true, "mode": "always_allow" },
        "dangerous":  { "enabled": false }
      }
    }
  }'

Mixed: per-tool settings with pattern fallback

curl -X PATCH http://localhost:8080/api/sessions/{id}/permissions \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": {
      "tools": {
        "shell": { "enabled": true, "mode": "ask" }
      },
      "allow": ["read_*", "think"],
      "deny": ["exec_*"]
    }
  }'

In this example:

  • shell requires confirmation (per-tool setting)
  • read_file, read_directory, think are auto-approved (pattern match)
  • exec_command is blocked (deny pattern)
  • Other tools fall through to default behavior

Code Examples

// Per-tool settings - granular control per tool
sess.Permissions = &session.PermissionsConfig{
    Tools: map[string]session.ToolPermission{
        "shell":      {Enabled: ptr(true), Mode: "ask"},          // require confirmation
        "filesystem": {Enabled: ptr(true), Mode: "always_allow"}, // auto-approve
        "dangerous":  {Enabled: ptr(false)},                      // disabled
    },
}

// Pattern-based rules - apply to multiple tools at once
sess.Permissions = &session.PermissionsConfig{
    Allow: []string{"read_*", "think"},  // auto-approve matching tools
    Deny:  []string{"shell", "exec_*"},  // block matching tools
}

// Mixed: per-tool settings take priority over patterns
sess.Permissions = &session.PermissionsConfig{
    Tools: map[string]session.ToolPermission{
        "shell": {Enabled: ptr(true), Mode: "ask"}, // overrides Deny pattern
    },
    Allow: []string{"*"},     // applies to tools not in Tools map
    Deny:  []string{"shell"}, // ignored for shell since it's in Tools map
}

New Types

const (
    PermissionModeAsk         = "ask"
    PermissionModeAlwaysAllow = "always_allow"
)

type ToolPermission struct {
    Enabled *bool  `json:"enabled,omitempty"`  // default: true
    Mode    string `json:"mode,omitempty"`     // "ask" (default) or "always_allow"
}

type PermissionsConfig struct {
    Tools map[string]ToolPermission `json:"tools,omitempty"`
    Allow []string                  `json:"allow,omitempty"`
    Deny  []string                  `json:"deny,omitempty"`
}

Testing

Added comprehensive tests for:

  • Per-tool always_allow mode auto-approves
  • Per-tool ask mode requires confirmation
  • Per-tool enabled: false rejects tool
  • Per-tool settings override pattern-based Allow rules
  • Tools not in Tools map fall through to pattern-based rules

@stanislavHamara stanislavHamara requested a review from a team as a code owner January 7, 2026 16:31
@stanislavHamara stanislavHamara marked this pull request as draft January 7, 2026 16:36
@stanislavHamara stanislavHamara marked this pull request as ready for review January 7, 2026 16:39
@dgageot dgageot merged commit 391f538 into docker:main Jan 8, 2026
5 checks passed
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