CoursesAWS security engineeringSecurity Hub & standards

Security Hub & standards

Aggregate, normalize, and score against CIS/FSBP.

Advanced30 min · lesson 5 of 15

A building manager with twenty buildings has a choice. Walk every lobby by hand and read each alarm panel one at a time, hoping you reach the one that's actually on fire before it spreads. Or wire every panel back to a single wall of screens in one room and watch them all at once. Security Hub is that room. Turn on GuardDuty, Inspector, Macie, IAM Access Analyzer, and Config across a real AWS estate and each one shouts from its own console, in its own format, separately, in every account and region you run. Nobody watches thirty consoles. Security Hub is the inbox that collects every alarm from every building and lays them out in one place, in one shape.

One inbox, one form

You don't wire the fire panel into a random tenant's apartment. You put it in a dedicated security office. AWS works the same way. You pick one account, usually a purpose-built security account, and designate it as the delegated administrator for Security Hub. Then you tell the organization to auto-enable every current account and every future one. Coverage stops being a checklist somebody forgets on the next new account and becomes a property of the org itself. The enable calls print nothing on success, so you confirm the wiring with a list call.

designate the security account, auto-enroll the org, verify
aws securityhub enable-organization-admin-account --admin-account-id 333333333333
aws securityhub update-organization-configuration --auto-enable --auto-enable-standards DEFAULT
aws organizations list-delegated-administrators --service-principal securityhub.amazonaws.com
{
"DelegatedAdministrators": [
{
"Id": "333333333333",
"Arn": "arn:aws:organizations::111111111111:account/o-a1b2c3d4e5/333333333333",
"Email": "[email protected]",
"Name": "Security-Tooling",
"Status": "ACTIVE",
"JoinedMethod": "CREATED"
}
]
}

Enrolling every account still leaves you looking region by region. A finding raised in us-west-2 lands in the us-west-2 console and stays there. A finding aggregator links your regions into one home region so the security office sees everything without switching tabs. This is the part people miss. Cross-account coverage is the delegated admin. Cross-region coverage is the aggregator. Two different switches, and turning on one does not turn on the other.

link every region into one aggregation region
aws securityhub create-finding-aggregator --region-linking-mode ALL_REGIONS
{
"FindingAggregatorArn": "arn:aws:securityhub:us-east-1:333333333333:finding-aggregator/9d1e7a4c-2f6b-4a0e-b8c1-7c3f2a5d9e01",
"FindingAggregationRegion": "us-east-1",
"RegionLinkingMode": "ALL_REGIONS",
"Regions": []
}

Now hand it a benchmark to grade against. FSBP is AWS's own Foundational Security Best Practices. CIS, from the Center for Internet Security, is the independent industry baseline that auditors know and trust. Subscribing to a standard runs hundreds of automated checks continuously and scores your posture, telling you which control is failing in which account. Each control has a stable id like EC2.13 or IAM.1, so a failing check points at an exact fix rather than a vague warning, and Security Hub folds the same control failing from several providers into one row instead of five.

subscribe to the standard you must evidence
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"}]'
{
"StandardsSubscriptions": [
{
"StandardsSubscriptionArn": "arn:aws:securityhub:us-east-1:333333333333:subscription/aws-foundational-security-best-practices/v/1.0.0",
"StandardsArn": "arn:aws:securityhub:us-east-1::standards/aws-foundational-security-best-practices/v/1.0.0",
"StandardsInput": {},
"StandardsStatus": "PENDING"
}
]
}

Reading an actual finding

Every provider files its complaint on the same form, and that form is the AWS Security Finding Format, or ASFF. It's the reason a partner scanner's alert and an AWS service's alert can sit side by side in the same list. Read one and you can read them all. Pull the high-severity, untriaged findings and look at the shape.

