The new cbapi: Unifying the Python Carbon Black APIs
Posted on May 16, 2016
The EDR product was developed as an “API-first” application. Every action in the product can be performed programmatically through the API. In fact, the entire Carbon Black EDR web user interface is implemented on top of the API — the web user interface is a JavaScript application that calls API calls straight from your web browser (check out the Chrome Developer Tools screencast if you’re interested in more details).
To expose the power of this API in Python applications, the first version of the cbapi module was published on August 21, 2013 on GitHub. Since then, the product has significantly evolved, Carbon Black and Bit9 merged forces to become one company, and major new features were introduced, such as the Event Bus and Live Response. While cbapi grew organically to support these new features over time, there was no unity between the Python modules required to access the growing product portfolio. Additionally, as customers and partners built more complex tooling around the APIs, it was clear there was a need to make the APIs not just accessible, but easy to use as well.
The new API
Therefore, we embarked on a mission to rethink the cbapi from the ground up. The new cbapi takes a “data-first” approach to API design, meaning that accessing the data that resides in either the Carbon Black App Control or EDR product should be as easy as manipulating Python variables. We drew inspiration from other well-designed APIs as well as libraries such as Ruby on Rails' ActiveRecord. These tools and libraries have proven successful in the marketplace because they allow developers to focus on the task at hand: solving their “itch”, rather than burdening them with complexities of the underlying data model.
If you’re anything like me, an example is worth about a thousand blog posts. So here are two examples, one for each product. First, a simple example to show how to enumerate network connections established by a given set of processes monitored by EDR:
from cbapi.response import CbEnterpriseResponseAPI, Process, Sensor
c = CbEnterpriseResponseAPI(profile="dev")
# what are the netconns for every chrome process?
for proc in c.select(Process).where('process_name:chrome.exe netconn_count:[1 TO \*]'):
print("{0:s} ran Chrome on {1:s} and had the following netconns:".format(proc.username, proc.hostname))
for nc in proc.netconns:
print(" {3:s}: {0:s} -> {1:s} ({2:s})".format(nc.local_ip, nc.remote_ip, nc.domain, str(nc.timestamp)))
And here’s how you can move a computer to a new policy in Carbon Black App Control:
from cbapi.protection import CbEnterpriseProtectionAPI, Computer, Policy
p=CbEnterpriseProtectionAPI(profile="production")
# move the first computer to “test policy”
computer = p.select(Computer).where('name:CORP\\JOHN-DESKTOP').first()
computer.policy = p.select(Policy).where('name:restricted policy').one()
computer.save()
As you can see, you can search and manipulate data in both products using the same set of core functions. In addition, since everything is represented in terms of Python objects, “joining” data sets becomes trivial. For example, if you want to quarantine every endpoint that performed a specific action - let’s just say for now that you want to automatically isolate any host that has spawned a command shell from java.exe in the past day:
for proc in c.select(Process).where('process_name:cmd.exe parent_name:java.exe start:-24h'):
proc.sensor.network_isolation_enabled = True
proc.sensor.save()
The simple statement proc.sensor
automatically selects and retrieves the sensor data associated with each given
process. Behind the scenes, layers of caching and lazy evaluation ensure that the Python code does not unnecessarily
hammer the REST API requesting the same information or requesting an update to an object with no changes.
All of this code is now available in the new cbapi module. Version 0.9.1 of cbapi is now released and available for
pip install
via PyPI. Read the docs and pip install cbapi
to get started! We are
continuing to add functionality and the module will become feature frozen at 1.0.0. Rest assured that the underlying
HTTP-based REST API is unchanged
for both products and existing scripts written for earlier versions of the cbapi Python module will continue to run
without changes while we transition to this new API.
This is just the beginning. We are presenting on this new API at the 2016 Regional User Exchange Tour and posting new blog entries to show off more useful features over the coming months. For now, happy hunting!