Advanced7 min read

Custom Risk Policies

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

1Step 1 of 5

Why Custom Policies?

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.

Why Custom Policies?

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:

  • Which files contain secrets or sensitive configuration
  • Which directories hold critical infrastructure code
  • Which patterns indicate safe, routine changes

Custom risk policies let you encode this organizational knowledge as rules that adjust risk scores after the AI analysis completes. For example:

  • Any change to files matching *.env* or secrets/* should always be treated as high risk
  • PRs from your internal dependency update bot are consistently safe and should have their scores reduced
  • Changes under docs/ are always low-risk and should be capped at 15

Policies 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.

Policy Types

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 depth
  • src/auth/** — Matches anything in the authentication directory
  • *.lock — Matches lockfiles in the root

label_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/".

Creating a Policy

To create a risk policy:

  1. 1Navigate to the repository detail page and scroll to the Risk Policies section
  2. 2Click Add Policy
  3. 3Configure the policy type, condition, score adjustment, and priority

The form dynamically adapts based on the selected policy type, showing appropriate input fields for the condition. Each policy has:

  • Name — For identification in the dashboard
  • Enabled toggle — Turn policies on/off without deleting them
  • Priority — Determines evaluation order (lower = evaluated first)
  • Condition — Depends on type: glob string, regex, comma-separated usernames, or path prefix
  • Adjustment — Delta, cap, and/or floor values (see Score Adjustments)

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.

Example: Bump risk for environment files
{
  "name": "Sensitive env files",
  "type": "file_pattern",
  "enabled": true,
  "priority": 0,
  "condition": { "pattern": "**/*.env*" },
  "adjustment": {
    "delta": 25,
    "floorAtScore": 50
  }
}

Priority & Layering

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:

  1. 1Priority 0 — Broad rule that bumps risk +20 for all infrastructure files (infra/**)
  2. 2Priority 10 — Specific override that reduces risk -10 for Terraform formatting-only changes

Policies stack sequentially, meaning each policy adjusts the score that the previous policy produced. If the AI scores a PR at 30:

  • Priority-0 policy adds +20 → now 50
  • Priority-10 policy adds -10 → now 40
  • Final adjusted score: 40 (original AI score of 30 is always preserved)

When designing your policy stack, follow these guidelines:

  • Start with broad rules at low priority numbers
  • Add specific exceptions at higher priority numbers
  • Use floorAtScore and capAtScore for absolute boundaries that should not be overridden by subsequent policies
  • Use delta for relative adjustments that stack with other policies

Tip

Use floorAtScore and capAtScore constraints for absolute limits. Deltas are better for relative adjustments that stack with other policies.

Score Adjustments

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.

Risk Policy

High risk for env files

Typefile_pattern
Pattern*.env*
EffectScore +30
Priority0

Policy-as-Code (.mergeshield.yml)

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:

  • Maximum 50 policies per file (excess are silently ignored)
  • Adjustments are clamped to -50 / +50 for delta, 0–100 for cap/floor
  • Policy IDs are automatically prefixed with file: to distinguish them from dashboard policies
  • If the YAML file is missing or invalid, the analysis proceeds normally using only dashboard policies
  • Available on Pro and Enterprise plans

Tip

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.

.mergeshield.yml
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