AWS Security Hub: Unified Security Posture Management
The average AWS account running production workloads generates findings from at least four different security services: GuardDuty for threat detection, Inspector for vulnerability scanning, Config for compliance drift, and IAM Access Analyzer for unintended resource exposure. Each service has its own console, its own finding format, its own severity scale. Security Hub exists to solve the aggregation problem — one place where findings from all those services land, in a normalized format, with compliance scoring across your entire organization.
It launched in 2018 and still gets underused because people treat it as a dashboard rather than a control plane. This guide covers what Security Hub actually provides, how the standards and scoring work, how to deploy it across an organization, and how to turn findings into automated actions.
The Finding Model
Every finding in Security Hub follows the AWS Security Finding Format (ASFF) — a normalized JSON schema that all integrated services write to. The benefit is that a Lambda function handling Security Hub findings doesn’t need to know whether the source was GuardDuty, Inspector, or a third-party tool. The structure is consistent.
Key ASFF fields:
{
"SchemaVersion": "2018-10-08",
"Id": "arn:aws:securityhub:us-east-1:123456789012:...",
"ProductArn": "arn:aws:securityhub:us-east-1::product/aws/guardduty",
"GeneratorId": "arn:aws:guardduty:us-east-1:123456789012:detector/abc123",
"AwsAccountId": "123456789012",
"Types": ["TTPs/Defense Evasion/CloudTrail was disabled"],
"Severity": {
"Label": "HIGH",
"Normalized": 70
},
"Title": "CloudTrail was disabled",
"Resources": [{
"Type": "AwsCloudTrailTrail",
"Id": "arn:aws:cloudtrail:us-east-1:123456789012:trail/main"
}],
"Compliance": {
"Status": "FAILED"
},
"WorkflowState": "NEW",
"RecordState": "ACTIVE"
}
The WorkflowState field is the triage mechanism: NEW, NOTIFIED, SUPPRESSED, or RESOLVED. Security teams set workflow states as they process findings. RecordState tracks whether the underlying issue is still present — once Config or Inspector determines the finding is remediated, it flips to ARCHIVED.
Security Standards and Scoring
Security Hub runs continuous automated checks against security standards. Each standard has controls, and each control maps to specific AWS Config rules that evaluate your resources. The result is a percentage score per standard, per account, and per region.
The available standards as of 2026:
AWS Foundational Security Best Practices (FSBP): AWS’s own standard covering 300+ controls across 50+ services. This is the most comprehensive and the one to start with. Controls cover things like “S3 buckets should have server-side encryption enabled,” “RDS instances should not be publicly accessible,” and “EC2 instances should not have a public IP by default.”
CIS AWS Foundations Benchmark: Version 1.2 (legacy), 1.4, and 3.0 available. The CIS benchmark is widely recognized for compliance reporting. Version 3.0 adds controls for newer services like EKS and SageMaker. If you’re doing SOC 2 or ISO 27001, auditors often want to see CIS benchmark scores.
PCI DSS v3.2.1: For organizations handling cardholder data. The controls map to PCI DSS requirements directly, which simplifies audit preparation.
NIST SP 800-53 Rev 5: For US federal workloads or organizations that need to demonstrate NIST compliance.
Enable standards selectively. Running all four generates a lot of findings and the controls overlap significantly between standards. Start with FSBP to get a baseline score, add CIS if you have compliance requirements, and add PCI or NIST only for environments that specifically need those certifications.
# Enable Security Hub
aws securityhub enable-security-hub \
--enable-default-standards \
--region us-east-1
# Check which standards are available
aws securityhub describe-standards
# Enable a specific standard
aws securityhub batch-enable-standards \
--standards-subscription-requests \
'[{"StandardsArn":"arn:aws:securityhub:us-east-1::standards/cis-aws-foundations-benchmark/v/3.0.0"}]'
# Get your current score per standard
aws securityhub get-findings \
--filters '{"ComplianceStatus":[{"Value":"FAILED","Comparison":"EQUALS"}]}' \
--query 'Findings[].{Title:Title,Severity:Severity.Label,Resource:Resources[0].Id}' \
--output table
Organization-Wide Deployment
Like GuardDuty, Security Hub has an Organizations integration with a delegated administrator account. All findings from member accounts appear in the admin account’s Security Hub console.
# Run from management account — designate security account as admin
aws securityhub enable-organization-admin-account \
--admin-account-id 999999999999
# Switch to security account
# Configure auto-enrollment for member accounts
aws securityhub update-organization-configuration \
--auto-enable \
--auto-enable-standards NONE # or DEFAULT to auto-enable FSBP
# Verify member accounts are enrolled
aws securityhub list-members \
--only-associated \
--query 'Members[].{Account:AccountId,Status:MemberStatus}'
The AutoEnable flag ensures new accounts joining the organization automatically get Security Hub enabled. If you use Control Tower, it handles this automatically through its guardrails.
Cross-region aggregation lets you designate one aggregator region that pulls findings from all other regions. Without it, you need to log into us-east-1, us-west-2, eu-west-1 etc. separately to see the full picture.
# Configure aggregation (run in your aggregator region)
aws securityhub create-finding-aggregator \
--region-linking-mode ALL_REGIONS
After this, your aggregator region shows findings from all regions across all member accounts in one place.
Suppressing Noise
Out of the box, Security Hub generates a lot of findings. Many are valid issues you need to fix. Some are expected deviations from the standard that don’t apply to your environment. Suppression keeps the signal-to-noise ratio manageable.
Automation rules (added in 2023) let you define criteria that automatically update finding workflow states:
# Create an automation rule to suppress a specific control for dev accounts
aws securityhub create-automation-rule \
--rule-name "SuppressDevPublicS3" \
--rule-order 1 \
--criteria '{
"AwsAccountId": [{"Value":"111111111111","Comparison":"EQUALS"}],
"ComplianceSecurityControlId": [{"Value":"S3.2","Comparison":"EQUALS"}]
}' \
--actions '[{
"Type": "FINDING_FIELDS_UPDATE",
"FindingFieldsUpdate": {
"Workflow": {"Status": "SUPPRESSED"},
"Note": {
"Text": "Dev account — public S3 access is intentional for testing",
"UpdatedBy": "automation-rule"
}
}
}]'
Automation rules run on finding creation and on updates, so they apply retroactively to existing findings that match the criteria. This is more scalable than manually suppressing findings one by one.
Custom Actions and Automated Remediation
Custom actions are named triggers that send selected findings to EventBridge. Security analysts use them to kick off remediation workflows directly from the Security Hub console.
# Create a custom action
ACTION_ARN=$(aws securityhub create-action-target \
--name "RemediatePublicS3" \
--description "Trigger Lambda to block public access on S3 bucket" \
--id "RemediatePublicS3" \
--query 'ActionTargetArn' --output text)
# Create EventBridge rule for this action
aws events put-rule \
--name "SecurityHub-RemediatePublicS3" \
--event-pattern "{
\"source\": [\"aws.securityhub\"],
\"detail-type\": [\"Security Hub Findings - Custom Action\"],
\"resources\": [\"$ACTION_ARN\"]
}"
The Lambda behind the action reads the finding detail and performs remediation. For the S3 public access finding:
import boto3
import json
def handler(event, context):
findings = event['detail']['findings']
for finding in findings:
# Extract the S3 bucket name from the resource ARN
for resource in finding.get('Resources', []):
if resource['Type'] == 'AwsS3Bucket':
bucket_name = resource['Id'].split(':')[-1]
s3 = boto3.client('s3')
# Block all public access
s3.put_public_access_block(
Bucket=bucket_name,
PublicAccessBlockConfiguration={
'BlockPublicAcls': True,
'IgnorePublicAcls': True,
'BlockPublicPolicy': True,
'RestrictPublicBuckets': True
}
)
# Update the finding workflow in Security Hub
securityhub = boto3.client('securityhub')
securityhub.batch_update_findings(
FindingIdentifiers=[{
'Id': finding['Id'],
'ProductArn': finding['ProductArn']
}],
Workflow={'Status': 'RESOLVED'},
Note={
'Text': f'Auto-remediated: blocked public access on {bucket_name}',
'UpdatedBy': 'remediation-lambda'
}
)
print(f"Blocked public access on bucket: {bucket_name}")
For fully automated remediation (without a human clicking the custom action), wire EventBridge directly to Lambda using a filter on finding type and severity. Reserve automated remediation for high-confidence, low-risk remediations like blocking public S3 access or enabling encryption. Anything that could break a running application — like modifying security groups — should still require human approval.
Insights
Insights are saved queries that aggregate findings across accounts. Security Hub includes 35 managed insights out of the box, covering things like “AWS resources with the most findings,” “S3 buckets with public write or read permissions,” and “EC2 instances that have missing security patches.”
Custom insights let you build views tailored to your environment:
# Create an insight showing unresolved HIGH findings per account
aws securityhub create-insight \
--name "High-Severity Unresolved by Account" \
--filters '{
"SeverityLabel": [{"Value":"HIGH","Comparison":"EQUALS"}],
"WorkflowStatus": [{"Value":"NEW","Comparison":"EQUALS"},
{"Value":"NOTIFIED","Comparison":"EQUALS"}],
"RecordState": [{"Value":"ACTIVE","Comparison":"EQUALS"}]
}' \
--group-by-attribute "AwsAccountId"
This gives you a per-account breakdown of open high-severity findings — useful for a weekly security review meeting where you want to show which accounts have the most work to do.
Pricing
Security Hub pricing has two components. Finding ingestion: $0.0010 per finding per month, with the first 10,000 findings per account per region free. Security checks: $0.0008 per check per month for the first 100,000 checks, dropping to $0.0005 beyond that.
For a typical account with FSBP enabled and active GuardDuty feeding findings, expect $5–25/month per account. An organization with 20 accounts across two regions would run $200–500/month total. The 30-day free trial covers both components.
The cost per finding drops significantly at scale — if GuardDuty is generating 50,000 findings/month across your organization, you’re paying fractions of a cent per finding for unified visibility.
What It Doesn’t Replace
Security Hub aggregates and correlates — it doesn’t generate findings on its own. If you disable GuardDuty, those findings stop appearing in Security Hub. If you don’t enable AWS Inspector, you won’t see vulnerability findings. Security Hub is only as useful as the services feeding it.
It also doesn’t replace a SIEM for log-level analysis. Security Hub works at the finding level — normalized, already-analyzed events. For raw CloudTrail log analysis, anomaly detection on log patterns, or long-horizon correlation across months of data, you need AWS CloudTrail Lake or an external SIEM. Security Hub is the right layer for operationalizing findings; it’s not a log analytics platform.
The combination of Security Hub + GuardDuty + Inspector + Config covers the primary attack surface for most AWS workloads. Add Macie if you process sensitive personal data, and wire everything to EventBridge for automated remediation. That stack, running organization-wide, catches the vast majority of misconfigurations and active threats before they become incidents.
Comments