All posts

AWS Security Hub: ASFF, Severity Normalisation and Cross-Account Aggregation

If you've enabled GuardDuty and Macie in AWS, you already have two separate consoles generating findings in two different formats with two different severity scales. Add Inspector, Config, and a third-party SIEM integration and the problem compounds quickly. Security Hub exists to solve that.

AWS Security Hub is a managed service that pulls findings from 30+ integrations into a single place, translates them into a common format, and gives you one API and console to query across all of them. It doesn't detect threats itself. It aggregates and normalises what other services detect.

At the centre of that normalisation is the Amazon Security Finding Format (ASFF): a standardised JSON schema that every integrated service must map its findings to before Security Hub will accept them. Every finding, regardless of source, ends up with the same set of fields: severity, affected resource, finding type, workflow state.

Beyond aggregation, Security Hub provides two additional capabilities:

Security Hub must be enabled per account and per region. Integrations with GuardDuty, Macie, Inspector, Config, and IAM Access Analyzer are enabled separately within Security Hub after the service is turned on.


Finding Categories

Security Hub classifies every finding using the ASFF Types field — a three-level Namespace/Category/Classifier taxonomy that maps findings from GuardDuty, Macie, Config, and other integrations to a consistent set of threat categories.

Security Hub classifies every finding using the ASFF Types field, which follows a three-level namespace taxonomy: Namespace/Category/Classifier. A finding can carry multiple Types values when it maps to more than one classification.

The five namespaces in use across Security Hub integrations:

Namespace What it covers Example sources
Software and Configuration Checks Compliance controls, configuration drift, patch status Security Hub Controls, AWS Config
TTPs Threat behaviours aligned to MITRE ATT&CK GuardDuty, third-party integrations
Sensitive Data Identifications Sensitive data discovered in cloud resources Amazon Macie
Effects The impact of a finding: data exposure, resource consumption GuardDuty, Macie
Unusual Behaviors Anomalous activity relative to an established baseline GuardDuty

A GuardDuty finding for a console login from an unusual location might carry both TTPs/Initial Access/Valid Accounts and Unusual Behaviors/User/ConsoleLogin. Two Types values reflecting different facets of the same event.

Security Hub Controls findings always fall under Software and Configuration Checks/Industry and Regulatory Standards or Software and Configuration Checks/AWS Security Best Practices, depending on which standard the control belongs to.


The Amazon Security Finding Format (ASFF)

The Amazon Security Finding Format (ASFF) is the standardised JSON schema that every Security Hub integration must map its findings to — giving every finding from every source the same set of fields, including severity, affected resource, finding type, and workflow state.

ASFF is the JSON schema that all Security Hub findings conform to. Every integrated service must translate its native finding format into ASFF before Security Hub will ingest it. This normalisation is what makes cross-service querying and filtering possible.

The key fields:

Field Purpose
SchemaVersion Always 2018-10-08
Id Unique finding ARN within Security Hub
ProductArn ARN of the service that generated the finding: product/aws/guardduty, product/aws/macie, etc.
GeneratorId Product-specific identifier: the GuardDuty detector ARN, the Config rule name, the Security Hub control ID
AwsAccountId The account the finding relates to. In a multi-account setup, this is the member account, not the aggregator
Types Array of Namespace/Category/Classifier strings classifying the finding
CreatedAt / UpdatedAt ISO 8601 timestamps; UpdatedAt reflects when the originating service last updated the finding
Severity.Label Normalised severity label: INFORMATIONAL, LOW, MEDIUM, HIGH, or CRITICAL
Severity.Normalized Integer 0-100; the score Security Hub uses to derive Severity.Label
FindingProviderFields.Severity The original severity from the source product, preserved alongside the normalised ASFF score
Resources Array of affected AWS resources, each with Type, Id, ARN, Region, and optional Details
Compliance Present on Security Hub control findings only (contains Status: PASSED, FAILED, WARNING, NOT_AVAILABLE)
WorkflowState / Workflow.Status Triage state: NEW, NOTIFIED, RESOLVED, or SUPPRESSED
RecordState ACTIVE or ARCHIVED; set by the originating service when a finding is no longer relevant

The distinction between RecordState and Workflow.Status trips people up. RecordState is controlled by the originating service. GuardDuty sets a finding to ARCHIVED when it stops observing the behaviour. Workflow.Status is controlled by your team. It reflects where the finding sits in your triage process and is set manually or via Security Hub automation rules. They are independent of each other.


Severity Normalisation

Security Hub maps every integrated service's native severity scale to a Severity.Normalized integer between 0 and 100, deriving a common Severity.LabelINFORMATIONAL, LOW, MEDIUM, HIGH, or CRITICAL — that can be compared across GuardDuty, Macie, Inspector, and other sources in a single query.

Every finding ingested by Security Hub is assigned a Severity.Normalized score between 0 and 100. This score determines the Severity.Label displayed in the console and returned by the API:

Normalized range Severity.Label
0 INFORMATIONAL
1-39 LOW
40-69 MEDIUM
70-89 HIGH
90-100 CRITICAL

Each integrated service maps its own native severity scale to this range. For the three AWS services most commonly used together:

