🌙
 

Subscribe to the Taegis™ XDR Documentation RSS Feed at .

Learn more about RSS readers or RSS browser extensions.

Getting Started with the XDR Python SDK

Note

Use the following region or environment identifiers, depending on your tenant region:

  • US1 or charlie or production for https://ctpx.secureworks.com/
  • US2 or delta for https://delta.taegis.secureworks.com/
  • US3 or foxtrot for https://foxtrot.taegis.secureworks.com/
  • EU or echo for https://echo.taegis.secureworks.com/

Install the Python SDK

Assuming you have Python 3.8+ already installed, install the Python SDK:

python -m pip install taegis-sdk-python

Authenticate

The install will ask to authenticate with your Secureworks® Taegis™ XDR account. This requires a password and MFA token, unless your organization has registered your organization with SSO authentication. If SSO is enabled, you will be presented with a device code authentication link.

For more information, see Authentication With the Taegis™ XDR Python SDK.

Example Usage

from taegis_sdk_python import GraphQLService

from pprint import pprint as pp

service = GraphQLService()

results = service.users.query.current_tdruser()

pp(results)

Exploring the SDK

Standard Python help is built into XDR’s Python SDK. You can use it on any object in the GraphQLService object structure to find out what is available and how to call it.

from taegis_sdk_python import GraphQLService
from taegis_sdk_python.services.alerts.types import SearchRequestInput

service = GraphQLService()

# Find available services (Service Endpoints)
help(service)
# Find available service queries (or mutations or subscriptions)
help(service.alerts.query)
help(service.alerts.mutation)
help(service.alerts.subscription)
# Reference documentation on specific endpoint
help(service.alerts.query.alerts_service_search)
# Help on an Input variable
help(SearchRequestInput)
# service
class GraphQLService(builtins.object)
 |  GraphQLService(*, environment: Optional[str] = None, tenant_id: Optional[str] = None, environments: Optional[Dict[str, str]] = None, gateway: Optional[str] = None)
...
 |  agent
 |      Events Service Endpoint.
 |
 |  alerts
 |      Alerts2 Service Endpoint.
 |
 |  assets
 |      Assets
...
# Alerts Query
class TaegisSDKAlertsQuery(builtins.object)
 |  TaegisS
...
 |  alerts_service_aggregate_alerts_by_severity(self, in_: 'Optional[AggregateAlertsBySeverityInputInput]' = None) -> 'AlertsAggregateResponse'
 |      Pull alert severity aggregates based on `group_by` parameters: domain, watchlist, hostname, detector, user..
 |
 |  alerts_service_alerts_dashboard_triage(self, in_: 'Optional[TriageDashboardInputInput]' = None) -> 'TriageDashboardOutput'
 |      None.
 |
 |  alerts_service_poll(self, in_: 'Optional[PollRequestInput]' = None) -> 'AlertsResponse'
 |      Poll for results for a specific `search
...
# SearchRequestInput
class SearchRequestInput(builtins.object)
 |  SearchRequestInput(cql_query: Optional[str] = None, offset: Optional[int] = None, limit: Optional[int] = None) -> None
...

Context Manager

The service object is also a context manager to help temporarily override default values when you make an API call. This can include fields like the environment, tenant_id, output, or access_token.

from taegis_sdk_python import GraphQLService
from taegis_sdk_python.services.alerts.types import SearchRequestInput

service = GraphQLService()

with service(
    environment="delta",
    tenant_id="00000",
    output="""
        reason
        alerts {
            total_results
            list {
                id
                tenant_id
                metadata {
                    title
                    severity
                }
                status
            }
        }
    """,
):
    result = service.alerts.query.alerts_service_search(SearchRequestInput(
        offset=0,
        limit=10,
        cql_query="""
        FROM alert
        WHERE
            severity >= 0.6
        EARLIEST=-1d
        """
    ))

Pruning the GraphQL Output

The XDR Python SDK provides all available fields returned by the GraphQL API by default. This aids in exploration, but you can define which fields you want returned.

To help determine what you need, you can use the build_output_string utility, which returns a string representation of the output object with all possible fields for the return type. You can use that as a reference to build your own, and remove fields that you don’t need.

from taegis_sdk_python import build_output_string
from taegis_sdk_python.services.alerts.types import AlertsResponse

print(build_output_string(AlertsResponse))
reason search_id status alerts { previous_offset total_parts list { reference_details { reference {
description url type } } parent_tenant_id entities { entities relationships { relationship to_entity
from_entity type } } sensor_types suppression_rules { id version } resolution_history { timestamp {
nanos seconds } user_id status num_alerts_affected id reason } enrichment_details {
business_email_compromise { user_name source_address_geo_summary { country { confidence iso_code
geoname_id code } city { confidence locale_names { record { value key } } geoname_id name } location {
timezone latitude longitude us_metro_code radius metro_code gmt_offset } asn { autonomous_system_no
autonomous_system_org } continent { code geoname_id } } source_address }
...

The service object is called as a context manager; output is assigned with the new GraphQL output fields. The same object is returned, any undefined fields are assigned a value of None.

from taegis_sdk_python import GraphQLService
from taegis_sdk_python.services.alerts.types import SearchRequestInput

from pprint import pprint as pp

service = GraphQLService()
with service(output="search_id alerts { list { id status metadata { title severity confidence } } }")
    results = service.alerts.query.alerts_service_search(
        SearchRequestInput(
            offset=0,
            limit=10,
            cql_query="""
            FROM alert
            WHERE
                severity >= 0.6
            EARLIEST=-1d
            """,
        )
    )
pp(results)

Arbitrary Queries

You can craft your own API call for a query, mutation, or subscription. Note that certain services may be configured differently; it is recommended to use the service endpoint you want to query against when available.

from taegis_sdk_python import GraphQLService

from pprint import pprint as pp

service = GraphQLService()

results = service.alerts.execute_query(
    endpoint="alertsServiceSearch",
    variables={
        "in": {
            "limit": 3,
            "offset": 0,
            "cql_query": """
            FROM alert
            WHERE
                severity >= 0.6
            EARLIEST=-1d
            """
        }
    },
    output="""
        search_id
        alerts {
            list {
                id
                tenant_id
                metadata {
                    title
                    severity
                }
                status
            }
        }
    """
)
pp(results)

Raw Queries

You can also run your own raw GraphQL strings. This provides the most flexibility but least amount of guard rails.

from taegis_sdk_python import GraphQLService

from pprint import pprint as pp

service = GraphQLService()

results = service.investigations.execute("""
    query investigationsStatusCount
    {
        investigationsStatusCount
        {
            open closed active awaiting_action suspended total
        }
    }
""")
pp(results)

Helpers

build_output_string Utility

The build_output_string utility returns a string representation of the output object with all possible fields for the return type.

from taegis_sdk_python import build_output_string
from taegis_sdk_python.services.alerts.types import AlertsResponse

print(build_output_string(AlertsResponse))

_build_output_query Utility

The _build_output_query service endpoint helps build complete GraphQL query strings. It builds the query from the schema, so make sure you are pulling the schema from the correct service endpoint.

from taegis_sdk_python import GraphQLService, build_output_string
from taegis_sdk_python.services.investigations.types import InvestigationStatusCountResponse

service = GraphQLService()
schema = service.alerts.get_sync_schema()

print(service.alerts._build_output_query(
    operation_type="query",
    endpoint="investigationsStatusCount",
    graphql_field=schema.query_type.fields.get("investigationsStatusCount"),
    output=build_output_string(InvestigationStatusCountResponse)
))

 

On this page: