Class: SwarmSDK::Permissions::Config
- Inherits:
-
Object
- Object
- SwarmSDK::Permissions::Config
- Defined in:
- lib/swarm_sdk/permissions/config.rb
Overview
Config parses and validates permission configuration for tools
Handles:
- Allowed path patterns (allowlist)
- Denied path patterns (explicit denylist)
- Allowed command patterns (regex for Bash tool)
- Denied command patterns (regex for Bash tool)
- Relative paths converted to absolute based on agent directory
- Glob pattern matching with absolute paths
All paths and patterns are converted to absolute:
- Patterns starting with / are kept as-is
- Relative patterns are expanded against the agent's base directory
- Paths starting with / are kept as-is
- Relative paths are expanded against the agent's base directory
Example:
config = Config.new(
{
allowed_paths: ["tmp/**/*"],
denied_paths: ["tmp/secrets/**"],
allowed_commands: ["^git (status|diff|log)$"],
denied_commands: ["^rm -rf"]
},
base_directories: ["/home/user/project"]
)
config.allowed?("tmp/file.txt") # => true (checks /home/user/project/tmp/file.txt)
config.allowed?("tmp/secrets/key.pem") # => false (denied takes precedence)
config.command_allowed?("git status") # => true
config.command_allowed?("rm -rf /") # => false (denied takes precedence)
Instance Attribute Summary collapse
-
#allowed_commands ⇒ Object
readonly
Returns the value of attribute allowed_commands.
-
#allowed_patterns ⇒ Object
readonly
Returns the value of attribute allowed_patterns.
-
#denied_commands ⇒ Object
readonly
Returns the value of attribute denied_commands.
-
#denied_patterns ⇒ Object
readonly
Returns the value of attribute denied_patterns.
Instance Method Summary collapse
-
#allowed?(path, directory_search: false) ⇒ Boolean
Check if a path is allowed according to this configuration.
-
#command_allowed?(command) ⇒ Boolean
Check if a command is allowed according to this configuration.
-
#find_blocking_command_pattern(command) ⇒ String?
Find the specific pattern that denies or doesn't allow a command.
-
#find_blocking_pattern(path, directory_search: false) ⇒ String?
Find the specific pattern that denies or doesn't allow a path.
-
#initialize(config_hash, base_directory:) ⇒ Config
constructor
Initialize permission configuration.
-
#to_absolute(path) ⇒ String
Convert a path to absolute form.
Constructor Details
#initialize(config_hash, base_directory:) ⇒ Config
Initialize permission configuration
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/swarm_sdk/permissions/config.rb', line 42 def initialize(config_hash, base_directory:) # Use agent's directory as the base for path resolution @base_directory = File.(base_directory) # Expand all patterns to absolute paths @allowed_patterns = (config_hash[:allowed_paths] || []) @denied_patterns = (config_hash[:denied_paths] || []) # Parse command patterns (regex strings) @allowed_commands = compile_regex_patterns(config_hash[:allowed_commands] || []) @denied_commands = compile_regex_patterns(config_hash[:denied_commands] || []) end |
Instance Attribute Details
#allowed_commands ⇒ Object (readonly)
Returns the value of attribute allowed_commands.
36 37 38 |
# File 'lib/swarm_sdk/permissions/config.rb', line 36 def allowed_commands @allowed_commands end |
#allowed_patterns ⇒ Object (readonly)
Returns the value of attribute allowed_patterns.
36 37 38 |
# File 'lib/swarm_sdk/permissions/config.rb', line 36 def allowed_patterns @allowed_patterns end |
#denied_commands ⇒ Object (readonly)
Returns the value of attribute denied_commands.
36 37 38 |
# File 'lib/swarm_sdk/permissions/config.rb', line 36 def denied_commands @denied_commands end |
#denied_patterns ⇒ Object (readonly)
Returns the value of attribute denied_patterns.
36 37 38 |
# File 'lib/swarm_sdk/permissions/config.rb', line 36 def denied_patterns @denied_patterns end |
Instance Method Details
#allowed?(path, directory_search: false) ⇒ Boolean
Check if a path is allowed according to this configuration
Rules:
- Denied patterns take precedence and always block
- If allowed_paths specified: must match at least one pattern (allowlist)
- If allowed_paths NOT specified: allow everything (except denied)
- All paths are converted to absolute for consistent matching
- For directories used as search bases (Glob/Grep), allow if any pattern would match inside
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/swarm_sdk/permissions/config.rb', line 67 def allowed?(path, directory_search: false) # Convert path to absolute absolute_path = to_absolute_path(path) # Denied patterns take precedence - check first return false if matches_any?(@denied_patterns, absolute_path) # If no allowed patterns, allow everything (except denied) return true if @allowed_patterns.empty? # For directory searches, check if directory is a prefix of any allowed pattern # Don't check if directory exists - allow non-existent directories as search bases if directory_search return true if allowed_as_search_base?(absolute_path) end # Must match at least one allowed pattern matches_any?(@allowed_patterns, absolute_path) end |
#command_allowed?(command) ⇒ Boolean
Check if a command is allowed according to this configuration
Rules:
- Denied command patterns take precedence and always block
- If allowed_commands specified: must match at least one pattern (allowlist)
- If allowed_commands NOT specified: allow everything (except denied)
134 135 136 137 138 139 140 141 142 143 |
# File 'lib/swarm_sdk/permissions/config.rb', line 134 def command_allowed?(command) # Denied patterns take precedence - check first return false if matches_any_regex?(@denied_commands, command) # If no allowed patterns, allow everything (except denied) return true if @allowed_commands.empty? # Must match at least one allowed pattern matches_any_regex?(@allowed_commands, command) end |
#find_blocking_command_pattern(command) ⇒ String?
Find the specific pattern that denies or doesn't allow a command
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/swarm_sdk/permissions/config.rb', line 149 def find_blocking_command_pattern(command) # Check denied patterns first denied_match = @denied_commands.find { |pattern| pattern.match?(command) } return denied_match.source if denied_match # Check allowed patterns if @allowed_commands.any? # Check if command matches any allowed pattern return if @allowed_commands.any? { |pattern| pattern.match?(command) } # Command doesn't match any allowed pattern return "(not in allowed list)" end nil end |
#find_blocking_pattern(path, directory_search: false) ⇒ String?
Find the specific pattern that denies or doesn't allow a path
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/swarm_sdk/permissions/config.rb', line 92 def find_blocking_pattern(path, directory_search: false) absolute_path = to_absolute_path(path) # Check denied patterns first denied_match = @denied_patterns.find { |pattern| PathMatcher.matches?(pattern, absolute_path) } return denied_match if denied_match # Check allowed patterns if @allowed_patterns.any? # For directory searches, check if allowed as search base # Don't check if directory exists - allow non-existent directories as search bases if directory_search return if allowed_as_search_base?(absolute_path) end # Check if path matches any allowed pattern return if @allowed_patterns.any? { |pattern| PathMatcher.matches?(pattern, absolute_path) } # Path doesn't match any allowed pattern return "(not in allowed list)" end nil end |
#to_absolute(path) ⇒ String
Convert a path to absolute form
121 122 123 |
# File 'lib/swarm_sdk/permissions/config.rb', line 121 def to_absolute(path) to_absolute_path(path) end |