Skip to main content

Custom Rules

Define project-specific rules in .bouncerfox.yml without writing Go code.

Basic Structure

custom_rules:
- id: CUSTOM_001
name: No hardcoded model names
category: cfg
severity: warn
file_types: [claude_md, settings_json]
match:
type: line_pattern
pattern: 'claude-3\.[a-z]|gpt-4'
remediation: "Use model aliases instead of hardcoded model names"

Fields

FieldRequiredDescription
idYesUnique rule identifier (e.g. CUSTOM_001)
nameYesHuman-readable rule name
categoryYesOne of: security, quality, cfg, prompt-safety
severityYesOne of: critical, high, warn, info
file_typesNoRestrict to specific file types (omit to match all)
matchYesMatch configuration (see primitives below)
remediationNoHow to fix the issue

Available File Types

claude_md, claude_local_md, agents_md, settings_json, rules_md, mcp_json, lsp_json, hooks_json, plugin_json, cursorrules, windsurfrules, copilot_instructions, agents_gemini, skill_md

Match Primitives (19 types)

Text matching:

  • line_pattern: Regex against each line
  • line_patterns: Multiple regexes (OR)
  • content_contains: Content contains string
  • content_not_contains: Content lacks string

Field checks (for YAML/JSON):

  • field_equals: Field equals value
  • field_exists: Field is present
  • field_missing: Field is absent
  • field_in: Field is in enum list
  • field_not_in: Field is not in enum list
  • field_matches: Field matches regex

Collection checks:

  • collection_any: At least one item matches predicate
  • collection_none: No items match predicate

Size checks:

  • min_length: String minimum length
  • max_length: String maximum length
  • max_size_bytes: File size limit

Logic combinators:

  • all_of: All conditions must match (AND)
  • any_of: At least one condition must match (OR)
  • not: Negates a condition
  • per_file_type: Different rules for different file types

Examples

Require model aliases:

custom_rules:
- id: CUSTOM_001
name: No hardcoded model names
category: cfg
severity: warn
file_types: [claude_md, skill_md]
match:
type: line_pattern
pattern: 'claude-3\.[a-z]|gpt-4|gemini-'
remediation: "Use model aliases instead of hardcoded model names"

Require description in all skills:

custom_rules:
- id: CUSTOM_002
name: Skills must have detailed descriptions
category: quality
severity: warn
file_types: [skill_md]
match:
type: any_of
conditions:
- type: field_missing
field: description
- type: max_length
field: description
value: 30
remediation: "Add a description of at least 30 characters"

Block specific MCP servers:

custom_rules:
- id: CUSTOM_003
name: Disallowed MCP server
category: security
severity: high
file_types: [mcp_json]
match:
type: content_contains
value: "untrusted-server.example.com"
remediation: "Remove untrusted MCP server references"

Important Notes

  • All regex patterns use RE2 syntax (no lookaheads or backreferences). This prevents ReDoS attacks.
  • Maximum regex length: 4096 characters
  • Collection iteration limit: 1000 items
  • Nesting depth limit: 10 levels for logic combinators