Guide · AWS Security Hub · Compliance Standards

AWS Security Hub Compliance Standards — CIS, PCI DSS, FSBP, NIST for MCP Servers

Security Hub compliance standards run continuously as AWS Config rules against your account's resources, generating findings when a resource deviates from the standard's control requirements. For MCP server operators the practical starting point is the AWS Foundational Security Best Practices (FSBP) standard — it covers the AWS services most commonly used in MCP deployments (EC2, ECS, Lambda, S3, IAM, KMS) without the full audit rigor of CIS or PCI DSS. The critical operational detail: every enabled control in every standard runs as a separate Config rule with a name like SecurityHub-<ControlId>-<hash>. AWS Config charges $0.001 per configuration item recorded and $0.003 per Config rule evaluation per month after the free tier. Enabling all five available standards across 200+ controls in an account with 100+ resources can generate thousands of Config evaluations per month — always audit which controls are relevant before enabling a standard.

TL;DR

Enable FSBP first — best coverage for MCP infrastructure with least overhead. Add CIS v1.4 if you need compliance certification. Enable standards with batch-enable-standards, disable irrelevant controls with update-standards-control (or update-standards-control-associations in SECURITY_CONTROL mode), and monitor compliance score with list-standards-control-associations. Controls run as Config rules — each enabled control incurs Config evaluation charges. See Security Hub setup guide for initial configuration, automation rules guide for automatically suppressing low-signal controls, and cross-account guide for enabling standards across Organizations.

Available standards and Standard ARNs

Security Hub offers six standards. The ARN format includes the region — each standard must be enabled per-region.

# List all available standards in current region
aws securityhub describe-standards \
  --query 'Standards[*].{Name:Name,Arn:StandardsArn,Status:EnabledByDefault}'

# Standard ARNs (us-east-1 — replace region for other regions):
# AWS Foundational Security Best Practices v1.0.0 (FSBP):
#   arn:aws:securityhub:us-east-1::standards/aws-foundational-security-best-practices/v/1.0.0
#
# CIS AWS Foundations Benchmark v1.2.0 (legacy — prefer 1.4 or 3.0):
#   arn:aws:securityhub:us-east-1::standards/cis-aws-foundations-benchmark/v/1.2.0
#
# CIS AWS Foundations Benchmark v1.4.0:
#   arn:aws:securityhub:us-east-1::standards/cis-aws-foundations-benchmark/v/1.4.0
#
# CIS AWS Foundations Benchmark v3.0.0:
#   arn:aws:securityhub:us-east-1::standards/cis-aws-foundations-benchmark/v/3.0.0
#
# PCI DSS v3.2.1:
#   arn:aws:securityhub:us-east-1::standards/pci-dss/v/3.2.1
#
# NIST SP 800-53 Rev 5:
#   arn:aws:securityhub:us-east-1::standards/nist-800-53/v/5.0.0

# Enable FSBP and CIS v1.4 (no default standards — selective choice):
aws securityhub batch-enable-standards \
  --standards-subscription-requests '[
    {"StandardsArn": "arn:aws:securityhub:us-east-1::standards/aws-foundational-security-best-practices/v/1.0.0"},
    {"StandardsArn": "arn:aws:securityhub:us-east-1::standards/cis-aws-foundations-benchmark/v/1.4.0"}
  ]'

# Check enabled standards and their status
aws securityhub get-enabled-standards
# Status: READY = controls running; INCOMPLETE = some controls failed to initialize
# StandardsSubscriptionArn returned — needed for control management
StandardControl countBest for MCP use caseConfig rules created
FSBP v1.0.0~280 controlsGeneral AWS best practices for all MCP deployments — start here~280 (one per control)
CIS v1.4.0~55 controlsBaseline hygiene; needed for SOC 2 Type II or compliance certifications~55
CIS v3.0.0~58 controlsUpdated CIS — use this instead of v1.4 for new deployments~58
PCI DSS v3.2.1~240 controlsOnly if MCP server processes cardholder data~240
NIST SP 800-53 Rev 5~220 controlsOnly for US government or FedRAMP workloads~220

Disabling irrelevant controls

After enabling a standard, disable controls that don't apply to your MCP server infrastructure. A FAILED finding on a disabled control does not affect your compliance score and does not generate chargeable Config evaluations.