read one HIGH, NEW finding as ASFF
aws securityhub get-findings \
--filters '{"SeverityLabel":[{"Value":"HIGH","Comparison":"EQUALS"}],"WorkflowStatus":[{"Value":"NEW","Comparison":"EQUALS"}]}' \
--max-results 1
{
"Findings": [
{
"SchemaVersion": "2018-10-08",
"Id": "arn:aws:securityhub:us-east-1:444455556666:security-control/EC2.13/finding/6f1a2b3c-8d90-4e12-a5f7-0c9b1d2e3f4a",
"ProductArn": "arn:aws:securityhub:us-east-1::product/aws/securityhub",
"ProductName": "Security Hub",
"CompanyName": "AWS",
"GeneratorId": "security-control/EC2.13",
"AwsAccountId": "444455556666",
"Types": ["Software and Configuration Checks/Industry and Regulatory Standards"],
"CreatedAt": "2026-07-14T02:31:07.004Z",
"UpdatedAt": "2026-07-16T06:12:44.118Z",
"Severity": { "Label": "HIGH", "Normalized": 70, "Original": "HIGH" },
"Title": "EC2.13 Security groups should not allow ingress from 0.0.0.0/0 or ::/0 to port 22",
"Description": "This control checks whether an Amazon EC2 security group allows ingress from 0.0.0.0/0 or ::/0 to port 22. The control fails if the security group allows ingress from 0.0.0.0/0 or ::/0 to port 22.",
"Remediation": {
"Recommendation": {
"Text": "Remove the rule that allows 0.0.0.0/0 to port 22 and scope ingress to known CIDRs.",
"Url": "https://docs.aws.amazon.com/console/securityhub/EC2.13/remediation"
}
},
"Resources": [
{
"Type": "AwsEc2SecurityGroup",
"Id": "arn:aws:ec2:us-east-1:444455556666:security-group/sg-0abc1234def567890",
"Partition": "aws",
"Region": "us-east-1",
"Details": {
"AwsEc2SecurityGroup": {
"GroupName": "prod-web-sg",
"VpcId": "vpc-0a1b2c3d",
"IpPermissions": [
{ "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "IpRanges": [{ "CidrIp": "0.0.0.0/0" }] }
]
}
}
}
],
"Compliance": {
"Status": "FAILED",
"SecurityControlId": "EC2.13",
"AssociatedStandards": [{ "StandardsId": "standards/aws-foundational-security-best-practices/v/1.0.0" }]
},
"Workflow": { "Status": "NEW" },
"RecordState": "ACTIVE"
}
],
"NextToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJI..."
}

Five fields carry the weight. Resources tells you exactly which door is open: a security group with 0.0.0.0/0 allowed to port 22, which means anyone on the public internet can reach the remote-login service (SSH, the tool admins use to sign into a Linux box) on that machine. Compliance ties it back to the benchmark, here a FAILED status against FSBP control EC2.13. Severity carries a Normalized number (70) that every provider maps onto, so you can sort a GuardDuty finding next to a Config one on the same scale. Workflow is where the finding sits in your process: NEW means no human has touched it, and you move it to NOTIFIED, RESOLVED, or SUPPRESSED as it travels. RecordState ACTIVE means the underlying problem is still real. Fix the rule and Security Hub archives the finding on the next check.

A score is a floor, not a finish line

A 96 percent FSBP score feels great and proves less than you'd hope. It means the checks Security Hub can evaluate mostly pass. It says nothing about the risks no benchmark inspects: a valid role that's quietly over-permissioned, or data moving somewhere it shouldn't. Hold the number as a floor while you build the threat-specific detections that no standard covers. And a finding sitting in a console nobody watches changes nothing on its own. The payoff comes when you route the HIGH and NEW findings out through EventBridge into ticketing and automated response, which is exactly where the next lesson picks up.

Auto-enable can switch on more than you meant to bill for
Subscribing to a standard turns on all of its controls at once, and Security Hub bills per security check and per finding it ingests. On a large org with auto-enable across every account and region, that adds up quickly, and any control that depends on AWS Config quietly reports nothing until Config recording is actually on everywhere. Turn standards on deliberately, confirm Config is recording, and disable the controls you've consciously chosen not to run instead of letting them pile up failing findings nobody will action.
Cross-account aggregation into one delegated admin
Member accounts (each building)
Prod account 4444…
GuardDuty, Inspector, Config emit ASFF
Dev / Network accounts
same providers, auto-enrolled on join
Delegated admin — the single security inbox
Security Hub aggregator
normalize to ASFF, dedupe, one severity
Standards: FSBP / CIS
continuous control scoring per account
Act on the signal
EventBridge rule
match SeverityLabel HIGH + Workflow NEW
Automation / ticketing
automated first response
Cross-account coverage comes from the delegated admin plus org auto-enable; cross-region coverage comes from a finding aggregator. One schema, one severity model, then routing turns findings into work.
Quick check
01Every account in your org is enrolled in Security Hub and the delegated admin looks healthy, but findings generated in us-west-2 never show up in your central us-east-1 view. What's the most likely cause?
Incorrect — Aggregation doesn't filter by severity. Every finding is aggregated regardless of how bad it is.
Correct — The delegated admin gives you cross-account coverage, but each region stays siloed until a finding aggregator links your regions into one home region.
Incorrect — That would change which standards findings appear, not whether any us-west-2 findings reach the central region at all.
Incorrect — Possible for GuardDuty findings specifically, but Config and other providers would still generate findings, and those would still be missing centrally without an aggregator.
02Findings from GuardDuty, a third-party partner scanner, and an AWS Config control all appear in one Security Hub list and can be sorted on a single severity scale. What makes that possible?
Correct — ASFF is the single form every provider files on, and its Normalized severity lets a GuardDuty finding sort next to a Config one on the same scale.
Incorrect — Security Hub does not re-scan resources; it ingests each provider's finding and normalizes the format, preserving the reported severity via ASFF.
Incorrect — providers use different native severity schemes; it is the ASFF Normalized value, not shared vocabulary, that puts them on one scale.
Incorrect — the finding aggregator handles cross-region consolidation, not format conversion, and the shared shape is ASFF, not GuardDuty's own schema.
03You subscribe your whole organization to the AWS Foundational Security Best Practices (FSBP) standard, but a batch of controls stays stuck reporting nothing, neither pass nor fail, in several accounts. Every other control scores normally. What is the most likely cause?
Incorrect — a missing aggregator hides findings from the central region but does not stop controls from evaluating; these controls produce no result at all, which points elsewhere.
Correct — many FSBP controls read their evidence from AWS Config, so any account where Config recording is off leaves those controls with nothing to evaluate; confirm Config is recording everywhere.
Incorrect — a broken delegated admin would disrupt enrollment broadly, not leave most controls scoring normally while only a Config-dependent subset reports nothing.
Incorrect — subscribed standards run their checks continuously, not quarterly, so a waiting period is not why these controls are blank.

Try this

Work through “A score is a floor, not a finish line” yourself on a sandbox you can throw away, following the commands above in order. Then break one step deliberately and re-run, so you have seen the failure before it finds you.

Takeaway

The trap worth remembering here: auto-enable can switch on more than you meant to bill for. Check that on your own systems before you need to, because it is cheaper to find on a quiet afternoon than during an incident.

Related