Skip to content

Commit 8dacdad

Browse files
committed
add wiz detection workflow
Signed-off-by: suraj-metron <suraj@metronlabs.com>
1 parent d6a451a commit 8dacdad

File tree

5 files changed

+364
-6
lines changed

5 files changed

+364
-6
lines changed

Community Developed/Wiz/ReadMe.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## Data Types to Retrieve from Wiz
22
1. **Wiz-Workflow.xml**: This file retrieves various types of Wiz issues from the Wiz server and imports them into QRadar.
33
2. **Wiz-AuditLogs-Workflow.xml**: This file retrieves different categories of Wiz audit logs from the Wiz server and imports them into QRadar.
4+
3. **Wiz-Detections-Workflow.xml**: This file retrieves different types of Wiz Detections from the Wiz server and imports them into QRadar.
45

56
## Collect authentication info from Wiz
67

@@ -24,7 +25,7 @@ To generate a client ID and client secret:
2425
1. Go to <a href="https://app.wiz.io/settings/service-accounts" target="_blank">Settings > Service Accounts</a>, then click **Add Service Account**.
2526
2. On the New Service Account page:
2627
1. Give the new service account a meaningful name, e.g. "QRadar integration".
27-
2. Select the permission **read:issues** and **admin:audit**.
28+
2. Select the permission **read:issues** and **admin:audit** and **read:detections**.
2829
3. Click **Add Service Account**.
2930
3. From the secret credential dialog, copy the **Client ID** and **Client Secret** to a local file or secret manager for use below.
3031
**Note: The Client ID and Client Secret are only shown once. Do not close the dialog without copying them to a local file or secret manager.**
@@ -59,3 +60,4 @@ Parameter Values).
5960
5. auth_type : The Authentication type used to fetch JWT Token from Wiz.
6061
6. gql_query : The GraphQL query to be used while fetching the Issues from Wiz (default GraphQL query already present).
6162
7. audit_logs_gql_query : The GraphQL query to be used while fetching the Audit Logs from Wiz (default GraphQL query already present).
63+
8. detections_gql_query : The GraphQL query to be used while fetching the Detections from Wiz (default GraphQL query already present).

Community Developed/Wiz/Wiz-AuditLogs-Workflow.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
<Parameter name="auth_type" label="Authentication Type" required="true" />
1010
<Parameter name="audit_logs_gql_query" label="GraphQL Query" required="true" />
1111
<Parameter name="gql_query" label="GraphQL Query" required="false" />
12+
<Parameter name="detections_gql_query" label="GraphQL Query" required="false" />
1213
</Parameters>
1314

1415

