Cisco Webex¶
Table of Contents¶
Release Notes¶
Version |
Date |
Notes |
---|---|---|
2.0.0 |
7/2022 |
Migrated to REST API and added the ability to create rooms, teams and meetings |
1.1.1 |
8/2021 |
Rebuild app.zip |
1.1.0 |
2/2021 |
App Host Support |
1.0.0 |
8/2018 |
Initial Release |
Overview¶
Cisco Webex for IBM QRadar SOAR
This package extends the meeting and collaboration functionality of Webex to IBM Security QRadar SOAR Platform. This package provides SOAR platform with the ability to interface with Cisco Webex and create rooms, teams and meetings. The user now can create Meeitngs, Rooms and teams from within a SOAR incident and assign its members to it.
Key Features¶
This package provides functions to create of one or more Webex Teams and Rooms and allows you to add members of an incident or task to them.
Functionality to delete Teams or Rooms created from an incident or task is also possible using this package.
It allows for creating Rooms and Teams with additional members who are not a part of the Team or Room.
It has the ability to create instant meetings or to schedule meetings in advance from within a task or an incident.
Example workflows are included that performs the above mentioned operation and stores the meeting, room or team related information as note.
Example rules are included that activate a menu popup that prompts the user for inputs to customize the team, room or a meeting.
Requirements¶
This app supports the IBM Security QRadar SOAR Platform and the IBM Security QRadar SOAR for IBM Cloud Pak for Security.
SOAR platform¶
The SOAR platform supports two app deployment mechanisms, App Host and integration server.
If deploying to a SOAR platform with an App Host, the requirements are:
SOAR platform >=
43.1
.The app is in a container-based format (available from the AppExchange as a
zip
file).
If deploying to a SOAR platform with an integration server, the requirements are:
SOAR platform >=
43.1
.The app is in the older integration format (available from the AppExchange as a
zip
file which contains atar.gz
file).Integration server is running
resilient-circuits>=45.0.0
.If using an API key account, make sure the account provides the following minimum permissions:
Name
Permissions
Org Data
Read
Function
Read
The following SOAR platform guides provide additional information:
App Host Deployment Guide: provides installation, configuration, and troubleshooting information, including proxy server settings.
Integration Server Guide: provides installation, configuration, and troubleshooting information, including proxy server settings.
System Administrator Guide: provides the procedure to install, configure and deploy apps.
The above guides are available on the IBM Documentation website at ibm.biz/soar-docs. On this web page, select your SOAR platform version. On the follow-on page, you can find the App Host Deployment Guide or Integration Server Guide by expanding Apps in the Table of Contents pane. The System Administrator Guide is available by expanding System Administrator.
Cloud Pak for Security¶
If you are deploying to IBM Cloud Pak for Security, the requirements are:
IBM Cloud Pak for Security >= 1.9.
Cloud Pak is configured with an App Host.
The app is in a container-based format (available from the AppExchange as a
zip
file).
The following Cloud Pak guides provide additional information:
App Host Deployment Guide: provides installation, configuration, and troubleshooting information, including proxy server settings. From the Table of Contents, select Case Management and Orchestration & Automation > Orchestration and Automation Apps.
System Administrator Guide: provides information to install, configure, and deploy apps. From the IBM Cloud Pak for Security IBM Documentation table of contents, select Case Management and Orchestration & Automation > System administrator.
These guides are available on the IBM Documentation website at ibm.biz/cp4s-docs. From this web page, select your IBM Cloud Pak for Security version. From the version-specific IBM Documentation page, select Case Management and Orchestration & Automation.
Proxy Server¶
The app does support a proxy server.
Python Environment¶
Python 3.6 is supported. Additional package dependencies may exist for each of these packages:
resilient-circuits>=45.0.0
Installation¶
To install or uninstall an App or Integration on the SOAR platform, see the documentation at ibm.biz/soar-docs.
To install or uninstall an App on IBM Cloud Pak for Security, see the documentation at ibm.biz/cp4s-docs and follow the instructions above to navigate to Orchestration and Automation.
Webex Configuration¶
For this application to perform the above-mentioned functions, a Webex app integration must be created at Webex Developer using the user’s organization account. This Integrations is how the SOAR platform requests permission to invoke the Webex REST API from SOAR platform. To do this in a secure way, OAuth 2 standard is used, which allows third-party integrations to get a temporary access token for authenticating API calls. The OAuth Utilities package developed for IBM SOAR apps is to be used to perform this Authentication.
The following steps can be followed to create an app integration:
Navigate to Webex Developer and click on Create an Integration
The webesite will then present the user with a series of questions. The three primary field that is required for this integratio to work would be Mobile SDK, Redirect URI and Scopes.
Select No for using Mobile SDk.
Redirect URI is required for completing the OAuth grant flow. In this case :
https://localhost:8080/callback
Scopes define the level of access that your integration requires. All meetings related scopes are to be selected.
Upon completion, the user will be provided with a Client ID, Client Secret and an OAuth Authorization URL, which is then used for authentication.
OAuth Authentication¶
To establish a secure connection between the Webex integration and SOAR platform, the OAuth Utilities Documentation is to be used.
The tool is used to generate a unique Refresh token, which is then used by the app.
There are several ways to generate this Refresh token using the OAuth Utilities tool, please refer to the documentation OAuth Utilities Documentation
Once such method would be using the CLI. A sample command has been provided below:
oauth-utils oauth2_generate_refresh_token \
-tu https://webexapis.com/v1/access_token \
-au https://webexapis.com/v1/authorize \
-ci <CLIENT_ID> \
-cs <CLIENT_SECRET> \
-sc "meeting:recordings_read meeting:schedules_read"
This generates the required Refresh Token for app configuration.
App Configuration¶
The following table provides the settings you need to configure the app. These settings are made in the app.config file. See the documentation discussed in the Requirements section for the procedure.
Config |
Required |
Example |
Description |
---|---|---|---|
webex_site_url |
Yes |
|
Webex endpoint URL |
webex_timezone |
Yes |
|
Reference Timezone for the meeting |
client_id |
Yes |
|
Issued while creating the integration |
client_secret |
Yes |
|
Issued while creating the integration |
refresh_token |
Yes |
|
Generated using the OAuth Utilities Tool |
scope |
Yes |
|
Issued while creating the integration |
Function - Webex: Create Meeting¶
A function to schedule meetings or create instant meetings from a task or a incident. This function prompts the user for inputs and schedules meetings in accordance with that. The user is provided with a certain level of flexibility when it comes to choosing the time or date of the meeting. The user can set a start time or end time, or just provide the duration of the meeting. The package will automatically determine the start and end time based on these values. Should the user only provide an end time, the start time is assumed to be 2 mins from current time. If the user only provides a duration, the meeting starts 2 minutes from current time and ends after the specified duration. Note that the duration of the meeting cannot be set to a value more than 24 hours (1440 minutes).
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Meeting name |
|
|
Yes |
|
Meeting password. The value must always be more than 4 characters |
|
|
No |
|
Agenda for the meeting |
|
|
No |
|
Duration of meeting in minutes. Cannot be more that 1 day (1440 minutes). Takes effect when End time is not specified |
|
|
No |
|
Meeting start date and time |
|
|
No |
|
Meeting end date and time |
Outputs:
NOTE: This example might be in JSON format, but
results
is a Python Dictionary on the SOAR platform.
results = {
"content": {
"agenda": "Sample meeting",
"allowAnyUserToBeCoHost": "false",
"allowAuthenticatedDevices": "true",
"allowFirstUserToBeCoHost": "false",
"callInNumber": "+1-000-000-0000",
"callInNumbers": "label:United States Toll",
"dialInIpAddress": "173.000.0.00",
"end": "2022-08-11T14:18:00Z",
"excludePassword": "false",
"hostDisplayName": "admin@admin.ai",
"hostEmail": "admin@admin.ai",
"hostKey": "100001",
"hostUserId": "hostuserid123",
"href": "/v1/meetings/hostuserid123/globalCallinNumbers",
"id": "7abca37c1c124cb2a4e74661f4a8c47e",
"joinBeforeHostMinutes": "0",
"links": "rel:globalCallinNumbers",
"meetingNumber": "11111112222222",
"meetingOptions": "enabledChat:true",
"meetingType": "meetingSeries",
"method": "GET",
"noteType": "allowAll",
"password": "abcd1234",
"phoneAndVideoSystemPassword": "22231234",
"publicMeeting": "false",
"scheduledType": "meeting",
"sessionTypeId": "3",
"simultaneousInterpretation": "enabled:false",
"sipAddress": "25967357926@example.com",
"siteUrl": "example-ex.webex.com",
"start": "2022-08-11T13:33:00Z",
"state": "active",
"status": true,
"telephony": "accessCode:25967357926",
"timezone": "UTC",
"title": "Soar Sample Instant Meeting",
"tollType": "toll",
"unlockedMeetingJoinSecurity": "allowJoin",
"webLink": "https://example.com/php?MTID=m4a809400de110cbedaa89ff5e55b3d73"
},
"inputs": {
"webex_meeting_name": "Incident Meeting",
"webex_meeting_password": "abcd1234",
"webex_meeting_agenda": "Sample meeting",
"webex_meeting_start_time" : "05/16/2022 11:08:09 +01:00",
"webex_meeting_end_time" : "05/16/2022 12:08:09 +01:00"
},
"metrics": {
"execution_time_ms": 5448,
"host": "AppHost",
"package": "fn-webex",
"package_version": "2.0.0",
"timestamp": "2022-08-11 13:31:40",
"version": "1.0"
},
"raw": null,
"reason": null,
"success": true,
"version": 2.0
}
Example Pre-Process Script:
inputs.webex_meeting_name = incident.name if rule.properties.webex_meeting_name is None else rule.properties.webex_meeting_name
if rule.properties.webex_meeting_agenda is None:
if incident.description is not None and incident.description.content is not None:
inputs.webex_meeting_agenda = incident.description.content
else:
inputs.webex_meeting_agenda = ""
else:
inputs.webex_meeting_agenda = rule.properties.webex_meeting_agenda
inputs.webex_meeting_password = inputs.webex_meeting_password if rule.properties.webex_meeting_password is None else rule.properties.webex_meeting_password
Example Post-Process Script:
content = results.get("content")
if not results.success:
text = u"Unable to create Cisco WebEx Meeting"
fail_reason = content.get("fail_reason")
if fail_reason:
text = u"{0}:\n\tFailure reason: {1}".format(text, fail_reason)
else:
ref_html_room = u"""<a href='{0}'>Link</a>""".format(content.get("webLink"))
text = u"<b>Cisco WebEx Meeting:</b><br />Webex Room URL: {0}".format(ref_html_room)
text += u"<br />Meeting Name: {}".format(content.get("title"))
text += u"<br />Password: {}".format(content.get("password"))
text += u"<br />Agenda: {}".format(content.get("agenda"))
text += u"<br />Start Time: {}".format(content.get("start"))
text += u"<br />End Time: {}".format(content.get("end"))
text += u"<br />Timezone: {}".format(content.get("timezone"))
text += u"<br />Meeting Id: {}".format(content.get("id"))
note = helper.createRichText(text)
incident.addNote(note)
Function - Webex: Create Room¶
A function to create a Webex Room from an incident or a task. If no participants are added, Webex will create a blank Room. If a team has already been created and needs to be assigned to this room, it can be added by specifying the team ID in the team ID field. It also has the ability to include all incident or task members and add additonal members to the team or room using the additional attendees field.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Name of the Room |
|
|
No |
|
If a Webex team is already available, the entire team can be directly added by specifying its ID |
|
|
Yes |
|
Select this option to include all incident members to this Webex room |
|
|
No |
|
The list of email address of the attendees in a comma-separated format |
Outputs:
NOTE: This example might be in JSON format, but
results
is a Python Dictionary on the SOAR platform.
results = {
"content": {
"attendees": "",
"callInTollFreeNumber": "",
"callInTollNumber": "+1-650-479-3208",
"meetingId": "725c8064c775432fb85ea16d7b7c85c7",
"meetingLink": "https://5xth.webex.com/m/a9a09646-9c84-4c9b-92f3-142faa4598ba",
"meetingNumber": "25923177804",
"roomId": "Y2lzY29zcGFyazovL3VybjpURUFNOnVzLXdlc3QtMl9yL1JPT00vZmU4ZjFmNTAtMWEwMy0xMWVkLWJiZDktMzcwMDcyNTIyMGJl",
"roomName": "Incident Room",
"sipAddress": "25923177804@5xth.webex.com",
"status": true
},
"inputs": {
"webex_add_all_members": true,
"webex_incident_id": "2096",
"webex_meeting_attendees": "sara@example.com, mathew@example.com",
"webex_room_name": "Incident Room",
"webex_team_id": "Ydca551c7dXXXX930aeXXXX509cda551c7ddXXXX930ae68d54b971XXXXXXXXX"
},
"metrics": {
"execution_time_ms": 9591,
"host": "AppHost",
"package": "fn-webex",
"package_version": "2.0.0",
"timestamp": "2022-08-12 07:00:17",
"version": "1.0"
},
"raw": null,
"reason": null,
"success": true,
"version": 2.0
}
Example Pre-Process Script:
inputs.webex_incident_id = str(incident.id)
inputs.webex_room_name = "Incident {}: {}".format(str(incident.id), incident.name) if rule.properties.webex_room_name is None else rule.properties.webex_room_name
if rule.properties.webex_team_id is not None:
inputs.webex_team_id = rule.properties.webex_team_id
if rule.properties.webex_meeting_attendees.content is not None:
inputs.webex_meeting_attendees = rule.properties.webex_meeting_attendees.content
if rule.properties.webex_add_all_members is not None:
inputs.webex_add_all_members = rule.properties.webex_add_all_members
Example Post-Process Script:
content = results.get("content")
if not results.success:
text = u"Unable to create Cisco WebEx Room"
fail_reason = content.get("fail_reason")
if fail_reason:
text = u"{0}:\n\tFailure reason: {1}".format(text, fail_reason)
else:
ref_html_room = u"""<a href='{0}'>Link</a>""".format(content.get("meetingLink"))
text = u"<b>Cisco Webex Room Details:</b><br />"
text += u"<br />Room Name: {}".format(content.get("roomName"))
text += u"<br />Room URL: {}".format(ref_html_room)
text += u"<br />Room ID: {}".format(content.get("roomId"))
text += u"<br />Meeting ID: {}".format(content.get("meetingId"))
text += u"<br />Created Time: {}".format(content.get("created"))
text += u"<br />Call in TollNumber: {}".format(content.get("callInTollNumber"))
note = helper.createRichText(text)
incident.addNote(note)
Function - Webex: Create Team¶
A function to create a Webex Team from an incident or a task. The Team that is created using this function is automatically assigned with a room. It also has the ability to include all incident or task members and add additonal members to the team or room using the additional attendees field.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
Name of the team being created. If blank, uses the incident name and task ID as the team name |
|
|
Yes |
|
Adds all incident members or task members to the webex meeting. If only selected members are to be added, specify their email address in the below field |
|
|
No |
|
The list of email address of the attendees in a comma-seperated format. Leave blank to select all attendees |
|
|
No |
|
Incident Number |
|
|
No |
|
Task ID |
Outputs:
NOTE: This example might be in JSON format, but
results
is a Python Dictionary on the SOAR platform.
results = {
"content": {
"attendees": "sara@example.com, mathew@example.com, soaruser@example.com",
"created": "2022-08-12T05:59:57.637Z",
"creatorId": "Y2lzY29zcGFyazovL3VzL1BFT1BMRS85ODM0YjBlYi1mZmY1LTRjY2YtYTcwOC04Nzk1YmFjYjQ3NzU",
"id": "Y2lzY29zcGFyazovL3VybjpURUFNOnVzLXdlc3QtMl9yL1RFQU0vZmU4ZjFmNTAtMWEwMy0xMWVkLWJiZDktMzcwMDcyNTIyMGJl",
"name": "SOAR Team",
"status": true
},
"inputs": {
"webex_team_name": "SOAR Team",
"webex_incident_id": "2096",
"webex_add_all_members": true,
"webex_meeting_attendees" : "sara@example.com, mathew@example.com"
},
"metrics": {
"execution_time_ms": 13623,
"host": "AppHost",
"package": "fn-webex",
"package_version": "2.0.0",
"timestamp": "2022-08-12 07:00:05",
"version": "1.0"
},
"raw": null,
"reason": null,
"success": true,
"version": 2.0
}
Example Pre-Process Script:
# To set meeting name to the workflow inputs, uncomment the following lines
inputs.webex_incident_id = str(incident.id)
inputs.webex_team_name = "Incident {}: {}".format(str(incident.id), incident.name) if rule.properties.webex_team_name is None else rule.properties.webex_team_name
if rule.properties.webex_meeting_attendees.content is not None:
inputs.webex_meeting_attendees = rule.properties.webex_meeting_attendees.content
if rule.properties.webex_add_all_members is not None:
inputs.webex_add_all_members = rule.properties.webex_add_all_members
Example Post-Process Script:
content = results.get("content")
if not results.success:
text = u"Unable to create Cisco WebEx Meeting"
fail_reason = content.get("fail_reason")
if fail_reason:
text = u"{0}:\n\tFailure reason: {1}".format(text, fail_reason)
else:
text = u"<b>Cisco Webex Team Details:</b><br />"
text += u"<br />Team Name: {}".format(content.get("name"))
text += u"<br />Created Time: {}".format(content.get("created"))
text += u"<br />Team ID: {}".format(content.get("id"))
text += u"<br />Team Members: {}".format(content.get("attendees"))
note = helper.createRichText(text)
incident.addNote(note)
Function - Webex: Delete Room¶
Function to delete a Webex Room from an incident or task. For this function to work, either the Room ID or Room Name must be provided. In order to avoid any accidental deletion, it is strongly recommended to use the Room ID to delete a Room.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Unique ID used to identify a room, generated while creating a room |
|
|
No |
|
Name of the room to be deleted. It is strongly recommended to use Room ID for deletion |
Outputs:
NOTE: This example might be in JSON format, but
results
is a Python Dictionary on the SOAR platform.
results = {
"content": {
"message": "Successfully deleted room : Incident 2096 Task 102: Webex Initial Test",
"status_code": 204
},
"inputs": {
"webex_room_name": "Incident 2096 Task 102: Webex Initial Test"
},
"metrics": {
"execution_time_ms": 3383,
"host": "AppHost",
"package": "fn-webex",
"package_version": "2.0.0",
"timestamp": "2022-09-19 11:29:54",
"version": "1.0"
},
"raw": null,
"reason": null,
"success": true,
"version": 2.0
}
Example Pre-Process Script:
if rule.properties.webex_room_id:
inputs.webex_room_id = rule.properties.webex_room_id
if rule.properties.webex_room_name:
inputs.webex_room_name = rule.properties.webex_room_name
Example Post-Process Script:
content = results.get("content")
if not results.success:
text = u"Unable to delete the room"
fail_reason = results.reason
if fail_reason:
text = u"{0}:\n\tFailure reason: {1}".format(text, fail_reason)
else:
text = u"<b>Cisco Webex:</b><br />"
text += content.get("message")
note = helper.createRichText(text)
incident.addNote(note)
Function - Webex: Delete Team¶
Function to delete a Webex team from an incident or task. For this function to work, either the Team ID or Team Name must be provided. In order to avoid any accidental deletion, it is strongly recommended to use the Team ID to delete a Team.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Unique ID used to identify a team, generated while creating a team |
|
|
Yes |
|
Name of the team to be deleted. It is strongly recommended to use Team ID for deletion |
Outputs:
NOTE: This example might be in JSON format, but
results
is a Python Dictionary on the SOAR platform.
results = {
"content": {
"message": "Successfully deleted team : Incident 2096 task 102: Webex Initial Test",
"status_code": 204
},
"inputs": {
"webex_team_name": "Incident 2096 task 102: Webex Initial Test"
},
"metrics": {
"execution_time_ms": 4362,
"host": "AppHost",
"package": "fn-webex",
"package_version": "2.0.0",
"timestamp": "2022-09-19 11:31:16",
"version": "1.0"
},
"raw": null,
"reason": null,
"success": true,
"version": 2.0
}
Example Pre-Process Script:
if rule.properties.webex_team_id:
inputs.webex_team_id = rule.properties.webex_team_id
if rule.properties.webex_team_name:
inputs.webex_team_name = rule.properties.webex_team_name
Example Post-Process Script:
content = results.get("content")
if not results.success:
text = u"Unable to delete the team"
fail_reason = results.reason
if fail_reason:
text = u"{0}:\n\tFailure reason: {1}".format(text, fail_reason)
else:
text = u"<b>Cisco Webex:</b><br />"
text += content.get("message")
note = helper.createRichText(text)
incident.addNote(note)
Troubleshooting & Support¶
Refer to the documentation listed in the Requirements section for troubleshooting information.
For Support¶
This is a IBM Community provided App. Please search the Community ibm.biz/soarcommunity for assistance.