Tanium Control Icon

Deploying Actions

One of the most powerful features of Tanium is the ability to take immediate real-time action on endpoints. Incorporating Tanium's Action Deployment API into an integration gives remote systems the power to instantly remediate a wide variety of issues; anything from security and compliance, to performance and licensing. 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.

The core Tanium Platform comes with an extensive library of packages out of the box, which is expanded depending on which modules you have licensed. Some integration use cases do require custom package development, usually to allow Tanium to directly interact with another application on the endpoint. The Integration License that is granted as part of the Technical Partnership Program is limited to API based integrations and does not cover authoring custom packages or sensors. Partners that want to build custom content as part of their integration can reach out to the Tanium Technical Partnership Team at integrations@tanium.com with details of the use case and we will work with you to evaluate the request for an expanded license.

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 with the 'packageSpecs' query. There are 2 types of parameters that a package can require: regular package parameters and sensor-sourced package parameters. When deploying an action manually through the console, the user will enter the values for the regular package parameters. The sensor-sourced parameters are pulled from the results of the question that was used for targeting. When deploying a package with API Gateway, the caller will need to include the values for both the regular and sensor-sourced parameters.

Get Package Definition

Before you can deploy an action, you will need to retrieve the package definition to see what parameters are required to be passed in. The 'packageSpecs' query allows you to pull the definition for any package. In this example, we pull the definition for the "Custom Tagging - Add Tags" package.

GraphQL Query:

query getPackageSpec($packagename: String!) {
  packageSpecs(filter: {path: "name", value: $packagename, op: EQ}) {
    edges {
      node {
        name
        id
        params {
          key
        }
        sensorSourcedParams {
          name
        }
      }
    }
  }
}

Variables:

{
  "packagename": "Custom Tagging - Add Tags"
}

Regular Parameters

Any required action parameters must be included as a list of String values in the 'params' field of the PackageRefInput that you pass into the 'actionPerform' mutation. The order of the parameter values corresponds to the positional package parameter variables ($1, $2, and so on).
In this example, we will apply a custom tag to an endpoint using the "Custom Tagging - Add Tags" package. It expects the tag value as a single positional parameter.

GraphQL Mutation

mutation performActionOperation($comment: String, $name: String, $package: PackageRefInput!, $targeting: ActionTargetsInput!) {
  actionPerform(
    input: {comment: $comment, name: $name, package: $package, targets: $targeting}
  ) {
    scheduledActions {
      platforms
      scheduledAction {
        id
        lastAction {id}
      }
    }
    error {
      message
      retryable
      timedOut
    }
  }
}

Variables

{
  "package": {
    "name": "Custom Tagging - Add Tags",
    "params": ["TheBestEndpoint"]
  },
  "comment": "Testing Parameterized Actions",
  "name": "Test1",
  "targeting": {
    "actionGroup": {
      "name": "All Computers"
    },
    "targetGroup": {
      "filter": {
        "any": true,
        "filters": [
          {
            "sensor": {
              "name": "Computer Name"
            },
            "op": "EQ",
            "value": "testmachine999"
          }
        ]
      }
    }
  }
}

Sensor-sourced Parameters

Unlike in Interact and the REST API where the use of regular and sensor-sourced package parameters are fairly different, in API Gateway they are treated basically the same way. They are not actually sourced from a sensor; you instead pass the value to use just like you would for a regular parameter. The Targeting example below illustrates the difference in using a sensor-sourced parameter in Interact and API Gateway.

Targeting

Targeting Ad-Hoc Endpoint Group

When incorporating Tanium actions into runbooks or investigation scenarios, you need to define the targeting criteria for the endpoints you want to run the action. When deploying an action manually through the Tanium Console, a question is used to define this targeting. You use a question to identify candidate endpoints and then pivot to Deploy Action, where the correct targeting question is generated for you. Targeting for actions through the Platform REST API is performed similarly to the console.
When deploying an action through API Gateway, a ComputerGroupFilter applied against a Computer Group is used to define the targeting. Regardless of whether you are deploying actions through Interact or the API, you should be as specific as possible with your targeting criteria.