# List all controls for a standard with their current status
aws securityhub describe-standards-controls \
  --standards-subscription-arn "arn:aws:securityhub:us-east-1:123456789012:subscription/aws-foundational-security-best-practices/v/1.0.0" \
  --query 'Controls[*].{Id:ControlId,Title:Title,Status:ControlStatus,Severity:SeverityRating}'

# Disable a specific control (legacy STANDARD_CONTROL mode)
aws securityhub update-standards-control \
  --standards-control-arn "arn:aws:securityhub:us-east-1:123456789012:control/aws-foundational-security-best-practices/v/1.0.0/IAM.6" \
  --control-status DISABLED \
  --disabled-reason "MFA hardware tokens not applicable to service accounts used by MCP automation"

# In SECURITY_CONTROL mode (recommended), disable across all standards at once:
aws securityhub batch-update-standards-control-associations \
  --standards-control-association-updates '[
    {
      "SecurityControlId": "IAM.6",
      "StandardsArn": "arn:aws:securityhub:us-east-1::standards/aws-foundational-security-best-practices/v/1.0.0",
      "AssociationStatus": "DISABLED",
      "UpdatedReason": "Hardware MFA not applicable to machine accounts"
    },
    {
      "SecurityControlId": "IAM.9",
      "StandardsArn": "arn:aws:securityhub:us-east-1::standards/aws-foundational-security-best-practices/v/1.0.0",
      "AssociationStatus": "DISABLED",
      "UpdatedReason": "Virtual MFA on root account managed by Organizations SCP"
    }
  ]'

# Get compliance score for a specific standard
aws securityhub get-enabled-standards \
  --query 'StandardsSubscriptions[?StandardsArn==`arn:aws:securityhub:us-east-1::standards/aws-foundational-security-best-practices/v/1.0.0`].StandardsStatus'

Controls to commonly disable for MCP server accounts that use AWS Organizations service control policies (SCPs) to govern root account access:

Control IDTitleWhy disable for MCP accounts
IAM.4IAM root user access key should not existRoot access keys automatically absent in Organizations member accounts; will show as NOT_AVAILABLE not FAILED
IAM.6Hardware MFA should be enabled for root userRoot login blocked via SCP in Organizations; hardware MFA enrollment impossible when root login is blocked
IAM.9Virtual MFA should be enabled for root userSame as IAM.6 — root blocked by SCP
CloudTrail.2CloudTrail should have encryption at-rest enabledIf your trail uses SSE-S3 (not KMS) by design for cost reasons; override after documenting rationale
Config.1AWS Config should be enabledOnly if you use Config via Security Hub exclusively and have it enabled — this control is satisfied automatically when Security Hub enables its Config rules
EC2.10Amazon VPC security groups should not allow ingress from 0.0.0.0/0 to port 22If MCP server uses SSM Session Manager exclusively and has no SSH port — control will show FAILED on any SG with port 22 open, even if SSH daemon is not running

Key FSBP controls for MCP server deployments

FSBP covers the AWS services MCP servers most commonly use. These are the highest-signal controls for a typical MCP deployment on ECS, Lambda, or EC2.

# Query findings for specific control IDs to assess current compliance
aws securityhub get-findings \
  --filters '{
    "ComplianceSecurityControlId": [
      {"Value": "EC2.2", "Comparison": "EQUALS"},
      {"Value": "EC2.19", "Comparison": "EQUALS"},
      {"Value": "Lambda.1", "Comparison": "EQUALS"},
      {"Value": "ECS.2", "Comparison": "EQUALS"}
    ],
    "ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}],
    "RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}]
  }' \
  --query 'Findings[*].{Control:Compliance.SecurityControlId,Resource:Resources[0].Id,Status:Compliance.Status}'
