HOWTOIntermediate

AWS Security Hub: Centralized Security Findings

Implement AWS Security Hub for centralized security findings across accounts. Covers security standards, GuardDuty/Inspector integration, custom insights,...

Dylan H.

Cloud Security Engineering

February 3, 2026
13 min read
AWS Security Hub: Centralized Security Findings

Prerequisites

  • AWS account with administrator access
  • AWS CLI configured
  • Understanding of AWS Organizations (for multi-account)
  • Familiarity with AWS security services

Overview

AWS Security Hub provides a comprehensive view of security alerts and compliance status across AWS accounts. It aggregates findings from AWS security services and third-party tools, enabling centralized security management and automated remediation.

Who Should Use This Guide:

  • Cloud security engineers securing AWS environments
  • Security operations teams managing multi-account AWS
  • Compliance officers monitoring cloud security posture
  • DevSecOps engineers automating security workflows

Security Hub Capabilities:

FeatureDescription
Aggregated FindingsCentralize findings from AWS services
Security StandardsCIS, PCI DSS, NIST, AWS Foundational
Custom InsightsCreate custom security metrics
Cross-AccountAggregate findings across AWS Organization
AutomationEventBridge rules for auto-remediation
Third-PartyIntegrate with partner security tools

Integrated AWS Services:

ServiceFinding Types
GuardDutyThreat detection, anomalies
InspectorVulnerability findings
MacieSensitive data exposure
IAM Access AnalyzerExternal access, unused permissions
Firewall ManagerFirewall policy violations
ConfigResource configuration issues
Systems ManagerPatch compliance

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                    AWS Security Hub Architecture                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  AWS Account (Member)              AWS Account (Member)             │
│  ┌────────────────────┐           ┌────────────────────┐           │
│  │   ┌──────────┐     │           │   ┌──────────┐     │           │
│  │   │GuardDuty │     │           │   │Inspector │     │           │
│  │   └────┬─────┘     │           │   └────┬─────┘     │           │
│  │        │           │           │        │           │           │
│  │   ┌────▼─────┐     │           │   ┌────▼─────┐     │           │
│  │   │Security  │     │           │   │Security  │     │           │
│  │   │Hub Local │     │           │   │Hub Local │     │           │
│  │   └────┬─────┘     │           │   └────┬─────┘     │           │
│  └────────┼───────────┘           └────────┼───────────┘           │
│           │                                │                        │
│           └────────────────┬───────────────┘                        │
│                            │                                        │
│                            ▼                                        │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │              Security Hub Administrator Account               │  │
│  │  ┌─────────────────────────────────────────────────────────┐ │  │
│  │  │               Aggregated Findings                        │ │  │
│  │  │  ┌───────────┐ ┌───────────┐ ┌───────────┐              │ │  │
│  │  │  │ Critical  │ │   High    │ │  Medium   │              │ │  │
│  │  │  │    23     │ │    156    │ │    892    │              │ │  │
│  │  │  └───────────┘ └───────────┘ └───────────┘              │ │  │
│  │  └─────────────────────────────────────────────────────────┘ │  │
│  │                                                               │  │
│  │  ┌─────────────────────────────────────────────────────────┐ │  │
│  │  │               Security Standards                         │ │  │
│  │  │  □ AWS Foundational  □ CIS Benchmark  □ PCI DSS         │ │  │
│  │  └─────────────────────────────────────────────────────────┘ │  │
│  │                           │                                   │  │
│  │                           ▼                                   │  │
│  │  ┌─────────────────────────────────────────────────────────┐ │  │
│  │  │               EventBridge → Lambda → Remediation         │ │  │
│  │  └─────────────────────────────────────────────────────────┘ │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Step 1: Enable Security Hub

Enable via AWS CLI

# Enable Security Hub in the current region
aws securityhub enable-security-hub \
  --enable-default-standards \
  --region us-east-1
 
# Verify Security Hub is enabled
aws securityhub describe-hub \
  --region us-east-1

Enable via Terraform

# main.tf
provider "aws" {
  region = "us-east-1"
}
 
resource "aws_securityhub_account" "main" {}
 
resource "aws_securityhub_standards_subscription" "cis" {
  depends_on    = [aws_securityhub_account.main]
  standards_arn = "arn:aws:securityhub:us-east-1::standards/cis-aws-foundations-benchmark/v/1.4.0"
}
 
