Create per-repo rules that adjust risk scores after AI analysis. Bump scores for sensitive files, reduce them for safe patterns. Define policies in the dashboard or as code via .mergeshield.yml.
How custom policies work
Interactive walkthrough · 5 steps · 35 seconds
The AI doesn't know your org's unique rules. Custom policies layer your domain knowledge on top of AI analysis for more accurate risk scores.
Bridge the gap
Policies add org-specific knowledge the AI doesn't have.
The AI risk analysis provides a strong general-purpose evaluation, but every organization has domain-specific knowledge that the AI cannot know. Your team knows:
Custom risk policies let you encode this organizational knowledge as rules that adjust risk scores after the AI analysis completes. For example:
*.env* or secrets/* should always be treated as high riskdocs/ are always low-risk and should be capped at 15Policies operate as post-processing adjustments. The AI runs first and produces an original score. Then policies evaluate sequentially and adjust the score up or down. Both the original AI score and the adjusted score are preserved, giving you full visibility into what the AI scored versus what your policies adjusted.
There are four policy types, each matching against different aspects of a pull request:
file_pattern — Uses minimatch glob syntax to match against file paths in the PR diff. Dot files are matched by default. Examples:
**/*.env* — Matches environment files at any depthsrc/auth/** — Matches anything in the authentication directory*.lock — Matches lockfiles in the rootlabel_match — Uses a regular expression to match against the PR title. Useful for tagging conventions — if your team prefixes titles with [HOTFIX] or [INFRA], you can write policies that trigger on those patterns. Invalid regex patterns are caught gracefully.
author_match — Performs a case-insensitive exact match against a list of GitHub usernames. Use this to adjust scores for specific users or bot accounts (e.g., lower scores for your trusted internal deployment bot).
path_severity — Uses a startsWith prefix match against file paths. Simpler than file_pattern but useful for directory-based rules like "increase risk for anything in migrations/" or "decrease risk for changes in docs/".
To create a risk policy:
The form dynamically adapts based on the selected policy type, showing appropriate input fields for the condition. Each policy has:
Policies are scoped to the individual repository and managed through the API with role-based access control. Only organization owners and admins can create, update, or delete policies. Regular members can view policies and their effects on analysis results.
{
"name": "Sensitive env files",
"type": "file_pattern",
"enabled": true,
"priority": 0,
"condition": { "pattern": "**/*.env*" },
"adjustment": {
"delta": 25,
"floorAtScore": 50
}
}Policies are evaluated in priority order, with lower priority numbers evaluated first. This lets you layer broad rules with specific overrides.
For example, you might have:
0 — Broad rule that bumps risk +20 for all infrastructure files (infra/**)10 — Specific override that reduces risk -10 for Terraform formatting-only changesPolicies stack sequentially, meaning each policy adjusts the score that the previous policy produced. If the AI scores a PR at 30:
+20 → now 50-10 → now 4040 (original AI score of 30 is always preserved)When designing your policy stack, follow these guidelines:
floorAtScore and capAtScore for absolute boundaries that should not be overridden by subsequent policiesdelta for relative adjustments that stack with other policiesTip
Use floorAtScore and capAtScore constraints for absolute limits. Deltas are better for relative adjustments that stack with other policies.
Each policy can adjust the risk score using three mechanisms:
delta (-50 to +50) — Adds or subtracts a fixed amount from the current score. A delta of +25 bumps the score up by 25 points; -15 reduces it by 15.capAtScore — Sets an upper bound on the score after this policy. If the current score is above the cap, it is reduced. Example: *"PRs from our trusted bot should never score above 30."*floorAtScore — Sets a minimum score. Example: *"Any PR touching secrets/* should always be at least 50."*All adjustments are clamped to the 0–100 range after application.
The full audit trail is displayed on the PR detail page: the original AI score, each policy adjustment (with name and delta), and the final adjusted score. This creates complete transparency into exactly how the final risk score was derived.
Policy adjustments are also visible in the GitHub PR comment when policies have modified the AI's original score.
High risk for env files
*.env*In addition to creating policies from the dashboard, you can define risk policies in your repository using a .mergeshield.yml file at the repository root. This lets you version-control your risk policies alongside your code.
The YAML file uses the same four policy types as the dashboard — file_pattern, label_match, author_match, and path_severity — with identical adjustment options (delta, capAtScore, floorAtScore).
File-based policies merge with dashboard policies during analysis. Dashboard policies are evaluated first (sorted by priority), followed by file-based policies (which always receive priority 1000+). This means file-based rules always apply last, giving the repository owner the final say.
Key details:
-50 / +50 for delta, 0–100 for cap/floorfile: to distinguish them from dashboard policiesTip
Commit .mergeshield.yml to your default branch. MergeShield reads it from the PR's base branch during analysis, so policy changes take effect as soon as they're merged.
policies:
- name: Sensitive env files
type: file_pattern
enabled: true
condition:
pattern: "**/*.env*"
adjustment:
delta: 25
floorAtScore: 50
- name: Safe documentation
type: path_severity
enabled: true
condition:
pathPrefix: "docs/"
adjustment:
delta: -15
capAtScore: 20
- name: Dependabot always low risk
type: author_match
enabled: true
condition:
authors:
- dependabot[bot]
- renovate[bot]
adjustment:
delta: -20
capAtScore: 25
- name: Hotfix PRs need attention
type: label_match
enabled: true
condition:
titlePattern: "\\[HOTFIX\\]"
adjustment:
delta: 15