Script API
This API request schedules a script and returns an object that provides information needed to collect the results. Orbital Script uses Python scripts. Orbital Script output is python schema and will throw appropriate errors when necessary.
Note: Orbital will retain the results of all queries (scripts) for a minimum of 48 hours.
Scheduled Scripts have a specific time and duration in which they are run. Use the Schedule Orbital Script function to set the script’s expiry and interval. expiry is the Unix time stamp of how long the script will be active. interval is how often in seconds the script will be active before expiring.
Live Scripts run immediately and return information from only those nodes that are connected at the time the script is run. See the Results API for how to retrieve results.
Request Parameters
Orbital accepts the following parameters when creating a script.
name-- A descriptive name for the script, used by the UI to help users distinguish queries.nodes-- A list of Orbital node identifiers. One or more of these prefixes must be used: nodes, os, nodeversion, or netmask. Refer toSpecifying Nodes as Subjects of Queriesfor more details.expiry-- The Unix epoch time when the script will expire. This field is required and must be at least one minute in the future.interval-- A period in seconds that determines how long until Orbital will want a new result from a node for the script. This field is required and must be set to at least a value of 0. The script runs on each applicable node only once for up to a maximum of 24 hours if set to 0. The interval is anapianalog of the Run Once function located on the Scheduled Script form of the User Interface.os-- A list of operating systems such as["windows"]. Orbital will add all hosts with the given operating systems to the list of nodes if defined. Having an explicit node in the list along with its os will not cause scripts to run twice on that node.script_info-- This struct contains the various different parameters that describes the script to be executed.content-- This includes the customized script content of thepythonscript to be executed encoded inbase64format. Cannot be combined withstock scriptstockorcatalog_id-- ID of thecatalogorstockscript. Cannot be combined withcontent, custom script.label-- Desired label of this script.name-- Desired name for this script.timeout-- Maximum allowed time for script execution before timing out.args-- Argument(s) that are passed into the script that can be passed withtypes,value,nameanddescription.argsare passed as json formatted list.argtype-- Argtype of theargthat is passed in, could be any ofORBITAL_BASIC_STRING,ORBITAL_RAW_STRING,ORBITAL_INT,ORBITAL_FLOAT,ORBITAL_EMAIL,ORBITAL_URL,ORBITAL_IPV4,ORBITAL_IPV6or be left as a blank stringvalue-- The value of the given argument. For example, an arg withORBITAL_BASIC_STRING,ORBITAL_RAW_STRINGcould be pass as something like "hello world"name-- The name given to thearg. This value is used when replacing matching placeholder within a script.description-- A general description of thearg.
context-- A table of strings stored with each result. Used to pass opaque metadata on to webhooks like CTR or Threat Grid URL for more information.postbacks-- A list of Postback objects - each describing a remote data store - where results from a scheduled query get sent. SeePostback Objects in Queriesfor more details.
Postback Objects and Specifying Nodes
For guide on Postback Objects and Specifying Nodes, see those sections in Query
Custom Script Content
For orbital script, custom script content is allowed, but cannot be used concurently with catalog or stock scripts. Custom script content will need to be encoded into base64 from original string encoding.
Example of Python code encoded as base64:
import sys
print("hello")
becomes
cHJpbnQoImhlbGxvIik=
This content will then be used within content for live script, scheduled script, and catalog script.
Script Argument Types
Arguments or variable fields within custom scripts and certain stock and/or catalog scripts can be specified and changed upon request. Currently, the allowed parameters are listed below. These parameters will initially be passed through the API as string types, and then validated based on the associated regex expressions.
| Name | Regex Expression | Example | Other Comment |
|---|---|---|---|
| ORBITAL_BASIC_STRING | .* |
"Hello World" | This string type is escaped when character(s) " \ ' are involved |
| ORBITAL_RAW_STRING | .* |
"Hello World" | This string type is the raw non-escaped string type |
| ORBITAL_INT | ^[ \\t]*[-+]?\\d+[ \\t]*$ |
"123" | |
| ORBITAL_FLOAT | ^[ \\t]*[-+]?([\\d]*[.]?)[\\d]*[ \\t]*$ |
"123.5" | |
| ORBITAL_EMAIL | [a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$ |
"john.smith@cisco.com" | |
| ORBITAL_URL | ((((https?|ftps?|gopher|telnet|nntp)://)|(mailto:|news:))([-%()_.!~*';/?:@&=+$,A-Za-z0-9])+) |
"https://www.cisco.com" | |
| ORBITAL_IPV4 | ^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$ |
"192.0.2.146" | |
| ORBITAL_IPV6 | (([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$ |
"2001:0000:130F:0000:0000:09C0:876A:130B" |
Argument Types Content Replacement
In order for script args to work properly, the name field within the python code will need to be encapsulated like this {{ .arg_name }}.
For example, given python script of below
import sys
def printHobbies(name, hobbies):
print(f"My name is {name} and my hobbies are {hobbies}")
if __name__ == '__main__':
name = '{{ .name }}'
hobbies = '{{ .hobbies }}'
printHobbies(name, hobbies)
sys.exit(3)
Additionally, in order for the python script to be used in custom script content, it will need to be first converted to base64 format within within the request, forming into below content.
aW1wb3J0IHN5cwoKZGVmIHByaW50SG9iYmllcyhuYW1lLCBob2JiaWVzKToKICAgIHByaW50KGYiTXkgbmFtZSBpcyB7bmFtZX0gYW5kIG15IGhvYmJpZXMgYXJlIHtob2JiaWVzfSIpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbmFtZSA9ICd7eyAubmFtZSB9fScKICAgIGhvYmJpZXMgPSAne3sgLmhvYmJpZXMgfX0nCiAgICBwcmludEhvYmJpZXMobmFtZSwgaG9iYmllcykKICAgIHN5cy5leGl0KDMp
Script arg param defined something like this
{
...
"script": {
...
"args": [
{"name": "name", "argtype": "ORBITAL_BASIC_STRING", "value": "bobby"},
{"name": "hobbies", "argtype": "ORBITAL_BASIC_STRING", "value": "skiing, basketball"}
]
...
]
...
}
Combined together a request with custom script content and args could look something similar to the format below.
{
...
"script": {
"args": [
{"name": "name", "argtype": "ORBITAL_BASIC_STRING", "value": "bobby"},
{"name": "hobbies", "argtype": "ORBITAL_BASIC_STRING", "value": "skiing, basketball"}
],
"content": "aW1wb3J0IHN5cwoKZGVmIHByaW50SG9iYmllcyhuYW1lLCBob2JiaWVzKToKICAgIHByaW50KGYiTXkgbmFtZSBpcyB7bmFtZX0gYW5kIG15IGhvYmJpZXMgYXJlIHtob2JiaWVzfSIpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbmFtZSA9ICd7eyAubmFtZSB9fScKICAgIGhvYmJpZXMgPSAne3sgLmhvYmJpZXMgfX0nCiAgICBwcmludEhvYmJpZXMobmFtZSwgaG9iYmllcykKICAgIHN5cy5leGl0KDMp",
"label": "string",
"name": "hello world script",
"timeout": 600
}
...
}
Example 1: A Non-Stock/Custom Script
Scheduled Script Example
curl -X 'POST' \
'https://orbital.amp.cisco.com/v0/script' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJ...' \
-H 'Content-Type: application/json' \
-d '{
"creator": "creator_name",
"expiry": 1733818623,
"interval": 600,
"name": "sample script name",
"nodes": [
"all"
],
"nodeversions": [
""
],
"os": [
"windows", "darwin", "linux"
],
"script": {
"args": [
{"name": "name", "argtype": "ORBITAL_BASIC_STRING", "value": "bobby"},
{"name": "hobbies", "argtype": "ORBITAL_BASIC_STRING", "value": "skiing, basketball"}
],
"content":
"aW1wb3J0IHN5cwoKZGVmIHByaW50SG9iYmllcyhuYW1lLCBob2JiaWVzKToKICAgIHByaW50KGYiTXkgbmFtZSBpcyB7bmFtZX0gYW5kIG15IGhvYmJpZXMgYXJlIHtob2JiaWVzfSIpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbmFtZSA9ICd7eyAubmFtZSB9fScKICAgIGhvYmJpZXMgPSAne3sgLmhvYmJpZXMgfX0nCiAgICBwcmludEhvYmJpZXMobmFtZSwgaG9iYmllcykKICAgIHN5cy5leGl0KDMp",
"label": "string",
"name": "hello world script",
"timeout": 600
}
}'
Live Script
curl -X 'POST' \
'https://orbital.amp.cisco.com/v0/script/run' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJ...' \
-H 'Content-Type: application/json' \
-d '{
"cidr": "netmask:10.0.0.0/24",
"expiryinminutes": "60",
"name": "sample livescript name",
"nodes": [
"all"
],
"nodeversions": [
"string"
],
"os": [
"string"
],
"requestdurationsec": "5",
"script": {
"args": [
{"name": "name", "argtype": "ORBITAL_BASIC_STRING", "value": "bobby"},
{"name": "hobbies", "argtype": "ORBITAL_BASIC_STRING", "value": "skiing, basketball"}
],
"content": "aW1wb3J0IHN5cwoKZGVmIHByaW50SG9iYmllcyhuYW1lLCBob2JiaWVzKToKICAgIHByaW50KGYiTXkgbmFtZSBpcyB7bmFtZX0gYW5kIG15IGhvYmJpZXMgYXJlIHtob2JiaWVzfSIpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbmFtZSA9ICd7eyAubmFtZSB9fScKICAgIGhvYmJpZXMgPSAne3sgLmhvYmJpZXMgfX0nCiAgICBwcmludEhvYmJpZXMobmFtZSwgaG9iYmllcykKICAgIHN5cy5leGl0KDMp",
"label": "string",
"name": "hello world script",
"timeout": 600
}
}'
Typical 200 Response will show all result(s), error(s), exit_code, etc. of nodes called in the request.
{
"result_id": "result uuid",
"results": [
{
"stdout": "My name is bobby and my hobbies are skiing, basketball",
"stderr": "",
"exit_code": 3,
"hostname": "node-...",
"nodeId": "nodeid123",
"activeIp": "127.0.0.1",
"reported": "202X-...Z"
},
...
]
}
Example 2: A Stock/Catalog Script
This Example uses reference of script using catalog_id field, content field will be left empty. Below examples uses catalog_id of list_user_sessions, which requires no args. Stock or catalog script with defined args will have to be expressed within args in script content.
To Find all available catalog or [stock] script.
Get All Stock Script Example
curl -X 'GET' \
'https://orbital.amp.cisco.com/v0/catalogs/cisco/scripts' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJ...'
The list of stock script will be defined as a list in the response body similar to format below. ID field is used to reference script catalog_id in catalog script execution and scheduled request(s).
{
"data": [
{
"ID": "script_id",
"title": "Script Title",
"created": "202X-...Z",
"config": {
"platform": [
"windows",
"darwin",
"linux"
],
"description": "This is a script",
"script": {
"content": "script content in base64",
"name": null,
"args": [
{
"name": "user_name",
"value": "",
"description": "The user script."
}
]
}
},
"updated": "202X-...Z"
},
...
]
}
Similarly user defined catalog script could be acquired with request below.
curl -X 'GET' \
'https://orbital.amp.cisco.com/v0/catalogs/scripts' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJ...'
Scheduled Script Example
curl -X 'POST' \
'https://orbital.amp.cisco.com/v0/script' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJ...' \
-H 'Content-Type: application/json' \
-d '{
"creator": "creator_name",
"expiry": 1733868156,
"interval": 600,
"name": "sample script name",
"nodes": [
"all"
],
"nodeversions": [
""
],
"os": [
"windows", "darwin"
],
"script": {
"args": [
],
"catalog_id": "list_user_sessions",
"label": "string",
"name": "list user session script run",
"timeout": 600
}
}''
Live Script
curl -X 'POST' \
'https://orbital.amp.cisco.com/v0/script/run' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJ...' \
-H 'Content-Type: application/json' \
-d '{
"cidr": "netmask:10.0.0.0/24",
"expiryinminutes": "60",
"name": "sample livescript name",
"nodes": [
"all"
],
"nodeversions": [
"string"
],
"os": [
"string"
],
"requestdurationsec": "5",
"script": {
"args": [
],
"catalog_id": "list_user_sessions",
"label": "string",
"name": "list user session script run",
"timeout": 600
}
}'
Example 4: Create Organization Catalog Script
This Example shows the creation of a new catalog script. The previous name and hobbies example is used here. In create catalog script request arg value can be left as empty or set with an default value.
Catalog Script Example
curl -X 'POST' \
'https://orbital.amp.cisco.com/v0/catalogs/scripts' \
-H 'accept: application/json' \
-H 'authorization: Bearer eyJ...' \
-H 'Content-Type: application/json' \
-d '{
"description": "test script",
"platform": [
"darwin",
"windows",
"linux"
],
"script": {
"args": [
{
"ArgType": "ORBITAL_BASIC_STRING",
"description": "name of the person",
"name": "name",
"optional": true,
"value": ""
},
{
"ArgType": "ORBITAL_BASIC_STRING",
"description": "hobbies of the person",
"name": "hobbies",
"optional": true,
"value": ""
}
],
"content": "aW1wb3J0IHN5cwoKZGVmIHByaW50SG9iYmllcyhuYW1lLCBob2JiaWVzKToKICAgIHByaW50KGYiTXkgbmFtZSBpcyB7bmFtZX0gYW5kIG15IGhvYmJpZXMgYXJlIHtob2JiaWVzfSIpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbmFtZSA9ICd7eyAubmFtZSB9fScKICAgIGhvYmJpZXMgPSAne3sgLmhvYmJpZXMgfX0nCiAgICBwcmludEhvYmJpZXMobmFtZSwgaG9iYmllcykKICAgIHN5cy5leGl0KDMp",
"label": "string",
"name": "person hobbies",
"timeout": 600
},
"title": "terminate processes",
"version": "1"
}'
In the Response Body if 200 is received. ID will be returned. The ID of the cataloged script could be used in livescript and scheduled script requests under catalog_id.
{
"data": {
"ID": "org:idnumber...",
"title": "terminate processes",
...
}