This document explains how to configure the v1.0.0 Rubrik plugin with the Threat Exchange module of the Cloud Exchange platform. This plugin supports sharing the threat IoCs of type MD5 and SHA256 to the Rubrik’s Threat Hunt page, and can perform a Start Threat Hunt action.
Prerequisites
To complete the plugin configuration, you’ll need:
- A Netskope tenant (or multiple, for example, production and development/test instances).
- A Netskope Cloud Exchange tenant with the Tenant plugin and Threat Exchange plugin already configured.
- Connectivity to your Rubrik Security Cloud instance (for example: <customername>.my.rubrik.com).
Rubrik Plugin Support
The plugin supports pushing SHA256, and MD5 to Rubrik. The plugin also supports performing the Start Threat Hunt action on the Shared IoCs.
| Fetched indicator types | Not Supported |
| Shared indicator types | SHA256, MD5 |
API Details
List of APIs used
| Use Case | Method | Endpoint | API Scope |
|---|---|---|---|
| Get auth token | POST | /api/client_token | None |
| Get objectFids from Rubrik platform | POST | /api/graphql | Threat Hunt (Read) |
| Get the clusters present on Rubrik | POST | /api/graphql | Threat Hunt
(Read) |
| Start Threat Hunt on Rubrik | POST | /api/graphql | Threat Hunt (Read) |
Get Auth Token
API Endpoint: /api/client_token
Method: POST
Headers
| Key | Value |
|---|---|
| User-Agent | netskope-ce-5.0.1-cte-rubrik-v1.0.0 |
Payload
| Parameter | Value |
|---|---|
| client_id | <Client ID> |
| client_secret | <Client Secret> |
Sample API Response
{
"access_token": "",
"expires_in": 43200,
"Client_id" : “”
}
API for Start Threat Hunt Action
Get ObjectFids from Rubrik
API Endpoint: /api/graphql
Method: POST
Headers
| Key | Value |
| User-Agent | netskope-ce-5.0.1-cte-rubrik-v1.0.0 |
| Authorization | Bearer <Bearer Token> |
| Content-Type | application/json |
Payload
| GraphQL Query | Variables |
|---|---|
query SnappableQuery($first: Int, $after: String, $typeFilter: [HierarchyObjectTypeEnum!], $filter: [Filter!], $sortBy: HierarchySortByField, $sortOrder: SortOrder) {
inventoryRoot {
descendantConnection(first: $first, after: $after, typeFilter: $typeFilter, filter: $filter, sortBy: $sortBy, sortOrder: $sortOrder) {
edges {
cursor
node {
id
... on WindowsFileset {
isPassThrough
__typename
}
... on ShareFileset {
isPassThrough
__typename
}
... on LinuxFileset {
isPassThrough
__typename
}
... on O365Onedrive {
userPrincipalName
__typename
}
...EffectiveSlaColumnFragment
...HierarchyObjectClusterColumnFragment
...HierarchyObjectLocationColumnFragment
...HierarchyObjectNameColumnFragment
...HierarchyObjectTypeFragment
... on AzureNativeVirtualMachine {
region
isAdeEnabled
resourceGroup {
subscription {
name
__typename
}
__typename
}
effectiveSlaDomain {
...ArchivalSpecFragment
__typename
}
__typename
}
... on AzureNativeManagedDisk {
region
isAdeEnabled
resourceGroup {
subscription {
name
__typename
}
__typename
}
effectiveSlaDomain {
...ArchivalSpecFragment
__typename
}
__typename
}
... on CloudDirectNasExport {
exportPath
__typename
}
__typename
}
__typename
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
__typename
}
__typename
}
__typename
}
}
fragment EffectiveSlaColumnFragment on HierarchyObject {
id
effectiveSlaDomain {
...EffectiveSlaDomainFragment
... on GlobalSlaReply {
description
__typename
}
__typename
}
... on CdmHierarchyObject {
pendingSla {
...SLADomainFragment
__typename
}
__typename
}
__typename
}
fragment EffectiveSlaDomainFragment on SlaDomain {
id
name
... on GlobalSlaReply {
isRetentionLockedSla
retentionLockMode
__typename
}
... on ClusterSlaDomain {
fid
cluster {
id
name
__typename
}
isRetentionLockedSla
retentionLockMode
__typename
}
__typename
}
fragment SLADomainFragment on SlaDomain {
id
name
... on ClusterSlaDomain {
fid
cluster {
id
name
__typename
}
__typename
}
__typename
}
fragment HierarchyObjectClusterColumnFragment on HierarchyObject {
...CdmClusterLabelFragment
... on CloudDirectHierarchyObject {
cluster {
id
name
__typename
}
__typename
}
__typename
}
fragment CdmClusterLabelFragment on CdmHierarchyObject {
cluster {
id
name
version
__typename
}
primaryClusterLocation {
id
__typename
}
__typename
}
fragment HierarchyObjectLocationColumnFragment on HierarchyObject {
logicalPath {
name
objectType
__typename
}
physicalPath {
name
objectType
__typename
}
__typename
}
fragment HierarchyObjectNameColumnFragment on HierarchyObject {
name
__typename
}
fragment HierarchyObjectTypeFragment on HierarchyObject {
objectType
__typename
}
fragment ArchivalSpecFragment on GlobalSlaReply {
archivalSpec {
storageSetting {
targetType
__typename
}
__typename
}
archivalSpecs {
storageSetting {
targetType
__typename
}
__typename
}
__typename
}
|
{
"first": 1,
"filter": [
{
"texts": [
"false"
],
"field": "IS_GHOST"
},
{
"texts": [
“”
],
"field": "CLUSTER_ID"
}
],
"sortBy": "NAME",
"sortOrder": "ASC",
"typeFilter": [
"LinuxFileset",
"ShareFileset",
"VmwareVirtualMachine",
"WindowsFileset",
"HypervVirtualMachine",
"NutanixVirtualMachine",
"NAS_FILESET"
],
"after":"Y3Vyc29yOmludDow"
}
|
Sample API Response
{
"data": {
"inventoryRoot": {
"descendantConnection": {
"edges": [
{
"cursor": "Y3Vyc29yOmludDox",
"node": {
"id": "",
"effectiveSlaDomain": {
"id": "",
"name": "MGMT-12H-30D-1Y-AWS-USW1",
"isRetentionLockedSla": false,
"retentionLockMode": "NO_MODE",
"__typename": "GlobalSlaReply",
"description": "Upgraded from Cluster_A"
},
"pendingSla": null,
"__typename": "NasFileset",
"cluster": {
"id": "",
"name": "Cluster_A",
"version": "8.1.3-p11-25483",
"__typename": "Cluster"
},
"primaryClusterLocation": {
"id": "",
"__typename": "DataLocation"
},
"logicalPath": [
{
"name": "/volume1/ISO: **",
"objectType": "FilesetTemplate",
"__typename": "PathNode"
},
{
"name": "/volume1/ISO",
"objectType": "NasShare",
"__typename": "PathNode"
},
{
"name": "domain.com",
"objectType": "NasSystem",
"__typename": "PathNode"
}
],
"physicalPath": [
{
"name": "/volume1/ISO: **",
"objectType": "FilesetTemplate",
"__typename": "PathNode"
},
{
"name": "/volume1/ISO",
"objectType": "NasShare",
"__typename": "PathNode"
},
{
"name": "domain.com",
"objectType": "NasSystem",
"__typename": "PathNode"
}
],
"name": "/volume1/ISO: **",
"objectType": "NAS_FILESET"
},
"__typename": "HierarchyObjectEdge"
}
],
"pageInfo": {
"endCursor": "Y3Vyc29yOmludDox",
"hasNextPage": true,
"hasPreviousPage": true,
"__typename": "PageInfo"
},
"__typename": "HierarchyObjectConnection"
},
"__typename": "InventoryRoot"
}
}
}
Get Clusters Present on Rubrik
API Endpoint: /api/graphql
Method: POST
Headers
| Key | Value |
|---|---|
| User-Agent | netskope-ce-5.0.1-cte-rubrik-v1.0.0 |
| Authorization | Bearer <Bearer Token> |
| Content-Type | application/json |
Payload
| GraphQL Query | Variables |
|---|---|
query ClusterPickerQuery($first: Int, $after: String, $filter: ClusterFilterInput, $sortBy: ClusterSortByEnum, $sortOrder: SortOrder) {
clusterConnection(filter: $filter, sortBy: $sortBy, sortOrder: $sortOrder, first: $first, after: $after) {
edges {
cursor
node {
id
status
...ClusterIconNameFragment
...ClusterVersionColumnFragment
...ClusterTypeColumnFragment
...ClusterCapacityColumnFragment
...ClusterProtectedCountColumnFragment
...ClusterGeoLocationColumnFragment
...ClusterNameColumnFragment
__typename
}
__typename
}
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
__typename
}
__typename
}
}
fragment ClusterIconNameFragment on Cluster {
id
name
status
pauseStatus
state {
clusterRemovalState
__typename
}
defaultAddress
passesConnectivityCheck
connectivityLastUpdated
...ClusterNodeConnectionFragment
globalManagerConnectivityStatus {
urls {
url
isReachable
__typename
}
__typename
}
systemStatus
ccprovisionInfo {
jobStatus
jobType
progress
vendor
__typename
}
__typename
}
fragment ClusterNodeConnectionFragment on Cluster {
clusterNodeConnection {
nodes {
id
status
ipAddress
__typename
}
__typename
}
__typename
}
fragment ClusterVersionColumnFragment on Cluster {
version
eosDate
eosStatus
__typename
}
fragment ClusterTypeColumnFragment on Cluster {
name
productType
type
clusterNodeConnection {
nodes {
id
__typename
}
__typename
}
__typename
}
fragment ClusterCapacityColumnFragment on Cluster {
metric {
usedCapacity
availableCapacity
totalCapacity
__typename
}
__typename
}
fragment ClusterProtectedCountColumnFragment on Cluster {
productType
noSqlWorkloadCount
...ClusterProtectedSnappablesFragment
__typename
}
fragment ClusterProtectedSnappablesFragment on Cluster {
protectedSnappables: snappableConnection(filter: {protectionStatus: Protected}) {
count
__typename
}
__typename
}
fragment ClusterGeoLocationColumnFragment on Cluster {
geoLocation {
address
__typename
}
__typename
}
fragment ClusterNameColumnFragment on Cluster {
name
__typename
}
|
{
"sortBy": "ClusterName",
"sortOrder": "ASC",
"filter": {
"type": [],
"name": [
""
]
},
"first": 1
}
|
Sample API Response
{
"data": {
"clusterConnection": {
"edges": [
{
"cursor": "Y3Vyc29yOmludDow",
"node": {
"id": "40fdb2a5-3591-40ee-a37a-50bce5240d62",
"status": "Connected",
"name": "Cluster_A",
"pauseStatus": "NOT_PAUSED",
"state": {
"clusterRemovalState": "REGISTERED",
"__typename": "clusterState"
},
"defaultAddress": "cluster-a.domain.com",
"passesConnectivityCheck": true,
"connectivityLastUpdated": "2024-08-05T10:16:10.000Z",
"clusterNodeConnection": {
"nodes": [
{
"id": "RVMHM223S002373",
"status": "OK",
"ipAddress": "10.8.107.107",
"__typename": "ClusterNode"
},
{
"id": "RVMHM223S002379",
"status": "OK",
"ipAddress": "10.8.107.106",
"__typename": "ClusterNode"
},
{
"id": "RVMHM223S002714",
"status": "OK",
"ipAddress": "10.8.107.104",
"__typename": "ClusterNode"
},
{
"id": "RVMHM223S002718",
"status": "OK",
"ipAddress": "10.8.107.105",
"__typename": "ClusterNode"
}
],
"__typename": "ClusterNodeConnection"
},
"__typename": "Cluster",
"globalManagerConnectivityStatus": {
"urls": [
{
"url": "https://mycustomername.my.rubrik.com",
"isReachable": true,
"__typename": "GlobalManagerUrl"
}
],
"__typename": "GlobalManagerConnectivity"
},
"systemStatus": "OK",
"ccprovisionInfo": {
"jobStatus": "INITIALIZING",
"jobType": "ADD_NODE",
"progress": 0,
"vendor": "VENDOR_UNKNOWN",
"__typename": "CcprovisionInfo"
},
"version": "8.1.3-p11-25483",
"eosDate": "2024-07-25",
"eosStatus": "EOS_STATUS_UNSUPPORTED",
"productType": "CDM",
"type": "OnPrem",
"metric": {
"usedCapacity": 7113709735936,
"availableCapacity": 54306599845888,
"totalCapacity": 61420309581824,
"__typename": "ClusterMetric"
},
"noSqlWorkloadCount": 0,
"protectedSnappables": {
"count": 148,
"__typename": "SnappableConnection"
},
"geoLocation": {
"address": "Santa Clara, CA, USA",
"__typename": "GeoLocation"
}
},
"__typename": "ClusterEdge"
}
],
"pageInfo": {
"startCursor": "Y3Vyc29yOmludDow",
"endCursor": "Y3Vyc29yOmludDow",
"hasNextPage": true,
"hasPreviousPage": false,
"__typename": "PageInfo"
},
"__typename": "ClusterConnection"
}
}
}
Start Threat Hunt on Rubrik
API Endpoint: /api/graphql
Method: POST
Headers
| Key | Value |
|---|---|
| User-Agent | netskope-ce-5.0.1-cte-rubrik-v1.0.0 |
| Authorization | Bearer <Bearer Token> |
| Content-Type | application/json |
Payload
| GraphQL Query | Variables |
|---|---|
mutation StartThreatHuntMutation($input: StartThreatHuntInput!)
{
startThreatHunt(input: $input)
{
huntId isSyncSuccessful __typename
}
}
|
{
"input": {
"clusterUuid": "40fdb2a5-3591-40ee-a37a-50bce5240d62",
"indicatorsOfCompromise": [
{
"iocKind": "IOC_HASH",
"iocValue": "sha256:a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
},
{
"iocKind": "IOC_HASH",
"iocValue": "sha256:a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146f"
}
],
"objectFids": [
“”
],
"fileScanCriteria": {
"fileSizeLimits": {
"maximumSizeInBytes": 1024,
"minimumSizeInBytes": 5
},
"pathFilter": {
"includes": [
"*.acm",
"*.ax",
"*.cpl",
"*.dll",
"*.drv",
"*.efi",
"*.exe",
"*.mui",
"*.ocx",
"*.scr",
"*.sys",
"*.tsp"
],
"excludes": [],
"exceptions": []
}
},
"maxMatchesPerSnapshot": 1,
"name": "Sample threat hunt",
"shouldTrustFilesystemTimeInfo": true,
"snapshotScanLimit": {
"maxSnapshotsPerObject": 1
}
}
}
|
Sample API Response
{
"data": {
"startThreatHunt": {
"huntId": "892caaf9-90d3-5c87-8297-5862e972a032",
"isSyncSuccessful": true,
"__typename": "StartThreatHuntReply"
}
}
}
Performance Matrix
Here is the performance reading conducted by sharing 100K indicators to Rubrik on a Large CE Stack with these specifications.
| Stack details | Size: Large RAM: 32 GB CPU: 16 Cores |
| Indicators fetched from Rubrik | NA |
| Indicators shared with Rubrik | ~26K per minute |
User Agent
netskope-ce-5.0.1-cte-rubrik-v1.0-0
Workflow
- Get your Client ID and Client Secret.
- Configure the Rubrik plugin.
- Configure a Threat Exchange Business Rule.
- Configure Threat Exchange Sharing.
- Validate the Rubrik plugin.
Click play to watch a video:
Get your Configuration Parameters
Follow the steps in this document to generate the Client ID and Client Secret:
https://docs.rubrik.com/en-us/saas/saas/adding_a_service_account.html?hl=adding%2Cservice%2Caccount
Configure the Rubrik Plugin
- Log in to Cloud Exchange and go to Settings > Plugins.
- Search for and select the CTE Rubrik plugin box.

