Class: Rubino::Security::PatternMatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/security/pattern_matcher.rb

Overview

Pattern-based permission matcher supporting wildcards. Matches tool names, commands, and file paths against configured rules.

Rules format in config:

permissions:
  "git *": "allow"
  "shell rm -rf *": "deny"
  "file_system write ~/.env": "deny"
  "shell bundle *": "allow"

Actions: “allow”, “ask”, “deny”

Constant Summary collapse

ACTIONS =
%w[allow ask deny].freeze

Instance Method Summary collapse

Constructor Details

#initialize(rules: {}) ⇒ PatternMatcher

Returns a new instance of PatternMatcher.



19
20
21
# File 'lib/rubino/security/pattern_matcher.rb', line 19

def initialize(rules: {})
  @rules = parse_rules(rules)
end

Instance Method Details

#match(tool_name, command_or_args = nil) ⇒ Object

Returns the action for a given tool call description Returns :allow, :ask, or :deny



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rubino/security/pattern_matcher.rb', line 25

def match(tool_name, command_or_args = nil)
  full_string = [tool_name, command_or_args].compact.join(" ")

  # Check rules from most specific to least specific
  @rules.each do |pattern, action|
    return action.to_sym if matches_pattern?(full_string, pattern)
  end

  # Default: no explicit match
  nil
end

#matches_pattern?(input, pattern) ⇒ Boolean

Returns true if the pattern matches the input

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
# File 'lib/rubino/security/pattern_matcher.rb', line 38

def matches_pattern?(input, pattern)
  # Convert glob-style pattern to regex
  regex_str = Regexp.escape(pattern)
                    .gsub('\*', ".*")
                    .gsub('\?', ".")
  regex = Regexp.new("\\A#{regex_str}\\z", Regexp::IGNORECASE)
  input.match?(regex)
end