resource "aws_securityhub_standards_subscription" "aws_foundational" {
  depends_on    = [aws_securityhub_account.main]
  standards_arn = "arn:aws:securityhub:us-east-1::standards/aws-foundational-security-best-practices/v/1.0.0"
}
 
resource "aws_securityhub_standards_subscription" "pci_dss" {
  depends_on    = [aws_securityhub_account.main]
  standards_arn = "arn:aws:securityhub:us-east-1::standards/pci-dss/v/3.2.1"
}

Enable in Multiple Regions

#!/bin/bash
# enable-securityhub-all-regions.sh
 
REGIONS=$(aws ec2 describe-regions --query "Regions[].RegionName" --output text)
 
for region in $REGIONS; do
  echo "Enabling Security Hub in $region..."
  aws securityhub enable-security-hub \
    --enable-default-standards \
    --region $region 2>/dev/null || echo "Already enabled or error in $region"
done

Step 2: Configure Security Standards

Available Security Standards

StandardARNFocus
AWS Foundationalstandards/aws-foundational-security-best-practices/v/1.0.0AWS best practices
CIS AWS Foundationsstandards/cis-aws-foundations-benchmark/v/1.4.0CIS hardening
PCI DSSstandards/pci-dss/v/3.2.1Payment card compliance
NIST 800-53standards/nist-800-53/v/5.0.0Federal security

Enable Specific Standards

# Get available standards ARNs
aws securityhub describe-standards \
  --region us-east-1 \
  --query "Standards[].StandardsArn"
 
# Enable AWS Foundational Best Practices
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"}
  ]' \
  --region us-east-1
 
# Enable CIS Benchmark
aws securityhub batch-enable-standards \
  --standards-subscription-requests '[
    {"StandardsArn": "arn:aws:securityhub:us-east-1::standards/cis-aws-foundations-benchmark/v/1.4.0"}
  ]' \
  --region us-east-1

Disable Specific Controls

# List controls for a standard
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[?ControlStatus=='ENABLED'].{Id:ControlId,Title:Title}" \
  --region us-east-1
 
# Disable a control (if not applicable)
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 "Not applicable - using SSO for user management" \
  --region us-east-1

Step 3: Integrate AWS Security Services

Enable GuardDuty Integration

# Enable GuardDuty
aws guardduty create-detector \
  --enable \
  --finding-publishing-frequency FIFTEEN_MINUTES \
  --region us-east-1
 
# GuardDuty findings automatically appear in Security Hub
# Verify integration
aws securityhub describe-products \
  --region us-east-1 \
  --query "Products[?ProductName=='GuardDuty']"

Enable Inspector Integration

# Enable Inspector for EC2 and ECR
aws inspector2 enable \
  --resource-types EC2 ECR LAMBDA \
  --region us-east-1
 
# Verify integration
aws securityhub list-enabled-products-for-import \
  --region us-east-1

Enable IAM Access Analyzer

# Create analyzer
aws accessanalyzer create-analyzer \
  --analyzer-name org-analyzer \
  --type ORGANIZATION \
  --region us-east-1
 
# Findings flow to Security Hub automatically

Enable Macie

# Enable Macie
aws macie2 enable-macie \
  --finding-publishing-frequency FIFTEEN_MINUTES \
  --region us-east-1
 
# Create discovery job for S3 buckets
aws macie2 create-classification-job \
  --job-type SCHEDULED \
  --name "s3-sensitive-data-scan" \
  --s3-job-definition '{
    "bucketDefinitions": [{
      "accountId": "123456789012",
      "buckets": ["my-data-bucket"]
    }]
  }' \
  --schedule-frequency '{"dailySchedule": {}}' \
  --region us-east-1

Step 4: Multi-Account Setup (AWS Organizations)

Designate Administrator Account

# From Organizations management account
aws securityhub enable-organization-admin-account \
  --admin-account-id 123456789012 \
  --region us-east-1

Enable for All Organization Accounts

# From administrator account - auto-enable for new accounts
aws securityhub update-organization-configuration \
  --auto-enable \
  --region us-east-1
 
# Enable for existing accounts
aws securityhub create-members \
  --account-details '[
    {"AccountId": "111111111111"},
    {"AccountId": "222222222222"}
  ]' \
  --region us-east-1

Create Aggregator Region

# Designate aggregator region
aws securityhub create-finding-aggregator \
  --region us-east-1 \
  --region-linking-mode ALL_REGIONS
 
