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, both under the same ingestion label IMPERVA_WAF:
- API collection: With this method, Google SecOps pulls the logs directly from the Imperva API. This is a direct connection and only supports audit logs as described in Imperva Audit Trail .
- 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. This allows collecting security events and access logs, generated by the Cloud WAF, as described in Imperva log integration.
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 Console with 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 Roles section, select the Reader role.
 
- Click Save to create the user with read-only access.
Optional: Configure Reader user as API-Only
- In the Users list, locate the newly created user.
- Click the Actions button (three dots) next to the user's name.
- Select Set as API-only user.
Generate the API ID and API key
- In the Users list, select the newly created user.
- Select Settings and 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 in list, 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 name field, enter a name for the feed; for example, Imperva Incapsula WAF Logs.
- Select Third party API as the Source type.
- Select Imperva as 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 Finalize screen, and then click Submit.
Collect Imperva WAF logs using Amazon S3
Configure AWS IAM and S3
- Create an Amazon S3 bucket following this user guide: Creating a bucket
- Save the bucket Name and Region for later use.
- Create a User following this user guide: Creating an IAM user.
- Select the created User.
- Select the Security credentials tab.
- Click Create Access Key in the Access Keys section.
- Select Third-party service as the Use case.
- Click Next.
- Optional: Add a description tag.
- Click Create access key.
- Click Download .csv file and save the Access Key and Secret Access Key for later use.
- Click Done.
- Select the Permissions tab.
- Click Add permissions in the Permissions policies section.
- Select Add permissions.
- Select Attach policies directly.
- Search for and select the AmazonS3FullAccess policy.
- Click Next.
- Click Add permissions.
Configure Imperva WAF Amazon S3 connection
- Sign in to the Imperva Console with 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 connection to 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 name field, enter a name for the feed; for example, Imperva WAF Logs.
- Select Amazon S3 V2 as the Source type.
- Select Imperva as 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-namewith 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 Finalize screen, 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 actisallowed,alert, starts withREQ_PASSED, or starts withREQ_CACHED, set toALLOW. Ifactisdeny,blocked, starts withREQ_BLOCKED, or starts withREQ_CHALLENGE, set toBLOCK. Ifactmatches regex(?i)REQ_BAD, set toFAIL. Otherwise, set toUNKNOWN_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 catstarts withREQ_PASSEDorREQ_CACHED, setactiontoALLOWand setaction_detailsto a description based on the value ofcat. Ifcatstarts withREQ_BAD, setactiontoFAILand setaction_detailsto a description based on the value ofcat. Ifcatstarts withREQ_BLOCKEDorREQ_CHALLENGE, setactiontoBLOCKand setaction_detailsto a description based on the value ofcat. | 
| cicode | principal.location.city | Renamed from cicode. | 
| classified_client | security_result.detection_fields | If classified_clientis not empty, create a newdetection_fieldsentry with keyclassified_clientand valueclassified_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.ipandprincipal.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_fieldsentry with keycredentials_leakedand valuecredentials_leaked. | 
| cs1 | security_result.detection_fields | If cs1is not empty,NA, or `, create a newdetection_fieldsentry with keycs1Labeland valuecs1`. | 
| cs1Label | security_result.detection_fields | Used as the key for the detection_fieldsentry created fromcs1. | 
| cs2 | security_result.detection_fields | If cs2is not empty, create a newdetection_fieldsentry with keycs2Labeland valuecs2. | 
| cs2Label | security_result.detection_fields | Used as the key for the detection_fieldsentry created fromcs2. | 
| cs3 | security_result.detection_fields | If cs3is not empty,-, or `, create a newdetection_fieldsentry with keycs3Labeland valuecs3`. | 
| cs3Label | security_result.detection_fields | Used as the key for the detection_fieldsentry created fromcs3. | 
| cs4 | security_result.detection_fields | If cs4is not empty, create a newdetection_fieldsentry with keycs4Labeland valuecs4. | 
| cs4Label | security_result.detection_fields | Used as the key for the detection_fieldsentry created fromcs4. | 
| cs5 | security_result.detection_fields | If cs5is not empty, create a newdetection_fieldsentry with keycs5Labeland valuecs5. | 
| cs5Label | security_result.detection_fields | Used as the key for the detection_fieldsentry created fromcs5. | 
| cs6 | principal.application | Renamed from cs6. | 
| cs7 | principal.location.region_latitude | If cs7Labelislatitude, renamed toprincipal.location.region_latitude. Converted to float. | 
| cs7Label | If cs7Labelislatitude, used to determine the mapping ofcs7. | |
| cs8 | principal.location.region_longitude | If cs8Labelislongitude, renamed toprincipal.location.region_longitude. Converted to float. | 
| cs8Label | If cs8Labelislongitude, used to determine the mapping ofcs8. | |
| cs9 | security_result.rule_name, extensions.vulns.vulnerabilities.name | If cs9is not empty, set tosecurity_result.rule_nameand create a newvulnerabilitiesentry with namecs9. | 
| Customer | target.user.user_display_name | Renamed from Customer. | 
| declared_client | security_result.detection_fields | If declared_clientis not empty, create a newdetection_fieldsentry with keydeclared_clientand valuedeclared_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_timestamporkv.startis 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 dstis not empty, merged intotarget.ipandtarget.asset.ip. | 
| dstPort | target.port | Renamed from dstPort. Converted to integer. | 
| duser | target.user.userid | If duserdoes not match regex.*?Alert.*and is not empty, renamed totarget.user.userid. | 
| end | security_result.detection_fields | If endis not empty, create a newdetection_fieldsentry with keyevent_end_timeand valueend. | 
| 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_fieldsentry with keyfailed_logins_last_24hand valuefailed_logins_last_24h. | 
| fileId | network.session_id | Renamed from fileId. | 
| filePermission | security_result.detection_fields | If filePermissionis not empty, create a newdetection_fieldsentry with keyfilePermissionand valuefilePermission. | 
| fileType | security_result.detection_fields | If fileTypeis not empty, create a newdetection_fieldsentry with keyfileTypeand valuefileType. | 
| fingerprint | security_result.detection_fields | If fingerprintis not empty, create a newdetection_fieldsentry with keylog_imperva_fingerprintand valuefingerprint. | 
| 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 newdetection_fieldsentry with keyapollo_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 newdetection_fieldsentry with keybot_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 newdetection_fieldsentry with keybot_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 newdetection_fieldsentry with keybot_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 newdetection_fieldsentry with keybot_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 newdetection_fieldsentry with keybot_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 newdetection_fieldsentry with keybot_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_encodingis not empty, create a newdetection_fieldsentry with keyAccept Encodingand valueimperva.abp.headers_accept_encoding. | 
| imperva.abp.headers_accept_language | security_result.detection_fields | If imperva.abp.headers_accept_languageis not empty, create a newdetection_fieldsentry with keyAccept Languageand valueimperva.abp.headers_accept_language. | 
| imperva.abp.headers_connection | security_result.detection_fields | If imperva.abp.headers_connectionis not empty, create a newdetection_fieldsentry with keyheaders_connectionand valueimperva.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.hsigis not empty, create a newdetection_fieldsentry with keyhsigand valueimperva.abp.hsig. | 
| imperva.abp.monitor_action | security_result.action, security_result.severity | If imperva.abp.monitor_actionmatches regex(?i)allow, setsecurity_actiontoALLOWandseveritytoINFORMATIONAL. Ifimperva.abp.monitor_actionmatches regex(?i)captchaor(?i)block, setsecurity_actiontoBLOCK. | 
| imperva.abp.pid | principal.process.pid | Renamed from imperva.abp.pid. | 
| imperva.abp.policy_id | security_result.detection_fields | If imperva.abp.policy_idis not empty, create a newdetection_fieldsentry with keyPolicy Idand valueimperva.abp.policy_id. | 
| imperva.abp.policy_name | security_result.detection_fields | If imperva.abp.policy_nameis not empty, create a newdetection_fieldsentry with keyPolicy Nameand valueimperva.abp.policy_name. | 
| imperva.abp.random_id | additional.fields | If imperva.abp.random_idis not empty, create a newadditional.fieldsentry with keyRandom Idand valueimperva.abp.random_id. | 
| imperva.abp.request_type | principal.labels | If imperva.abp.request_typeis not empty, create a newprincipal.labelsentry with keyrequest_typeand valueimperva.abp.request_type. | 
| imperva.abp.selector | security_result.detection_fields | If imperva.abp.selectoris not empty, create a newdetection_fieldsentry with keyselectorand valueimperva.abp.selector. | 
| imperva.abp.selector_derived_id | security_result.detection_fields | If imperva.abp.selector_derived_idis not empty, create a newdetection_fieldsentry with keyselector_derived_idand valueimperva.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.zuidis not empty, create a newadditional.fieldsentry with keyzuidand valueimperva.abp.zuid. | 
| imperva.additional_factors | additional.fields | For each entry in imperva.additional_factors, create a newadditional.fieldsentry with keyadditional_factors_{index}and value equal to the entry. | 
| imperva.audit_trail.event_action | security_result.detection_fields | If imperva.audit_trail.event_actionis not empty, create a newdetection_fieldsentry with keyimperva.audit_trail.event_actionand valueimperva.audit_trail.event_action_description. | 
| imperva.audit_trail.event_action_description | security_result.detection_fields | Used as the value for the detection_fieldsentry created fromimperva.audit_trail.event_action. | 
| imperva.audit_trail.event_context | security_result.detection_fields | If imperva.audit_trail.event_contextis not empty, create a newdetection_fieldsentry with keyimperva.audit_trail.event_contextand valueimperva.audit_trail.event_context_description. | 
| imperva.audit_trail.event_context_description | security_result.detection_fields | Used as the value for the detection_fieldsentry created fromimperva.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_clientis not empty, create a newdetection_fieldsentry with keydeclared_clientand valueimperva.declared_client. | 
| imperva.device_reputation | additional.fields | For each entry in imperva.device_reputation, create a newadditional.fieldsentry with keydevice_reputationand a list value containing the entry. | 
| imperva.domain_risk | security_result.detection_fields | If imperva.domain_riskis not empty, create a newdetection_fieldsentry with keydomain_riskand valueimperva.domain_risk. | 
| imperva.failed_logins_last_24h | security_result.detection_fields | Converted to string. If not empty, create a new detection_fieldsentry with keyfailed_logins_last_24hand valuefailed_logins_last_24h. | 
| imperva.fingerprint | security_result.detection_fields | If imperva.fingerprintis not empty, create a newdetection_fieldsentry with keylog_imperva_fingerprintand valueimperva.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_idis not empty, create a newadditional.fieldsentry with keysite_idand valueimperva.ids.site_id. | 
| imperva.ids.site_name | additional.fields | If imperva.ids.site_nameis not empty, create a newadditional.fieldsentry with keysite_nameand valueimperva.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_useris not empty, create a newdetection_fieldsentry with keyrequest_userand valueimperva.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_nameis not empty, create a newdetection_fieldsentry with keysignificant_domain_nameand valueimperva.significant_domain_name. | 
| imperva.violated_directives | security_result.detection_fields | For each entry in imperva.violated_directives, create a newdetection_fieldsentry with keyviolated_directivesand value equal to the entry. | 
| in | network.received_bytes | Renamed from in. Converted to unsigned integer. | 
| log_timestamp | metadata.event_timestamp | If deviceReceiptTimeis empty andkv.startis empty, set tometadata.event_timestamp. | 
| message | metadata.description | If messageis not empty andevent.provider,imperva.ids.account_name, andclient.ipare all empty, set tometadata.description. | 
| postbody | security_result.detection_fields | If postbodyis not empty, create a newdetection_fieldsentry with keypost_body_infoand valuepostbody. | 
| proto | network.application_protocol | Renamed from proto. | 
| protoVer | network.tls.version, network.tls.cipher | If protoVeris not empty, parsed to extracttls_versionandtls_cipher, which are then renamed tonetwork.tls.versionandnetwork.tls.cipherrespectively. | 
| 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 tometadata.event_timestamp. | 
| security_result.action | security_result.action | Merged with the value of the _actionfield. | 
| security_result.severity | security_result.severity | If sevsiserrororwarning, set toHIGH. Ifsevsiscritical, set toCRITICAL. Ifsevsismediumornotice, set toMEDIUM. Ifsevsisinformationorinfo, set toLOW. | 
| 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 siteidis not empty, create a newdetection_fieldsentry with keysiteidand valuesiteid. | 
| sourceServiceName | target.hostname | Renamed from kv.sourceServiceName. | 
| spt | principal.port | Renamed from kv.spt. Converted to integer. | 
| src | principal.ip, principal.asset.ip | If srcis not empty, merged intoprincipal.ipandprincipal.asset.ip. | 
| srcPort | principal.port | Renamed from srcPort. Converted to integer. | 
| start | security_result.detection_fields, metadata.event_timestamp | If startis not empty, create a newdetection_fieldsentry with keyevent_start_timeand valuestart. Also parsed as a date and set tometadata.event_timestampifdeviceReceiptTimeis empty. | 
| successful_logins_last_24h | security_result.detection_fields | Converted to string. If not empty, create a new detection_fieldsentry with keysuccessful_logins_last_24hand valuesuccessful_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.pathis not empty or/, set totarget.process.file.full_path. | 
| url | target.url | Renamed from url. Ifqstris not empty, appended tourlwith a?separator. | 
| user.email | principal.user.email_addresses | If user.emailis not empty and matches regex^.+@.+$, merged intoprincipal.user.email_addresses. | 
| user_agent | network.http.user_agent | Renamed from user_agent. | 
| user_agent.original | network.http.parsed_user_agent | If user_agent.originalis not empty or*, converted toparseduseragentand renamed tonetwork.http.parsed_user_agent. | 
| user_details | principal.user.email_addresses | If user_detailsis not empty and matches regex^.+@.+$, merged intoprincipal.user.email_addresses. | 
| user_id | principal.user.userid | Renamed from user_id. | 
| ver | network.tls.version, network.tls.cipher | If veris not empty, parsed to extracttls_versionandtls_cipher, which are then renamed tonetwork.tls.versionandnetwork.tls.cipherrespectively. | 
| xff | intermediary.ip, intermediary.asset.ip, intermediary.hostname, intermediary.asset.hostname | If xffis not empty, processed to extract IP addresses and hostnames. IP addresses are merged intointermediary.ipandintermediary.asset.ip. Hostnames are set tointermediary.hostnameandintermediary.asset.hostname. | 
Need more help? Get answers from Community members and Google SecOps professionals.