Collect Zscaler CASB logs
This document describes how you can export Zscaler CASB logs by setting up a Google Security Operations feed and mapping log fields to the Unified Data Model (UDM).
For more information, see Data ingestion to Google SecOps overview.
A typical deployment consists of Zscaler CASB and a Google SecOps Webhook feed configured to send logs to Google SecOps. However, deployment details can differ by customer and could be more complex.
The deployment contains the following components:
Zscaler CASB: The platform from which you collect logs.
Google SecOps feed: The Google SecOps feed that fetches logs from Zscaler CASB and writes logs to Google SecOps.
Google SecOps: Retains and analyzes the logs.
An ingestion label identifies the parser that normalizes raw log data into the structured UDM format. This document applies specifically to the parser associated with the ZSCALER_CASB ingestion label.
Before you begin
- Ensure that you have access to Zscaler Internet Access console. For more information, see Secure Internet and SaaS Access ZIA Help.
- Ensure that you're using Zscaler CASB version 1.0 or 2.0.
- Ensure that all systems in the deployment architecture are configured with the UTC time zone.
- Ensure that you have the API key required to complete feed setup in Google SecOps. For more information, see Setting up API keys.
Set up an ingestion feed in Google SecOps to ingest Zscaler CASB logs
- Go to Settings > Feeds.
- Click Add new.
- In the Feed name field, enter a name for the feed (for example,
Zscaler CASB Logs
). - Select Webhook as the Source Type.
- Select Zscaler CASB as the Log Type.
- Click Next.
- Optional: Enter values for the following input parameters:
- Split delimiter: the character used to separate logs lines. Leave blank if no delimiter is used.
- Asset namespace: the asset namespace.
- Ingestion labels: the label to be applied to the events from this feed.
- Click Next.
- Review your new feed configuration, and then click Submit.
- Click Generate Secret Key to generate a secret key to authenticate this feed.
Set up Zscaler CASB
- In the Zscaler Internet Access Console, click Administration > Nanolog Streaming Service > Cloud NSS Feeds > Add Cloud NSS Feed.
- In the Add Cloud NSS Feed window, enter the details.
- In the Feed Name field, enter a unique name for the feed.
- Select Zscaler for Web in NSS Type.
- In the Status list, select a status to activate or deactivate the NSS feed.
- Leave SIEM Rate as Unlimited, unless you need to throttle the output stream due to licensing or other constraints.
- In the SIEM Type list, select Other.
- In the OAuth 2.0 Authentication list, select Disabled.
- In the Max Batch Size field, enter a size limit for an individual HTTP request payload to the SIEM's best practice; for example,
512 KB
. In the API URL field, enter the HTTPS URL of the Chronicle API endpoint using the following format:
https://<CHRONICLE_REGION>-chronicle.googleapis.com/v1alpha/projects/<GOOGLE_PROJECT_NUMBER>/locations/<LOCATION>/instances/<CUSTOMER_ID>/feeds/<FEED_ID>:importPushLogs
CHRONICLE_REGION
: Region where your Google SecOps instance is hosted. For example,US
.GOOGLE_PROJECT_NUMBER
: Your BYOP project number. Obtain this from C4.LOCATION
: Chronicle (Google SecOps) region (same asCHRONICLE_REGION
). For example,US
.CUSTOMER_ID
: Your Google SecOps customer ID. Obtain from C4.FEED_ID
: ID of the newly created webhook feed (shown in the Feed UI).Sample API URL:
https://us-chronicle.googleapis.com/v1alpha/projects/12345678910/locations/US/instances/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/feeds/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy:importPushLogs
Click Add HTTP Header, and then add HTTP headers in the following format:
Header 1
: Key1:X-goog-api-key
and Value1: API Key generated from Google Cloud BYOP's API Credentials.Header 2
: Key2:X-Webhook-Access-Key
and Value2: API secret key generated in webhook's "SECRET KEY".
In the Log Types list, select SaaS Security or SaaS Security Activity.
In the Feed Output Type list, select JSON.
Set Feed Escape Character to
, \ "
.In the Feed Output Type list, select Custom to add a new field to the Feed Output Format.
Copy and paste the Feed Output Format, and then add new fields, as needed. Ensure the key names match the actual field names.
Following are the default Feed Output Formats:
- SaaS Security
\{ "sourcetype" : "zscalernss-casb", "event" :\{"datetime":"%s{time}","recordid":"%d{recordid}","company":"%s{company}","tenant":"%s{tenant}","login":"%s{user}","dept":"%s{department}","applicationname":"%s{applicationname}","filename":"%s{filename}","filesource":"%s{filesource}","filemd5":"%s{filemd5}","threatname":"%s{threatname}","policy":"%s{policy}","dlpdictnames":"%s{dlpdictnames}","dlpdictcount":"%s{dlpdictcount}","dlpenginenames":"%s{dlpenginenames}","fullurl":"%s{fullurl}","lastmodtime":"%s{lastmodtime}","filescantimems":"%d{filescantimems}","filedownloadtimems":"%d{filedownloadtimems}"\}\}
- SaaS Security Activity
\{ "sourcetype" : "zscalernss-casb", "event" :\{"login":"%s{username}","tenant":"%s{tenant}","object_type":"%d{objtype1}","applicationname":"%s{appname}","object_name_1":"%s{objnames1}","object_name_2":"%s{objnames2}"\}\}
From the Timezone list, select the time zone for the Time field in the output file. By default, the time zone is set to your organization's time zone.
Review the configured settings.
Click Save to test connectivity. If the connection is successful, a green tick accompanied by the message Test Connectivity Successful: OK (200) appears.
For more information about Google SecOps feeds, see Google SecOps feeds documentation. For information about requirements for each feed type, see Feed configuration by type.
If you encounter issues when you create feeds, contact Google SecOps support.
Field mapping reference
Field mapping reference: ZSCALER_CASB
The following table lists the log fields of the ZSCALER_CASB
log type and their corresponding UDM fields.
Log field | UDM mapping | Logic |
---|---|---|
sourcetype |
security_result.detection_fields[sourcetype] |
|
objnames2 |
about.resource.name |
|
object_name_2 |
about.resource.name |
|
objtypename2 |
about.resource.resource_subtype |
|
externalownername |
additional.fields[externalownername] |
|
act_cnt |
additional.fields[act_cnt] |
|
attchcomponentfiletypes |
additional.fields[attchcomponentfiletypes] |
|
channel_name |
additional.fields[channel_name] |
|
collabscope |
additional.fields[collabscope] |
|
day |
additional.fields[day] |
|
dd |
additional.fields[dd] |
|
dlpdictcount |
security_result.detection_fields[dlpdictcount] |
If the dlpdictcount log field value is not empty and the dlpdictcount log field value is not equal to None , then the dlpdictcount log field is mapped to the security_result.detection_fields.dlpdictcount UDM field. |
dlpenginenames |
security_result.detection_fields[dlpenginenames] |
If the dlpenginenames log field value is not empty and the dlpenginenames log field value is not equal to None , then the dlpenginenames log field is mapped to the security_result.detection_fields.dlpenginenames UDM field. |
epochlastmodtime |
additional.fields[epochlastmodtime] |
|
extcollabnames |
additional.fields[extcollabnames] |
|
extownername |
additional.fields[extownername] |
|
file_msg_id |
additional.fields[file_msg_id] |
|
fileid |
additional.fields[fileid] |
|
filescantimems |
additional.fields[filescantimems] |
|
filetypecategory |
additional.fields[filetypecategory] |
|
hh |
additional.fields[hh] |
|
messageid |
additional.fields[messageid] |
|
mm |
additional.fields[mm] |
|
mon |
additional.fields[mon] |
|
msgsize |
additional.fields[msgsize] |
|
mth |
additional.fields[mth] |
|
num_ext_recpts |
additional.fields[num_ext_recpts] |
|
num_int_recpts |
additional.fields[num_int_recpts] |
|
numcollab |
additional.fields[numcollab] |
|
rtime |
additional.fields[rtime] |
|
ss |
additional.fields[ss] |
|
suburl |
additional.fields[suburl] |
|
tenant |
additional.fields[tenant] |
|
tz |
additional.fields[tz] |
|
upload_doctypename |
additional.fields[upload_doctypename] |
|
yyyy |
additional.fields[yyyy] |
|
collabnames |
additional.fields[collabnames] |
|
companyid |
additional.fields[companyid] |
|
component |
additional.fields[component] |
|
intcollabnames |
additional.fields[intcollabnames] |
If intcollabnames log field value does not match the regular expression pattern None then, for index in intcollabnames , the index is mapped to the additional.fields.value.list_value UDM field. |
internal_collabnames |
additional.fields[internal_collabnames] |
|
external_collabnames |
additional.fields[externalcollabnames] |
|
num_external_collab |
additional.fields[num_external_collab] |
|
num_internal_collab |
additional.fields[num_internal_collab] |
|
repochtime |
additional.fields[repochtime] |
|
eventtime |
metadata.event_timestamp |
If the eventtime log field value is not empty, then the eventtime log field is mapped to the metadata.event_timestamp UDM field. |
epochtime |
metadata.event_timestamp |
If the epochtime log field value is not empty, then the epochtime log field is mapped to the metadata.event_timestamp UDM field. |
time |
metadata.event_timestamp |
If the time log field value is not empty, then the time log field is mapped to the metadata.event_timestamp UDM field. |
datetime |
metadata.event_timestamp |
If the datetime log field value is not empty, then the datetime log field is mapped to the metadata.event_timestamp UDM field. |
|
metadata.event_type |
The metadata.event_type UDM field is set to USER_UNCATEGORIZED . |
act_type_name |
metadata.product_event_type |
|
recordid |
metadata.product_log_id |
|
|
metadata.product_name |
The metadata.product_name UDM field is set to CASB . |
|
metadata.vendor_name |
The metadata.vendor_name UDM field is set to Zscaler . |
sender |
network.email.from |
If the sender log field value matches the regular expression pattern (^.*@.*$) , then the sender log field is mapped to the network.email.from UDM field. |
extrecptnames |
network.email.to |
For index in extrecptnames , the index is mapped to the network.email.to UDM field. |
internal_recptnames |
network.email.to |
For index in internal_recptnames , the index is mapped to the network.email.to UDM field. |
external_recptnames |
network.email.to |
For index in external_recptnames , the index is mapped to the network.email.to UDM field. |
intrecptnames |
network.email.to |
For index in intrecptnames , the index is mapped to the network.email.to UDM field. |
applicationname |
principal.application |
If the applicationname log field value is not empty, then the applicationname log field is mapped to the principal.application UDM field.Else, the appname log field is mapped to the principal.application UDM field. |
src_ip |
principal.ip |
|
fullurl |
principal.url |
If the fullurl log field is not empty and the fullurl log field value is not equal to Unknown URL , then the fullurl log field is mapped to the principal.url UDM field. |
is_admin_act |
principal.user.attribute.labels[is_admin_act] |
|
|
principal.user.attribute.roles.type |
If the is_admin_act log field value is equal to 1 , then the principal.user.attribute.roles.type UDM field is set to ADMINISTRATOR . |
company |
principal.user.company_name |
|
department |
principal.user.department |
|
dept |
principal.user.department |
|
user |
principal.user.email_addresses |
If the user log field value matches the regular expression pattern (^.*@.*$) , then the user log field is mapped to the principal.user.email_addresses UDM field. |
username |
principal.user.email_addresses |
If the username log field value matches the regular expression pattern (^.*@.*$) , then the username log field is mapped to the principal.user.email_addresses UDM field. |
owner |
principal.user.email_addresses |
If the owner log field value matches the regular expression pattern (^.*@.*$) , then the owner log field is mapped to the principal.user.email_addresses UDM field. |
login |
principal.user.email_addresses |
If the login log field value matches the regular expression pattern (^.*@.*$) , then the login log field is mapped to the principal.user.email_addresses UDM field. |
login |
principal.user.userid |
If the login log field value does not match the regular expression pattern ^.+@.+$ , then the login log field is mapped to the principal.user.userid UDM field. |
malware |
security_result.associations.name |
|
|
security_result.associations.type |
If the malware log field value is not empty, then the security_result.associations.type UDM field is set to MALWARE . |
dlpdictnames |
security_result.detection_fields[dlpdictnames] |
|
dlpidentifier |
security_result.detection_fields[dlpidentifier] |
|
filedownloadtimems |
additional.fields[filedownloadtimems] |
|
malwareclass |
security_result.detection_fields[malwareclass] |
|
msgid |
security_result.detection_fields[msgid] |
|
oattchcomponentfilenames |
security_result.detection_fields[oattchcomponentfilenames] |
|
obucketname |
security_result.detection_fields[obucketname] |
|
obucketowner |
security_result.detection_fields[obucketowner] |
|
ochannel_name |
security_result.detection_fields[ochannel_name] |
|
ocollabnames |
security_result.detection_fields[ocollabnames] |
|
odlpdictnames |
security_result.detection_fields[odlpdictnames] |
|
odlpenginenames |
security_result.detection_fields[odlpenginenames] |
|
oextcollabnames |
security_result.detection_fields[oextcollabnames] |
|
oexternal_collabnames |
security_result.detection_fields[oexternal_collabnames] |
|
oexternal_recptnames |
security_result.detection_fields[oexternal_recptnames] |
|
oexternalownername |
security_result.detection_fields[oexternalownername] |
|
oextownername |
security_result.detection_fields[oextownername] |
|
oextrecptnames |
security_result.detection_fields[oextrecptnames] |
|
ofile_msg_id |
security_result.detection_fields[ofile_msg_id] |
|
ofileid |
security_result.detection_fields[ofileid] |
|
ofullurl |
security_result.detection_fields[ofullurl] |
|
ohostname |
security_result.detection_fields[ohostname] |
|
ointcollabnames |
security_result.detection_fields[ointcollabnames] |
|
ointernal_collabnames |
security_result.detection_fields[ointernal_collabnames] |
|
ointernal_recptnames |
security_result.detection_fields[ointernal_recptnames] |
|
ointrecptnames |
security_result.detection_fields[ointrecptnames] |
|
omessageid |
security_result.detection_fields[omessageid] |
|
omsgid |
security_result.detection_fields[omsgid] |
|
oowner |
security_result.detection_fields[oowner] |
|
orulelabel |
security_result.detection_fields[orulelabel] |
|
osender |
security_result.detection_fields[osender] |
|
osharedchannel_hostname |
security_result.detection_fields[osharedchannel_hostname] |
|
otenant |
security_result.detection_fields[otenant] |
|
ouser |
security_result.detection_fields[ouser] |
|
any_incident |
security_result.detection_fields[any_incident] |
|
is_inbound |
security_result.detection_fields[is_inbound] |
|
policy |
security_result.rule_labels[policy] |
|
ruletype |
security_result.rule_labels[ruletype] |
|
rulelabel |
security_result.rule_name |
|
|
security_result.severity |
If the severity log field value is equal to High , then the security_result.severity UDM field is set to HIGH .Else, if the severity log field value is equal to Medium , then the security_result.severity UDM field is set to MEDIUM .Else, if the severity log field value is equal to Low , then the security_result.sevrity UDM field is set to LOW .Else, if the severity log field value is equal to Information , then the security_result.severity UDM field is set to INFORMATIONAL . |
threatname |
security_result.threat_name |
If the threatname log field value is not empty and the dlpdictcount log field value is not equal to None , then the threatname log field is mapped to the security_result.threat_name UDM field. |
filesource |
target.file.full_path |
If the filesource log field value is not empty, then the filesource log field is mapped to the target.file.full_path UDM field. |
filepath |
target.file.full_path |
If the filesource log field value is not empty, then the filesource log field is mapped to the target.file.full_path UDM field.Else if the filepath log field value is not empty, then the filepath log field is mapped to the target.file.full_path UDM field. |
lastmodtime |
target.file.last_modification_time |
If the lastmodtime log field value is not empty, then the lastmodtime log field is mapped to the target.file.last_modification_time UDM field. |
file_msg_mod_time |
target.file.last_modification_time |
If the lastmodtime log field value is not empty, then the lastmodtime log field is mapped to the target.file.last_modification_time UDM field.Else if the file_msg_mod_time log field value is not empty, then the file_msg_mod_time log field is mapped to the target.file.fullpath UDM field. |
filemd5 |
target.file.md5 |
If the filemd5 log field value is not equal to None and the filemd5 log field value matches the regular expression pattern ^[a-fA-F0-9]{32}$ , then the filemd5 log field is mapped to the target.file.md5 UDM field.Else, if the attchcomponentmd5s log field value matches the regular expression pattern ^[a-fA-F0-9]{32}$ , then the attchcomponentmd5s log field is mapped to the target.file.md5 UDM field. |
filetypename |
target.file.mime_type |
|
filename |
target.file.names |
|
attchcomponentfilenames |
target.file.names |
|
sha |
target.file.sha256 |
|
attchcomponentfilesizes |
target.file.size |
If the attchcomponentfilesizes log field value is not empty, then the attchcomponentfilesizes log field is mapped to the target.file.size UDM field. |
filesize |
target.file.size |
If the attchcomponentfilesizes log field value is not empty, then the attchcomponentfilesizes log field is mapped to the target.file.size UDM field.Else if the filesize log field value is not empty, then the filesize log field is mapped to the target.file.size UDM field. |
sharedchannel_hostname |
target.hostname |
If the hostname log field value is not empty, then the hostname log field is mapped to the target.hostname UDM field.Else if the sharedchannel_hostname log field value is not empty, then the sharedchannel_hostname log field is mapped to the target.hostname UDM field. |
hostname |
target.hostname |
If the hostname log field value is not empty, then the hostname log field is mapped to the target.hostname UDM field. |
datacentercity |
target.location.city |
|
datacentercountry |
target.location.country_or_region |
|
datacenter |
target.location.name |
|
bucketowner |
target.resource.attribute.labels[bucketowner] |
|
projectname |
target.resource.attribute.labels[projectname] |
|
bucketname |
target.resource.name |
If the bucketname log field value is not empty, then the bucketname log field is mapped to the target.resource.name UDM field. |
objnames1 |
target.resource.name |
If the objnames1 log field value is not empty, then the objnames1 log field is mapped to the target.resource.name UDM field. |
objectname |
target.resource.name |
If the objectname log field value is not empty, then the objectname log field is mapped to the target.resource.name UDM field. |
reponame |
target.resource.name |
If the reponame log field value is not empty, then the reponame log field is mapped to the target.resource.name UDM field. |
object_name_1 |
target.resource.name |
If the object_name_1 log field value is not empty, then the object_name_1 log field is mapped to the target.resource.name UDM field. |
bucketid |
target.resource.product_object_id |
|
objtypename1 |
target.resource.resource_subtype |
If the objtypename1 log field value is not empty, then the objtypename1 log field is mapped to the target.resource.resource_subtype UDM field. |
objecttype |
target.resource.resource_subtype |
If the objecttype log field value is not empty, then the objecttype log field is mapped to the target.resource.resource_subtype UDM field. |
object_type |
target.resource.resource_subtype |
|
|
target.resource.resource_type |
If the bucketname log field value is not empty, then the target.resource.resource_type UDM field is set to STORAGE_BUCKET .If the reponame log field value is not empty, then the target.resource.resource_type UDM field is set to REPOSITORY . |
What's next
Need more help? Get answers from Community members and Google SecOps professionals.