Class: RosettAi::Policy::DenyList

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/policy/deny_list.rb

Overview

Manages glob-based deny list patterns for AI tool access control.

Deny list patterns prevent AI tools from reading or modifying sensitive files such as SSH keys, credentials, and secrets. Patterns are compiled to engine-specific formats during compilation.

All patterns are sanitized (ANSI/control chars stripped) and validated (path traversal rejected) on initialization.

Author:

  • hugo

  • claude

Constant Summary collapse

PATH_TRAVERSAL_PATTERN =

matches ../ at start or after /

%r{(?:^|/)\.\./}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(patterns: []) ⇒ DenyList

Returns a new instance of DenyList.

Parameters:

  • patterns (Array<String>) (defaults to: [])

    glob patterns to deny

Raises:



26
27
28
29
30
# File 'lib/rosett_ai/policy/deny_list.rb', line 26

def initialize(patterns: [])
  sanitized = patterns.map { |pat| RosettAi::TextSanitizer.strip_ansi(pat) }
  validate_patterns!(sanitized)
  @patterns = sanitized.map(&:freeze).freeze
end

Instance Attribute Details

#patternsObject (readonly)

Returns the value of attribute patterns.



22
23
24
# File 'lib/rosett_ai/policy/deny_list.rb', line 22

def patterns
  @patterns
end

Instance Method Details

#denied?(path) ⇒ Boolean

Tests whether a file path matches any deny pattern.

Parameters:

  • path (String)

    relative file path to test

Returns:

  • (Boolean)

    true if the path matches any deny pattern



36
37
38
# File 'lib/rosett_ai/policy/deny_list.rb', line 36

def denied?(path)
  @patterns.any? { |pattern| File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_DOTMATCH) }
end

#empty?Boolean

Returns true if no patterns defined.

Returns:

  • (Boolean)

    true if no patterns defined



54
55
56
# File 'lib/rosett_ai/policy/deny_list.rb', line 54

def empty?
  @patterns.empty?
end

#merge(other) ⇒ DenyList

Merges another deny list into this one (union of patterns).

Parameters:

  • other (DenyList)

    deny list to merge

Returns:

  • (DenyList)

    new deny list with combined patterns



44
45
46
# File 'lib/rosett_ai/policy/deny_list.rb', line 44

def merge(other)
  self.class.new(patterns: (@patterns + other.patterns).uniq)
end

#sizeInteger

Returns number of patterns.

Returns:

  • (Integer)

    number of patterns



49
50
51
# File 'lib/rosett_ai/policy/deny_list.rb', line 49

def size
  @patterns.size
end