AWS Bedrock Model Invocation From High Number of Countries
Description
Detects a single AWS principal invoking Amazon Bedrock models from three or more countries and three or more source IPs within the lookback window. LLMjacking operators often distribute stolen AWS credentials across proxies or resell them to multiple buyers, which produces inference traffic for one identity from many unrelated locations.
Query · esql
from logs-aws.cloudtrail-*
| where
data_stream.dataset == "aws.cloudtrail" and
event.provider == "bedrock.amazonaws.com" and
event.action in ("InvokeModel", "InvokeModelWithResponseStream", "Converse", "ConverseStream") and
event.outcome == "success" and
aws.cloudtrail.user_identity.arn is not null and
source.ip is not null and
source.geo.country_name is not null
| eval
Esql.identity = coalesce(
aws.cloudtrail.user_identity.session_context.session_issuer.arn,
aws.cloudtrail.user_identity.arn
)
| stats
Esql.country_count = count_distinct(source.geo.country_name),
Esql.source_ip_count = count_distinct(source.ip),
Esql.user_agent_count = count_distinct(user_agent.original),
Esql.event_count = count(*),
Esql.event_action_values = values(event.action),
Esql.source_ip_values = values(source.ip),
Esql.source_geo_country_name_values = values(source.geo.country_name),
Esql.source_geo_city_name_values = values(source.geo.city_name),
Esql.source_as_organization_name_values = values(source.as.organization.name),
Esql.user_agent_original_values = values(user_agent.original),
Esql.aws_cloudtrail_user_identity_arn_values = values(aws.cloudtrail.user_identity.arn),
Esql.aws_cloudtrail_user_identity_type_values = values(aws.cloudtrail.user_identity.type),
Esql.aws_cloudtrail_user_identity_access_key_id_values = values(aws.cloudtrail.user_identity.access_key_id),
Esql.cloud_region_values = values(cloud.region),
Esql.timestamp_first_seen = min(@timestamp),
Esql.timestamp_last_seen = max(@timestamp)
by
Esql.identity,
cloud.account.id
| where Esql.country_count >= 3 and Esql.source_ip_count >= 3
| eval source.ip = mv_first(Esql.source_ip_values)
| keep
Esql.identity,
cloud.account.id,
source.ip,
Esql.country_count,
Esql.source_ip_count,
Esql.user_agent_count,
Esql.event_count,
Esql.event_action_values,
Esql.source_ip_values,
Esql.source_geo_country_name_values,
Esql.source_geo_city_name_values,
Esql.source_as_organization_name_values,
Esql.user_agent_original_values,
Esql.aws_cloudtrail_user_identity_arn_values,
Esql.aws_cloudtrail_user_identity_type_values,
Esql.aws_cloudtrail_user_identity_access_key_id_values,
Esql.cloud_region_values,
Esql.timestamp_first_seen,
Esql.timestamp_last_seen
Investigation fields
Pivot points the source recommends for triage.
Esql.identitycloud.account.idsource.ipEsql.country_countEsql.source_ip_countEsql.user_agent_countEsql.event_countEsql.source_geo_country_name_valuesEsql.source_ip_valuesEsql.source_as_organization_name_valuesEsql.user_agent_original_valuesEsql.aws_cloudtrail_user_identity_arn_valuesEsql.aws_cloudtrail_user_identity_access_key_id_values
Implementation guide
This rule requires AWS CloudTrail management events ingested via the AWS integration (aws.cloudtrail data stream)
with source.geo.country_name populated by the integration's GeoIP enrichment. Bedrock runtime operations are logged
as management events by default; no Bedrock model invocation logging is required.
Known false positives
- Globally distributed applications or CI runners that call Bedrock with one shared IAM user or role. Prefer per-region identities, or raise the country threshold for these principals.
- Users on VPNs or privacy relays that rotate exit countries. Corroborate with ASN and user agent before acting.
Analyst notes
Investigating AWS Bedrock Model Invocation From High Number of Countries
One AWS principal (role issuer ARN when present, otherwise aws.cloudtrail.user_identity.arn) invoked Amazon Bedrock
models from at least three countries and three source IPs inside the lookback window. Assumed-role sessions are grouped
by the issuing role so re-assumes of the same role still correlate. This pattern fits credentials that have been shared,
resold, or proxied for LLMjacking.
Possible investigation steps
- Review
Esql.source_geo_country_name_values,Esql.source_ip_values, andEsql.source_as_organization_name_values. Residential proxies and hosting ASNs across several countries are more suspicious than one corporate VPN provider. - Check
Esql.aws_cloudtrail_user_identity_access_key_id_valuesandEsql.aws_cloudtrail_user_identity_type_values. A single long-termAKIAkey seen in many countries is a strong indicator of credential theft. - Compare
Esql.user_agent_original_values. Several distinct clients for one identity often means several operators. - Search CloudTrail for the principal's other activity in the window, especially model access changes, guardrail or logging changes, and IAM changes.
- Review Bedrock cost and usage for the account over the same period.
False positive analysis
- Shared identities for global workloads. Move these to region-scoped roles or add an exception for the principal.
- VPN and privacy relay users. Confirm with the account owner before rotating credentials.
Response and remediation
- If the activity is not explained, deactivate the access key or revoke the role session, rotate credentials, and
restrict
bedrock:InvokeModel*permissions. - Set AWS Budgets or service quotas to limit the cost of further abuse.