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, andEsql.event_counton 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_valuesfor 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
SetPublisherModelConfigchanges that could hide or redirect logging. - Identify
client.user.emailon 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
- GCP Vertex AI High Request and Token Volume
- GCP Vertex AI Caller Activity From High Number of Countries
- GCP Vertex AI Caller Impossible Travel
- GCP Vertex AI Prompt or Response Containing Credentials
- GCP Vertex AI Elevated Safety Rating on Response