Guide · AWS Security Hub · Automation Rules

AWS Security Hub Automation Rules — Auto-Triage, Suppression, Severity Overrides for MCP Servers

Security Hub automation rules evaluate every incoming and updated finding against a set of conditions and, when matched, apply finding field updates — changing severity labels, workflow states, notes, or custom fields — without requiring a Lambda function or EventBridge rule. For MCP server operators the highest-value use case is automatic suppression of low-signal findings from known-safe sources: if your test environment accounts generate hundreds of EC2 findings that you have accepted as risk, an automation rule can set Workflow.Status = SUPPRESSED and add an explanatory note on every matching finding automatically. The critical architectural point: automation rules update finding metadata within Security Hub. They do not trigger external actions like sending a Slack message, isolating a resource, or creating a JIRA ticket. For those outcomes, combine automation rules (to normalize finding state) with EventBridge rules that react to Security Hub finding events (to execute actions).

TL;DR

Automation rules match findings using ASFF field conditions (string, number, date comparators) and apply FINDING_FIELDS_UPDATE actions to update Severity.Label, Workflow.Status, Note, Confidence, or UserDefinedFields. Rules evaluate in ascending RuleOrder (1 = first); set IsTerminal: true to stop further rule evaluation on a match. Use automation rules for finding triage within Security Hub; use EventBridge for external responses. See Security Hub setup guide, findings API guide, and cross-account guide for related configuration.

Create an automation rule

Each rule has a name, description, evaluation order, conditions (what to match), and actions (what to update). Conditions are AND'd together; multiple values within a single condition field are OR'd.

# Rule 1: Auto-suppress LOW severity findings from dev/test accounts
# Matches any LOW finding from accounts tagged as non-production
aws securityhub create-automation-rule \
  --rule-name "suppress-low-sev-dev-accounts" \
  --description "Auto-suppress LOW severity findings in dev and test environments — accepted risk" \
  --rule-order 100 \
  --is-terminal true \
  --rule-status ENABLED \
  --criteria '{
    "SeverityLabel": [{"Value": "LOW", "Comparison": "EQUALS"}],
    "AwsAccountId": [
      {"Value": "111111111111", "Comparison": "EQUALS"},
      {"Value": "222222222222", "Comparison": "EQUALS"}
    ]
  }' \
  --actions '[{
    "Type": "FINDING_FIELDS_UPDATE",
    "FindingFieldsUpdate": {
      "Workflow": {"Status": "SUPPRESSED"},
      "Note": {
        "Text": "Auto-suppressed: LOW severity finding in dev/test account — accepted risk per security policy 2026-09",
        "UpdatedBy": "security-hub-automation"
      }
    }
  }]'

# Rule 2: Escalate HIGH findings on production MCP endpoints to CRITICAL
# Matches HIGH severity findings on resources tagged Environment=production
aws securityhub create-automation-rule \
  --rule-name "escalate-prod-mcp-to-critical" \
  --description "Escalate HIGH findings on production MCP resources to CRITICAL for immediate paging" \
  --rule-order 50 \
  --is-terminal false \
  --rule-status ENABLED \
  --criteria '{
    "SeverityLabel": [{"Value": "HIGH", "Comparison": "EQUALS"}],
    "ResourceTags": [
      {
        "Key": "Environment",
        "Value": "production",
        "Comparison": "EQUALS"
      },
      {
        "Key": "Service",
        "Value": "mcp-server",
        "Comparison": "EQUALS"
      }
    ]
  }' \
  --actions '[{
    "Type": "FINDING_FIELDS_UPDATE",
    "FindingFieldsUpdate": {
      "Severity": {"Label": "CRITICAL"},
      "Note": {
        "Text": "Severity escalated to CRITICAL: production MCP server resource — immediate response required",
        "UpdatedBy": "security-hub-automation"
      }
    }
  }]'

Rule evaluation order and terminal rules

When a finding arrives or is updated, Security Hub evaluates all enabled automation rules in ascending order by RuleOrder (1 evaluates before 1000). If a rule matches and has IsTerminal: true, evaluation stops — no subsequent rules are applied to that finding. If a rule matches but IsTerminal: false, evaluation continues to the next rule.