Service Native severity ASFF Normalized Label
GuardDuty Low (1.0-3.9) 1-39 LOW
GuardDuty Medium (4.0-6.9) 40-69 MEDIUM
GuardDuty High (7.0-8.9) 70-89 HIGH
GuardDuty Critical (9.0+) 90-100 CRITICAL
Macie LOW 1-39 LOW
Macie MEDIUM 40-69 MEDIUM
Macie HIGH 70-89 HIGH
Inspector INFORMATIONAL 0 INFORMATIONAL
Inspector LOW 1-39 LOW
Inspector MEDIUM 40-69 MEDIUM
Inspector HIGH 70-89 HIGH
Inspector CRITICAL 90-100 CRITICAL

The normalised score gives you a common severity axis across services. What it doesn't give you is context.

A GuardDuty HIGH finding for UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS (Normalized: 80) and a Macie HIGH finding for SensitiveData:S3Object/Credentials (Normalized: 70) both show up as HIGH in Security Hub. The first means someone is actively exfiltrating EC2 instance credentials outside AWS. The second means Macie found AWS credentials embedded in an S3 object. Same label, very different urgency.

This is why ProductArn and Types matter when building filters, suppression rules, or automation. Filtering on Severity.Label = HIGH alone surfaces both. Filtering on ProductArn = product/aws/guardduty AND Severity.Label = HIGH narrows to active threat findings from GuardDuty only.

The original source severity is always available in FindingProviderFields.Severity.Original, which preserves the native score (e.g. "5.0" for a GuardDuty Medium) alongside the normalised value.


Cross-Account Aggregation

Security Hub cross-account aggregation centralises findings from all member accounts into a single administrator account view — one API, one console, one place to query across your entire AWS organisation.

In a multi-account AWS organisation, Security Hub findings are generated locally in each member account. Cross-account aggregation centralises them into a single view without requiring you to log into each account separately.

Delegated Administrator

One account is designated as the Security Hub delegated administrator via AWS Organizations. Typically this is the security tooling or audit account. Member accounts are enrolled automatically (if auto-enable is configured in Organizations) or manually. Once enrolled, each member account's findings are visible to the administrator account.

The AwsAccountId field on each finding identifies the originating member account. In the administrator account's console and API, findings from all members are queryable alongside findings from the administrator account itself.

Aggregation Region

Security Hub findings are regional by default. Cross-region aggregation must be explicitly configured: one region is designated as the aggregation region, and linked regions forward their findings into it. This gives you a single-region view across both accounts and regions.

The aggregation region must be the same region where your delegated administrator is configured. Regions are linked individually.

Filtering by Account

When querying aggregated findings, the AwsAccountId filter attribute scopes results to specific member accounts. This is useful when a known-noisy account, such as a development sandbox or penetration testing account, generates volume that would otherwise dilute signal from production. You can build Security Hub automation rules that apply Workflow.Status = SUPPRESSED to findings from specific accounts matching specific criteria, without affecting the same finding types in other accounts.


Example ASFF Finding

The following UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B finding shows how a GuardDuty alert looks after Security Hub normalises it into ASFF — with the original GuardDuty severity preserved in FindingProviderFields alongside the normalised score.

The following is a GuardDuty UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B finding as it appears in Security Hub after normalisation, in the format returned by the GetFindings API.

{
  "SchemaVersion": "2018-10-08",
  "Id": "arn:aws:securityhub:eu-west-1:123456789012:subscription/guardduty/v1/eu-west-1/123456789012/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
  "ProductArn": "arn:aws:securityhub:eu-west-1::product/aws/guardduty",
  "GeneratorId": "arn:aws:guardduty:eu-west-1:123456789012:detector/abc123def456abc123def456abc123de",
  "AwsAccountId": "123456789012",
  "Types": [
    "TTPs/Initial Access/Valid Accounts",
    "Unusual Behaviors/User/ConsoleLogin"
  ],
  "CreatedAt": "2026-05-10T08:42:17Z",
  "UpdatedAt": "2026-05-10T08:42:17Z",
  "Severity": {
    "Label": "MEDIUM",
    "Normalized": 50,
    "Original": "MEDIUM"
  },
  "FindingProviderFields": {
    "Severity": {
      "Label": "MEDIUM",
      "Original": "5.0"
    },
    "Types": [
      "TTPs/Initial Access/Valid Accounts",
      "Unusual Behaviors/User/ConsoleLogin"
    ]
  },
  "Title": "Successful console login from anomalous location.",
  "Description": "AWS Management Console login was observed from an anomalous location. The principal john.doe successfully authenticated from Spain, which is inconsistent with the geographic baseline established for this user.",
  "Resources": [
    {
      "Type": "AwsIamUser",
      "Id": "arn:aws:iam::123456789012:user/john.doe",
      "Partition": "aws",
      "Region": "eu-west-1",
      "Details": {
        "AwsIamUser": {
          "UserName": "john.doe"
        }
      }
    }
  ],
  "WorkflowState": "NEW",
  "Workflow": {
    "Status": "NEW"
  },
  "RecordState": "ACTIVE"
}

Key fields to note:


Further Reading