# Or specific regions only
aws securityhub create-finding-aggregator \
  --region us-east-1 \
  --region-linking-mode SPECIFIED_REGIONS \
  --regions us-east-1 us-west-2 eu-west-1

Step 5: View and Manage Findings

Query Findings via CLI

# Get all critical findings
aws securityhub get-findings \
  --filters '{
    "SeverityLabel": [{"Value": "CRITICAL", "Comparison": "EQUALS"}]
  }' \
  --region us-east-1 \
  --query "Findings[].{Title:Title,Resource:Resources[0].Id,Account:AwsAccountId}"
 
# Get findings for specific resource
aws securityhub get-findings \
  --filters '{
    "ResourceId": [{"Value": "arn:aws:s3:::my-bucket", "Comparison": "EQUALS"}]
  }' \
  --region us-east-1
 
# Get failed compliance checks
aws securityhub get-findings \
  --filters '{
    "ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}],
    "RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}]
  }' \
  --region us-east-1

Update Finding Status

# Mark finding as resolved
aws securityhub batch-update-findings \
  --finding-identifiers '[
    {
      "Id": "arn:aws:securityhub:us-east-1:123456789012:finding/12345",
      "ProductArn": "arn:aws:securityhub:us-east-1::product/aws/securityhub"
    }
  ]' \
  --workflow '{"Status": "RESOLVED"}' \
  --region us-east-1
 
# Suppress finding (false positive)
aws securityhub batch-update-findings \
  --finding-identifiers '[{"Id": "...", "ProductArn": "..."}]' \
  --workflow '{"Status": "SUPPRESSED"}' \
  --note '{"Text": "False positive - verified manually", "UpdatedBy": "security-team"}' \
  --region us-east-1

Step 6: Create Custom Insights

Create Insight via CLI

# Critical findings by account
aws securityhub create-insight \
  --name "Critical Findings by Account" \
  --filters '{
    "SeverityLabel": [{"Value": "CRITICAL", "Comparison": "EQUALS"}],
    "RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}]
  }' \
  --group-by-attribute "AwsAccountId" \
  --region us-east-1
 
# Findings by resource type
aws securityhub create-insight \
  --name "Findings by Resource Type" \
  --filters '{
    "RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}]
  }' \
  --group-by-attribute "ResourceType" \
  --region us-east-1
 
# Failed controls by standard
aws securityhub create-insight \
  --name "Failed Controls by Standard" \
  --filters '{
    "ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}],
    "RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}]
  }' \
  --group-by-attribute "ComplianceSecurityControlId" \
  --region us-east-1

Useful Custom Insights

Insight NameGroup ByFilter
Critical by AccountAwsAccountIdSeverity=CRITICAL
Public ResourcesResourceTypeNetworkConfiguration.Public=true
Unpatched ResourcesResourceIdType=Software and Vulnerability
IAM IssuesResourceIdProductName=IAM Access Analyzer
Top Failing ControlsComplianceSecurityControlIdComplianceStatus=FAILED

Step 7: Automate Remediation

EventBridge Rule for High Severity Findings

# Create EventBridge rule
aws events put-rule \
  --name "SecurityHub-HighSeverity" \
  --event-pattern '{
    "source": ["aws.securityhub"],
    "detail-type": ["Security Hub Findings - Imported"],
    "detail": {
      "findings": {
        "Severity": {
          "Label": ["CRITICAL", "HIGH"]
        },
        "Workflow": {
          "Status": ["NEW"]
        }
      }
    }
  }' \
  --state ENABLED \
  --region us-east-1

Lambda Auto-Remediation Example

# lambda_function.py
import boto3
import json
 
def lambda_handler(event, context):
    """Auto-remediate Security Hub findings."""
 
    finding = event['detail']['findings'][0]
    finding_id = finding['Id']
    resource_id = finding['Resources'][0]['Id']
    control_id = finding.get('Compliance', {}).get('SecurityControlId', 'Unknown')
 
    print(f"Processing finding: {finding_id}")
    print(f"Control: {control_id}, Resource: {resource_id}")
 
    remediation_result = None
 
    # S3.2 - Block public access
    if control_id == 'S3.2':
        remediation_result = remediate_s3_public_access(resource_id)
 
    # EC2.19 - Default security group restricts all traffic
    elif control_id == 'EC2.19':
        remediation_result = remediate_default_sg(resource_id)
 
    # IAM.3 - Access keys should be rotated
    elif control_id == 'IAM.3':
        remediation_result = notify_key_rotation(resource_id)
 
    if remediation_result:
        # Update finding status
        update_finding_status(finding_id, finding['ProductArn'])
 
    return {"statusCode": 200, "body": json.dumps(remediation_result)}
 