# List all automation rules with their order and status
aws securityhub list-automation-rules \
  --query 'AutomationRulesMetadata[*].{Name:RuleName,Order:RuleOrder,Status:RuleStatus,Terminal:IsTerminal}'

# Recommended rule ordering for MCP server environments:
# Order 10-49:  Critical escalations (NEVER terminal — let other rules also run)
# Order 50-99:  Enrichment rules (add context, tags, notes — never terminal)
# Order 100-499: Standard suppression rules (terminal=true — stop after suppression)
# Order 500-999: Catch-all fallbacks

# Example: both rules below apply to a single HIGH prod finding
# Rule order 50 (is_terminal=false): escalates HIGH → CRITICAL for prod resources
# Rule order 200 (is_terminal=true): suppresses CRITICAL findings from approved scanner
#
# If finding comes from prod resource AND approved scanner:
# 1. Order 50 runs: severity escalated to CRITICAL, continues evaluation
# 2. Order 200 runs: CRITICAL + approved-scanner matches → workflow = SUPPRESSED, stops
# Result: finding escalated AND suppressed (scanner output accepted as known risk)

# Update rule order (re-priority without recreating)
aws securityhub update-automation-rules \
  --update-automation-rules-request-items '[{
    "RuleArn": "arn:aws:securityhub:us-east-1:123456789012:automation-rule/suppress-low-sev-dev-accounts",
    "RuleOrder": 150
  }]'

Condition types and comparators

Automation rule conditions use the same filter structure as GetFindings. Different ASFF fields support different comparator types.

# String comparators: EQUALS | PREFIX | NOT_EQUALS | PREFIX_NOT_EQUALS | CONTAINS | NOT_CONTAINS
# Number comparators: EQUALS | NOT_EQUALS | GT | GTE | LT | LTE
# Date comparators: Start, End (ISO 8601 date range)

# Match findings by generator type prefix (all GuardDuty findings)
aws securityhub create-automation-rule \
  --rule-name "tag-guardduty-findings" \
  --rule-order 10 \
  --is-terminal false \
  --rule-status ENABLED \
  --criteria '{
    "GeneratorId": [{"Value": "arn:aws:guardduty:", "Comparison": "PREFIX"}]
  }' \
  --actions '[{
    "Type": "FINDING_FIELDS_UPDATE",
    "FindingFieldsUpdate": {
      "UserDefinedFields": {
        "finding_source": "guardduty",
        "requires_incident_response": "true"
      }
    }
  }]'

# Match by finding type prefix
# criteria: {"Type": [{"Value": "TTPs/", "Comparison": "PREFIX"}]}

# Match by normalized severity number range (equivalent to CRITICAL: 76-100)
# criteria: {"SeverityNormalized": [{"Gte": 76, "Lte": 100}]}

# Match by resource type
# criteria: {"ResourceType": [{"Value": "AwsLambdaFunction", "Comparison": "EQUALS"}]}

# Match by specific finding title containing keyword
# criteria: {"Title": [{"Value": "credential", "Comparison": "CONTAINS"}]}

# Match by date — findings created in the last 24 hours
# criteria: {"CreatedAt": [{"Start": "2026-10-07T00:00:00Z", "End": "2026-10-08T23:59:59Z"}]}
Condition fieldComparatorsMCP automation use case
SeverityLabelEQUALS, NOT_EQUALSSuppress all INFORMATIONAL, escalate HIGH on prod
SeverityNormalizedGT, GTE, LT, LTEFine-grained escalation (e.g., normalize GuardDuty 7.5 differently from 8.9)
AwsAccountIdEQUALS, NOT_EQUALSApply different rules to dev vs prod accounts
ResourceTagsEQUALS, NOT_EQUALS (key+value)Suppress findings on resources tagged Environment=test
GeneratorIdPREFIX, CONTAINSDifferent rules for GuardDuty findings vs Inspector findings
ProductNameEQUALS, NOT_EQUALSSource-specific rules (GuardDuty vs Inspector vs Macie)
TypePREFIX, EQUALSRules targeting TTPs namespace vs Software and Config namespace
WorkflowStatusEQUALS, NOT_EQUALSOnly re-process findings still in NEW state (avoid re-suppressing resolved findings)