ControlWhat it checksMCP relevanceSeverity
EC2.2VPC default security group restricts all trafficHIGH — MCP servers should never use the default SGMEDIUM
EC2.6VPC flow logging enabledHIGH — required for network threat detection via GuardDutyMEDIUM
EC2.19Security groups should not allow unrestricted access to high-risk portsHIGH — MCP server SGs should restrict ingress to known portsCRITICAL
Lambda.1Lambda function policy should prohibit public accessHIGH — Lambda-based MCPs should not be publicly invokable except via API GatewayCRITICAL
Lambda.2Lambda functions should use supported runtimesMEDIUM — outdated Node.js/Python runtimes introduce CVEs in MCP function codeMEDIUM
ECS.2ECS services should not have public IP addresses assigned automaticallyHIGH — ECS-based MCP servers should route traffic through a load balancerHIGH
ECS.10ECS Fargate tasks should use the latest Fargate platform versionMEDIUM — older Fargate versions may have container runtime CVEsMEDIUM
S3.2S3 buckets should prohibit public read accessHIGH — MCP server data buckets must not be publicly readableCRITICAL
KMS.4AWS KMS key rotation should be enabledMEDIUM — encrypt MCP server data at rest with rotating keysMEDIUM
IAM.1IAM policies should not allow full "*:*" administrative privilegesCRITICAL — MCP server IAM roles should follow least-privilegeHIGH

Control evaluation types and timing

Security Hub controls run as Config rules with two evaluation modes: periodic (runs on a schedule) and change-triggered (runs when the relevant resource is created or modified). Understanding the mode matters for how quickly a finding appears after you fix a misconfiguration.

# Find out if a control is periodic or change-triggered
aws configservice describe-config-rules \
  --config-rule-names "SecurityHub-EC2.2-a1b2c3d4e5" \
  --query 'ConfigRules[0].{Source:Source.SourceDetails[0].MessageType,Frequency:MaximumExecutionFrequency}'

# Periodic controls run on these frequencies:
# One_Hour | Three_Hours | Six_Hours | Twelve_Hours | TwentyFour_Hours
# Most CIS and FSBP controls run every 12 or 24 hours for periodic checks

# Force a re-evaluation on a specific rule (for change-triggered rules):
aws configservice start-config-rules-evaluation \
  --config-rule-names "SecurityHub-IAM.1-f6g7h8i9j0"

# After fixing a control violation, findings update on next evaluation cycle
# For periodic controls: may take up to 24 hours to show PASSED
# For change-triggered controls: typically updates within 5-15 minutes of resource change

# Check what Config rules Security Hub has created in your account
aws configservice describe-config-rules \
  --query 'ConfigRules[?contains(ConfigRuleName, `SecurityHub`)].{Name:ConfigRuleName,State:ConfigRuleState}' \
  | head -30

After remediating a failing control (e.g., enabling VPC flow logs for EC2.6), the finding does not immediately update to PASSED. Change-triggered controls re-evaluate within minutes of the resource change. Periodic controls (common for account-level checks like root MFA, GuardDuty enablement) re-evaluate on their fixed schedule — up to 24 hours. Use start-config-rules-evaluation to trigger an immediate re-evaluation without waiting for the next scheduled cycle.

Failure modes reference

FailureSymptomFix
Standard stuck in INCOMPLETE statusget-enabled-standards shows StandardsStatus=INCOMPLETE for daysAWS Config not enabled in the region; Security Hub requires Config to create its rules — enable Config with a delivery channel
Compliance score not improving after fixing resourcesFixed misconfiguration but compliance score stays the samePeriodic control — re-evaluate manually via start-config-rules-evaluation or wait up to 24 hours for next cycle
Unexpected Config charges after enabling standardsAWS bill shows Config rule evaluation charges within hours of enablingEach enabled control = one Config rule; 280 FSBP controls × 100 resources × monthly evaluations can exceed free tier quickly — disable controls not relevant to your stack
update-standards-control returns error in SECURITY_CONTROL modeCannot disable control via legacy APIIn SECURITY_CONTROL mode, use batch-update-standards-control-associations instead of update-standards-control; the legacy API rejects calls when ControlFindingGenerator=SECURITY_CONTROL
Control shows NOT_AVAILABLE instead of PASSED or FAILEDControl present in standard but showing NOT_AVAILABLE statusThe relevant AWS service is not enabled or has no resources of the relevant type in this region — e.g., EKS controls on an account with no EKS clusters; safe to disable these controls or ignore them
Same control finding appears in multiple standardsOne S3 bucket generates findings for both FSBP and CISControlFindingGenerator set to STANDARD_CONTROL (legacy); switch to SECURITY_CONTROL via update-security-hub-configuration to generate one finding per control per resource across all standards