Techniques
Sample rules
AWS Bedrock High-Frequency Single-Model Inference API Probing
- source: elastic
- technicques:
Description
Identifies an AWS principal performing a high volume of Amazon Bedrock inference API calls against a single model within a short window. Membership inference attacks require hundreds to thousands of statistically similar queries whose prompts and responses are intentionally content-benign, making guardrail- and content-based rules ineffective. This rule detects the high-frequency single-model probing pattern that precedes membership inference and related exfiltration via the inference API. It is a behavioral / volumetric precursor: it does not observe model confidence scores and a fixed call-count threshold only catches the loud variant, so paced, low-and-slow, or credential-distributed probing will evade it. Definitive membership inference detection requires ML anomaly analysis over per-entity inference-rate and response-distribution baselines.
Detection logic
FROM logs-aws.cloudtrail-*
| WHERE event.provider == "bedrock.amazonaws.com"
AND event.action IN (
"InvokeModel",
"Converse",
"ConverseStream",
"InvokeModelWithResponseStream"
)
AND event.outcome == "success"
AND aws.cloudtrail.user_identity.arn IS NOT NULL
AND aws.cloudtrail.request_parameters IS NOT NULL
| GROK aws.cloudtrail.request_parameters """modelId=(?<Esql.model_id>[^,}\]]+)"""
| WHERE Esql.model_id IS NOT NULL
| STATS
Esql.inference_call_count = COUNT(*),
Esql.timestamp_min = MIN(@timestamp),
Esql.timestamp_max = MAX(@timestamp),
Esql.event_ingested_min = MIN(event.ingested),
Esql.event_ingested_max = MAX(event.ingested),
Esql.event_action_values = VALUES(event.action),
Esql.source_ip_values = VALUES(source.ip),
Esql.source_as_organization_name_values =
VALUES(source.as.organization.name),
Esql.source_geo_country_iso_code_values =
VALUES(source.geo.country_iso_code),
Esql.source_geo_city_name_values =
VALUES(source.geo.city_name),
Esql.user_name_values = VALUES(user.name),
Esql.user_agent_original_values = VALUES(user_agent.original),
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.session_issuer_arn_values =
VALUES(aws.cloudtrail.user_identity.session_context.session_issuer.arn),
Esql.cloud_region_values = VALUES(cloud.region),
Esql.data_stream_namespace_values = VALUES(data_stream.namespace)
BY aws.cloudtrail.user_identity.arn,
cloud.account.id,
Esql.model_id
| WHERE Esql.inference_call_count >= 500
| KEEP
aws.cloudtrail.user_identity.arn,
cloud.account.id,
Esql.*
| sort Esql.inference_call_count desc