Collect Imperva WAF logs
This document explains how to collect logs from the Imperva Web Application Firewall (WAF) to Google Security Operations using either an API or Amazon S3. The parser transforms logs from SYSLOG+KV, JSON, CEF, and LEEF formats into a unified data model (UDM). It processes various log structures, extracts relevant fields, normalizes them into UDM attributes, and enriches the data with contextual information for enhanced security analysis.
Collection method differences
The Imperva WAF integration with Google SecOps supports the following methods for log ingestion:
- API collection: With this method, Google SecOps pulls the logs directly from the Imperva API. This is a direct connection and only supports the
IMPERVA_WAF
log type. - Amazon S3 V2 bucket collection: With this method, Imperva WAF pushes logs into a designated Amazon S3 bucket. Google SecOps then pulls the logs from this bucket. Because the S3 bucket can receive logs from many sources, this method supports the collection of many different Imperva log types, provided you configure those logs to be explicitly pushed to the bucket.
Before you begin
Ensure that you have the following prerequisites:
- Ingestion type (API or Amazon S3) that best fits your configuration requirements.
- Google SecOps instance.
- Privileged access to AWS.
- Privileged access to Imperva WAF.
Collect Imperva WAF logs using API
Configure a Read-Only user for Imperva WAF
- Sign in to the Imperva Consolewith a privileged account.
- Go to Settings > Users & Roles.
- Click Add User.
- Fill in the required fields:
- Username: enter a unique username.
- Password: set a strong password.
- Email: provide the user's email address.
- In the Rolessection, select the Readerrole.
- Click Saveto create the user with read-only access.
Optional: Configure Reader user as API-Only
- In the Userslist, locate the newly created user.
- Click the Actionsbutton (three dots) next to the user's name.
- Select Set as API-onlyuser.
Generate the API ID and API key
- In the Userslist, select the newly created user.
- Select Settingsand click API Keys.
- Click Add API Key.
- Fill in the required fields:
- Name: enter a descriptive name for the API key.
- Optional: Description: provide an optional description.
- In the API key will expire inlist, select Never.
- To enable, select Status.
- Click Save.
The system displays the API ID and API Key. Copy and save these credentials, as they won't be displayed again.
Set up feeds
To configure a feed, follow these steps:
- Go to SIEM Settings > Feeds.
- Click Add New Feed.
- On the next page, click Configure a single feed.
- In the Feed namefield, enter a name for the feed; for example, Imperva Incapsula WAF Logs.
- Select Third party APIas the Source type.
- Select Impervaas the Log type.
- Click Next.
- Specify values for the following input parameters:
- Authentication HTTP header: enter the Imperva API ID and Key in two lines:
apiId:<YOUR_API_ID>
andapiKey:<YOUR_API_KEY>
.
- Authentication HTTP header: enter the Imperva API ID and Key in two lines:
- Click Next.
- Review the feed configuration in the Finalizescreen, and then click Submit.
Collect Imperva WAF logs using Amazon S3
Configure AWS IAM and S3
- Create an Amazon S3 bucketfollowing this user guide: Creating a bucket
- Save the bucket Nameand Regionfor later use.
- Create a Userfollowing this user guide: Creating an IAM user .
- Select the created User.
- Select the Security credentialstab.
- Click Create Access Keyin the Access Keyssection.
- Select Third-party serviceas the Use case.
- Click Next.
- Optional: Add a description tag.
- Click Create access key.
- Click Download .csv fileand save the Access Keyand Secret Access Keyfor later use.
- Click Done.
- Select the Permissionstab.
- Click Add permissionsin the Permissions policiessection.
- Select Add permissions.
- Select Attach policies directly.
- Search for and select the AmazonS3FullAccesspolicy.
- Click Next.
- Click Add permissions.
Configure Imperva WAF Amazon S3 connection
- Sign in to the Imperva Consolewith a privileged account.
- Go to Logs > Log Setup.
- Select Amazon S3.
- Fill in the required fields:
- Access key
- Secret key
- Path: enter the path in the following format:
<Amazon S3 bucket name>/<log folder>
; for example:MyBucket/MyIncapsulaLogFolder
.
- Click Test connectionto perform a full testing cycle in which a test file is transferred to your designated folder.
- Select the format for the log files as CEF.
- By default, log files are compressed. Set the option to not compress files.
Configure a feed in Google SecOps to ingest Imperva WAF logs from Amazon S3 V2
- Go to SIEM Settings > Feeds.
- Click Add New Feed.
- In the Feed namefield, enter a name for the feed; for example,
Imperva WAF Logs
. - Select Amazon S3 V2as the Source type.
- Select Impervaas the Log type.
- Click Next.
-
Specify values for the following input parameters:
- S3 URI: the bucket URI.
-
s3://your-log-bucket-name/
- Replace
your-log-bucket-name
with the actual name of the bucket.
- Replace
-
-
Source deletion options: Select the deletion option according to your preference.
-
Maximum File Age: Include files modified in the last number of days. Default is 180 days.
-
Access Key ID: User access key with access to the S3 bucket.
-
Secret Access Key: User secret key with access to the S3 bucket.
-
Asset namespace: The asset namespace .
-
Ingestion labels: The label to be applied to the events from this feed.
- S3 URI: the bucket URI.
-
Click Next.
-
Review your new feed configuration in the Finalizescreen, and then click Submit.
UDM Mapping Table
Log field | UDM mapping | Logic |
---|---|---|
account_id
|
target.user.userid | The account id from the json object |
act
|
security_result.action | If act
is allowed
, alert
, starts with REQ_PASSED
, or starts with REQ_CACHED
, set to ALLOW
. If act
is deny
, blocked
, starts with REQ_BLOCKED
, or starts with REQ_CHALLENGE
, set to BLOCK
. If act
matches regex (?i)REQ_BAD
, set to FAIL
. Otherwise, set to UNKNOWN_ACTION
. |
app
|
network.application_protocol | Renamed from kv.app
. Converted to uppercase. |
calCountryOrRegion
|
principal.location.country_or_region | Renamed from calCountryOrRegion
. |
cat
|
security_result.action_details | If cat
starts with REQ_PASSED
or REQ_CACHED
, set action
to ALLOW
and set action_details
to a description based on the value of cat
. If cat
starts with REQ_BAD
, set action
to FAIL
and set action_details
to a description based on the value of cat
. If cat
starts with REQ_BLOCKED
or REQ_CHALLENGE
, set action
to BLOCK
and set action_details
to a description based on the value of cat
. |
cicode
|
principal.location.city | Renamed from cicode
. |
classified_client
|
security_result.detection_fields | If classified_client
is not empty, create a new detection_fields
entry with key classified_client
and value classified_client
. |
client.domain
|
principal.hostname, principal.asset.hostname | Renamed from client.domain
. |
client.geo.country_iso_code
|
principal.location.country_or_region | Renamed from client.geo.country_iso_code
. |
client.ip
|
principal.ip, principal.asset.ip | Merged into principal.ip
and principal.asset.ip
. |
cn1
|
network.http.response_code | Renamed from cn1
. Converted to integer. |
context_key
|
target.resource.name | Renamed from context_key
. |
country
|
principal.location.country_or_region | Renamed from country
. |
credentials_leaked
|
security_result.detection_fields | Converted to string. If not empty, create a new detection_fields
entry with key credentials_leaked
and value credentials_leaked
. |
cs1
|
security_result.detection_fields | If cs1
is not empty, NA
, or ` , create a new
detection_fields entry with key
cs1Label and value
cs1`. |
cs1Label
|
security_result.detection_fields | Used as the key for the detection_fields
entry created from cs1
. |
cs2
|
security_result.detection_fields | If cs2
is not empty, create a new detection_fields
entry with key cs2Label
and value cs2
. |
cs2Label
|
security_result.detection_fields | Used as the key for the detection_fields
entry created from cs2
. |
cs3
|
security_result.detection_fields | If cs3
is not empty, -
, or ` , create a new
detection_fields entry with key
cs3Label and value
cs3`. |
cs3Label
|
security_result.detection_fields | Used as the key for the detection_fields
entry created from cs3
. |
cs4
|
security_result.detection_fields | If cs4
is not empty, create a new detection_fields
entry with key cs4Label
and value cs4
. |
cs4Label
|
security_result.detection_fields | Used as the key for the detection_fields
entry created from cs4
. |
cs5
|
security_result.detection_fields | If cs5
is not empty, create a new detection_fields
entry with key cs5Label
and value cs5
. |
cs5Label
|
security_result.detection_fields | Used as the key for the detection_fields
entry created from cs5
. |
cs6
|
principal.application | Renamed from cs6
. |
cs7
|
principal.location.region_latitude | If cs7Label
is latitude
, renamed to principal.location.region_latitude
. Converted to float. |
cs7Label
|
If cs7Label
is latitude
, used to determine the mapping of cs7
. |
|
cs8
|
principal.location.region_longitude | If cs8Label
is longitude
, renamed to principal.location.region_longitude
. Converted to float. |
cs8Label
|
If cs8Label
is longitude
, used to determine the mapping of cs8
. |
|
cs9
|
security_result.rule_name, extensions.vulns.vulnerabilities.name | If cs9
is not empty, set to security_result.rule_name
and create a new vulnerabilities
entry with name cs9
. |
Customer
|
target.user.user_display_name | Renamed from Customer
. |
declared_client
|
security_result.detection_fields | If declared_client
is not empty, create a new detection_fields
entry with key declared_client
and value declared_client
. |
description
|
security_result.threat_name | Renamed from description
. |
deviceExternalId
|
network.community_id | Renamed from deviceExternalId
. |
deviceReceiptTime
|
metadata.event_timestamp | Parsed as a date and set to metadata.event_timestamp
. If empty, log_timestamp
or kv.start
is used instead. |
dhost
|
target.hostname | Renamed from kv.dhost
. |
dproc
|
security_result.category_details | Renamed from dproc
. |
dpt
|
target.port | Renamed from kv.dpt
. Converted to integer. |
dst
|
target.ip, target.asset.ip | If dst
is not empty, merged into target.ip
and target.asset.ip
. |
dstPort
|
target.port | Renamed from dstPort
. Converted to integer. |
duser
|
target.user.userid | If duser
does not match regex .*?Alert.*
and is not empty, renamed to target.user.userid
. |
end
|
security_result.detection_fields | If end
is not empty, create a new detection_fields
entry with key event_end_time
and value end
. |
event.id
|
The event id from the json object | |
event.provider
|
principal.user.user_display_name | Renamed from event.provider
. |
failed_logins_last_24h
|
security_result.detection_fields | Converted to string. If not empty, create a new detection_fields
entry with key failed_logins_last_24h
and value failed_logins_last_24h
. |
fileId
|
network.session_id | Renamed from fileId
. |
filePermission
|
security_result.detection_fields | If filePermission
is not empty, create a new detection_fields
entry with key filePermission
and value filePermission
. |
fileType
|
security_result.detection_fields | If fileType
is not empty, create a new detection_fields
entry with key fileType
and value fileType
. |
fingerprint
|
security_result.detection_fields | If fingerprint
is not empty, create a new detection_fields
entry with key log_imperva_fingerprint
and value fingerprint
. |
flexString1
|
network.http.response_code | Renamed from kv.flexString1
. Converted to integer. |
http.request.body.bytes
|
network.sent_bytes | Converted to unsigned integer. Renamed from http.request.body.bytes
. |
http.request.method
|
network.http.method | Renamed from http.request.method
. |
imperva.abp.apollo_rule_versions
|
security_result.detection_fields | For each entry in imperva.abp.apollo_rule_versions
, create a new detection_fields
entry with key apollo_rule_versions_{index}
and value equal to the entry. |
imperva.abp.bot_behaviors
|
security_result.detection_fields | For each entry in imperva.abp.bot_behaviors
, create a new detection_fields
entry with key bot_behaviors_{index}
and value equal to the entry. |
imperva.abp.bot_deciding_condition_ids
|
security_result.detection_fields | For each entry in imperva.abp.bot_deciding_condition_ids
, create a new detection_fields
entry with key bot_deciding_condition_ids_{index}
and value equal to the entry. |
imperva.abp.bot_deciding_condition_names
|
security_result.detection_fields | For each entry in imperva.abp.bot_deciding_condition_names
, create a new detection_fields
entry with key bot_deciding_condition_names_{index}
and value equal to the entry. |
imperva.abp.bot_triggered_condition_ids
|
security_result.detection_fields | For each entry in imperva.abp.bot_triggered_condition_ids
, create a new detection_fields
entry with key bot_triggered_condition_ids_{index}
and value equal to the entry. |
imperva.abp.bot_triggered_condition_names
|
security_result.detection_fields | For each entry in imperva.abp.bot_triggered_condition_names
, create a new detection_fields
entry with key bot_triggered_condition_names_{index}
and value equal to the entry. |
imperva.abp.bot_violations
|
security_result.detection_fields | For each entry in imperva.abp.bot_violations
, create a new detection_fields
entry with key bot_violations_{index}
and value equal to the entry. |
imperva.abp.customer_request_id
|
network.session_id | Renamed from imperva.abp.customer_request_id
. |
imperva.abp.headers_accept_encoding
|
security_result.detection_fields | If imperva.abp.headers_accept_encoding
is not empty, create a new detection_fields
entry with key Accept Encoding
and value imperva.abp.headers_accept_encoding
. |
imperva.abp.headers_accept_language
|
security_result.detection_fields | If imperva.abp.headers_accept_language
is not empty, create a new detection_fields
entry with key Accept Language
and value imperva.abp.headers_accept_language
. |
imperva.abp.headers_connection
|
security_result.detection_fields | If imperva.abp.headers_connection
is not empty, create a new detection_fields
entry with key headers_connection
and value imperva.abp.headers_connection
. |
imperva.abp.headers_referer
|
network.http.referral_url | Renamed from imperva.abp.headers_referer
. |
imperva.abp.hsig
|
security_result.detection_fields | If imperva.abp.hsig
is not empty, create a new detection_fields
entry with key hsig
and value imperva.abp.hsig
. |
imperva.abp.monitor_action
|
security_result.action, security_result.severity | If imperva.abp.monitor_action
matches regex (?i)allow
, set security_action
to ALLOW
and severity
to INFORMATIONAL
. If imperva.abp.monitor_action
matches regex (?i)captcha
or (?i)block
, set security_action
to BLOCK
. |
imperva.abp.pid
|
principal.process.pid | Renamed from imperva.abp.pid
. |
imperva.abp.policy_id
|
security_result.detection_fields | If imperva.abp.policy_id
is not empty, create a new detection_fields
entry with key Policy Id
and value imperva.abp.policy_id
. |
imperva.abp.policy_name
|
security_result.detection_fields | If imperva.abp.policy_name
is not empty, create a new detection_fields
entry with key Policy Name
and value imperva.abp.policy_name
. |
imperva.abp.random_id
|
additional.fields | If imperva.abp.random_id
is not empty, create a new additional.fields
entry with key Random Id
and value imperva.abp.random_id
. |
imperva.abp.request_type
|
principal.labels | If imperva.abp.request_type
is not empty, create a new principal.labels
entry with key request_type
and value imperva.abp.request_type
. |
imperva.abp.selector
|
security_result.detection_fields | If imperva.abp.selector
is not empty, create a new detection_fields
entry with key selector
and value imperva.abp.selector
. |
imperva.abp.selector_derived_id
|
security_result.detection_fields | If imperva.abp.selector_derived_id
is not empty, create a new detection_fields
entry with key selector_derived_id
and value imperva.abp.selector_derived_id
. |
imperva.abp.tls_fingerprint
|
security_result.description | Renamed from imperva.abp.tls_fingerprint
. |
imperva.abp.token_id
|
target.resource.product_object_id | Renamed from imperva.abp.token_id
. |
imperva.abp.zuid
|
additional.fields | If imperva.abp.zuid
is not empty, create a new additional.fields
entry with key zuid
and value imperva.abp.zuid
. |
imperva.additional_factors
|
additional.fields | For each entry in imperva.additional_factors
, create a new additional.fields
entry with key additional_factors_{index}
and value equal to the entry. |
imperva.audit_trail.event_action
|
security_result.detection_fields | If imperva.audit_trail.event_action
is not empty, create a new detection_fields
entry with key imperva.audit_trail.event_action
and value imperva.audit_trail.event_action_description
. |
imperva.audit_trail.event_action_description
|
security_result.detection_fields | Used as the value for the detection_fields
entry created from imperva.audit_trail.event_action
. |
imperva.audit_trail.event_context
|
security_result.detection_fields | If imperva.audit_trail.event_context
is not empty, create a new detection_fields
entry with key imperva.audit_trail.event_context
and value imperva.audit_trail.event_context_description
. |
imperva.audit_trail.event_context_description
|
security_result.detection_fields | Used as the value for the detection_fields
entry created from imperva.audit_trail.event_context
. |
imperva.country
|
principal.location.country_or_region | Renamed from imperva.country
. |
imperva.declared_client
|
security_result.detection_fields | If imperva.declared_client
is not empty, create a new detection_fields
entry with key declared_client
and value imperva.declared_client
. |
imperva.device_reputation
|
additional.fields | For each entry in imperva.device_reputation
, create a new additional.fields
entry with key device_reputation
and a list value containing the entry. |
imperva.domain_risk
|
security_result.detection_fields | If imperva.domain_risk
is not empty, create a new detection_fields
entry with key domain_risk
and value imperva.domain_risk
. |
imperva.failed_logins_last_24h
|
security_result.detection_fields | Converted to string. If not empty, create a new detection_fields
entry with key failed_logins_last_24h
and value failed_logins_last_24h
. |
imperva.fingerprint
|
security_result.detection_fields | If imperva.fingerprint
is not empty, create a new detection_fields
entry with key log_imperva_fingerprint
and value imperva.fingerprint
. |
imperva.ids.account_id
|
metadata.product_log_id | Renamed from imperva.ids.account_id
. |
imperva.ids.account_name
|
metadata.product_event_type | Renamed from imperva.ids.account_name
. |
imperva.ids.site_id
|
additional.fields | If imperva.ids.site_id
is not empty, create a new additional.fields
entry with key site_id
and value imperva.ids.site_id
. |
imperva.ids.site_name
|
additional.fields | If imperva.ids.site_name
is not empty, create a new additional.fields
entry with key site_name
and value imperva.ids.site_name
. |
imperva.referrer
|
network.http.referral_url | Renamed from imperva.referrer
. |
imperva.request_session_id
|
network.session_id | Renamed from imperva.request_session_id
. |
imperva.request_user
|
security_result.detection_fields | If imperva.request_user
is not empty, create a new detection_fields
entry with key request_user
and value imperva.request_user
. |
imperva.risk_level
|
security_result.severity_details | Renamed from imperva.risk_level
. |
imperva.risk_reason
|
security_result.description | Renamed from imperva.risk_reason
. |
imperva.significant_domain_name
|
security_result.detection_fields | If imperva.significant_domain_name
is not empty, create a new detection_fields
entry with key significant_domain_name
and value imperva.significant_domain_name
. |
imperva.violated_directives
|
security_result.detection_fields | For each entry in imperva.violated_directives
, create a new detection_fields
entry with key violated_directives
and value equal to the entry. |
in
|
network.received_bytes | Renamed from in
. Converted to unsigned integer. |
log_timestamp
|
metadata.event_timestamp | If deviceReceiptTime
is empty and kv.start
is empty, set to metadata.event_timestamp
. |
message
|
metadata.description | If message
is not empty and event.provider
, imperva.ids.account_name
, and client.ip
are all empty, set to metadata.description
. |
postbody
|
security_result.detection_fields | If postbody
is not empty, create a new detection_fields
entry with key post_body_info
and value postbody
. |
proto
|
network.application_protocol | Renamed from proto
. |
protoVer
|
network.tls.version, network.tls.cipher | If protoVer
is not empty, parsed to extract tls_version
and tls_cipher
, which are then renamed to network.tls.version
and network.tls.cipher
respectively. |
request
|
target.url | Renamed from kv.request
. |
requestClientApplication
|
network.http.user_agent | Renamed from requestClientApplication
. |
requestMethod
|
network.http.method | Renamed from requestMethod
. Converted to uppercase. |
resource_id
|
target.resource.id | Renamed from resource_id
. |
resource_type_key
|
target.resource.type | Renamed from resource_type_key
. |
rt
|
metadata.event_timestamp | Parsed to extract deviceReceiptTime
, which is then parsed as a date and set to metadata.event_timestamp
. |
security_result.action
|
security_result.action | Merged with the value of the _action
field. |
security_result.severity
|
security_result.severity | If sevs
is error
or warning
, set to HIGH
. If sevs
is critical
, set to CRITICAL
. If sevs
is medium
or notice
, set to MEDIUM
. If sevs
is information
or info
, set to LOW
. |
server.domain
|
target.hostname, target.asset.hostname | Renamed from server.domain
. |
server.geo.name
|
target.location.name | Renamed from server.geo.name
. |
severity
|
security_result.threat_id | Renamed from severity
. |
siteid
|
security_result.detection_fields | If siteid
is not empty, create a new detection_fields
entry with key siteid
and value siteid
. |
sourceServiceName
|
target.hostname | Renamed from kv.sourceServiceName
. |
spt
|
principal.port | Renamed from kv.spt
. Converted to integer. |
src
|
principal.ip, principal.asset.ip | If src
is not empty, merged into principal.ip
and principal.asset.ip
. |
srcPort
|
principal.port | Renamed from srcPort
. Converted to integer. |
start
|
security_result.detection_fields, metadata.event_timestamp | If start
is not empty, create a new detection_fields
entry with key event_start_time
and value start
. Also parsed as a date and set to metadata.event_timestamp
if deviceReceiptTime
is empty. |
successful_logins_last_24h
|
security_result.detection_fields | Converted to string. If not empty, create a new detection_fields
entry with key successful_logins_last_24h
and value successful_logins_last_24h
. |
suid
|
target.user.userid | Renamed from suid
. |
time
|
metadata.event_timestamp | Converted to string. Parsed as a date and set to metadata.event_timestamp
. |
type_key
|
metadata.product_event_type | Renamed from type_key
. |
url
|
target.process.file.full_path | If url.path
is not empty or /
, set to target.process.file.full_path
. |
url
|
target.url | Renamed from url
. If qstr
is not empty, appended to url
with a ?
separator. |
user.email
|
principal.user.email_addresses | If user.email
is not empty and matches regex ^.+@.+$
, merged into principal.user.email_addresses
. |
user_agent
|
network.http.user_agent | Renamed from user_agent
. |
user_agent.original
|
network.http.parsed_user_agent | If user_agent.original
is not empty or *
, converted to parseduseragent
and renamed to network.http.parsed_user_agent
. |
user_details
|
principal.user.email_addresses | If user_details
is not empty and matches regex ^.+@.+$
, merged into principal.user.email_addresses
. |
user_id
|
principal.user.userid | Renamed from user_id
. |
ver
|
network.tls.version, network.tls.cipher | If ver
is not empty, parsed to extract tls_version
and tls_cipher
, which are then renamed to network.tls.version
and network.tls.cipher
respectively. |
xff
|
intermediary.ip, intermediary.asset.ip, intermediary.hostname, intermediary.asset.hostname | If xff
is not empty, processed to extract IP addresses and hostnames. IP addresses are merged into intermediary.ip
and intermediary.asset.ip
. Hostnames are set to intermediary.hostname
and intermediary.asset.hostname
. |
Need more help? Get answers from Community members and Google SecOps professionals.