Introduction
One of the most powerful features of Tanium is the ability to take immediate real time action on endpoints. This is accomplished by targeting one or more endpoints and issuing an action. These actions are defined by a set of packages.
To get an overview of Actions and what a Tanium Package is, please review the Action Overview documentation.
Currently tech partner developers are limited to making use of the standard actions available through the Tanium manifest. However at a future time, creating custom packages and actions will be supported. If you feel that your use case requires a custom action or sensor, please contact us at integrations@tanium.com so that we can work with you.
Targeting
Targeting Ad-Hoc Endpoint Group
When incoporating Tanium actions into runbooks or investigation scenarios, it is often necessary to target one or more machines that are not part of previously defined group. In this case, it is necessary to create an "anonymous group" to use for the targeting. The targeting text is structured the same as the second half of a Tanium question and should be as specific as possible. For example:
curl --location --request POST 'https://some_tanium_domain/v2/groups' \
--header 'Content-Type: application/json' \
--header 'session: token-XXXXXXXX' \
--data-raw '{
"text": "Computer Name equals DESKTOP-IV7QEMU and IP Address equals \"fe80::fd89:64e2:73b:3074\" and IP Address equals 10.100.26.1 and Operating System equals Windows 10 Enterprise "
}'
{
"data": {
"id": 2543696
}
}
Save the ID value that is returned for use in the target_group portion of the action request.
Targeting Defined Endpoint Group
If you will be regularly targetting a set group of endpoints, then a filter group can be created that corresponds that group. Please review the Tanium Filter Groups Documentation for information on how to create and manage them.
The filter group ID is used in the target_group portion of the action request along with a filter_flag. Example:
{
"name":"TestTargeting",
"target_group":{
"filter_flag": true,
"id": 132113,
"management_rights_flag": false
},
"package_spec" : {
"source_id" : 961,
"parameters": [
{
"key" : "$1",
"value" : "TargetOnline"
}
]
},
"expire_seconds":43200,
"issue_seconds":0
}
Action Group
You will also need to specify the id of the action group to use for targeting. This should be an action group that has been previously defined in Tanium that contains the endpoint(s) being targeted. It is fine (and expected) that this action group would contain other endpoints as well. It is common to use an id for a group like "All Computers" or "All Windows". This will go in the action_group portion of the request. You should not be creating a new action group for each action issued.
For more information on Action Groups, please review the Tanium Documentation.
Issuing Action
Scheduling
As part of issueing an action, you will need to specify how it will be scheduled. You can have it run immediately or distribute it over the targeted endpoints over a specified period of time. You also specify how long until the action expires, after which time a targetted system that comes online would not have the action deployed. The relevant fields are expire_seconds and distribute_seconds. These are part of the action structure that makes up the POST body.
Issuing
In this example, we are tagging a single endpoint that is targeted using the anonymous group created above.
curl --location --request POST 'https://some_tanium_domain/v2/actions' \
--header 'Content-Type: application/json' \
--header 'session: token-XXXXXXXX' \
--data-raw '{
"action_group": {"id": "2543851"},
"name":"TestTargeting",
"target_group":{
"id": 2543696,
"management_rights_flag": false,
"not_flag": false
},
"package_spec" : {
"source_id" : 173205,
"parameters": [
{
"key" : "$1",
"value" : "TestTag"
}
]
},
"expire_seconds":43200
}'
{
"data": {
"id": 1362688,
"target_group": {
"id": 2543696,
"name": ""
},
"action_group": {
"id": 2543851,
"name": "TestGroup"
},
"package_spec": {
"id": 234169,
"content_set": {
"id": 430,
"name": ""
},
"name": "Custom Tagging - Add Tags [windows]",
"display_name": "",
"creation_time": "2021-07-21T19:00:06Z",
"modification_time": "2021-07-21T19:00:06Z",
"last_modified_by": "some.user@testdomain.com",
"mod_user": {
"id": 1185,
"name": "some.user@testdomain.com",
"domain": "",
"display_name": ""
},
"files": [
{
"id": 13820,
"hash": "17b2d8f6a5ab22a711c1cd832d8c180518cdaf7a50f372860f07f1cc86c98c39",
"name": "add-tags.vbs",
"size": 17229,
"source": "https://content.tanium.com/files/published/Core-Content/2020-06-24_10-46-45_1.1.1.0010/custom_tagging_-_add_tags/add-tags.vbs",
"download_seconds": 0,
"cache_status": "",
"bytes_total": 17229,
"status": 0,
"bytes_downloaded": 0,
"file_status": [
{
"server_id": 1,
"server_name": "taniumserver1.tanium.local:17472",
"status": 0,
"cache_status": "Processing",
"cache_message": "",
"bytes_downloaded": 0,
"bytes_total": 0
},
{
"server_id": 2,
"server_name": "taniumserver2.tanium.local:17472",
"status": 0,
"cache_status": "Processing",
"cache_message": "",
"bytes_downloaded": 0,
"bytes_total": 0
}
]
}
],
"command": "cmd.exe /c cscript.exe //E:VBScript //T:60 add-tags.vbs \"TestTag\"",
"command_timeout": 600,
"expire_seconds": 3600,
"verify_expire_seconds": 3600,
"skip_lock_flag": false,
"hidden_flag": true,
"process_group_flag": true,
"available_time": "2001-01-01T00:00:00Z",
"deleted_flag": false,
"last_update": "2021-07-21T19:00:06Z",
"source_id": 173205,
"source_hash": "e4ae502ef0025ea052ac1ebb64faa6b3d4e81fae4bd325ee10841c4d8184c607",
"source_hash_changed_flag": false,
"verify_group_id": 0,
"verify_group": {
"id": 0
},
"parameters": [
{
"key": "$1",
"value": "TestTag",
"type": 0
}
]
},
"skip_lock_flag": false,
"expire_seconds": 43200,
"creation_time": "2021-07-21T19:00:01Z",
"start_time": "2001-01-01T00:00:00Z",
"expiration_time": "2001-01-01T12:00:00Z",
"distribute_seconds": 0,
"status": "Pending",
"stopped_flag": false,
"user": {
"id": 1185,
"external_flag": 0,
"name": "some.user@testdomain.com",
"domain": "",
"display_name": "",
"group_id": 0,
"effective_group_id": 0,
"deleted_flag": false,
"locked_out": 0,
"last_login": "2021-07-21T18:29:25Z",
"creation_time": "2020-06-25T21:07:53Z",
"modification_time": "2021-04-23T13:06:22Z",
"mod_user": {
"id": 1185,
"name": "some.user@testdomain.com",
"domain": "",
"display_name": ""
}
},
"history_saved_question": {
"id": 0
},
"saved_action": {
"id": 134373
}
}
}
Parameterized Actions
Some actions require parameters to specify how to perform the task on the endpoint. You can determine what parameters are required for a package by looking up the package definition on the packages endpoint. /api/v2/packages/by-name/{package}. The parameter_definition field will contain a json-encoded string that you can parse. Example:
curl --location --request GET 'https://my_tanium_hostname/v2/packages/by-name/Set%20Windows%20Tanium%20Client%20Logging%20Level' \
--header 'Content-Type: application/json' \
--header 'session: token-XXXXXXXXX' \
--data-raw ''
{
"data": {
"id": 15,
"content_set": {
"id": 6,
"name": "Client Management"
},
"name": "Set Windows Tanium Client Logging Level",
"display_name": "Set Windows Tanium Client Logging Level",
"creation_time": "2020-05-20T14:25:48Z",
"modification_time": "2020-05-20T14:25:48Z",
"last_modified_by": "taniumconsole",
"mod_user": {
"id": 2,
"name": "taniumconsole",
"domain": "",
"display_name": ""
},
"command": "cmd /c reg add \"HKLM\\Software\\Tanium\\Tanium Client\" /v LogVerbosityLevel /t REG_DWORD /d $1 /f",
"command_timeout": 300,
"expire_seconds": 900,
"verify_expire_seconds": 600,
"skip_lock_flag": false,
"hidden_flag": false,
"process_group_flag": true,
"available_time": "2020-05-20T14:25:55Z",
"deleted_flag": false,
"last_update": "2020-05-20T14:25:48Z",
"source_id": 0,
"source_hash": "079b9709c5e15ed07f8a623b5d1e2571c74a355a58ff1debbc9076975ebfdf61",
"verify_group_id": 0,
"verify_group": {
"id": 0
},
"parameter_definition": "{\"parameters\":[{\"maximum\":99,\"key\":\"$1\",\"stepSize\":1,\"label\":\"Log Level (0-99)\",\"helpString\":\"Enter a logging level, 0=no logging, 99=verbose logging\",\"snapInterval\":1,\"defaultValue\":\"1\",\"minimum\":0,\"value\":\"1\",\"parameterType\":\"com.tanium.components.parameters::NumericParameter\",\"model\":\"com.tanium.components.parameters::NumericParameter\"}],\"parameterType\":\"com.tanium.components.parameters::ParametersArray\",\"model\":\"com.tanium.components.parameters::ParametersArray\"}"
}
}
You add the parameters structure to pass into the request with a list of key/value pairs along with the package "id" value as the "source_id". The keys will look like $1, $2, etc. Example:
{
"action_group": {"id": "6818"},
"name":"TEST_SetClientLogLevel",
"target_group":{
"id": 135978,
"management_rights_flag": false,
"not_flag": false
},
"package_spec": {
"source_id": 15,
"parameters": [
{
"key" : "$1",
"value" : 50
}
]
},
"expire_seconds":43200,
"issue_seconds":0
Approvals
Some organizations implement action approvals, meaning the actions deployed won't be taken until an authorized user has approved them. Documentation is available to learn more about this feature. Action Approval Documentation
Retrieving Results
Actions results are pulled from the /result/data/action/{id} endpoint. Typically, you will poll this endpoint for results on a regular interval until an acceptible percentage of the endpoints has returned results or enough time has elapsed that continued polling is unlikely to return new results.. This percentage will vary by customer environment, but a 90% completion target is usually a good starting point.
Use the action ID returned in the response to the post /actions as the {id} value in the URI.
The completion percentage is calculated by the formula (100.0 * (mr_tested/estimated_total))
In the below example, you can see 100% of the 1 total targetted machines has reported in with an Action Status of "Completed".
curl --location --request GET 'https://my_tanium_hostname/v2/result_data/action/1362231' \
--header 'Content-Type: application/json' \
--header 'session: token-XXXXXXXX'
{
"data": {
"now": "2021/07/21 15:48:38 GMT-0000",
"max_available_age": "",
"result_sets": [
{
"age": 0,
"id": 6338700,
"report_count": 488,
"saved_question_id": 195532,
"question_id": 6338700,
"archived_question_id": 0,
"seconds_since_issued": 607,
"issue_seconds": 0,
"expire_seconds": 3660,
"tested": 103,
"passed": 96,
"mr_tested": 103,
"mr_passed": 103,
"estimated_total": 100,
"select_count": 2,
"error_count": 0,
"no_results_count": 0,
"columns": [
{
"hash": 3409330187,
"name": "Computer Name",
"type": 1
},
{
"hash": 1792443391,
"name": "Action Statuses",
"type": 1
},
{
"hash": 0,
"name": "Count",
"type": 3
}
],
"filtered_row_count": 1,
"filtered_row_count_machines": 1,
"row_count": 1,
"row_count_machines": 1,
"item_count": 1,
"rows": [
{
"id": 2786028277,
"cid": 2335789940,
"data": [
[
{
"text": "SomeComputerName"
}
],
[
{
"text": "1362231:Completed."
}
],
[
{
"text": "1"
}
]
]
}
]
}
]
}
}
Example
This sample Python script is provided as an example for deploying Actions using the Tanium REST API.
Action Deployment Example