Skip to content

Commit

Permalink
docs: Add handcrafted documentation (#141)
Browse files Browse the repository at this point in the history
* docs: Add handcrafted documentation

To augment the autogenerated API docs

Signed-off-by: Timothy MacDonald <tim.macdonald@lacework.net>

* docs: minor doc updates

Signed-off-by: Timothy MacDonald <tim.macdonald@lacework.net>

* docs: minor docs changes

Signed-off-by: Timothy MacDonald <tim.macdonald@lacework.net>

---------

Signed-off-by: Timothy MacDonald <tim.macdonald@lacework.net>
  • Loading branch information
tmac1973 authored Jan 8, 2024
1 parent cc50f0f commit dea0162
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ this library aims to expose all publicly available APIs. For example, the follow
fetch events, fetch host vulnerabilities, and fetch container vulnerabilities. The latest version of the SDK supports
expressive searches as enabled by v2 of the Lacework APIs.

For more information read the [documentation](https://lacework.github.io/python-sdk/)
```python
from laceworksdk import LaceworkClient

Expand Down
1 change: 1 addition & 0 deletions docs-source/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
!.gitignore
!conf.py
!index.rst
!static/

7 changes: 6 additions & 1 deletion docs-source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ Welcome to Lacework Python SDK's documentation!
.. toctree::
:maxdepth: 5


static/overview.rst
static/installation.rst
static/authentication.rst
static/usage.rst
static/timestamps.rst
static/troubleshooting.rst
autoapi/index


Expand Down
94 changes: 94 additions & 0 deletions docs-source/static/authentication.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
==================================
Lacework Python SDK Authentication
==================================

Once you have installed the SDK you will need to determine how you
want to pass authentication information to the SDK. There are a
variety of ways to do this, however they all require a valid API key
for the Lacework account you wish to access with the SDK. Note that
API keys are generated at the account level only, not a the organization level.
You must have/generate a key for each account you need access to.

Learn more about generating Lacework API keys
`here <https://docs.lacework.net/api/api-access-keys-and-tokens>`_.

Learn more about Lacework organizations `here <https://docs.lacework.net/console/organization-overview>`_.

Once you have created an API key in the Lacework console you should download
the JSON file containing your new API credentials. This will contain 3 or 4 properties
depending on whether the keys you generated are part of a Lacework organization. These
properties are will be ``keyId``, ``secret``, ``account``, and optionally ``subaccount``.
If your key comes from a Lacework organization then the ``account`` property represents the
name of the organization and the ``subaccount`` property represents that name of the account
within that organization.

Be sure keep these credentials **SECURE**!

Now that you have this file you can choose which method of authentication to use:

Auth Method 1: Install the Lacework CLI
=======================================

The Lacework Python SDK does **NOT** require that you install the Lacework CLI tool. However, if you do
have the Lacework CLI `installed <https://docs.lacework.net/cli#install-the-lacework-cli>`_ AND
`configured <https://docs.lacework.net/cli#configure-the-cli>`_ then as part of it's configuration
process the CLI will create a file in your home directory called ``.lacework.toml`` which will contain
one or more sections containing Lacework credentials, with each section representing information for a
single Lacework account.

If you have this file in place and you have not specified credentials using any other method then
the Python SDK will use the credentials stored there to access the Lacework API endpoints. Note that by
default the SDK will use the creds in the ``default`` section of the ``.lacework.toml`` file.
You can tell the SDK to use a different section using the ``profile=`` keyword argument when
instantiating the class.

.. code-block:: python
:caption: Using the default profile
from laceworksdk import LaceworkClient
lw = LaceworkClient()
.. code-block:: python
:caption: Specifying a profile
from laceworksdk import LaceworkClient
lw = LaceworkClient(profile="testprofile")
Auth Method 2: Specify the Credentials as Environment Variables
===============================================================

You can specify your account credentials or the profile to use in environmental variables.

======================= ====================================================================== ==========
Environment Variable Description Required
--------------------- ---------------------------------------------------------------------- ----------
``LW_PROFILE`` Lacework CLI profile to use (configured at ~/.lacework.toml) N
``LW_ACCOUNT`` Lacework account/organization domain (i.e. `<account>`.lacework.net) Y
``LW_SUBACCOUNT`` Lacework sub-account N
``LW_API_KEY`` Lacework API Access Key Y
``LW_API_SECRET`` Lacework API Access Secret Y
======================= ====================================================================== ==========

Note: Specifying creds this way will override your ``.lacework.toml`` default profile.

Auth Method 3: Specify the Credentials Manually
===============================================

The most straight forward way of specifying credentials is to pass them to the class instance at
instantiation.

.. code-block:: python
:caption: Specifying the credentials at class instantiation
from laceworksdk import LaceworkClient
lw = LaceworkClient(account="ACCOUNT",
subaccount="SUBACCOUNT",
api_key="API KEY",
api_secret="API SECRET")
Note: This will override your ``.lacework.toml`` default profile AND any credentials you may have
specified as environmental variables.
18 changes: 18 additions & 0 deletions docs-source/static/installation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
================================
Lacework Python SDK Installation
================================

The Lacework Python SDK is published on `PyPi <http://pypi.org/project/laceworksdk/>`_ as ``laceworksdk``

Installation and updates are managed using ``pip3``

.. code-block::
:caption: Installation
pip3 install laceworksdk
.. code-block::
:caption: Update
pip3 install laceworksdk --upgrade
12 changes: 12 additions & 0 deletions docs-source/static/overview.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
=======================
The Lacework Python SDK
=======================
`A Python module for interacting with the` `Lacework Cloud Security Platform <https://www.lacework.com/>`_

The Lacework Python SDK is an interface to the `Lacework
API <https://docs.lacework.net/api/v2/docs/>`_ with a few
additional quality of life features added in. It supports
all currently maintained versions of Python 3.

The Lacework Python SDK is an open source project and the source
code is available on Github in the `Lacework Python SDK repo <https://github.com/lacework/python-sdk/>`_.
40 changes: 40 additions & 0 deletions docs-source/static/timestamps.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
========================================
Lacework Python SDK Timestamp Generation
========================================

For all "search" methods Lacework requires ``start_time`` and ``end_time`` arguments which
are used to specify the search window. Additionally, some "get" methods also require them.
These must be specified as strings in the following format:

``"%Y-%m-%dT%H:%M:%S%z"``

Example:

``"2024-01-08T22:34:10+0000"``

You are free to generate these strings however you like, but you may find it useful to
use the following function (or something similar).

.. code-block::
:caption: Timestamp Generation Function
from datetime import datetime, timedelta, timezone
def generate_time_string(delta_days=0, delta_hours=0, delta_minutes=0, delta_seconds=0) -> str:
return (datetime.now(timezone.utc) - timedelta(days=delta_days, hours=delta_hours, minutes=delta_minutes, seconds=delta_seconds)).strftime("%Y-%m-%dT%H:%M:%SZ")
This will allow you to generate time stamps relative to "now" easily. For Example:

.. code-block::
:caption: Generating Timestamp
right_now = generate_time_string()
twelve_hours_ago = generate_time_string(delta_hours=12)
one_day_ago = generate_time_string(delta_days=1)
thirty_six_and_a_half_hours_ago = generate_time_string(delta_days=1,
delta_hours=12,
delta_minutes=30)
15 changes: 15 additions & 0 deletions docs-source/static/troubleshooting.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
===================================
Lacework Python SDK Troubleshooting
===================================

This SDK uses standard python logging facilities. To turn on all of the debug information
use the following:

.. code-block::
:caption: Turn on Debugging
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
123 changes: 123 additions & 0 deletions docs-source/static/usage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
=========================
Lacework Python SDK Usage
=========================

The Lacework Python SDK closely mirrors the `Lacework API <https://docs.lacework.net/api/v2/docs/>`_
in structure. The main class of the SDK is ``LaceworkClient`` which has attributes representing
the various resources/endpoints of the Lacework API. Depending on the resource, these attributes
will have some combination of CRUD and search methods, though a few have other unique methods.
You can read about the various attributes and methods of the SDK `here <https://lacework.github.io/python-sdk/autoapi/laceworksdk/index.html>`_.

Usage Examples
==============

Example 1: Create a New User
----------------------------

This example leverages the ``team_users`` `attribute <https://lacework.github.io/python-sdk/autoapi/laceworksdk/api/v2/team_users/index.html>`_
to create a new Lacework user.


.. code-block:: python
:caption: Creating a New User
from laceworksdk import LaceworkClient
lw = LaceworkClient(profile="default")
response = lw.team_users.create("testuser", "testuser@testdomain.com", "Test Company")
Example 2: Searching for an Alert
---------------------------------

This example leverages the ``alerts`` `attribute <https://lacework.github.io/python-sdk/autoapi/laceworksdk/api/v2/alerts/index.html>`_
to find all ``Critical`` alerts that occured in the last 24 hours.

.. code-block:: python
:caption: Searching for an Alert
from laceworksdk import LaceworkClient
from datetime import datetime, timedelta, timezone
lw = LaceworkClient(profile="default")
# Lacework will require us to specify a search window in a specific format
# The following will allow us to specify a window that starts 1 day ago
# and ends "now"
current_time = datetime.now(timezone.utc)
start_time = current_time - timedelta(days=1)
start_time = start_time.strftime("%Y-%m-%dT%H:%M:%S%z")
end_time = current_time.strftime("%Y-%m-%dT%H:%M:%S%z")
# We need to specify our start time, end time, and search criteria in this structure
# In this case we are specifying that the alert "severity" property should be equal
# to "Critical"
filters = {
"timeFilter": {
"startTime": start_time,
"endTime": end_time
},
"filters":
[
{
"field": "severity",
"expression": "eq",
"value": "critical"
}
]
}
# Make the API call, note that all search methods in this SDK will return
# Generators, not lists or dicts
alerts = lw.alerts.search(json=filters)
Note: This search will return a generator object, not a list or dict. If you are
unfamiliar with Python generators you may want to read up on them.
https://wiki.python.org/moin/Generators
Example 3: Retrieving a Compliance Report
-----------------------------------------
This example leverages the ``cloud_accounts`` `attribute <https://lacework.github.io/python-sdk/autoapi/laceworksdk/api/v2/cloud_accounts/index.html>`_
first to retrieve a list of AWS account integrations, specifically those that retrieve "config"
information. It uses a python list comprehension to select the first one it finds and parses the
AWS account ID from that data.
Once it has a valid AWS account integration it uses this to pull a CIS 1.4 report using the
``reports`` `attribute <https://lacework.github.io/python-sdk/autoapi/laceworksdk/api/v2/reports/index.html>`_.
.. code-block:: python
:caption: Retrieving a Report
from laceworksdk import LaceworkClient
# Get a list of accounts
accounts = lw.cloud_accounts.get()['data']
# List comprehension to filter out disabled or misconfigured integrations
# as well as only select for "config" type integrations
config_accounts = [account for account in accounts if ("Cfg" in account['type'] and account['enabled'] == 1 and account['state']['ok'] is True)]
# Loop through what's left and find the first AWS integration
for config_account in config_accounts:
if config_account['type'] == 'AwsCfg':
# Parse the AWS account ID from the account details
arn_elements = config_account['data']['crossAccountCredentials']['roleArn'].split(':')
primary_query_id = arn_elements[4]
break
# Leverage the retrieved account ID to pull a CIS 1.4 report for that account
# in html format
response = lw.reports.get(primary_query_id=primary_query_id,
format="html",
type="COMPLIANCE",
report_type="AWS_CIS_14")
More Examples
-------------
You can find more examples in the "examples" folder of the github repository
`here <https://github.com/lacework/python-sdk/tree/main/examples>`_.

0 comments on commit dea0162

Please sign in to comment.