GCP Vertex AI High GenerateContent Volume From Single IP

Detects a single source IP making a high number of Vertex AI GenerateContent (or StreamGenerateContent) audit calls against the same model resource in the lookback window. That pattern fits model extraction, automated scraping, or a compromised caller burning prediction quota.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/10/02"
  3integration = ["gcp_vertexai"]
  4maturity = "production"
  5updated_date = "2026/10/02"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Detects a single source IP making a high number of Vertex AI GenerateContent (or StreamGenerateContent) audit calls
 11against the same model resource in the lookback window. That pattern fits model extraction, automated scraping, or a
 12compromised caller burning prediction quota.
 13"""
 14false_positives = [
 15    """
 16    Approved batch evaluation clients or shared NAT egress. Raise the threshold or exclude known source IP prefixes.
 17    """,
 18]
 19from = "now-60m"
 20interval = "10m"
 21language = "esql"
 22license = "Elastic License v2"
 23name = "GCP Vertex AI High GenerateContent Volume From Single IP"
 24note = """## Triage and analysis
 25
 26### Investigating GCP Vertex AI High GenerateContent Volume From Single IP
 27
 28A single `source.ip` issued an unusually high number of Vertex AI `GenerateContent` /
 29`StreamGenerateContent` audit calls against one model resource
 30(`gcp.vertexai.audit.resource_name`) in the lookback window. That pattern is consistent with
 31model extraction, automated scraping, or a compromised caller burning prediction quota.
 32
 33#### Possible investigation steps
 34
 35- Note `source.ip`, `gcp.vertexai.audit.resource_name`, `cloud.project.id`, and `Esql.event_count`
 36  on the alert. Compare the count to the project's normal peak for that model.
 37- Confirm whether the IP is known egress for an approved app, CI runner, or shared NAT. Check
 38  `Esql.event_action_values` for StreamGenerateContent vs GenerateContent mix.
 39- Pivot to `logs-gcp_vertexai.prompt_response_logs-*` for the same time window and model: sample
 40  prompts, token volume, and whether content looks like systematic extraction (repetitive probes,
 41  large context dumps).
 42- Pivot auditlogs for the same IP: other aiplatform methods, new service accounts, or
 43  `SetPublisherModelConfig` changes that could hide or redirect logging.
 44- Identify `client.user.email` on matching GenerateContent audit events to map IP → principal.
 45
 46### False positive analysis
 47
 48- Shared corporate NAT or proxy egress aggregating many legitimate users onto one IP.
 49- Approved batch evaluation, load tests, or data-migration jobs. Validate with change tickets and
 50  expected schedules before escalating.
 51
 52### Response and remediation
 53
 54- If unauthorized: revoke or rotate credentials for the calling principal, restrict the IP via VPC
 55  Service Controls / firewall, and apply per-IP or per-principal quotas.
 56- Review billing and quota usage for the model; hunt for similar volume from other IPs in the same
 57  project.
 58"""
 59references = [
 60    "https://www.elastic.co/docs/reference/integrations/gcp_vertexai",
 61    "https://genai.owasp.org/llmrisk/llm10-model-theft",
 62]
 63risk_score = 47
 64rule_id = "a9f28b66-a69e-4d5b-be8d-94e5eda6c736"
 65setup = """## Setup
 66
 67Requires GCP Vertex AI `auditlogs` for `aiplatform.googleapis.com`. Raise `Esql.event_count` above your normal peak
 68before broad enablement.
 69"""
 70severity = "medium"
 71tags = [
 72    "Domain: GenAI",
 73    "Domain: Cloud",
 74    "Data Source: GCP Vertex AI",
 75    "Data Source: GCP",
 76    "Data Source: Google Cloud Platform",
 77    "Platform: GCP",
 78    "Service: GCP Vertex AI",
 79    "Use Case: Model Theft",
 80    "Use Case: Threat Detection",
 81    "Tactic: Collection",
 82    "Threat: LLMjacking",
 83    "Threat: Unauthorized AI Usage",
 84    "Mitre Atlas: AML.T0024",
 85    "Mitre Atlas: AML.T0024.002",
 86    "Mitre Atlas: AML.T0029",
 87    "Resources: Investigation Guide",
 88    "Rule Type: ES|QL",
 89]
 90timestamp_override = "event.ingested"
 91type = "esql"
 92
 93query = '''
 94from logs-gcp_vertexai.auditlogs-*
 95| where
 96    data_stream.dataset == "gcp_vertexai.auditlogs" and
 97    source.ip is not null and
 98    (
 99        event.action like "*PredictionService.GenerateContent*" or
100        event.action like "*PredictionService.StreamGenerateContent*"
101    ) and
102    (gcp.vertexai.audit.status.code is null or gcp.vertexai.audit.status.code == 0)
103| stats
104    Esql.event_count = count(*),
105    Esql.timestamp_first_seen = min(@timestamp),
106    Esql.timestamp_last_seen = max(@timestamp),
107    Esql.event_action_values = values(event.action)
108  by
109    source.ip,
110    gcp.vertexai.audit.resource_name,
111    cloud.project.id
112| where Esql.event_count >= 100
113| keep
114    source.ip,
115    gcp.vertexai.audit.resource_name,
116    cloud.project.id,
117    Esql.event_count,
118    Esql.timestamp_first_seen,
119    Esql.timestamp_last_seen,
120    Esql.event_action_values
121'''
122
123
124[[rule.threat]]
125framework = "MITRE ATT&CK"
126[[rule.threat.technique]]
127id = "T1530"
128name = "Data from Cloud Storage"
129reference = "https://attack.mitre.org/techniques/T1530/"
130
131
132[rule.threat.tactic]
133id = "TA0009"
134name = "Collection"
135reference = "https://attack.mitre.org/tactics/TA0009/"
136[[rule.threat_mappings]]
137framework = "MITRE ATLAS"
138version = "2026.08"
139[[rule.threat_mappings.threat]]
140framework = "MITRE ATLAS"
141[[rule.threat_mappings.threat.technique]]
142id = "AML.T0029"
143name = "Denial of AI Service"
144reference = "https://atlas.mitre.org/techniques/AML.T0029/"
145
146
147[rule.threat_mappings.threat.tactic]
148id = "AML.TA0011"
149name = "Impact"
150reference = "https://atlas.mitre.org/tactics/AML.TA0011/"
151[[rule.threat_mappings.threat]]
152framework = "MITRE ATLAS"
153[[rule.threat_mappings.threat.technique]]
154id = "AML.T0024"
155name = "Exfiltration via AI Inference API"
156reference = "https://atlas.mitre.org/techniques/AML.T0024/"
157[[rule.threat_mappings.threat.technique.subtechnique]]
158id = "AML.T0024.002"
159name = "Extract AI Model"
160reference = "https://atlas.mitre.org/techniques/AML.T0024.002/"
161
162
163
164[rule.threat_mappings.threat.tactic]
165id = "AML.TA0010"
166name = "Exfiltration"
167reference = "https://atlas.mitre.org/tactics/AML.TA0010/"
168
169[rule.alert_suppression]
170group_by = ["source.ip", "gcp.vertexai.audit.resource_name", "cloud.project.id"]
171missing_fields_strategy = "suppress"
172
173[rule.investigation_fields]
174field_names = [
175    "source.ip",
176    "gcp.vertexai.audit.resource_name",
177    "cloud.project.id",
178    "Esql.event_count",
179    "Esql.event_action_values",
180    "Esql.timestamp_first_seen",
181    "Esql.timestamp_last_seen",
182]
183
184[rule.alert_suppression.duration]
185unit = "h"
186value = 1

Triage and analysis

Investigating GCP Vertex AI High GenerateContent Volume From Single IP

A single source.ip issued an unusually high number of Vertex AI GenerateContent / StreamGenerateContent audit calls against one model resource (gcp.vertexai.audit.resource_name) in the lookback window. That pattern is consistent with model extraction, automated scraping, or a compromised caller burning prediction quota.

Possible investigation steps

  • Note source.ip, gcp.vertexai.audit.resource_name, cloud.project.id, and Esql.event_count on the alert. Compare the count to the project's normal peak for that model.
  • Confirm whether the IP is known egress for an approved app, CI runner, or shared NAT. Check Esql.event_action_values for StreamGenerateContent vs GenerateContent mix.
  • Pivot to logs-gcp_vertexai.prompt_response_logs-* for the same time window and model: sample prompts, token volume, and whether content looks like systematic extraction (repetitive probes, large context dumps).
  • Pivot auditlogs for the same IP: other aiplatform methods, new service accounts, or SetPublisherModelConfig changes that could hide or redirect logging.
  • Identify client.user.email on matching GenerateContent audit events to map IP → principal.

False positive analysis

  • Shared corporate NAT or proxy egress aggregating many legitimate users onto one IP.
  • Approved batch evaluation, load tests, or data-migration jobs. Validate with change tickets and expected schedules before escalating.

Response and remediation

  • If unauthorized: revoke or rotate credentials for the calling principal, restrict the IP via VPC Service Controls / firewall, and apply per-IP or per-principal quotas.
  • Review billing and quota usage for the model; hunt for similar volume from other IPs in the same project.

References

Related rules

to-top