def remediate_s3_public_access(bucket_arn):
    """Block public access on S3 bucket."""
    s3 = boto3.client('s3')
    bucket_name = bucket_arn.split(':')[-1]
 
    s3.put_public_access_block(
        Bucket=bucket_name,
        PublicAccessBlockConfiguration={
            'BlockPublicAcls': True,
            'IgnorePublicAcls': True,
            'BlockPublicPolicy': True,
            'RestrictPublicBuckets': True
        }
    )
    return {"bucket": bucket_name, "action": "blocked_public_access"}
 
def remediate_default_sg(sg_arn):
    """Remove all rules from default security group."""
    ec2 = boto3.client('ec2')
    sg_id = sg_arn.split('/')[-1]
 
    # Get security group
    sg = ec2.describe_security_groups(GroupIds=[sg_id])['SecurityGroups'][0]
 
    # Revoke all ingress rules
    if sg['IpPermissions']:
        ec2.revoke_security_group_ingress(
            GroupId=sg_id,
            IpPermissions=sg['IpPermissions']
        )
 
    # Revoke all egress rules
    if sg['IpPermissionsEgress']:
        ec2.revoke_security_group_egress(
            GroupId=sg_id,
            IpPermissions=sg['IpPermissionsEgress']
        )
 
    return {"sg_id": sg_id, "action": "removed_all_rules"}
 
def notify_key_rotation(resource_id):
    """Send notification for key rotation."""
    sns = boto3.client('sns')
    sns.publish(
        TopicArn='arn:aws:sns:us-east-1:123456789012:SecurityAlerts',
        Subject='Action Required: Rotate AWS Access Key',
        Message=f'Access key requires rotation: {resource_id}'
    )
    return {"resource": resource_id, "action": "notification_sent"}
 
def update_finding_status(finding_id, product_arn):
    """Mark finding as resolved after remediation."""
    securityhub = boto3.client('securityhub')
    securityhub.batch_update_findings(
        FindingIdentifiers=[{'Id': finding_id, 'ProductArn': product_arn}],
        Workflow={'Status': 'RESOLVED'},
        Note={'Text': 'Auto-remediated by Lambda', 'UpdatedBy': 'auto-remediation'}
    )

Deploy Lambda with EventBridge

# Create Lambda function
aws lambda create-function \
  --function-name SecurityHub-AutoRemediation \
  --runtime python3.11 \
  --handler lambda_function.lambda_handler \
  --role arn:aws:iam::123456789012:role/SecurityHubRemediationRole \
  --zip-file fileb://function.zip \
  --region us-east-1
 
# Add Lambda as EventBridge target
aws events put-targets \
  --rule SecurityHub-HighSeverity \
  --targets '[
    {
      "Id": "SecurityHubRemediation",
      "Arn": "arn:aws:lambda:us-east-1:123456789012:function:SecurityHub-AutoRemediation"
    }
  ]' \
  --region us-east-1
 
# Grant EventBridge permission to invoke Lambda
aws lambda add-permission \
  --function-name SecurityHub-AutoRemediation \
  --statement-id EventBridgeInvoke \
  --action lambda:InvokeFunction \
  --principal events.amazonaws.com \
  --source-arn arn:aws:events:us-east-1:123456789012:rule/SecurityHub-HighSeverity \
  --region us-east-1

Step 8: Integrate Third-Party Tools

Enable Partner Integrations

# List available integrations
aws securityhub describe-products \
  --region us-east-1 \
  --query "Products[?IntegrationTypes[?contains(@,'SEND_FINDINGS_TO_SECURITY_HUB')]].{Name:ProductName,Arn:ProductArn}"
 
# Enable integration (example: Splunk)
aws securityhub enable-import-findings-for-product \
  --product-arn "arn:aws:securityhub:us-east-1::product/splunk/splunk-enterprise" \
  --region us-east-1

Send Findings to SIEM

# Lambda to forward findings to Splunk HEC
import boto3
import requests
import json
 
