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
| Field | Required | Description |
|---|---|---|
| id | Yes | Unique rule identifier (e.g. CUSTOM_001) |
| name | Yes | Human-readable rule name |
| category | Yes | One of: security, quality, cfg, prompt-safety |
| severity | Yes | One of: critical, high, warn, info |
| file_types | No | Restrict to specific file types (omit to match all) |
| match | Yes | Match configuration (see primitives below) |
| remediation | No | How 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 lineline_patterns: Multiple regexes (OR)content_contains: Content contains stringcontent_not_contains: Content lacks string
Field checks (for YAML/JSON):
field_equals: Field equals valuefield_exists: Field is presentfield_missing: Field is absentfield_in: Field is in enum listfield_not_in: Field is not in enum listfield_matches: Field matches regex
Collection checks:
collection_any: At least one item matches predicatecollection_none: No items match predicate
Size checks:
min_length: String minimum lengthmax_length: String maximum lengthmax_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 conditionper_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