AWS IAM Long-Term Access Key Correlated with Elevated Detection Alerts
Description
Correlates open detection alerts that share the same long-term IAM access key ID ( prefix AKIA). It fires when the rule AWS Long-Term Access Key First Seen from Source IP (rule_id: 9f8e3c5e-f72e-4e91-93f6-e98a4fae3e4f) has triggered for that key and at least one other open alert for the same key is medium, high, or critical severity. This higher-order rule helps prioritize long-term key novelty when it co-occurs with elevated detections that may indicate post-compromise activity.
Query · esql
from .alerts-security.* METADATA _id, _version, _index
// Sibling rule: AWS Long-Term Access Key First Seen from Source IP
// rule_id = 9f8e3c5e-f72e-4e91-93f6-e98a4fae3e4f
| where kibana.alert.workflow_status == "open"
and event.kind == "signal"
and source.ip is not null
and kibana.alert.rule.name is not null
and not kibana.alert.rule.type in ("threat_match", "machine_learning")
and not kibana.alert.rule.name like "Deprecated - *"
and not KQL("""kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)
and (
kibana.alert.rule.rule_id == "9f8e3c5e-f72e-4e91-93f6-e98a4fae3e4f"
or kibana.alert.risk_score >= 47
or kibana.alert.severity in ("medium", "high", "critical")
)
| eval Esql.is_long_term_key_new_ip_rule = kibana.alert.rule.rule_id == "9f8e3c5e-f72e-4e91-93f6-e98a4fae3e4f"
| eval Esql.is_other_elevated_rule = kibana.alert.rule.rule_id != "9f8e3c5e-f72e-4e91-93f6-e98a4fae3e4f"
and (
kibana.alert.risk_score >= 47
or kibana.alert.severity in ("medium", "high", "critical")
)
| stats
Esql.alert_count_long_term_key_new_ip_rule = SUM(CASE(Esql.is_long_term_key_new_ip_rule, 1, 0)),
Esql.alert_count_other_elevated_rule = SUM(CASE(Esql.is_other_elevated_rule, 1, 0)),
Esql.kibana_alert_rule_name_values = VALUES(kibana.alert.rule.name),
Esql.kibana_alert_rule_id_values = VALUES(kibana.alert.rule.rule_id),
Esql.kibana_alert_risk_score_values = VALUES(kibana.alert.risk_score),
Esql.kibana_alert_severity_values = VALUES(kibana.alert.severity),
Esql.user_entity_id_values = VALUES(user.entity.id),
Esql.timestamp_min = MIN(@timestamp),
Esql.timestamp_max = MAX(@timestamp)
by source.ip
| where Esql.alert_count_long_term_key_new_ip_rule > 0
and Esql.alert_count_other_elevated_rule > 0
| keep
source.ip,
Esql.alert_count_long_term_key_new_ip_rule,
Esql.alert_count_other_elevated_rule,
Esql.kibana_alert_rule_name_values,
Esql.kibana_alert_rule_id_values,
Esql.kibana_alert_risk_score_values,
Esql.kibana_alert_severity_values,
Esql.user_entity_id_values,
Esql.timestamp_min,
Esql.timestamp_max
Rule dependencies
⚠ Higher-order rule. It fires on other rules' alerts, not on raw events, so it cannot fire on its own. Deploy the rules it depends on too.
Depends on
-
correlates · Elastic alerts index
9f8e3c5e-f72e-4e91-93f6-e98a4fae3e4f
Excludes
9f8e3c5e-f72e-4e91-93f6-e98a4fae3e4f— excluded, not a dependencyRule Type: Higher-Order Rule— excluded, not a dependency
Investigation fields
Pivot points the source recommends for triage.
source.ipEsql.user_entity_id_valuesEsql.alert_count_long_term_key_new_ip_ruleEsql.alert_count_other_elevated_ruleEsql.kibana_alert_rule_name_valuesEsql.kibana_alert_rule_id_valuesEsql.kibana_alert_risk_score_valuesEsql.kibana_alert_severity_valuesEsql.timestamp_minEsql.timestamp_max
Known false positives
- The same automation identity may legitimately trigger a first-seen-IP alert and unrelated medium-or-higher findings in the same window (for example, a noisy compliance rule). Review sibling `kibana.alert.rule.name` values, rule tags, and CloudTrail context for the access key before escalating.
Analyst notes
Investigating AWS IAM Long-Term Access Key Correlated with Elevated Detection Alerts
This is a higher-order rule. It evaluates open signals in .alerts-security.* grouped by
aws.cloudtrail.user_identity.access_key_id. A match requires:
- At least one alert from AWS Long-Term Access Key First Seen from Source IP (
kibana.alert.rule.rule_id9f8e3c5e-f72e-4e91-93f6-e98a4fae3e4f). - At least one different alert on the same access key with medium or higher severity, implemented as
kibana.alert.risk_score >= 47orkibana.alert.severityinmedium,high, orcritical.
Possible investigation steps
Esql.alert_count_long_term_key_new_ip_rule: Confirm the first-seen-IP rule contributed to the correlation.Esql.alert_count_other_elevated: Count of sibling alerts meeting the elevated threshold (excluding the long-term-key new-IP rule).Esql.kibana_alert_rule_name_values/Esql.kibana_alert_rule_id_values: Identify which rules fired; map tactics and whether activity looks like post-compromise follow-through.aws.cloudtrail.user_identity.access_key_id: Pivot in CloudTrail and IAM (last used, attached policies, user or root context).Esql.aws_cloudtrail_user_identity_arn_values,Esql.source_ip_values: Reconstruct session context across alerts.
False positive analysis
- Overlapping scheduled jobs, penetration tests, or purple-team runs that reuse the same IAM access key across many detectors.
- Custom rules calibrated with medium severity but low risk scores still qualify via
kibana.alert.severity.
Response and remediation
- Treat as elevated priority versus the standalone first-seen-IP rule: rotate or disable the access key if abuse is suspected, scope CloudTrail for the key, and review open sibling alerts to closure.
Additional information
- Default risk score to severity mapping in Elastic Security is commonly 21 low, 47 medium, 73 high, 99 critical; confirm in your deployment if customized.