Cisco Orbital - Getting Started

Getting Started

The following sections introduce you to the Orbital API resources and provide instructions to make your first API request. Examples will be shown using the command line with cURL.

Standard REST methods are supported with the API, for example POST, GET, and DELETE. All requests must be sent securely via HTTPS. All payloads to and from the REST interface must be in JSON format.

Below is high-level description of the API resources:

Query - Represents a Query for information from an endpoint

  • Get List of Catalog Queries

  • Create or Update a Catalog Query

  • Delete a Catalog Query

Scripts - Represents a Script that can executed on an endpoint

  • Get List of Catalog Scripts

  • Create or Update a Catalog Script

  • Delete an Organization Catalog Script

  • Fetch Script Results

  • Run a Script

API Base URI

Every API request will be sent to one of the region-specific base URIs below:

North America

https://orbital.amp.cisco.com/v0

Europe

https://orbital.eu.amp.cisco.com/v0

Asia Pacific, Japan, and China

https://orbital.apjc.amp.cisco.com/v0

Authorization

To make Orbital API requests, an access token must be provided with each request (see Authentication for details on how generate an access token.)

The resulting Bearer access token can be supplied as part of the HTTP request using an Authorization header:

Authorization: Bearer <token>

Note: Orbital API access tokens are region-specific, and are only valid for use when making requests to the associated region-specific base URL, as above.

Request Headers

In additionl to the base URL and Authorization header, API requests need to specify the format of data in the payload body of requests and responses.

Each API request shoud include in Accept header:

Accept: application/json

API requests that contain a body/data (e.g. POST or PUT) will also need to provide a Content-Type header indicating the format of that data:

Content-Type: application/json

Note: The Orbital API supports only JSON data format (application/json).

To summarize, a full API request will have the following parameters:

API Request Parameters

Method HTTP method (e.g. POST)
URL (Region-specific base URL as above)
Accept application/json
Content-Type application/json (if there is a request body)
Authorization Bearer +access token
Body JSON body data

Please see the documentation for specific APIs for any additional request header/parameter details.

Get List of Catalog Queries

Request

curl -X GET -H "Authorization: Bearer <token>" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/catalogs

Response

{
  "data": [
    {
      "ID": "string",
      "config": {
        "description": "string",
        "osquery": [
          {
            "bookkeeping": true,
            "label": "get all the processes",
            "name": "fetch process",
            "sql": "select * from processes",
            "types": [
              "process",
              "query"
            ]
          }
        ],
        "platform": [
          "string"
        ],
        "version": "string"
      },
      "created": "2023-11-07T21:58:51.691Z",
      "creator": "string",
      "disabled": true,
      "organization": "string",
      "title": "string",
      "updated": "2023-11-07T21:58:51.691Z"
    }
  ],
  "errors": [
    "string"
  ]
}

Get List of Catalog Scripts

Request

curl -X GET -H "Authorization: Bearer <token>" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/catalogs/scripts

Response

  {
    "data": [
      {
        "ID": "123",
        "config": {
          "description": "script to terminate procs",
          "platform": [
            "darwin",
            "windows"
          ],
          "script": "string",
          "version": "1.23"
        },
        "created": "2023-08-23T18:10:44.732Z",
        "creator": "user123",
        "disabled": false,
        "organization": "11111111-1111-1111-1111-111111111111",
        "title": "script to terminate procs",
        "updated": "2023-08-23T18:10:44.732Z"
      }
    ],
    "errors": [
      "string"
    ]
  }

Fetch Script Results

Request

curl -X GET -H "Authorization: Bearer <token>" -H "Content-Type: application/json" "https://orbital.amp.cisco.com/v0/script/<job_id>/results"