- Enter the Basic Information:
- Configuration Name: Plugin configuration name
- Sync Interval: Interval to fetch data from this plugin source.
- Aging Criteria: Expire indicators after a specific time.
- Override Reputation: Set value to override reputation of indicators received from this configuration. Leave empty to keep default.
- Enable SSL Validation: Enable SSL Certificate validation.
- Use System Proxy: Use system proxy configured in Settings.

- Click Next.
- Enter the Configuration Parameters:
- Base URL: Base URL of Rubrik instance, like https://rubrik01.rubrikdemo.com.
- Client ID: Client ID generated from the Rubrik platform. To obtain the Client ID, a Service Account JSON needs to be generated. In Rubrik, go to Apps > Settings > Users and Access to generate it.
- Client Secret: Client Secret generated from the Rubrik platform. To obtain the Client Secret, a Service Account JSON needs to be generated. In Rubrik, go to Apps > Settings > Users and Access to generate it.
- Click Save.
Configure a Business Rule for the Rubrik Plugin
A Business Rule is used to filter out the indicators that are to be shared. In order to share IoCs with Rubrik, create a business rule using these steps:
- Go to Threat Exchange > Business Rules and click Create New Rule.

- Add the Rule name and select the fields through which you want to filter the IoCs. When finished, click Save.
Add Sharing for the Rubrik Plugin
To configure the Sharing, follow these steps:
- Go to Threat Exchange > Sharing and click Add Sharing Configuration.
- Select a Source configuration (Source from which you want to share data to Rubrik), a Business Rule, and a Destination.
- Select the Target value, and enter these values:
- Threat Hunt Name: Enter the name of the Threat Hunt. A Threat Hunt with this name will be initiated on Rubrik.
- Cluster Name: Rubrik Cluster for which you want to initiate Threat Hunt.
- Max File Size to Scan (in KB): Maximum file size in KB to scan. Default is 1024 KB. Maximum supported size is 15000000 KB and minimum supported size is 1 KB.
- Min File Size to Scan (in KB): Minimum file size in KB to scan. Default is 5 KB. Maximum supported size is 15000000 KB and minimum supported size is 1 KB.
- Max IOC Matches (Per Snapshot): Maximum IOC matches per snapshot. Default is 1. Maximum supported value is 1000 and minimum supported value is 1.
- Include Files: Files to include in Threat Hunt.
- Exclude Files: Files to exclude from Threat Hunt.
- Do not Exclude Files: File which should not be excluded from Threat Hunt.


