Class: Kward::Permissions::Policy
- Inherits:
-
Object
- Object
- Kward::Permissions::Policy
- Defined in:
- lib/kward/permissions/policy.rb
Overview
Evaluates the opt-in permission policy for model-requested tool calls.
The policy is intentionally a decision layer, not a process sandbox. It can prevent Kward from starting a tool, but it cannot constrain a shell command after it has begun. OS-enforced sandboxing belongs at a lower process boundary.
Defined Under Namespace
Classes: Decision
Constant Summary collapse
- MODES =
%w[ask read-only workspace-write deny-by-default].freeze
- NETWORK_TOOLS =
%w[web_search fetch_content fetch_raw].freeze
- FILE_CHANGE_TOOLS =
%w[write_file edit_file].freeze
Class Method Summary collapse
Instance Method Summary collapse
-
#allow_for_session!(tool_name) ⇒ Object
Allows this model tool for the remaining lifetime of this policy object.
- #decision_for(tool_name, arguments, source: nil) ⇒ Object
- #enabled? ⇒ Boolean
-
#initialize(enabled: false, mode: "ask", allow: [], ask: [], deny: [], write_scopes: nil) ⇒ Policy
constructor
A new instance of Policy.
Constructor Details
#initialize(enabled: false, mode: "ask", allow: [], ask: [], deny: [], write_scopes: nil) ⇒ Policy
Returns a new instance of Policy.
43 44 45 46 47 48 49 50 51 |
# File 'lib/kward/permissions/policy.rb', line 43 def initialize(enabled: false, mode: "ask", allow: [], ask: [], deny: [], write_scopes: nil) @enabled = enabled == true @mode = normalize_mode(mode) @allow = normalize_rules(allow) @ask = normalize_rules(ask) @deny = normalize_rules(deny) @write_scopes = normalize_scopes(write_scopes) @session_allowed_tools = {} end |
Class Method Details
.from_config(config) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/kward/permissions/policy.rb', line 31 def self.from_config(config) = config["permissions"].is_a?(Hash) ? config["permissions"] : {} new( enabled: ["enabled"] == true, mode: ["mode"], allow: ["allow"], ask: ["ask"], deny: ["deny"], write_scopes: .key?("write_scopes") ? ["write_scopes"] : nil ) end |
Instance Method Details
#allow_for_session!(tool_name) ⇒ Object
Allows this model tool for the remaining lifetime of this policy object. A matching deny or ask rule still takes precedence over this temporary grant.
59 60 61 |
# File 'lib/kward/permissions/policy.rb', line 59 def allow_for_session!(tool_name) @session_allowed_tools[tool_name.to_s] = true end |
#decision_for(tool_name, arguments, source: nil) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/kward/permissions/policy.rb', line 63 def decision_for(tool_name, arguments, source: nil) return Decision.new(action: :allow, reason: "permissions disabled") unless enabled? request = request_for(tool_name, arguments, source: source) return Decision.new(action: :deny, reason: "matched deny rule") if matches?(@deny, request) return Decision.new(action: :ask, reason: "matched ask rule") if matches?(@ask, request) return Decision.new(action: :allow, reason: "matched allow rule") if matches?(@allow, request) return Decision.new(action: :allow, reason: "allowed for this session") if @session_allowed_tools[request.fetch("tool")] default_decision(request) end |
#enabled? ⇒ Boolean
53 54 55 |
# File 'lib/kward/permissions/policy.rb', line 53 def enabled? @enabled end |