Ward allows you to write custom security rules in YAML format. DropDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Eljakani/ward/llms.txt
Use this file to discover all available pages before exploring further.
.yaml files into ~/.ward/rules/ and Ward automatically loads them on the next scan.
Quick Start
Custom rules are automatically loaded from:~/.ward/rules/— Your personal rules directory (created byward init)- Additional directories — Configured via
rules.custom_dirsinconfig.yaml
.yaml and .yml files in these directories are loaded and merged with the built-in rules.
Rule File Structure
Each rule file contains arules array with one or more rule definitions:
Rule Definition Fields
Required Fields
Unique identifier for the rule. Must be unique across all loaded rules.Naming convention: Use a prefix like
TEAM-, CUSTOM-, or your organization code.Example: TEAM-001, ACME-SEC-042Short, descriptive title for the finding. Displayed in reports and TUI.Example:
"Hardcoded database credentials"Detailed explanation of what the rule detects and why it’s a security concern.Example:
Severity level for findings from this rule.Valid values:
critical, high, medium, low, infoExample: severity: highCategory for grouping findings in reports.Common categories:
Secrets, Injection, XSS, Debug, Crypto, Configuration, Authentication, AuthorizationExample: category: SecretsWhether the rule is active. Set to
false to temporarily disable without deleting.Example: enabled: trueOptional Fields
Guidance on how to fix the finding. Supports multi-line text.Example:
List of URLs for additional documentation or context.Example:
Additional tags for filtering or categorization.Example:
Pattern Types
Each pattern in thepatterns array must specify a type, target, and pattern.
Regex Pattern
Matches a regular expression against file contents line-by-line.Regex patterns use Go’s RE2 syntax. Backslashes must be escaped in YAML strings (
\\ for literal backslash).Contains Pattern
Matches an exact substring in file contents.File-Exists Pattern
Checks whether a file matching the glob pattern exists.Pattern Targets
Thetarget field specifies which files to search.
Built-in Targets
| Target | Files Matched |
|---|---|
php-files | All .php files (recursive, skips vendor/) |
blade-files | resources/views/**/*.blade.php |
config-files | config/*.php |
env-files | .env, .env.* |
routes-files | routes/*.php |
migration-files | database/migrations/*.php |
js-files | resources/js/**/*.{js,ts,jsx,tsx} |
Custom Glob Patterns
You can also use any custom glob pattern as a target:Advanced Pattern Options
Negative Patterns
Setnegative: true to trigger when a pattern is absent. Useful for “must have X” checks.
Exclude Pattern
Useexclude_pattern to skip matches that also match a secondary pattern. Reduces false positives.
Custom Rule Example
Here’s a complete example from~/.ward/rules/custom-example.yaml:
custom-example.yaml
Loading Custom Rule Directories
To load rules from additional directories (e.g., team-wide or project-specific rules), add them to yourconfig.yaml:
config.yaml
.yaml and .yml files from these directories (internal/config/rules.go:54-82).
Rule Loading Process
Ward loads rules in the following order (internal/config/rules.go:86-113):- Built-in rules — Embedded in the binary from
internal/config/defaults/rules/ - User rules — From
~/.ward/rules/ - Custom directories — From
rules.custom_dirsinconfig.yaml - Overrides applied —
rules.disableandrules.overridefromconfig.yaml
Testing Custom Rules
After creating a custom rule:- Save the
.yamlfile in~/.ward/rules/ - Run
ward scan /path/to/test-project - Check the report for findings from your rule ID
Common Use Cases
Detect Missing Authorization Checks
Detect Unsafe File Uploads
Detect Hardcoded Team URLs
Related Pages
- Configuration File — Main config.yaml structure
- Rule Overrides — Disabling and customizing rules
- Rules Scanner — Default rules included with Ward