Keep it Secret, Keep it Safe, with Webex Teams APIs

Use this Script to Help Keep Your Bot (and Sensitive Information) Away from Prying Eyes

There are times – like when you are first developing it, or when it is handling sensitive information – when you want your bot to be only available AND only respond to folks within your company. Unfortunately, Webex Teams does not yet have the ability to restrict anyone from adding your bot to a space so we need to make sure you don’t respond to everyone.

You can take steps to make sure your bot does not respond to messages within a space where there are folks from other organizations. At runtime I typically use the spark helper membership check function before responding to a message from a room. The code can be found in the CiscoSE GitHub repository. It’s kind of like telling your kids to NOT open the door every time someone rings the door bell!

Unfortunately, this is reactive, so why don’t we be a bit more proactive and leverage the same great Webex Team’s API’s with solution that can be automated?

Solution

The basic idea behind the algorithm is as follows:

Use the bot’s access token to get a list of rooms it is in.

For each of those rooms, get a list of people and bots in the room. We check to make sure that everyone in the room is in your organization. If not, remove the bot from the room.

Pretty simple, so let’s take a look at the code.

First, let’s define a function called check_and_delete_membership and let’s pass it the bot’s access token and the Webex Team’s organization ID. With this helpful information, let’s exercise the Webex Team’s Membership API a bit to get the party started.

[cc lang=”python” width=”700″]
membership_url = “https://api.ciscospark.com/v1/memberships”
membership_message_response = requests.get(membership_url, verify=True, headers={‘Authorization’: ‘Bearer {}’.format(bot_token)})

response_json = json.loads(membership_message_response.text)
print(response_json, membership_message_response.status_code)

if membership_message_response.status_code != 200:
return
memberships = response_json[‘items’]
[/cc]

Easy peasy, lemon squeezy. The GET request returns back a list of room memberships for the bot. The next thing we do is iterate through all the rooms using the memberships API again.

[cc lang=”python” width=”700″]
bad_memberships = []

for membership_item in memberships:
roomId = membership_item[‘roomId’]
membership_id = membership_item[‘id’]
allowed_membership = membership_check(roomId, bot_token, allowed_person_Org_Id)

if allowed_membership == False:
bad_memberships.append(membership_id)
print(” Found Membership to delete:\n …roomId: {}\n…membershipId: {}\n”.format(roomId, membership_id))
[/cc]

We leverage a function membership_check, which checks the organization id of each person in the room against the org id that you supplied. If the organization id’s do not match, the function returns False. In the event that we do get a bad membership, we add the room to our “bad_memberships” list.

One we have the complete list of “bad_memberships” we can remove the bots from the rooms. This is relatively easy as well and…SURPRISE!!!…it uses another facet of the Memberships API!
[cc lang=”python” width=”700″]
for bad_membership_id in bad_memberships:
print(” …deleting membership: {}”.format(bad_membership_id))
delete_url = “https://api.ciscospark.com/v1/memberships/{}”.format(bad_membership_id)
delete_message_response = requests.delete(delete_url, verify=True, headers={‘Authorization’: ‘Bearer {}’.format(bot_token)})

if delete_message_response.status_code != 204:
print(“!!!***…unable to delete membership. Rerun audit to delete”)
else:
print(” …delete membership status code: {}”.format(delete_message_response.status_code))
[/cc]
In this snippet we simply iterate the bad membership id’s. To remove the bot from each room, we simply send a DELETE HTTP request with the Webex Teams’ membership id appended to the URL. That’s it!

All in all fairly simple. I periodically run this function, passing it my organization id and bot tokens just to be on the safe side. Conceivably in order to really stay on top of things, you could run a script using the function via regular cron job.

Caution!

This is by no means the only set of precautions you should take in safe guarding your organization’s sensitive information. Keep in mind that even if you run the bot periodically, someone could add your bot to a space and request info before you get a chance to remove it from the space. Therefore, if you do want to prevent other organizations from using the bot, you should also do a organization membership check for every message the bot receives. In addition you should check with your security organization to make sure you comply with their data handling policies.

Wrap Up and To Do

Hopefully you see how useful this function can be in at least helping to solve the problem of keeping sensitive information safe. The code can be found on the Cisco SE GitHub site. There is plenty of room for improvement: better error handling, returning a list of orgs that added the bot, etc. So feel free to branch, improve upon it, and share with the community!

And please visit DevNet to learn more about what you can do with Webex Teams APIs.

Get your free DevNet account for access to developer resources, learning labs, and sandbox.