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 Queries
for 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 anapi
analog 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 thepython
script to be executed encoded inbase64
format. Cannot be combined withstock script
stock
orcatalog_id
-- ID of thecatalog
orstock
script. 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
,name
anddescription
.args
are passed as json formatted list.argtype
-- Argtype of thearg
that is passed in, could be any ofORBITAL_BASIC_STRING
,ORBITAL_RAW_STRING
,ORBITAL_INT
,ORBITAL_FLOAT
,ORBITAL_EMAIL
,ORBITAL_URL
,ORBITAL_IPV4
,ORBITAL_IPV6
or be left as a blank stringvalue
-- The value of the given argument. For example, an arg withORBITAL_BASIC_STRING
,ORBITAL_RAW_STRING
could 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 Queries
for 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.
Scheduled Query 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",
...
}