def forward_to_splunk(event, context):
    """Forward Security Hub findings to Splunk."""
 
    splunk_hec_url = "https://splunk.company.com:8088/services/collector"
    hec_token = boto3.client('secretsmanager').get_secret_value(
        SecretId='splunk-hec-token'
    )['SecretString']
 
    findings = event['detail']['findings']
 
    for finding in findings:
        payload = {
            "event": finding,
            "sourcetype": "aws:securityhub",
            "source": "aws:securityhub:findings",
            "index": "security"
        }
 
        response = requests.post(
            splunk_hec_url,
            headers={"Authorization": f"Splunk {hec_token}"},
            json=payload,
            verify=True
        )
 
    return {"statusCode": 200}

Step 9: Generate Reports

Export Findings to S3

# Create export configuration
aws securityhub create-action-target \
  --name "ExportToS3" \
  --description "Export findings to S3 for reporting" \
  --id "ExportToS3" \
  --region us-east-1
 
# Use Athena to query findings
# First, enable findings export (via console)
# Then query with Athena:
-- Athena query for Security Hub findings
SELECT
    awsaccountid,
    severity.label as severity,
    title,
    COUNT(*) as finding_count
FROM security_hub_findings
WHERE recordstate = 'ACTIVE'
GROUP BY awsaccountid, severity.label, title
ORDER BY finding_count DESC
LIMIT 100;

Generate Compliance Summary

# Get compliance summary
aws securityhub get-insights \
  --insight-arns "arn:aws:securityhub:us-east-1:123456789012:insight/custom/summary" \
  --region us-east-1
 
# Export to CSV
aws securityhub get-findings \
  --filters '{"ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}]}' \
  --query "Findings[].{Control:Compliance.SecurityControlId,Title:Title,Resource:Resources[0].Id,Account:AwsAccountId}" \
  --output text \
  --region us-east-1 > compliance-failures.csv

Troubleshooting

Common Issues

SymptomPossible CauseSolution
No findings appearingStandards not enabledEnable security standards
GuardDuty not integratedNot in same regionEnable in matching regions
Cross-account not workingMember not acceptedAccept invitation in member
Controls showing UNKNOWNConfig not enabledEnable AWS Config
Finding stuck as NEWNo automationUpdate workflow manually/via Lambda

Diagnostic Commands

# Check Security Hub status
aws securityhub describe-hub --region us-east-1
 
# List enabled standards
aws securityhub get-enabled-standards --region us-east-1
 
# Check member account status
aws securityhub list-members --region us-east-1
 
# Verify product integrations
aws securityhub list-enabled-products-for-import --region us-east-1
 
# Check findings import health
aws securityhub get-insights \
  --insight-arns "arn:aws:securityhub:::insight/securityhub/default/1" \
  --region us-east-1

Security Best Practices

Least Privilege for Security Hub

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "securityhub:GetFindings",
        "securityhub:GetInsights",
        "securityhub:DescribeStandards"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": [
        "securityhub:DisableSecurityHub",
        "securityhub:BatchDisableStandards"
      ],
      "Resource": "*"
    }
  ]
}

Protect Administrator Account

# Enable MFA on administrator
# Use AWS Organizations SCPs to prevent disabling
 
# SCP to prevent Security Hub disable
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ProtectSecurityHub",
      "Effect": "Deny",
      "Action": [
        "securityhub:DisableSecurityHub",
        "securityhub:DeleteMembers",
        "securityhub:DisassociateFromAdministratorAccount"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:PrincipalArn": "arn:aws:iam::*:role/SecurityAdministrator"
        }
      }
    }
  ]
}

Verification Checklist

Setup:

  • Security Hub enabled in all required regions
  • Security standards enabled (Foundational, CIS, PCI)
  • Aggregator region configured
  • Member accounts added (multi-account)

Integrations:

  • GuardDuty findings flowing
  • Inspector findings flowing
  • Macie findings flowing (if data classification needed)
  • IAM Access Analyzer enabled

Operations:

  • Custom insights created
  • EventBridge rules for automation
  • Auto-remediation Lambda deployed
  • Notification/alerting configured

Compliance:

  • All controls reviewed
  • Non-applicable controls disabled with documentation
  • Regular compliance score review scheduled

Next Steps

After implementing Security Hub:

  1. Enable AWS Config Rules - Additional compliance checks
  2. Implement GuardDuty Threat Detection - Advanced threat hunting
  3. Deploy AWS Firewall Manager - Centralized firewall policies
  4. Create Security Dashboards - QuickSight/Grafana visualizations

References


Last Updated: February 2026