- Click Save.

Validate the Rubrik Plugin
Pull is not supported.
Validate the Push
Shared IoCs to Rubrik can be verified from logs available on the Logging page of Cloud Exchange.
IoCs shared on Rubrik can be verified at Apps > Data Threat Analytics > Threat Hunt. Click on the Threat Hunt that you created.
Click on the Parameters tab to view the shared IoCs.
Troubleshooting
Unable to configure the Rubrik Plugin
If you are unable to configure the Rubrik Plugin, then it could be due to one of the reasons mentioned-below:
- Proper permission is not provided to the credentials.
- Provided incorrect credentials.
To solve the issues mentioned above, follow these steps:
- Check the logs of the plugin in Cloud Exchange.
- Make sure that provided credentials have proper permissions.
- Make sure that correct credentials are provided while configuring the plugin.
Unable to push data to Rubrik
If you are unable to share the IoCs to the Rubrik Plugin, then it could be due to one of these reasons:
- Invalid value of MD5, and SHA256 provided.
- If the shared data has type other than MD5, or SHA256.
To solve the issues mentioned above, follow these steps:
- Check the logs of the plugin in Cloud Exchange.
- Make sure that the MD5, and SHA256 that needs to be shared are valid.
- Make sure that the IoCs are of type MD5, or SHA256.