In this example, we want to target machines where a particular process is running and kill it. Notice how we are able to translate the Interact-style question-based targeting into the API Gateway ComputerGroupFilter targeting. When deploying the action through Interact, we have the benefit of the "Preview" operation that is required before the action is deployed in order to validate the targeting. We can do the equivalent in API Gateway by verifying that our ComputerGroupFilter definition is targeting the desired endpoints by first running it in an 'endpoints' query and checking which endpoints respond. In the API Gateway example below, you can run the 'endpoints' query and the subsequent 'actionPerform' mutation using the same set of variable data. We are able to do this because the ComputerGroupFilter structure generally also works as an EndpointFieldFilter.

Interact Targeting Question

Interact Pivot To Action

GraphQL Query

query getEndpointsRunningOpenSSH($first: Int, $filter: EndpointFieldFilter!, $sensors: [EndpointSensorRef!]!) {
  endpoints(first: $first, filter: $filter, source: {ts: {expectedCount: 30}}) {
    edges {
      node {
        name
        ipAddress
        os {
          platform
        }
        sensorReadings(sensors: $sensors) {
          columns {
            name
            values
            sensor {
              name
            }
          }
        }
      }
    }
  }
}

GraphQL Mutation

mutation killProcess($comment: String, $name: String, $package: PackageRefInput!, $filter: ComputerGroupFilter!, $actionGroup: String!) {
  actionPerform(
    input: {comment: $comment, name: $name, package: $package, targets: {actionGroup: {name: $actionGroup}, targetGroup: {filter: $filter}}}
  ) {
    scheduledActions {
      platforms
      scheduledAction {
        id
        lastAction {
          id
        }
      }
    }
    error {
      message
      retryable
      timedOut
    }
  }
}

Variables

{
  "first": 100,
  "actionGroup": "All Computers",
  "package": {
    "name": "Kill Process - ||Running Processes with MD5 Hash_MD5 Hash||",
    "sensorSourcedParams": [
      {
        "name": "Running Processes with MD5 Hash_MD5 Hash",
        "value": "4bf0d5083604b3f8c67c6d0dd310e355"
      }
    ]
  },
  "comment": "Kill OpenSSH on Windows",
  "name": "Kill OpenSSH",
  "sensors": [
    {
      "name": "Running Processes with MD5 Hash",
      "filter": {
        "column": "MD5 Hash",
        "op": "EQ",
        "value": "4bf0d5083604b3f8c67c6d0dd310e355"
      }
    }
  ],
  "filter": {
    "filters": [
      {
        "op": "EQ",
        "sensor": {
          "name": "Running Processes with MD5 Hash",
          "column": "MD5 Hash"
        },
        "value": "4bf0d5083604b3f8c67c6d0dd310e355"
      },
      {
        "sensor": {
          "name": "OS Platform"
        },
        "op": "EQ",
        "value": "Windows"
      }
    ]
  }
}

Targeting Specific Endpoints

If you need to deploy an action to a single endpoint or small group of specific endpoints, then you can target them by Endpoint ID directly. You can use this method to target up 25 endpoints at once.
In the Regular Parameters Example above, we targeted a specific endpoint by Computer Name. We can run that same query with the variable modification shown below to perform the same function with simpler targeting. We replaced the 'targetGroup' portion of the variables from the above example with the much simpler 'endpoints' field.

Variables

{
  "package": {
    "name": "Custom Tagging - Add Tags",
    "params": ["TheBestEndpoint"]
  },
  "comment": "Testing Parameterized Actions",
  "name": "Test1",
  "targeting": {
    "actionGroup": {
      "name": "All Computers"
    },
  "endpoints": ["274177"]
  }
}

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 endpoints 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 Managing Action Group Documentation.