Response

  {
    "disabled": false,
    "id": "123",
    "is_active": false,
    "name": "sample script job",
    "next": "next_cursor_id",
    "organization": "11111111-1111-1111-1111-111111111111",
    "results": [
      {
        "endpoint_organization": "22222222-2222-2222-2222-222222222222",
        "error": "string",
        "hostinfo": {
          "anyconnectudid": "28e2c49a-40fb-11ee-be56-0242ac120002",
          "errors": [
            "string"
          ],
          "external": {
            "active": true,
            "ipv4": "192.168.0.1",
            "ipv6": "::1",
            "mac": "00-B0-D0-63-C2-26",
            "name": "en0"
          },
          "fqdn": {
            "192.168.0.1": "host.example.com"
          },
          "hostname": "host",
          "interfaces": {
            "additionalProp1": {
              "active": true,
              "ipv4": "192.168.0.1",
              "ipv6": "::1",
              "mac": "00-B0-D0-63-C2-26",
              "name": "en0"
            },
            "additionalProp2": {
              "active": true,
              "ipv4": "192.168.0.1",
              "ipv6": "::1",
              "mac": "00-B0-D0-63-C2-26",
              "name": "en0"
            },
            "additionalProp3": {
              "active": true,
              "ipv4": "192.168.0.1",
              "ipv6": "::1",
              "mac": "00-B0-D0-63-C2-26",
              "name": "en0"
            }
          },
          "machine": "194ec9f2-40fb-11ee-be56-0242ac120002",
          "osinfo": {
            "arch": "amd64",
            "os": "windows",
            "osname": "Windows 10 Pro",
            "release": "22H2",
            "version": "10.0.19045.3324"
          },
          "osqueryversion": "5.8.2",
          "updated": "2023-11-07T22:55:03.307Z",
          "version": "1.31"
        },
        "node": "node_id",
        "reported": "2023-11-07T22:55:03.307Z",
        "script_output": {
          "exit_code": 0,
          "stderr": "string",
          "stdout": "run successful."
        }
      }
    ],
    "script_info": {
      "args": [
        {
          "description": "name of person",
          "name": "name",
          "value": "bob"
        }
      ],
      "content": "cHJpbnQoImhlbGxvIHdvcmxkIik=",
      "stock": "stock_id"
    },
    "submitted": "2023-11-07T22:55:03.307Z"
  }

Managing Jobs

Example of scheduling a script, and fetching results:

Schedule a script

curl -X POST -H "Authorization: Bearer $token" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/script -d '{"expiry": 1714257868, "nodes": ["os:darwin"], "script": {"content": "cHJpbnQoImhlbGxvIHdvcmxkIik="}}'

response:

{
  "ID": "3Thbk6d_5pJ8WgLU9FEkuA",
  "done_count": 0,
  "submission": 1700022482,
  "update": 1700022482,
  "expiry": 1700108882,
  "interval": 0,
  "script_info": {
    "stock": "",
    "content": "cHJpbnQoImhlbGxvIHdvcmxkIik=",
    "args": null
  }
}

Get script job status

Now we'll use the ID returned above, to check the status of the scheduled script:

curl -X GET -H "Authorization: Bearer $token" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/script/3Thbk6d_5pJ8WgLU9FEkuA

response:

{
  "id": "3Thbk6d_5pJ8WgLU9FEkuA",
  "submitted": "2023-11-15T04:28:02Z",
  "name": "Script 2023-11-15 04:28:02",
  "organization": "<org>",
  "is_active": true,
  "disabled": false,
  "done_count": 3,
  "script_info": {
    "stock": "",
    "content": "cHJpbnQoImhlbGxvIHdvcmxkIik=",
    "args": null
  }
}

The content here is base64-encoded python:

print("hello world")

Get script job results

Let's fetch some results for the script run, again using the `ID`` from above:

curl -X GET -H "Authorization: Bearer $token" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/script/3Thbk6d_5pJ8WgLU9FEkuA/results

response:

{
  "id": "3Thbk6d_5pJ8WgLU9FEkuA",
  "submitted": "2023-11-15T04:36:27Z",
  "name": "Script 2023-11-15 04:36:27",
  "organization": "<org>",
  "is_active": true,
  "disabled": false,
  "results": [
    {
      "endpoint_organization": "<org>",
      "reported": "2023-11-15T04:36:28.14677Z",
      "error": null,
      "node": "orbital-dev",
      "hostinfo": {
        "osinfo": {
          "os": "darwin",
          "osname": "",
          "release": "23.1.0",
          "version": "Darwin Kernel Version 23.1.0: Mon Oct  9 21:27:27 PDT 2023; root:xnu-10002.41.9~6/RELEASE_X86_64",
          "arch": "amd64"
        },
        "hostname": "testmachine"
      },
      "script_output": {
        "stdout": "hello world",
        "stderr": "",
        "exit_code": 0
      }
    }
  ]
}

in the script_output response field, we can see the result of the python script run, and a 0 exit code, indicating success.

Download script job results

Jobs with a large amount of results can use the download request

First, create a download request

curl -X POST -H "Authorization: Bearer $token" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/download -d '{"type": "2", "format": "CSV"}'

response:

{
  "id": "iTBZE22uxhy74as8296EzA",
  "url": "",
  "created": "2023-11-15T05:00:46.46Z"
}

Download request is created with ID: iTBZE22uxhy74as8296EzA, now let's fetch it:

curl -X GET -H "Authorization: Bearer $token" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/download/iTBZE22uxhy74as8296EzA --output results.csv

now we can check the results in the saved .csv file:

cat results.csv
results_VMDhPqFV_WtW6BcZaOgAHw_script_0.csvUT~PTescript,id,reported,error,node,host,ampuuid,ip,stdout,stderr,exitcode
VMDhPqFV_WtW6BcZaOgAHw,lLPdN6CYfbryzrtV-pdWNg,2023-11-15 04:56:28.996249 +0000 UTC,,orbital-dev,testmachine,df1d9050-1111-4f38-9367-dec28d0e7350,,hello world,,0
VMDhPqFV_WtW6BcZaOgAHw,RDZPkjzl8cz11wXVGRMXZw,2023-11-15 04:56:28.996169 +0000 UTC,,orbital-dev2,testmachine,df1d9050-4444-4f38-9367-dec28d0e7350,,hello world,,0

Working with Webhooks

Orbital can deliver job results as a webhook payload. This is generally provided in the postbacks field of the Query or Script schedule or execution API.

In order to attach a webhook to a query or script execution, first create a webhook:

curl -X POST -H "Authorization: Bearer $token" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/webhooks -d '{"config": {"url": "https://example.com", "label": "test_webhook"}}'

response:

{
  "id": "bxOl8fIPFk6OvFrBOj8UGA",
  "application": "",
  "created": "2023-11-15T05:38:44.108667Z",
  "creator": "test-creator",
  "disabled": false,
  "organization": "<org>",
  "updated": "2023-11-15T05:38:44.108667Z",
  "lastcalled": "2023-11-15T05:38:44.198421Z",
  "laststatus": "success",
  "errormessage": "",
  "config": {
    "fingerprint": "",
    "label": "test_webhook",
    "token": "***",
    "url": "https://example.com",
    "accessKey": "***",
    "secretKey": "***"
  }
}

The webhook is created with ID: bxOl8fIPFk6OvFrBOj8UGA.

Now we can specify the webhook when scheduling a script for execution, using the ID from above:

curl -X POST -H "Authorization: Bearer $token" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/script -d '{"expiry": 1714257868, "nodes": ["os:darwin"], "script": {"content": "cHJpbnQoImhlbGxvIHdvcmxkIik="}, "postbacks": [{"webhookid":"bxOl8fIPFk6OvFrBOj8UGA"}]}'

response:

{
  "ID": "mX31fFslhNuDQn3vYzYQOw",
  "done_count": 0,
  ...
}

Now, if we list all jobs for webhook with ID: bxOl8fIPFk6OvFrBOj8UGA, we should see one result:

curl -X GET -H "Authorization: Bearer $token" -H "Content-Type: application/json" https://orbital.amp.cisco.com/v0/webhooks/bxOl8fIPFk6OvFrBOj8UGA/jobs

response:

{
  "jobs": [
    {
      "query": "",
      "script": "mX31fFslhNuDQn3vYzYQOw",
      "type": "script",
      "expired": false,
      "lastchanged": "0001-01-01T00:00:00Z",
      "laststatus": "",
      "errormessage": ""
    }
  ],
  "error": {
    "en": ""
  },
  "next": ""
}