Automation rules vs EventBridge — choosing the right tool

Both automation rules and EventBridge react to Security Hub findings, but they have different capabilities and purposes. Most MCP server security pipelines use both together.

CapabilityAutomation rulesEventBridge
Update finding fields (severity, workflow, notes)Yes — primary use caseNo — EventBridge triggers external actions, cannot write back to Security Hub findings directly
Call Lambda / send SNS notification / create JIRA ticketNoYes — EventBridge targets Lambda, SNS, SQS, Step Functions, etc.
Isolate compromised EC2 instanceNoYes — EventBridge → Lambda → EC2 SG modification
React to finding severity changesYes — re-evaluates on any finding updateYes — Security Hub sends EventBridge events on finding create/update
No-code / low-code configurationYes — JSON conditions, no Lambda requiredNo — typically requires Lambda or Step Functions for useful responses
Rate limitsNone — processes all findingsEventBridge rule invocations subject to Lambda concurrency limits
Cross-account scopeRuns in each account; admin account rules apply to its own findingsAdmin account EventBridge can receive all member account findings via aggregation
# Example combined pipeline: automation rule + EventBridge

# Step 1: Automation rule adds UserDefinedField to mark high-priority findings
# (done above — tags CRITICAL findings with requires_incident_response=true)

# Step 2: EventBridge rule fires on Security Hub findings where that field is set
# EventBridge pattern:
{
  "source": ["aws.securityhub"],
  "detail-type": ["Security Hub Findings - Imported"],
  "detail": {
    "findings": {
      "Severity": {"Label": ["CRITICAL"]},
      "UserDefinedFields": {
        "requires_incident_response": ["true"]
      }
    }
  }
}

# EventBridge target: Lambda that creates PagerDuty incident + JIRA ticket + Slack alert
# The automation rule ran first (normalized severity, added context)
# EventBridge sees the final normalized finding with full context

Managing automation rules

# List all rules (metadata only — no conditions/actions)
aws securityhub list-automation-rules

# Get full rule details including conditions and actions
aws securityhub batch-get-automation-rules \
  --automation-rules-arns '[
    "arn:aws:securityhub:us-east-1:123456789012:automation-rule/suppress-low-sev-dev-accounts"
  ]'

# Disable a rule (preserves configuration, stops evaluation)
aws securityhub update-automation-rules \
  --update-automation-rules-request-items '[{
    "RuleArn": "arn:aws:securityhub:us-east-1:123456789012:automation-rule/suppress-low-sev-dev-accounts",
    "RuleStatus": "DISABLED"
  }]'

# Delete rules (permanently removes)
aws securityhub batch-delete-automation-rules \
  --automation-rules-arns '[
    "arn:aws:securityhub:us-east-1:123456789012:automation-rule/old-rule-name"
  ]'

# Automation rules do NOT retroactively apply to existing findings
# They only run when a finding is created or updated
# To retroactively suppress existing findings: use batch-update-findings with a GetFindings filter

Failure modes reference

FailureSymptomFix
Automation rule not applying to existing findingsRule created but hundreds of existing findings unchangedRules only apply on finding create/update — use batch-update-findings to retroactively update existing findings matching the same criteria
Rule condition matches unintended findingsRule suppresses more findings than expectedCheck RuleOrder — earlier rule may be changing a field that a later rule depends on; use batch-get-automation-rules to review exact conditions; test with a restrictive AwsAccountId condition first
IsTerminal=true rule not stopping evaluationFinding processed by multiple rules including ones after the terminal ruleTerminal=true only stops rules with higher RuleOrder — earlier rules (lower number) always run first; reorder rules so terminal rule runs before the ones you want to skip
Severity override not persistingRule sets severity to CRITICAL but finding shows original severityA subsequent rule (higher RuleOrder, not terminal) may be overwriting the severity again; check all rules matching the same finding criteria; reorder or add IsTerminal=true
UserDefinedFields not appearing on findingRule action sets UserDefinedFields but finding doesn't show themGetFindings response includes UserDefinedFields only when they have values; verify with GetFindings + filter on the specific finding ID; check BatchGetAutomationRules to confirm action definition is correct