1516
<Actions>
1617
<Log type="INFO" message="WIZ: Workflow Actions started for Audit Logs..." />
17-
<Initialize path="/user_agent_header" value="127fb887-6a5e-99be-c1ef-5c62031e9614/qradar/2.0.3-v2" />
18+
<Initialize path="/user_agent_header" value="127fb887-6a5e-99be-c1ef-5c62031e9614/qradar/2.0.4" />
1819
<If condition="/audit_bookmark != null">
1920
<!-- Format Date to be passed in fetching events -->
2021
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss'Z'" timeZone="UTC" time="${/audit_bookmark}" savePath="/audit_timestamp" />
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<Workflow name="Wiz" version="1.0" xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/Workflow/V1">
3+
4+
<Parameters>
5+
<Parameter name="client_id" label="Client ID" required="true" />
6+
<Parameter name="client_secret" label="Client Secret" required="true" secret="true" />
7+
<Parameter name="token_url_domain" label="JWT Auth Endpoint" required="true" />
8+
<Parameter name="host" label="API Endpoint" required="true" />
9+
<Parameter name="auth_type" label="Authentication Type" required="true" />
10+
<Parameter name="detections_gql_query" label="Detections GraphQL Query" required="true" />
11+
<Parameter name="audit_logs_gql_query" label="GraphQL Query" required="false" />
12+
<Parameter name="gql_query" label="GraphQL Query" required="false" />
13+
</Parameters>
14+
15+
16+
<Actions>
17+
<Log type="INFO" message="WIZ: Workflow Actions started for Detections..." />
18+
<Initialize path="/user_agent_header" value="127fb887-6a5e-99be-c1ef-5c62031e9614/qradar/2.0.4" />
19+
<If condition="/detection_bookmark != null">
20+
<!-- Format Date to be passed in fetching events -->
21+
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss'Z'" timeZone="UTC" time="${/detection_bookmark}" savePath="/detection_timestamp" />
22+
</If>
23+
24+
25+
<If condition="/detection_timestamp != null">
26+
<Log type="INFO" message="WIZ: Incremental Polling started for Detections. Pulling Detections from: ${/detection_timestamp}" />
27+
</If>
28+
<Else>
29+
<!-- Set the date for 14 days before Historical Polling -->
30+
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss'Z'" timeZone="UTC" time="${time() - 14 * 86400000}" savePath="/detection_timestamp" />
31+
<Log type="INFO" message="WIZ: Historical Polling started. Pulling all Detections from: ${/detection_timestamp}" />
32+
</Else>
33+
<Set path="/detection_bookmark" value="${time()}"/>
34+
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss'Z'" timeZone="UTC" time="${/detection_bookmark}" savePath="/before_time" />
35+
<!-- Updating the GraphQL query variable for Incremental/Historical Polling -->
36+
<Set
37+
path="/detection_gql_query_variables"
38+
value='{
39+
"first":500,
40+
"filterBy": {
41+
"createdAt":{
42+
"after": "${/detection_timestamp}"
43+
}
44+
},
45+
"orderBy": {
46+
"field": "CREATED_AT",
47+
"direction": "DESC"
48+
}
49+
}'
50+
/>
51+
52+
53+
<!-- Initialize the Audience Parameter -->
54+
<Initialize path="/audience_parameter" value="wiz-api" />
55+
56+
<If condition="'${/auth_type}' = 'auth0'">
57+
<Set path="/audience_parameter" value="beyond-api" />
58+
</If>
59+
60+
<!-- Fetch API Token -->
61+
<CallEndpoint url="https://${/token_url_domain}/oauth/token" method="POST" savePath="/get_access_token">
62+
<RequestHeader name="content-type" value="application/x-www-form-urlencoded" />
63+
<RequestHeader name="User-Agent" value="${/user_agent_header}" />
64+
<UrlEncodedFormRequestBody>
65+
<Parameter name="grant_type" value="client_credentials" />
66+
<Parameter name="client_id" value="${/client_id}" />
67+
<Parameter name="client_secret" value="${/client_secret}" />
68+
<Parameter name="audience" value="${/audience_parameter}" />
69+
</UrlEncodedFormRequestBody>
70+
</CallEndpoint>
71+
72+
<Log type="INFO" message="WIZ: Auth Token API call status code:: ${/get_access_token/status_code}" />
73+
74+
<!-- Handle Errors -->
75+
<If condition="/get_access_token/status_code != 200">
76+
<Log type="ERROR" message="WIZ: Workflow Aborting.. API Token Failure. Error:: ${/get_access_token/body}" />
77+
<Abort reason="Failed requesting API token. Error: ${/get_access_token/body}" />
78+
</If>
79+
80+
<!-- Extract the Access Token -->
81+
<Set path="/access_token" value="${/get_access_token/body/access_token}" />
82+
83+
<Log type="INFO" message="WIZ: First API call for Detections: Using this GraphQL variable ${/detection_gql_query_variables}" />
84+
85+
<!-- Fetch Events -->
86+
<CallEndpoint url="https://${/host}/graphql" method="POST" savePath="/get_detections">
87+
<RequestHeader name="Authorization" value="Bearer ${/access_token}" />
88+
<RequestHeader name="content-type" value="application/json" />
89+
<RequestHeader name="User-Agent" value="${/user_agent_header}" />
90+
<RequestBody type="application/json" encoding="UTF-8">
91+
{
92+
"query": "${/detections_gql_query}",
93+
"variables": ${/detection_gql_query_variables}
94+
}
95+
</RequestBody>
96+
</CallEndpoint>
97+
98+
<Log type="INFO" message="WIZ: First API call for Detections status code:: ${/get_detections/status_code}" />
99+
100+
<!-- Handle Errors -->
101+
<If condition="/get_detections/status_code != 200">
102+
<Log type="ERROR" message="WIZ: Workflow Aborting.. Failure while fetching Detections. Error:: ${/get_detections/body}" />
103+
<Abort reason="Failed while fetching Wiz Detections. Error:: ${/get_detections/body}" />
104+
</If>
105+
106+
<Log type="INFO" message="WIZ: First API call fetched ${count(/get_detections/body/data/detections/nodes)} Wiz Detections" />
107+
108+
<!-- Post Events, if any -->
109+
<If condition="count(/get_detections/body/data/detections/nodes) > 0">
110+
<PostEvents path="/get_detections/body/data/detections/nodes" source="${/host}__Detection" />
111+
<Log type="INFO" message="WIZ: First API call for Detections is done. Sent ${count(/get_detections/body/data/detections/nodes)} Wiz Detection Events to QRadar" />
112+
113+
</If>
114+
115+
116+
<!-- Fetch remaining events -->
117+
<While condition="/get_detections/body/data/detections/pageInfo/hasNextPage">
118+
119+
<Set
120+
path="/detection_gql_query_variables"
121+
value='{
122+
"first":500,
123+
"filterBy": {
124+
"createdAt":{
125+
"after": "${/detection_timestamp}"
126+
}
127+
},
128+
"orderBy": {
129+
"field": "CREATED_AT",
130+
"direction": "DESC"
131+
},
132+
"after": "${/get_detections/body/data/detections/pageInfo/endCursor}"
133+
}'
134+
/>
135+
136+
137+
138+
<Log type="INFO" message="WIZ: Paginated API call for Detections: Using this GraphQL variable : ${/detection_gql_query_variables}" />
139+
140+
<!-- Fetch events -->
141+
<CallEndpoint url="https://${/host}/graphql" method="POST" savePath="/get_detections">
142+
<RequestHeader name="Authorization" value="Bearer ${/access_token}" />
143+
<RequestHeader name="content-type" value="application/json" />
144+
<RequestHeader name="User-Agent" value="${/user_agent_header}" />
145+
<RequestBody type="application/json" encoding="UTF-8">
146+
{
147+
"query": "${/detections_gql_query}",
148+
"variables": ${/detection_gql_query_variables}
149+
}
150+
</RequestBody>
151+
</CallEndpoint>
152+
153+
<Log type="INFO" message="WIZ: Paginated API call for Detections status code: ${/get_detections/status_code}" />
154+
155+
<!-- Handle Errors -->
156+
<If condition="/get_detections/status_code != 200">
157+
<Log type="ERROR" message="WIZ: Workflow Aborting.. Failure while fetching Detections. Error:: ${/get_detections/body}" />
158+
<Abort reason="Failed while fetching Wiz Detections. Error:: ${/get_detections/body}" />
159+
</If>
160+
161+
<Log type="INFO" message="WIZ: Paginated API call for Detections. Fetched ${count(/get_detections/body/data/detections/nodes)} Wiz Detections" />
162+
163+
<!-- Post Events, if any -->
164+
<If condition="count(/get_detections/body/data/detections/nodes) > 0">
165+
<PostEvents path="/get_detections/body/data/detections/nodes" source="${/host}__Detection" />
166+
<Log type="INFO" message="WIZ: Paginated API call for Detections is done. Sent ${count(/get_detections/body/data/detections/nodes)} Wiz Detections to QRadar" />
167+
</If>
168+
169+
170+
</While>
171+
<Set path="/detection_bookmark" value="${/detection_bookmark + 1000}"/>
172+
<Log type="INFO" message="WIZ: Updated the bookmark for Detections ${/detection_bookmark}." />
173+
<Log type="INFO" message="WIZ: All Actions for Detections are completed." />
174+
175+
176+
</Actions>
177+
178+
<Tests>
179+
<DNSResolutionTest host="${/host}" />
180+
<TCPConnectionTest host="${/host}" />
181+
<SSLHandshakeTest host="${/host}" />
182+
<DNSResolutionTest host="${/token_url_domain}" />
183+
<TCPConnectionTest host="${/token_url_domain}" />
184+
<SSLHandshakeTest host="${/token_url_domain}" />
185+
</Tests>
186+
187+
188+
</Workflow>

0 commit comments

Comments
 (0)