Targeting Best Practices

  • The targeting parameters should naturally exclude endpoints where the action has already run. This means that upon successful completion of the action, the endpoint would no longer be included by the EndpointFieldFilter that was used to deploy the action. For example, if you want to quarantine all endpoints that have a specific application installed, then your targeting criteria should check for presence of that particular installed application and check that the machine is not already quarantined.
  • Make your targeting as specific as possible to avoid accidental spillover deployments to unintended targets.
  • Confirm what endpoints are being targeted. When doing manual deployments via the Console, you are required to preview the endpoints that will be targeted before the action is deployed. The API has no such safety mechanism built in. But you can take the ComputerGroupFilter you intend to use for your actionPerform command and first use it on an 'endpoints' query to do your own programmatic preview to ensure that you are targeting what you think you are targeting.

Scheduling

As part of issuing 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 targeted system that comes online would not have the action deployed. The schedule is defined in the ActionPerformScheduleInput object that is passed to the 'schedule' input field in the 'actionPerform' mutation. The default schedule will instruct the endpoints currently online to run the action immediately, exactly once. The above examples show this behavior.

Targeting Offline Endpoints

If the endpoint you need to run an action is not currently online, then you have a couple of options.

  1. Set the 'expireSeconds' time on your schedule to a timestamp that is after the endpoints you need to target should be back online
  2. Create a recurring action by setting the 'reissueSeconds' and 'endTime' on your schedule so that the action will keep being reissued until after the endpoints you need to target are back online

Recurring Actions

Scheduling Best Practices

  • When targeting a large number of endpoints, especially ones on shared hardware, utilize the 'distributeSeconds' option in your schedule so that all the endpoints don't try to run the action at the same time. This can avoid troublesome contention for limited resources.
  • Long-lived actions are OK when you know exactly which endpoints you are targeting. An expireSeconds value a week or 2 in the future is acceptable in this case. You should manually cancel them once all endpoints have run the action to avoid actions remaining active in Tanium unnecessarily. See an example here
  • Avoid long-lived actions when you are are targeting an unknown number of endpoints. You should use a recurring action and carefully refine your targeting to avoid running the action multiple times on any endpoints.

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
An example for using API Gateway to approve an action is found here.

Retrieving Results

Actions results and status are pulled using the 'action' query in API Gateway. It will be necessary to continue to poll for action results as long as the action status remains Open and the number of endpoints targeted is less than the sum of result counts indicating the action has finished (completed + expired + failed + failedVerification + verified). Use the scheduledAction.lastAction.id value returned from the actionPerform request as the id value in the variables. Do not use the scheduledAction.id value to try to get action results. You can read about the different action states in the Action States Guide.

GraphQL Query

query getActionStatus($id:ID!)
{
  action(ref: {id: $id})
  {
    status
    results {
      completed
      downloading
      expired
      failed
      failedVerification
      id
      pendingVerification
      running
      verified
      waiting
      waitingToRetry
    }
  }
}

Variables json { "id": 6242911 }

GraphQL Query graphql query getActionStatus($id:ID!) { action(ref: {id: $id}) { status results { completed downloading expired failed failedVerification id pendingVerification running verified waiting waitingToRetry } } }

Variables json { "id": 6112010 }

Auditing Actions

The Tanium Console has information that can also be used to review client Actions. The Action History page has a record of actions by ID. Review the action record and check important values such as Target Group, Action Group, Time values, and Command. Using descriptive names when you deploy actions will be helpful later when you are reviewing the action history. Please review the Managing Actions Guide for more information on Client Action Logs. Action History can be exported via Connect and used to monitor action executions. Many customers choose to collect this data in a SIEM or monitoring solution to audit targeting, frequency, and status of these executions.

Please see the following information on Connect Sources here.

Client-side Action Logs

When executing packages on endpoints the Tanium Client log can be used to troubleshoot and/or understand client changes. The client will generate an Action log by ID for each action. The file contains information on the execution of the package script. In addition to a log file, the client will generate a folder by Action ID that contains any package files.

Use the logs to follow each step of your package execution. Use the Action folder to verify package files were successfully transferred to the client system.

More information is available in the Client Action Logs Guide. While troubleshooting an action execution on an endpoint, it can be useful to adjust the client log verbosity level to a higher value.


Last Updated: