RubrikPolaris

The Rubrik Security Cloud integration will fetch the Rubrik Anomaly Event and is rich with commands to perform the on-demand scans, backups, recoveries and many more features to manage and protect the organizational data.

Data Enrichment & Threat Intelligence · Rubrik Security Cloud

Details

IDRubrikPolaris
ProviderRubrik
CategoryData Enrichment & Threat Intelligence
From Version6.0.0
Docker Imagedemisto/rubrik-polaris-sdk-py3:1.0.0.10133006
Supported ModulesAgentix XSIAM

README

The Rubrik Security Cloud integration will fetch the Rubrik Anomaly Event and is rich with commands to perform the on-demand scans, backups, recoveries and many more features to manage and protect the organizational data.
This integration was integrated and tested with version 1.0.0 of Rubrik Security Cloud

Configure Rubrik Security Cloud in Cortex

Parameter Description Required
Service Account JSON   False
Rubrik Account (e.g. ${rubrikAccount}.my.rubrik.com)   False
Email   False
Password   False
Fetch incidents   False
Incident type   False
RSC Fetch Types Select RSC types to fetch as incidents.

Note: Supports the listed options only. If not provided, it will fetch all listed options.
False
Event types to fetch as incidents Event types to fetch as incidents.
Note: Supports the listed options only. If not provided, it will fetch events for all listed options. Applies only when RSC fetch type is set to “Event”.
False
Event severities to fetch as incidents Event severities to fetch as incidents.
Note: Supports the listed options only. If not provided, it will fetch events for critical severity level. Applies only when RSC fetch type is set to “Event”.
False
Threat Monitoring Match Types Select Threat Monitoring Match Types to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “Threat Monitoring object”.
False
Threat Monitoring Object Types Select Threat Monitoring Object Types to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “Threat Monitoring object”.
False
First fetch time The time interval for the first fetch (retroactive). Examples of supported values can be found at https://dateparser.readthedocs.io/en/latest/#relative-dates. False
Fetch Limit (Maximum of 1000) Maximum number of incidents to fetch every time. The maximum value is 1000.

Note: If multiple fetch types (Events, Threat Monitoring objects, DSPM Violations, IR Violations, Sensitive Data Objects) are selected, the limit is distributed optimally among them to fetch all types.
False
Event Critical Severity Level Mapping When an event of Critical severity is detected and fetched, this setting indicates what severity will get assigned within XSOAR. False
Event Warning Severity Level Mapping When an event of Warning severity is detected and fetched, this setting indicates what severity will get assigned within XSOAR. False
Threat Monitoring Object Severity Level Mapping When a threat monitoring object is fetched, this setting indicates what severity will get assigned within XSOAR. False
DSPM Violation Statuses Select DSPM violation statuses to fetch as incidents. Default is OPEN and IN_PROGRESS.

Note: Applies only when RSC fetch type is set to “DSPM Violation”.
False
DSPM Violation Sensitivity Levels Select DSPM violation sensitivity levels to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “DSPM Violation”.
False
DSPM Violation Severity Levels Select DSPM violation severity levels to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “DSPM Violation”.
False
DSPM Violation Categories Select DSPM violation categories to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “DSPM Violation”.
False
DSPM Violation Object Types Select DSPM violation object types to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “DSPM Violation”. Values not included in the options can be found in the documentation.
False
IR Violation Policy Types Select IR violation policy types to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “IR Violation”.
False
IR Violation Statuses Select IR violation statuses to fetch as incidents. Default is OPEN and IN_PROGRESS.

Note: Applies only when RSC fetch type is set to “IR Violation”.
False
IR Violation Severity Levels Select IR violation severity levels to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “IR Violation”.
False
IR Violation Categories Select IR violation categories to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “IR Violation”.
False
IR Violation Identity Providers Select IR violation identity providers to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “IR Violation”.
False
IR Violation Identity Tags Select IR violation identity tags to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “IR Violation”.
False
Sensitive Data Object Sensitivity Levels Select Sensitive Data Object sensitivity levels to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “Sensitive Data Object”.
False
Sensitive Data Object Types Select Sensitive Data Object types to fetch as incidents. Default is all.

Note: Applies only when RSC fetch type is set to “Sensitive Data Object”. Values not included in the options can be found in the documentation.
False
Source Reliability Reliability of the source providing the intelligence data. False
Use system proxy settings Whether to use XSOAR’s system proxy settings to connect to the API. False
Trust any certificate (not secure) Whether to allow connections without verifying SSL certificates validity. False

Known Limitations

  • The fetch-incidents only ingests the events with “Critical” severity.
  • During the fetch cycle of threat monitoring objects, changing the filter parameters (Threat Monitoring Match Types or Threat Monitoring Object Types) may result in delayed ingestion of threat monitoring objects.

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

rubrik-radar-analysis-status


Check the Radar Event for updates.

Base Command

rubrik-radar-analysis-status

Input

Argument Name Description Required
activitySeriesId The ID of the Polaris Event Series. When used in combination with "Rubrik Radar Anomaly" incidents, this value will automatically be looked up using the incident context. Otherwise it is a required value.

Note: Users can retrieve the list of the activity series IDs by executing the "rubrik-event-list" command.
Required
clusterId The ID of the CDM cluster. When used in combination with "Rubrik Radar Anomaly" incidents, this value will automatically be looked up using the incident context. Otherwise, it is a required value.

Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command.
Required

Context Output

Path Type Description
Rubrik.Radar.EventComplete Boolean Flag that indicates whether Radar has finished analysing the object.
Rubrik.Radar.Message Unknown The text, ID, and timestamp of each message in the Activity Series.
Rubrik.Radar.ActivitySeriesId String The ID of the Rubrik Polaris Activity Series.
Rubrik.Radar.ClusterId String The ID of the cluster.

Command Example

!rubrik-radar-analysis-status activitySeriesId="" clusterId="cc19573c-db6c-418a-9d48-067a256543ba"

Human Readable Output

Radar Analysis Status

Activity Series ID Cluster ID Message Event Complete
ec9c48ce-5faf-474a-927c-33667355aecd cc19573c-db6c-418a-9d48-067a256543ba Completed backup of the transaction log for SQL Server database ‘AdventureWorks2012’ from ‘sx1-sql12-1\MSSQLSERVER’. True

rubrik-sonar-sensitive-hits


Find data classification hits on an object.

Base Command

rubrik-sonar-sensitive-hits

Input

Argument Name Description Required
objectName The name of the Rubrik object to check for sensitive hits. When used in combination with “Rubrik Radar Anomaly” incidents, this value will automatically be looked up using the incident context. Otherwise it is a required value.

Note: Users can get the list of the object names by executing the “rubrik-polaris-object-list” or “rubrik-polaris-object-search” command.
Optional
searchTimePeriod The number of days in the past to look for sensitive hits. If no value is provided, then today’s data will be returned and, if there is no data for today then the argument will default to 7 days.
Default is 7.
Optional

Context Output

Path Type Description
Rubrik.Sonar.totalHits String The total number of data classification hits found on the provided object.
Rubrik.Sonar.id String ID of the sensitive hits object.
Rubrik.Sonar.policy_hits Unknown Information of the policy analyzer group of the sensitive hits object.
Rubrik.Sonar.filesWithHits Number The total number of files with hits of the object.
Rubrik.Sonar.openAccessFiles Number The total number of open access files of the object.
Rubrik.Sonar.openAccessFilesWithHits Number The total number of open access files with hits of the object.
Rubrik.Sonar.openAccessFolders Number The total number of open access folders of the object.
Rubrik.Sonar.staleFiles Number The total number of stale files of the object.
Rubrik.Sonar.staleFilesWithHits Number The total number of stale files with hits of the object.
Rubrik.Sonar.openAccessStaleFiles Number The total number of open access stale files of the object.
Rubrik.Radar.Message Unknown The text, ID, and timestamp of each message in the Activity Series.
Rubrik.Radar.ActivitySeriesId String The ID of the Rubrik Polaris Activity Series.

Command Example

!rubrik-sonar-sensitive-hits objectName="sx1-radar15"

Human Readable Output

Sensitive Hits

ID Total Hits
afc0f6f0-148a-54c5-9927-c24c7cde1608 49684

rubrik-cdm-cluster-location


Find the CDM GeoLocation of a CDM Cluster.

Base Command

rubrik-cdm-cluster-location

Input

Argument Name Description Required
clusterId The ID of the CDM cluster. When used in combination with “Rubrik Radar Anomaly” incidents, this value will automatically be looked up using the incident context. Otherwise, it is a required value.

Note: Users can retrieve the list of the cluster IDs by executing the “rubrik-gps-cluster-list” command.
Required

Context Output

Path Type Description
Rubrik.CDM.Cluster.Location String The GeoLocation of the Rubrik CDM Cluster.
Rubrik.CDM.ClusterId String The ID of the cluster.

Command Example

!rubrik-cdm-cluster-location clusterId="cc19573c-db6c-418a-9d48-067a256543ba"

Human Readable Output

CDM Cluster Location

Location
San Francisco, CA, USA

rubrik-cdm-cluster-connection-state


Find the CDM Connection State of a CDM Cluster.

Base Command

rubrik-cdm-cluster-connection-state

Input

Argument Name Description Required
clusterId The ID of the CDM cluster. When used in combination with “Rubrik Radar Anomaly” incidents, this value will automatically be looked up using the incident context. Otherwise, it is a required value.

Note: Users can retrieve the list of the cluster IDs by executing the “rubrik-gps-cluster-list” command.
Required

Context Output

Path Type Description
Rubrik.CDM.Cluster.ConnectionState String The Connection State of the Rubrik CDM Cluster.
Rubrik.CDM.ClusterId String The ID of the cluster.

Command Example

!rubrik-cdm-cluster-connection-state clusterId="cc19573c-db6c-418a-9d48-067a256543ba"

Human Readable Output

CDM Cluster Connection State

Connection State
Connected

rubrik-polaris-object-search


Search for Rubrik discovered objects of any type, return zero or more matches.

Base Command

rubrik-polaris-object-search

Input

Argument Name Description Required
limit Number of results to retrieve in the response. Maximum size allowed is 1000. Default is 50. Optional
object_name The name of the object to search for. Required
sort_by Specify the field to use for sorting the response.

Note: Supported values are “ID” and “NAME” only. For any other values, the obtained result is sorted or not is not confirmed. Default is ID.
Optional
sort_order Specify the order to sort the data in.

Possible values are: “ASC”, “DESC”. Default is ASC.
Optional
next_page_token The next page cursor to retrieve the next set of results. Optional

Context Output

Path Type Description
RubrikPolaris.GlobalSearchObject.id String The ID of the object.
RubrikPolaris.GlobalSearchObject.name String The name of the object.
RubrikPolaris.GlobalSearchObject.objectType String The type of the object.
RubrikPolaris.GlobalSearchObject.physicalPath.fid String The FID of the physical path of the object.
RubrikPolaris.GlobalSearchObject.physicalPath.name String The name of the physical path where the object relies.
RubrikPolaris.GlobalSearchObject.physicalPath.objectType String The object type of the physical path where the object relies.
RubrikPolaris.GlobalSearchObject.azureRegion String The azure region of the object.
RubrikPolaris.GlobalSearchObject.awsRegion String The aws region of the object.
RubrikPolaris.GlobalSearchObject.emailAddress String The email address of the object.
RubrikPolaris.GlobalSearchObject.isRelic Boolean Whether the object is relic (historical) or not.
RubrikPolaris.GlobalSearchObject.effectiveSlaDomain.id String The effective SLA domain ID of the object.
RubrikPolaris.GlobalSearchObject.effectiveSlaDomain.name String The effective SLA domain name of the object.
RubrikPolaris.GlobalSearchObject.effectiveSlaDomain.description String The effective SLA domain description of the object.
RubrikPolaris.GlobalSearchObject.effectiveSlaDomain.fid String The FID of the object’s effective SLA domain.
RubrikPolaris.GlobalSearchObject.effectiveSlaDomain.cluster.id String The cluster ID of the object’s effective SLA domain.
RubrikPolaris.GlobalSearchObject.effectiveSlaDomain.cluster.name String The cluster name of the object’s effective SLA domain.
RubrikPolaris.GlobalSearchObject.physicalChildConnection.count String The count of physical child connection of the object.
RubrikPolaris.GlobalSearchObject.physicalChildConnection.edges.node.id String The ID of physical child connection of the object.
RubrikPolaris.GlobalSearchObject.physicalChildConnection.edges.node.name String The name of the physical child connection of the object.
RubrikPolaris.GlobalSearchObject.physicalChildConnection.edges.node.replicatedObjects.cluster.id String The cluster ID of the replicated objects of physical child connection of the object.
RubrikPolaris.GlobalSearchObject.physicalChildConnection.edges.node.replicatedObjects.cluster.name String The cluster name of the replicated objects of physical child connection of the object.
RubrikPolaris.GlobalSearchObject.cluster.id String The cluster ID related to the object.
RubrikPolaris.GlobalSearchObject.cluster.name String The name of the cluster related to the object.
RubrikPolaris.GlobalSearchObject.primaryClusterLocation.id String The primary cluster location ID of the object.
RubrikPolaris.GlobalSearchObject.gcpZone String The gcp zone of the object.
RubrikPolaris.GlobalSearchObject.gcpRegion String The gcp region of the object.
RubrikPolaris.GlobalSearchObject.gcpNativeProject.name String The gcp native project name of the object.
RubrikPolaris.PageToken.GlobalSearchObject.next_page_token String Next page token.
RubrikPolaris.PageToken.GlobalSearchObject.name String Name of the command.
RubrikPolaris.PageToken.GlobalSearchObject.has_next_page Boolean Whether the result has the next page or not.

Command Example

!rubrik-polaris-object-search object_name="admin" limit=2

Human Readable Output

Global Objects

Object ID Object Name Type SLA Domain
0f667954-9052-42c8-ac20-2149da4d0ec4 Hoang-Admin Nguyen O365Mailbox UNPROTECTED
3e5d0800-71f6-4e42-badc-ae8b98c8a808 Admin o365 O365Mailbox UNPROTECTED

Note: To retrieve the next set of results use, “next_page_token” = xyz

rubrik-sonar-policies-list


Retrieve the list of all the available Sonar policies.

Base Command

rubrik-sonar-policies-list

Input

There are no input arguments for this command.

Context Output

Path Type Description
RubrikPolaris.SonarPolicy.id String Unique ID of the policy.
RubrikPolaris.SonarPolicy.name String Name of the policy.
RubrikPolaris.SonarPolicy.description String Descriptive name of the policy.
RubrikPolaris.SonarPolicy.creator.email String Email of the user who created the policy.
RubrikPolaris.SonarPolicy.totalObjects Number Number of total objects present in the policy.
RubrikPolaris.SonarPolicy.numAnalyzers Number Number of analyzers present in the policy.
RubrikPolaris.SonarPolicy.objectStatuses.id String ID of the object present in the policy.
RubrikPolaris.SonarPolicy.objectStatuses.latestSnapshotResult.snapshotFid String Snapshot ID of the object present in the policy.
RubrikPolaris.SonarPolicy.objectStatuses.policyStatuses.policyId String Policy ID.
RubrikPolaris.SonarPolicy.objectStatuses.policyStatuses.status String Policy status.

Command Example


#### Human Readable Output

### Sonar Policies

|ID|Name|Description|Analyzers|Objects|Creator Email|
|---|---|---|---|---|---|
| bdb8c043-ee89-43ef-a3e2-73e94b5b3900 | CCPA | California Consumer Privacy Act | 5 | 3 | dummy.email@rubrik.com |
| 53e447ed-9114-4fcd-b5a6-7ac759980fde | GLBA | U.S. Gramm-Leach-Bliley Act | 4 | 3 |  |

### rubrik-sonar-policy-analyzer-groups-list

***
List the analyzer group policies.

#### Base Command

`rubrik-sonar-policy-analyzer-groups-list`

#### Input

There are no input arguments for this command.

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.SonarAnalyzerGroup.id | String | The analyzer group ID. |
| RubrikPolaris.SonarAnalyzerGroup.name | String | The name of the analyzer group. |
| RubrikPolaris.SonarAnalyzerGroup.groupType | String | The analyzer group type. |
| RubrikPolaris.SonarAnalyzerGroup.analyzers.id | String | The ID of the analyzers belong to the group. |
| RubrikPolaris.SonarAnalyzerGroup.analyzers.name | String | The name of the analyzers belong to the group. |
| RubrikPolaris.SonarAnalyzerGroup.analyzers.analyzerType | String | The type of the analyzers belong to the group. |

#### Command Example

```!rubrik-sonar-policy-analyzer-groups-list```

#### Human Readable Output

### Sonar Policy Analyzer Groups

|ID|Name|Group Type|Analyzers|
|---|---|---|---|
| 97c6a54a-acfc-5ab2-a24a-6a7f3a9a1553 | GLBA | GLBA | id: ed30dfa0-334f-55ff-a1b7-03b6bdd7849b, Name: Credit Card, Analyzer Type: CREDIT_CARD<br/><br/>id: 3e60a612-3e97-5f03-b3a1-cfb7a6a67e8f, Name: Test Bank Acct, Analyzer Type: US_BANK_ACCT<br/><br/>id: 03b3dc9e-81c1-561c-8235-17cf2fc1c729, Name: US ITIN, Analyzer Type: US_ITIN<br/><br/>id: d5ce3ae5-f530-562a-85b1-4a84264a350a, Name: US SSN, Analyzer Type: US_SSN |
| 543dd5e0-c72c-50e2-a3d9-1688343f472c | HIPAA | HIPAA | id: 9da675b3-944b-5da3-a2da-ed149d300075, Name: US/UK Passport, Analyzer Type: PASSPORT<br/><br/>id: 18665533-c28c-5a40-b747-4b6508fecdfa, Name: US NPI, Analyzer Type: US_HEALTHCARE_NPI<br/><br/>id: 03b3dc9e-81c1-561c-8235-17cf2fc1c729, Name: US ITIN, Analyzer Type: US_ITIN<br/><br/>id: d5ce3ae5-f530-562a-85b1-4a84264a350a, Name: US SSN, Analyzer Type: US_SSN<br/><br/>id: 6bcc8e4e-0ec9-5538-b91d-a506dac47ec6, Name: US DEA, Analyzer Type: DEA_NUMBER |
| 16bd3864-bad6-513b-b38d-a108e648cf4a |  | PCI_DSS |  |
| c8c8072a-9454-5e68-9a23-bbcb9824838e | U.S. Financials | US_FINANCE | id: bb9a929b-3f29-5d3f-a768-de74e8ee5a9c, Name: n/a, Analyzer Type: CUSIP_NUMBER |

### rubrik-polaris-vm-object-metadata-get

***
Retrieve details for a Vsphere object based on the provided object ID.

#### Base Command

`rubrik-polaris-vm-object-metadata-get`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| object_id | The ID of the object to get details.<br/><br/>Note: Users can get the list of the object IDs by executing the "rubrik-polaris-vm-objects-list" command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.VSphereVm.id | String | Unique ID of the object. |
| RubrikPolaris.VSphereVm.metadata.authorizedOperations | Unknown | List of operations performed by the object. |
| RubrikPolaris.VSphereVm.metadata.name | String | The name of the object. |
| RubrikPolaris.VSphereVm.metadata.isRelic | Boolean | Whether the object is relic or not. |
| RubrikPolaris.VSphereVm.metadata.effectiveSlaDomain.id | String | ID of the SLA domain. |
| RubrikPolaris.VSphereVm.metadata.effectiveSlaDomain.name | String | Name of the SLA domain. |
| RubrikPolaris.VSphereVm.metadata.effectiveSlaDomain.cluster.id | String | ID of the cluster of the SLA domain. |
| RubrikPolaris.VSphereVm.metadata.effectiveSlaDomain.cluster.name | String | Name of the cluster of the SLA domain. |
| RubrikPolaris.VSphereVm.metadata.effectiveSlaSourceObject.fid | String | SLA Source object FID. |
| RubrikPolaris.VSphereVm.metadata.effectiveSlaSourceObject.name | String | SLA source object name. |
| RubrikPolaris.VSphereVm.metadata.effectiveSlaSourceObject.objectType | String | SLA source object type. |
| RubrikPolaris.VSphereVm.metadata.protectionDate | String | Protection date of the object. |
| RubrikPolaris.VSphereVm.metadata.reportSnappable.id | String | The ID of the snappable for a particular report related to an object. Snappable supports backups or filesets of physical machines using the rubrik connector. |
| RubrikPolaris.VSphereVm.metadata.reportSnappable.logicalBytes | Number | Logical bytes of snappable report. |
| RubrikPolaris.VSphereVm.metadata.reportSnappable.physicalBytes | Number | The physical byte of the snappable for a particular report related to an object. |
| RubrikPolaris.VSphereVm.metadata.reportSnappable.archiveStorage | Number | The archived storage of the snappable for a particular report related to an object. |
| RubrikPolaris.VSphereVm.metadata.cluster.id | String | Unique ID of the cluster which is the datastore for the recovered virtual machine. |
| RubrikPolaris.VSphereVm.metadata.cluster.name | String | Cluster name of the VM to which the object belongs. |
| RubrikPolaris.VSphereVm.metadata.cluster.status | String | Cluster status of the VM to which the object belongs. |
| RubrikPolaris.VSphereVm.metadata.cluster.version | String | Cluster version of the VM to which the object belongs. |
| RubrikPolaris.VSphereVm.metadata.cluster.lastConnectionTime | String | Last time when the vm was connected to the cluster. |
| RubrikPolaris.VSphereVm.metadata.cluster.defaultAddress | String | Default address where the cluster is stored. |
| RubrikPolaris.VSphereVm.metadata.cluster.clusterNodeConnection.nodes.id | String | Node ID of the node connection related to cluster. |
| RubrikPolaris.VSphereVm.metadata.cluster.clusterNodeConnection.nodes.status | String | Node status of the node connection related to cluster. |
| RubrikPolaris.VSphereVm.metadata.cluster.clusterNodeConnection.nodes.ipAddress | String | IP address of the node connection related to cluster. |
| RubrikPolaris.VSphereVm.metadata.cluster.state.connectedState | String | Connected state of the cluster. |
| RubrikPolaris.VSphereVm.metadata.cluster.state.clusterRemovalState | String | State of the cluster if it is registered for removal or not. |
| RubrikPolaris.VSphereVm.metadata.cluster.passesConnectivityCheck | Boolean | Whether the cluster passes connectivity check or not. |
| RubrikPolaris.VSphereVm.metadata.cluster.globalManagerConnectivityStatus.urls.url | String | URL of Global Manager Connectivity Status. |
| RubrikPolaris.VSphereVm.metadata.cluster.globalManagerConnectivityStatus.urls.isReachable | Boolean | Whether the url in global Manager Connectivity Status is reachable or not. |
| RubrikPolaris.VSphereVm.metadata.cluster.connectivityLastUpdated | String | Date time when the connectivity status of the cluster is lastly updated. |
| RubrikPolaris.VSphereVm.metadata.primaryClusterLocation.id | String | The location ID of the primary cluster to which the object belongs. |
| RubrikPolaris.VSphereVm.metadata.primaryClusterLocation.name | String | The location name of the primary cluster to which the object belongs. |
| RubrikPolaris.VSphereVm.metadata.arrayIntegrationEnabled | Boolean | Whether the array integration is enabled or not. |
| RubrikPolaris.VSphereVm.metadata.snapshotConsistencyMandate | String | Data consistency in recovery points is the snapshot consistency mandate. It is broadly classified into 3 categories: inconsistent, crash-consistent, app-consistent. |
| RubrikPolaris.VSphereVm.metadata.agentStatus.agentStatus | String | The status of an agent related to an object. In Rubrik agents are connectors also known as Rubrik Backup Service. |
| RubrikPolaris.VSphereVm.metadata.logicalPath.fid | String | The logical path ID of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.metadata.logicalPath.objectType | String | The logical object type of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.metadata.logicalPath.name | String | The logical name of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.metadata.physicalPath.fid | String | The physical path of where the VM resides. |
| RubrikPolaris.VSphereVm.metadata.physicalPath.objectType | String | The physical path object type of the VM. |
| RubrikPolaris.VSphereVm.metadata.physicalPath.name | String | The physical Name of the VM. |
| RubrikPolaris.VSphereVm.metadata.vsphereTagPath.fid | String | FID of Vsphere tag. |
| RubrikPolaris.VSphereVm.metadata.vsphereTagPath.objectType | String | Object type of Vsphere tag. |
| RubrikPolaris.VSphereVm.metadata.vphereTagPath.name | String | Name of Vsphere tag. |
| RubrikPolaris.VSphereVm.metadata.oldestSnapshot.id | String | The ID of the oldest snapshot. |
| RubrikPolaris.VSphereVm.metadata.oldestSnapshot.date | String | The date when the oldest snapshot was generated. |
| RubrikPolaris.VSphereVm.metadata.oldestSnapshot.isIndexed | Boolean | Whether the oldest snapshot is indexed or not. |
| RubrikPolaris.VSphereVm.metadata.totalSnapshots.count | Number | Total snapshot counts. |
| RubrikPolaris.VSphereVm.metadata.replicatedObjects.id | String | The ID of the object which is replicated in the VM. |
| RubrikPolaris.VSphereVm.metadata.replicatedObjects.primaryClusterLocation.id | String | The primary cluster location ID where the replicated object resides. |
| RubrikPolaris.VSphereVm.metadata.replicatedObjects.primaryClusterLocation.name | String | The primary cluster location name where the replicated object resides. |
| RubrikPolaris.VSphereVm.metadata.replicatedObjects.cluster.name | String | The cluster name where the replicated object resides. |
| RubrikPolaris.VSphereVm.metadata.replicatedObjects.cluster.id | String | The cluster ID where the replicated object resides. |
| RubrikPolaris.VSphereVm.metadata.newestArchivedSnapshot.id | String | ID of the newest archived snapshot. |
| RubrikPolaris.VSphereVm.metadata.newestArchivedSnapshot.date | String | The date when the newest archived snapshot was generated. |
| RubrikPolaris.VSphereVm.metadata.newestArchivedSnapshot.isIndexed | Boolean | Whether the newest archived snapshot is indexed or not. |
| RubrikPolaris.VSphereVm.metadata.newestArchivedSnapshot.archivalLocations.id | String | ID of the archival location of the newest archived snapshot. |
| RubrikPolaris.VSphereVm.metadata.newestArchivedSnapshot.archivalLocations.name | String | Name of the archival location of the newest archival snapshot. |
| RubrikPolaris.VSphereVm.metadata.newestReplicatedSnapshot.id | String | The ID of the newest replicated snapshot. |
| RubrikPolaris.VSphereVm.metadata.newestReplicatedSnapshot.date | String | The date when the newest replicated snapshot was generated. |
| RubrikPolaris.VSphereVm.metadata.newestReplicatedSnapshot.isIndexed | Boolean | Whether the newest replicated snapshot is indexed or not. |
| RubrikPolaris.VSphereVm.metadata.newestReplicatedSnapshot.replicationLocations.id | String | The ID of the replication locations of the newest replicated snapshot. |
| RubrikPolaris.VSphereVm.metadata.newestReplicatedSnapshot.replicationLocations.name | String | The name of the replication locations of the newest replicated snapshot. |
| RubrikPolaris.VSphereVm.metadata.newestSnapshot.id | String | The ID of the newest snapshot. |
| RubrikPolaris.VSphereVm.metadata.newestSnapshot.date | String | The date when the newest snapshot was generated. |
| RubrikPolaris.VSphereVm.metadata.newestSnapshot.isIndexed | Boolean | Whether the newest snapshot is indexed or not. |
| RubrikPolaris.VSphereVm.metadata.onDemandSnapshotCount | Number | Count of how many on demand snapshot created in a VM. |
| RubrikPolaris.VSphereVm.metadata.vmwareToolsInstalled | Boolean | Whether the Vmware tools are installed or not. |
| RubrikPolaris.VSphereVm.metadata.cdmLink | String | The Cloud Data Management link to navigate to the VM on cloud. |

#### Command Example

```!rubrik-polaris-vm-object-metadata-get object_id="e060116b-f9dc-56a1-82a6-1b968d2f6cef"```

#### Human Readable Output

### VM Object Data

|Object ID|Name|Snappable ID|SLA Domain|Cluster Name|Total Snapshots|Oldest Snapshot Date|Latest Snapshot Date|
|---|---|---|---|---|---|---|---|
| e060116b-f9dc-56a1-82a6-1b968d2f6cef | Kali-VM | VirtualMachine:::ae4484c6-b4c0-4ce8-b2ba-206a4184540b-vm-521 | DO_NOT_PROTECT | sand2-rbk01 | 42 | 2019-04-24T16:21:12.000Z | 2020-02-12T14:00:36.000Z |

### rubrik-polaris-vm-objects-list

***
Retrieve a list of all the objects of the Vsphere Vm known to the Rubrik.

#### Base Command

`rubrik-polaris-vm-objects-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| is_relic | Filter based on whether VM objects are moved to relic/archive or not.<br/><br/>Possible values are: "True", "False". | Optional |
| is_replicated | Filter based on whether VM objects are replicated or not.<br/><br/>Possible values are: "True", "False". | Optional |
| limit | Number of results to retrieve in the response. Maximum size allowed is 1000. Default is 50. | Optional |
| sort_by | Specify the field to use for sorting the response.<br/><br/>Note: Supported values are "ID" and "NAME" only. For any other values, the obtained result is sorted or not is not confirmed. Default is ID. | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "ASC", "DESC". Default is ASC. | Optional |
| next_page_token | The next page cursor to retrieve the next set of results. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.VSphereVm.id | String | Unique ID of the object. |
| RubrikPolaris.VSphereVm.name | String | Name of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.objectType | String | Object type of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.replicatedObjectCount | Number | Number of objects replicated in the node in which the object relies. |
| RubrikPolaris.VSphereVm.cluster.id | String | ID of the cluster which is the datastore for the recovered virtual machine. |
| RubrikPolaris.VSphereVm.cluster.name | String | Cluster name of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.cluster.version | String | Cluster version of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.cluster.status | String | Cluster status of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.effectiveSlaDomain.id | String | ID of the SLA domain which is simply a set of policies that define at what frequencies backups should be performed of the protected objects within Rubrik and for how long they should be either locally or a replication partner or on the archival location. |
| RubrikPolaris.VSphereVm.effectiveSlaDomain.name | String | Descriptive name of the SLA domain. |
| RubrikPolaris.VSphereVm.effectiveSlaDomain.description | String | Description of the SLA domain. |
| RubrikPolaris.VSphereVm.effectiveSlaDomain.fid | String | FID of the SLA domain. |
| RubrikPolaris.VSphereVm.effectiveSlaDomain.cluster.id | String | ID of the cluster related to the effective SLA domain. |
| RubrikPolaris.VSphereVm.effectiveSlaDomain.cluster.name | String | Name of the cluster related to the effective SLA domain. |
| RubrikPolaris.VSphereVm.effectiveSlaSourceObject.fid | String | SLA source object FID. |
| RubrikPolaris.VSphereVm.effectiveSlaSourceObject.name | String | SLA source object name. |
| RubrikPolaris.VSphereVm.effectiveSlaSourceObject.objectType | String | SLA source object type. |
| RubrikPolaris.VSphereVm.slaAssignment | String | A SLA rule when referred at assignment is SLA assignment. |
| RubrikPolaris.VSphereVm.isRelic | Boolean | Whether the object is relic or not. |
| RubrikPolaris.VSphereVm.authorizedOperations | Unknown | List of operations that can be performed on the object. |
| RubrikPolaris.VSphereVm.primaryClusterLocation.id | String | The location ID of the primary cluster to which the object belongs. |
| RubrikPolaris.VSphereVm.primaryClusterLocation.name | String | The location name of the primary cluster to which the object belongs. |
| RubrikPolaris.VSphereVm.logicalPath.fid | String | The logical path ID of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.logicalPath.name | String | The logical path name of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.logicalPath.objectType | String | The logical object type of the node to which the object belongs. |
| RubrikPolaris.VSphereVm.snapshotDistribution.id | String | Rubrik uses a snapshot for powerful data protection. Snapshot distribution ID is the ID of the snapshot distribution node related to a particular object. |
| RubrikPolaris.VSphereVm.snapshotDistribution.onDemandCount | Number | The demand count of distribution of snapshot related to an object. |
| RubrikPolaris.VSphereVm.snapshotDistribution.retrievedCount | Number | The retrieved count of distribution of snapshot related to an object. |
| RubrikPolaris.VSphereVm.snapshotDistribution.scheduledCount | Number | The scheduled count of distribution of snapshot related to an object. |
| RubrikPolaris.VSphereVm.snapshotDistribution.totalCount | Number | The total count of distribution of snapshot related to an object. |
| RubrikPolaris.VSphereVm.reportSnappable.id | String | The ID of the snappable for a particular report related to an object. Snapple supports backups or filesets of physical machines using the rubrik connector. |
| RubrikPolaris.VSphereVm.reportSnappable.archieveStorage | Number | The archived storage of the snappable for a particular report related to an object. |
| RubrikPolaris.VSphereVm.reportSnappable.physicalBytes | Number | The physical byte of the snappable for a particular report related to an object. |
| RubrikPolaris.VSphereVm.vmwareToolsInstalled | Boolean | Whether the vm tools are installed or not. |
| RubrikPolaris.VSphereVm.agentStatus.agentStatus | String | The status of an agent related to an object. The Rubrik agents are connectors also known as Rubrik Backup Service. |
| RubrikPolaris.VSphereVm.agentStatus.disconnectReason | String | Displays the reason if the agent disconnects. |
| RubrikPolaris.PageToken.VSphereVm.next_page_token | String | Next page token. |
| RubrikPolaris.PageToken.VSphereVm.name | String | Name of the command. |
| RubrikPolaris.PageToken.VSphereVm.has_next_page | Boolean | Whether the result has the next page or not. |

#### Command Example

```!rubrik-polaris-vm-objects-list limit=2```

#### Human Readable Output

### Objects List

|Object ID|Name|Snappable ID|Cluster|Object Type|SLA Domain|Assignment|Snapshots|RBS Status|Source Storage|Archival Storage|
|---|---|---|---|---|---|---|---|---|---|---|
| 0242e84c-773a-5877-b955-1d52765ac852 | sx1-ganebala-l1 | VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-206037 | sand1-rbk01 | VmwareVirtualMachine | DO_NOT_PROTECT | Direct | 0 | Unregistered | 0 | 0 |
| 0556f691-b750-556c-baea-800dbb2920e7 | linux-a-Fri Feb 15 2019 04:43:40 GMT+0000 (Greenwich Mean Time)-9P4t | VirtualMachine:::d2f41f4b-5d53-4063-a618-25046a0f4c7d-vm-35806 | sand1-rbk01 | VmwareVirtualMachine | UNPROTECTED | Unassigned | 34 | Unregistered | 0 | 1.115023609 GB |

 Note: To retrieve the next set of results use, "next_page_token" = xyz

### rubrik-sonar-ondemand-scan

***
Trigger an on-demand scan of a system. Supports "Vsphere VM" object type only.

Note: To know the scan status use the "rubrik-sonar-ondemand-scan-status" command. To download the completed request use the "rubrik-sonar-ondemand-scan-result" command.

#### Base Command

`rubrik-sonar-ondemand-scan`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| scan_name | Name of the scan. If not provided, it defaults to "&lt;today's date&gt; Classification". | Optional |
| sonar_policy_analyzer_groups | List of sonar policies to scan.<br/><br/>Note: Users can get the list of analyzer groups by executing the "rubrik-sonar-policy-analyzer-groups-list" command. <br/><br/>Format Accepted: <br/>[<br/>        {<br/>            "id": "543dd5e0-c72c-50e2-a3d9-1688343f472c",<br/>            "name": "HIPAA",<br/>            "groupType": "HIPAA",<br/>            "analyzers": [<br/>                {<br/>                    "id": "9da675b3-944b-5da3-a2da-ed149d300075",<br/>                    "name": "US/UK Passport",<br/>                    "analyzerType": "PASSPORT"<br/>                },<br/>                {<br/>                    "id": "18665533-c28c-5a40-b747-4b6508fecdfa",<br/>                    "name": "US NPI",<br/>                    "analyzerType": "US_HEALTHCARE_NPI"<br/>                }<br/>            ]<br/>      }<br/>]. | Required |
| objects_to_scan | List of VM object IDs to scan.<br/><br/>Note: Users can get the list of VM object IDs by executing the "rubrik-polaris-vm-objects-list" command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.SonarOndemandScan.crawlId | String | Unique crawl ID. |

#### Command Example

```!rubrik-sonar-ondemand-scan scan_name="GLBA Scan for new user" sonar_policy_analyzer_groups='[{"id":"97c6a54a-acfc-5ab2-a24a-6a7f3a9a1553","name":"GLBA","groupType":"GLBA","analyzers":[{"id":"ed30dfa0-334f-55ff-a1b7-03b6bdd7849b","name":"CreditCard","analyzerType":"CREDIT_CARD"},{"id":"3e60a612-3e97-5f03-b3a1-cfb7a6a67e8f","name":"BANK_ACCT","analyzerType":"US_BANK_ACCT"},{"id":"03b3dc9e-81c1-561c-8235-17cf2fc1c729","name":"USITIN","analyzerType":"US_ITIN"},{"id":"d5ce3ae5-f530-562a-85b1-4a84264a350a","name":"USSSN","analyzerType":"US_SSN"}]}]' objects_to_scan="0887e71c-56ac-59f7-8763-54b726e64dd6, a82e888c-2440-5af9-8c2a-447a97f6746c"```

#### Human Readable Output

### Sonar On-Demand Scan

|Crawl ID|
|---|
| bb4eedc0-594b-4566-b06d-24de0bf752ca |

### rubrik-sonar-ondemand-scan-status

***
Retrieve the status of a scanned system.

Note: To download the completed request use the "rubrik-sonar-ondemand-scan-result" command.

#### Base Command

`rubrik-sonar-ondemand-scan-status`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| crawl_id | ID for which scanning status is to be obtained.<br/><br/>Note: Users can get the crawl ID by executing the "rubrik-sonar-ondemand-scan" command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.SonarOndemandScan.crawlId | String | Crawl ID of the scan for which the rubrik-sonar-ondemand-scan command is hit. |
| RubrikPolaris.SonarOndemandScan.Status.error | String | Error description if any. |
| RubrikPolaris.SonarOndemandScan.Status.snappable.id | String | Snappable ID of the scanned object. |
| RubrikPolaris.SonarOndemandScan.Status.snappable.name | String | Snappable Name of the scanned object. |
| RubrikPolaris.SonarOndemandScan.Status.snappable.objectType | String | Snappable object type of the scanned object. |
| RubrikPolaris.SonarOndemandScan.Status.snapshotTime | Number | Time when the snapshot is taken. |
| RubrikPolaris.SonarOndemandScan.Status.status | String | Status of the scanning or scanned object. |
| RubrikPolaris.SonarOndemandScan.Status.progress | Number | Count of objects that are in progress. |
| RubrikPolaris.SonarOndemandScan.Status.totalHits | Number | Number of total hits obtained from an object that is scanned. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.analyzerGroup.groupType | String | Group type of the analyzer. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.analyzerGroup.id | String | Group ID of the analyzer. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.analyzerGroup.name | String | Group Name of the analyzer. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.analyzerResults.hits.totalHits | Number | Number of total hits obtained from an analyzer that is scanned. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.analyzerResults.hits.violations | Number | Number of violations obtained from an analyzer that is scanned. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.analyzerResults.hits.permittedHits | Number | Number of permitted hits obtained from an analyzer that is scanned. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.analyzerResults.analyzer.id | String | ID of the analyzer that is scanned. |
| RubrikPolaris.SonarOndemandScan.Status.analzerGroupResults.analyzerResults.analyzer.name | String | Name of the analyzer that is scanned. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.analyzerResults.analyzer.analyzerType | String | Type of the analyzer that is scanned. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.hits.totalHits | Number | Number of total hits obtained from an analyzer group. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.hits.violations | Number | Number of violations obtained from an analyzer group. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.hits.permittedHits | Number | Number of permitted hits obtained from an analyzer group. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.hits.violationsDelta | Number | Number of violation delta obtained from an analyzer group. |
| RubrikPolaris.SonarOndemandScan.Status.analyzerGroupResults.hits.totalHitsDelta | Number | Number of total hits delta obtained from an analyzer group. |
| RubrikPolaris.SonarOndemandScan.Status.cluster.id | String | Cluster ID in which the object is getting scanned. |
| RubrikPolaris.SonarOndemandScan.Status.cluster.name | String | Cluster name in which the object is getting scanned. |
| RubrikPolaris.SonarOndemandScan.Status.cluster.type | String | Cluster type in which the object is getting scanned. |

#### Command Example

```!rubrik-sonar-ondemand-scan-status crawl_id="bb4eedc0-594b-4566-b06d-24de0bf752ca"```

#### Human Readable Output

### Sonar On-Demand Scan Status

Final status of scan with crawl ID bb4eedc0-594b-4566-b06d-24de0bf752ca is IN_PROGRESS

|Object ID|Object Name|Scan Status|
|---|---|---|
| 6e307121-e5dc-5e6a-9a6b-37e1c9afd6b1 | AllTheThings | COMPLETE |
| a82e888c-2440-5af9-8c2a-447a97f6746c | /tmp | IN_PROGRESS |

### rubrik-polaris-vm-object-snapshot-list

***
Search for a Rubrik snapshot of an object based on the provided snapshot ID, exact timestamp, or specific value like earliest/latest, or closest before/after a timestamp.

#### Base Command

`rubrik-polaris-vm-object-snapshot-list`

#### Input

| **Argument Name** | **Description**                                                                                                                                                                                              | **Required** |
| --- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- |
| object_id | The object ID for which the snapshots are to be searched.<br/><br/>Note: Users can get the list of the object IDs by executing the "rubrik-polaris-vm-objects-list" command.                                 | Required |
| snapshot_group_by | Grouping the snapshots on the basis of the selected value.<br/><br/>Possible values are: "Month", "Day", "Year", "Week", "Hour", "Quarter". Default is Day.                                                  | Optional |
| missed_snapshot_group_by | Grouping the missed snapshots on the basis of the selected value.<br/><br/>Possible values are: "MONTH", "DAY", "YEAR", "WEEK", "HOUR", "QUARTER". Default is DAY.                                           | Optional |
| start_date | The start date to get snapshots from.<br/><br/>Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.                                              | Required |
| end_date | The end date to get snapshots until.<br/><br/>Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.                                               | Required |
| timezone_offset | The timezone offset from UTC changes to match the configured time zone. Use this argument to filter the data according to the provided timezone offset.<br/><br/>Formats accepted: 1, 1.5, 2, 2.5, 5.5, etc. | Required |
| cluster_connected | Whether the cluster is connected or not.<br/><br/>Possible values are: "True", "False". Default is True.                                                                                                     | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.VSphereVm.id | String | Unique ID of the object. |
| RubrikPolaris.VSphereVm.Snapshot.snapshotGroupByConnection.nodes.groupByInfo.unit | String | Unit of snapshot group by connection nodes. |
| RubrikPolaris.VSphereVm.Snapshot.snapshotGroupByConnection.nodes.groupByInfo.start | String | Start date of snapshot group by connection nodes. |
| RubrikPolaris.VSphereVm.Snapshot.snapshotGroupByConnection.nodes.groupByInfo.end | String | End date of snapshot group by connection nodes. |
| RubrikPolaris.VSphereVm.Snapshot.snapshotGroupByConnection.nodes.snapshotConnection.count | Number | Count of snapshot connections related to the object. |
| RubrikPolaris.VSphereVm.Snapshot.snapshotGroupByConnection.nodes.snapshotConnection.nodes.id | String | ID of snapshot connection related to the object. |
| RubrikPolaris.VSphereVm.Snapshot.snapshotGroupByConnection.nodes.snapshotConnection.nodes.isIndexed | Boolean | Whether the node is indexed or not. |
| RubrikPolaris.VSphereVm.Snapshot.snapshotGroupByConnection.nodes.snapshotConnection.nodes.isUnindexable | Boolean | Whether the node is unindexable or not. |

#### Command Example

```!rubrik-polaris-vm-object-snapshot-list object_id="86db05d1-292f-5973-b616-2ae3977f4428" start_date="2020-05-19T18:30:00.000000Z" end_date="2020-05-20T18:30:00.000000Z" timezone_offset=5.5```

#### Human Readable Output

### VM Object Snapshots

|Snapshot Details|Snapshot IDs|
|---|---|
| Total Snapshots: 2<br/>Date Range: From 2020-05-19T22:30:00.000Z to 2020-05-20T22:29:59.999Z | 33060f59-9c99-5c48-8305-8d1edfe402d2,<br/>57eac609-9529-5cb5-845a-b7cc78998222 |

### rubrik-sonar-ondemand-scan-result

***
Retrieve the download link for the requested scanned file.

#### Base Command

`rubrik-sonar-ondemand-scan-result`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| crawl_id | ID for which file needs to be downloaded.<br/><br/>Note: Users can get the crawl_id by executing the "rubrik-sonar-ondemand-scan" command. | Required |
| file_type | The type of the file that needs to be downloaded.<br/><br/>Possible values are: "ANY", "HITS", "STALE", "OPEN_ACCESS", "STALE_HITS", "OPEN_ACCESS_HITS". | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.SonarOndemandScan.crawlId | String | Crawl ID of the file that needs to be downloaded. |
| RubrikPolaris.SonarOndemandScan.Result.downloadLink | String | Link to download the file when scan status is complete. |

#### Command Example

```!rubrik-sonar-ondemand-scan-result crawl_id="bb4eedc0-594b-4566-b06d-24de0bf752ca" file_type="HITS"```

#### Human Readable Output

### Sonar On-Demand Scan Result

|Scan result CSV Download Link|
|---|
| Download the [CSV](https://www.example.com/csv_file) file to see the result. |

### rubrik-radar-anomaly-csv-analysis

***
Request for the analysis and retrieve the download link or directly download file for the Radar CSV analyzed file.

#### Base Command

`rubrik-radar-anomaly-csv-analysis`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| cluster_id | The unique ID of the cluster.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command. | Required |
| snapshot_id | The CDM snapshot ID.<br/><br/>Note: Users can retrieve the list of snapshot IDs by executing the "rubrik-polaris-vm-object-snapshot-list" command.<br/>Use the "rubrik-radar-suspicious-file-list" command to retrieve the actual CDM ID from the Anomaly ID.<br/>Example format to get the snapshot CDM ID from Anomaly ID: "&lt;Cluster-ID&gt;:::VirtualMachine:::&lt;Snappable-ID&gt;:::&lt;CDM-ID&gt;". | Required |
| object_id | The VM object ID (Snappable ID).<br/><br/>Note: Users can retrieve the list of Snappable IDs by executing the "rubrik-polaris-vm-objects-list" command.<br/>Example format to get the Snappable ID: "VirtualMachine:::&lt;Snappable-ID&gt;". | Required |
| download_file | If set to True, the command downloads the anomaly analysis CSV file directly on XSOAR server.<br/><br/>Possible values are: True, False. Default is False. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.RadarAnomalyCSV.clusterId | String | Cluster ID of the CSV. |
| RubrikPolaris.RadarAnomalyCSV.snapshotId | String | Snapshot ID of the CSV. |
| RubrikPolaris.RadarAnomalyCSV.objectId | String | Object ID of the CSV. |
| RubrikPolaris.RadarAnomalyCSV.investigationCsvDownloadLink.downloadLink | String | The download link of the CSV analysis. |
| File.Size | String | File size in bytes. |
| File.SHA1 | String | SHA1 hash of file. |
| File.SHA256 | String | SHA256 hash of file. |
| File.SHA512 | String | SHA512 hash of file. |
| File.Name | String | File name. |
| File.SSDeep | String | SSDeep hash of the file. |
| File.EntryID | Unknown | The entry ID of the file. |
| File.Info | String | File information. |
| File.Type | String | The file type. |
| File.MD5 | String | MD5 hash of the file. |
| File.Extension | String | The file extension. |

#### Command Example

```!rubrik-radar-anomaly-csv-analysis cluster_id="0000-000-000-000-0000" snapshot_id="0000-000-000-000-0000" object_id="0000-000-000-000-vm-0000" download_file=True```

#### Human Readable Output
>
>### Radar Anomaly CSV Analysis
>
>|CSV Download Link|
>|---|
>| Download the analyzed [CSV](https://www.example.com/snapshot_000-000-000-000.csv) file. |

>Uploaded file: snapshot_000-000-000-000.csv Download
>
>|Property|Value|
>|---|---|
>| Type | text/csv; charset=utf-8 |
>| Size | 10,069 bytes |
>| Info | ASCII text, with very long lines |
>| MD5 | 10000000000000000000000000 |
>| SHA1 | 1000000000000000000000000000000 |
>| SHA256 | 1000000000000000000000000000000000000000000000000000000000 |
>| SHA512 | 10000000000000000000000000000000000000000000000000000000000000000000000 |
>| SSDeep | 1:100000000000000000000000000000000000000000000000000000000: |

### rubrik-sonar-csv-download

***
Request to download the Sonar CSV Snapshot results file.

Note: To know the ID and status of the download, use the "rubrik-user-downloads-list" command. To download the file, use the "rubrik-sonar-csv-result-download" command.

#### Base Command

`rubrik-sonar-csv-download`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| snapshot_id | ID of the snapshot.<br/><br/>Note: Users can retrieve the list of snapshot IDs by executing the "rubrik-polaris-vm-object-snapshot-list"  command. | Required |
| object_id | Object ID.<br/><br/>Note: Users can retrieve the list of object IDs by executing "rubrik-polaris-vm-objects-list" command. | Required |
| file_type | The type of the file that needs to be downloaded.<br/><br/>Possible values are: "ANY", "HITS", "STALE", "OPEN_ACCESS", "STALE_HITS", "OPEN_ACCESS_HITS". | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.SonarCSVDownload.snapshotId | String | Snapshot ID of the CSV requested to download. |
| RubrikPolaris.SonarCSVDownload.objectId | String | Object ID of the CSV requested to download. |
| RubrikPolaris.SonarCSVDownload.downloadSnapshotResultsCsv.isSuccessful | Boolean | The status of the download. |

#### Command Example

```!rubrik-sonar-csv-download snapshot_id="c38ec074-0c45-5c72-b611-3322cbd46776" object_id="ac0a6844-a2fc-52b0-bb71-6a55f43677be"```

#### Human Readable Output

### Sonar CSV Download

|Download Status|
|---|
| Success |

### rubrik-gps-snapshot-files-list

***
Retrieve the list of the available files that can be downloaded.

Note: To initiate the file download request use the "rubrik-gps-snapshot-files-download" command.

#### Base Command

`rubrik-gps-snapshot-files-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| snapshot_id | The Snapshot ID of the file that needs to be downloaded.<br/><br/>Note: Users can retrieve the list of the snapshot IDs by executing the "rubrik-polaris-vm-object-snapshot-list" command. | Required |
| path | The path of the folder to list the sub-files. If not provided the root directory files will be returned.<br/><br/>Format accepted : "/&lt;directory name&gt;/&lt;sub directory name or file name&gt;"<br/><br/>Example: "/C:", "/C:/Users". | Optional |
| search_prefix | Provide a keyword to search in the file names.<br/><br/>Example: "admin". | Optional |
| limit | Number of results to retrieve in the response. Maximum size allowed is 1000. Default is 50. | Optional |
| next_page_token | The next page cursor to retrieve the next set of results. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSSnapshotFile.snapshotId | String | Snapshot ID provided as an argument to retrieve the files. |
| RubrikPolaris.GPSSnapshotFile.node.absolutePath | String | The absolute path of the file. |
| RubrikPolaris.GPSSnapshotFile.node.displayPath | String | The display path of the file. |
| RubrikPolaris.GPSSnapshotFile.node.path | String | The path of the file. |
| RubrikPolaris.GPSSnapshotFile.node.filename | String | The name of the file. |
| RubrikPolaris.GPSSnapshotFile.node.fileMode | String | The mode of the file. |
| RubrikPolaris.GPSSnapshotFile.node.size | String | The size of the file. |
| RubrikPolaris.GPSSnapshotFile.node.lastModified | String | The last modified time of the file. |
| RubrikPolaris.PageToken.GPSSnapshotFile.next_page_token | String | Next page token. |
| RubrikPolaris.PageToken.GPSSnapshotFile.name | String | Name of the command. |
| RubrikPolaris.PageToken.GPSSnapshotFile.has_next_page | Boolean | Whether the result has the next page or not. |

#### Command Example

```!rubrik-gps-snapshot-files-list snapshot_id=90858c2f-e572-5b9c-b455-ba309d50c1a2```

#### Human Readable Output

### GPS Snapshot Files

|File Name|Absolute Path|Path|File Mode|Last Modified|
|---|---|---|---|---|
| C: | /C: | C: | DIRECTORY | 2020-10-05T18:56:18.000Z |
| disk_0_part_1 | /disk_0_part_1 |  | DIRECTORY | 2018-06-14T00:47:18.000Z |

Note: To retrieve the next set of results use, "next_page_token" = xyz

### rubrik-gps-vm-export

***
Request to initiate an export of a snapshot of a virtual machine.

Note: To know about the exported VM's status, use the "rubrik-gps-async-result" command.

#### Base Command

`rubrik-gps-vm-export`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| vm_name | Name given to the VM that runs the snapshot. If not provided the name will be "&lt;Snapshot VM Name&gt; &lt;MM/DD of snapshot creation&gt; &lt;hh/mm of snapshot creation&gt; &lt;Num&gt;". | Optional |
| object_id | The VM object ID whose snapshot needs to be exported.<br/><br/>Note: Users can get the list of object IDs by executing the "rubrik-polaris-vm-objects-list" command. | Required |
| snapshot_id | The ID of the snapshot that is to be exported.<br/><br/>Note: Users can get the list of snapshot IDs by executing the "rubrik-polaris-vm-object-snapshot-list" command. | Required |
| datastore_id | The ID of the datastore which will be used by the new VM.<br/><br/>Note: Users can get the list of  datastore IDs by executing the "rubrik-gps-vm-datastore-list" command. | Required |
| host_id | The ID of the Vsphere ESXi host on which the new VM will be made. Either host_id or host_compute_cluster_id must be provided.<br/><br/>Note: Users can get the list of host IDs by executing the "rubrik-gps-vm-host-list" command. | Optional |
| host_compute_cluster_id | The ID of the VSphere Compute Cluster of a host. Either host_id or host_compute_cluster_id must be provided. <br/><br/>Note: Users can get the list of Compute Cluster IDs by executing the "rubrik-gps-vm-host-list" command. The ID must belong to the VSphereComputeCluster objectType. | Optional |
| power_on | Whether to turn on the new VM or not.<br/><br/>Possible values are: "True", "False". | Optional |
| keep_mac_addresses | Whether the mac addresses of network devices of the new VM be removed or not.<br/><br/>Possible values are: "True", "False". | Optional |
| remove_network_devices | Whether the network devices on the original VM be kept or not.<br/><br/>Possible values are: "True", "False". | Optional |
| recover_tags | Whether to keep vSphere tags associated with the original VM or not.<br/><br/>Possible values are: "True", "False". | Optional |
| disable_network | Whether to disable networking on the new VM or not.<br/><br/>Possible values are: "True", "False". | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSVMSnapshotExport.id | String | Snapshot export request ID. |

#### Command Example

```!rubrik-gps-vm-export object_id=d39e956f-a3c9-5307-865b-58ed045b59c5 snapshot_id=07fa66e1-137a-5473-8a8e-825547075d7b datastore_id=5fe3a92a-d848-5325-a1a2-ef6cf7a16376 host_compute_cluster_id=0dc88a78-0d46-57d7-86c6-f1bd97ff979f```

#### Human Readable Output

### GPS VM Export

|Snapshot Export Request ID|
|---|
| dummy_id |

### rubrik-user-downloads-list

***
Retrieve the user downloads. This would return the current and past download history.

Note: To download the requested Sonar CSV Snapshot results file use the "rubrik-sonar-csv-result-download" command.

#### Base Command

`rubrik-user-downloads-list`

#### Input

There are no input arguments for this command.

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.UserDownload.id | Number | The ID of the download. |
| RubrikPolaris.UserDownload.name | String | The name of the download. |
| RubrikPolaris.UserDownload.status | String | The status of the download. |
| RubrikPolaris.UserDownload.progress | Number | The progress of the download. |
| RubrikPolaris.UserDownload.identifier | String | The identifier of the download or the type of download requested. |
| RubrikPolaris.UserDownload.createTime | String | The creation time of the download. |
| RubrikPolaris.UserDownload.completeTime | String | The completion time of the download. |

#### Command Example

```!rubrik-user-downloads-list```

#### Human Readable Output

### User Downloads

|Download ID|Name|Status|Identifier|Creation Time|Completion Time|
|---|---|---|---|---|---|
| 156 | GDIT-billing-test-oct10 | COMPLETED | SONAR_DOWNLOAD | 2021-10-06T07:25:51.676432470Z | 2021-10-06T07:25:51.856374014Z |

### rubrik-gps-sla-domain-list

***
Enumerates the available SLA Domains to apply to the on-demand snapshot as a retention policy.

#### Base Command

`rubrik-gps-sla-domain-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| name | Name of the SLA Domain to search for. | Optional |
| cluster_id | Cluster, the SLA domain is managed by.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command. | Optional |
| object_type | Filters SLA domain based on the provided object types. Supports comma separated values. <br/><br/>Possible values are: "FILESET_OBJECT_TYPE", "VSPHERE_OBJECT_TYPE". | Optional |
| show_cluster_slas_only | Whether to show Cluster SLAs and not Global SLAs. "False" value will result in showing only Global SLAs. <br/><br/>Possible values are: "True", "False". Default is True. | Optional |
| sort_by | Specify the field to use for sorting the response.<br/><br/>Possible values are: "NAME", "PROTECTED_OBJECT_COUNT". Default is NAME. | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "ASC", "DESC". Default is ASC. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSSLADomain.name | String | Name of the SLA domain. |
| RubrikPolaris.GPSSLADomain.id | String | ID of the SLA domain. |
| RubrikPolaris.GPSSLADomain.description | String | Description of the SLA domain. |
| RubrikPolaris.GPSSLADomain.protectedObjectCount | Number | Number of objects under the SLA Domain. |
| RubrikPolaris.GPSSLADomain.baseFrequency.duration | Number | Base snapshot frequency duration. |
| RubrikPolaris.GPSSLADomain.baseFrequency.unit | String | Base snapshot frequency unit \(HOURS, DAYS etc\). |
| RubrikPolaris.GPSSLADomain.archivalSpec.archivalLocationName | String | Location where the archives are stored. |
| RubrikPolaris.GPSSLADomain.archivalSpecs.storageSetting.id | String | ID of the archival target. |
| RubrikPolaris.GPSSLADomain.archivalSpecs.storageSetting.name | String | Name of the archival target. |
| RubrikPolaris.GPSSLADomain.archivalSpecs.storageSetting.groupType | String | Group type of the archival target. |
| RubrikPolaris.GPSSLADomain.archivalSpecs.storageSetting.targetType | String | Target type of the archival target. |
| RubrikPolaris.GPSSLADomain.replicationSpec.replicationType | String | Enum value representing the type of replication. Values: UNKNOWN_REPLICATION_TYPE, UNIDIRECTIONAL_REPLICATION_TO_CLUSTER, REPLICATION_TO_CLOUD_REGION, REPLICATION_TO_CLOUD_LOCATION. |
| RubrikPolaris.GPSSLADomain.replicationSpec.specificReplicationSpec.unidirectionalSpec.replicationTargetName | String | Cloud replication target name. |
| RubrikPolaris.GPSSLADomain.replicationSpec.specificReplicationSpec.cloudRegionSpec.replicationTargetRegion | String | Cloud replication target region. |
| RubrikPolaris.GPSSLADomain.replicationSpec.specificReplicationSpec.cloudRegionSpec.cloudProvider | String | Cloud replication service provider. Values:  AWS, AZURE. |
| RubrikPolaris.GPSSLADomain.replicationSpec.specificReplicationSpec.cloudLocationSpec.targetMapping.id | String | ID of the cloud target where replication takes place. |
| RubrikPolaris.GPSSLADomain.replicationSpec.specificReplicationSpec.cloudLocationSpec.targetMapping.name | String | Name of the cloud target where replication takes place. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.cluster.id | String | ID of the cluster where replication takes place. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.cluster.name | String | Name of the cluster where replication takes place. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.awsTarget.accountId | String | Account ID on AWS where the replication happens. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.awsTarget.accountName | String | Account name on AWS where the replication happens. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.awsTarget.region | String | Account region on AWS where the replication happens. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.azureTarget.region | String | Account region on Azure where the replication happens. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.retentionDuration.duration | Number | Replication retention duration. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.retentionDuration.unit | String | Replication retention duration unit. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.targetMapping.id | String | ID of the object target where replication takes place. |
| RubrikPolaris.GPSSLADomain.replicationSpecsV2.targetMapping.name | String | Name of the object target where replication takes place. |
| RubrikPolaris.GPSSLADomain.localRetentionLimit.duration | Number | Local retention limit duration. |
| RubrikPolaris.GPSSLADomain.localRetentionLimit.unit | String | Local retention limit duration unit. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.minute.basicSchedule.frequency | Number | Snapshot frequency every minute. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.minute.basicSchedule.retention | Number | Snapshot retention value per minute snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.minute.basicSchedule.retentionUnit | String | Snapshot retention time unit per minute snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.hourly.basicSchedule.frequency | Number | Snapshot hourly frequency. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.hourly.basicSchedule.retention | Number | Snapshot retention value per hour snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.hourly.basicSchedule.retentionUnit | String | Snapshot retention time unit per hour snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.daily.basicSchedule.frequency | Number | Snapshot daily frequency. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.daily.basicSchedule.retention | Number | Snapshot retention value per day snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.daily.basicSchedule.retentionUnit | String | Snapshot retention unit per day snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.weekly.basicSchedule.frequency | Number | Snapshot weekly frequency. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.weekly.basicSchedule.retention | Number | Snapshot retention value per week snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.weekly.basicSchedule.retentionUnit | String | Snapshot retention unit per week snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.weekly.dayOfWeek | String | Starting day of the weekly snapshot. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.monthly.basicSchedule.frequency | Number | Snapshot monthly frequency. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.monthly.basicSchedule.retention | Number | Snapshot retention value per month snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.monthly.basicSchedule.retentionUnit | String | Snapshot retention unit per month snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.monthly.dayOfMonth | String | Starting day of the month snapshot. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.quarterly.basicSchedule.frequency | Number | Snapshot quarterly frequency. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.quarterly.basicSchedule.retention | Number | Snapshot retention value per quarter snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.quarterly.basicSchedule.retentionUnit | String | Snapshot retention unit per quarter snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.quarterly.dayOfQuarter | String | Starting day of the quarterly snapshot. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.quarterly.quarterStartMonth | String | Starting month of the quarterly snapshot. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.yearly.basicSchedule.frequency | Number | Snapshot yearly frequency. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.yearly.basicSchedule.retention | Number | Snapshot retention value per year snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.yearly.basicSchedule.retentionUnit | String | Snapshot retention unit per year snapshots. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.yearly.dayOfYear | String | Starting day of the yearly snapshot. |
| RubrikPolaris.GPSSLADomain.snapshotSchedule.yearly.yearStartMonth | String | Starting month of the yearly snapshot. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.awsRdsConfig.logRetention.duration | Number | Duration of retentioning AWS Relational database logs. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.awsRdsConfig.logRetention.unit | String | Unit of duration of retentioning AWS Relational database logs. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.sapHanaConfig.incrementalFrequency.duration | Number | Duration of retentioning SAP HANA incremental backups. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.sapHanaConfig.incrementalFrequency.unit | String | Unit of duration of retentioning SAP HANA incremental backups. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.sapHanaConfig.differentialFrequency.duration | Number | Duration of retentioning SAP HANA differential backups. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.sapHanaConfig.differentialFrequency.unit | String | Unit of duration of retentioning SAP HANA differential backups. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.sapHanaConfig.logRetention.duration | Number | Duration of retensioning SAP HANA Database logs. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.sapHanaConfig.logRetention.unit | String | Unit of duration of retentioning SAP HANA Database logs. |
| RubrikPolaris.GPSSLADomain.objectSpecificConfigs.vmwareVmConfig.logRetentionSeconds | Number | Seconds of retentioning VMWare virtual machine logs. |
| RubrikPolaris.GPSSLADomain.objectTypes | Unknown | List of object types associated with this SLA Domain. |

#### Command Example

```!rubrik-gps-sla-domain-list cluster_id=4d4a41d5-8910-4e4d-9dca-0798f5fc6d61 limit=2```

#### Human Readable Output

### GPS SLA Domains

|SLA Domain ID|SLA Domain Name|Base Frequency|Protected Object Count|Archival Location|Description|Replication Target 1|Replication Target 2|
|---|---|---|---|---|---|---|---|
| 00000000-0000-0000-0000-000000000002 | Bronzecd | 1 Days | 0 | AWS S3:bucket-1234 | Rubrik default Bronze level SLA Domain policy | sand2-rbk01 | sand2-rbk02 |
| 00000000-0000-0000-0000-000000000000 | Gold | 4 Hours | 0 |  | Rubrik default Gold level SLA Domain policy | sand2-rbk01 |  |

### rubrik-sonar-csv-result-download

***
Retrieve the download link for the requested Sonar CSV Snapshot file.

#### Base Command

`rubrik-sonar-csv-result-download`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| download_id | The ID of the download, requested using "rubrik-sonar-csv-download" command.<br/><br/>Note: Users can retrieve the list of downloads containing ID by executing the "rubrik-user-downloads-list" command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.SonarCSVDownload.downloadId | String | The download ID of the download request. |
| RubrikPolaris.SonarCSVDownload.getDownloadUrl.url | String | The link of the file that needs to be downloaded. |

#### Command Example

```!rubrik-sonar-csv-result-download download_id=65```

#### Human Readable Output

### Sonar CSV Result

|Download URL|
|---|
| Download the [CSV](https://www.example.com/csv_file) file to see the result. |

### rubrik-gps-vm-snapshot-create

***
Triggers an on-demand snapshot of a system.

Note: To know about the status of the on-demand snapshot creation, use the "rubrik-gps-async-result" command.

#### Base Command

`rubrik-gps-vm-snapshot-create`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| object_id | The ID of the object whose snapshot is to be created. <br/><br/>Note: Users can get the list of object IDs by executing the "rubrik-polaris-vm-objects-list" command. | Required |
| sla_domain_id | The ID of the SLA domain retention policy to be applied on the object.<br/><br/>Note: Users can get the list of SLA Domain IDs by executing the "rubrik-gps-sla-domain-list" command. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSOndemandSnapshot.id | String | ID of the requested snapshot. |
| RubrikPolaris.GPSOndemandSnapshot.status | String | Status of the requested snapshot. |

#### Command Example

```!rubrik-gps-vm-snapshot-create object_id=ac0a6844-a2fc-52b0-bb71-6a55f43677be```

#### Human Readable Output

### GPS VM Snapshot

|On-Demand Snapshot Request ID|Status|
|---|---|
| dummy_id | QUEUED |

### rubrik-gps-snapshot-files-download

***
Request to download the snapshot file from the backup.

Note: To know about the file information and which file can be downloaded, use the "rubrik-gps-snapshot-files-list" command. To know about the status of the downloadable files, use the "rubrik-gps-async-result" command.

#### Base Command

`rubrik-gps-snapshot-files-download`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| snapshot_id | The Snapshot ID of the file that needs to be downloaded.<br/><br/>Note: Users can retrieve the list of the snapshot IDs by executing the "rubrik-polaris-vm-object-snapshot-list" command. | Required |
| file_path | The absolute path of the file to be downloaded. A list of files can be downloaded as a zip folder. Multiple file paths can be separated with comma(,).<br/><br/>Note: Users can retrieve the list of the files with absolute path by executing the "rubrik-gps-snapshot-files-list" command.<br/><br/>Format accepted: "/&lt;directory name&gt;/&lt;sub directory name or file name&gt;"<br/><br/>Example: "/C:/PerfLogs/Admin", "/C:/Windows/Microsoft.NET". | Required |
| object_type | The type of object for which the file to be downloaded.<br/><br/>Possible values are: "WindowsFileset", "LinuxFileset", "VolumeGroup", "VmwareVm". Default is VmwareVm. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSSnapshotFileDownload.id | String | The ID of the download. |
| RubrikPolaris.GPSSnapshotFileDownload.status | String | Status of the download. |
| RubrikPolaris.GPSSnapshotFileDownload.links.href | String | Link of the download. |
| RubrikPolaris.GPSSnapshotFileDownload.links.rel | String | Relationship of the download. |

#### Command Example

```!rubrik-gps-snapshot-files-download snapshot_id=3765b5b5-827b-5588-8c34-5cb737a28685 file_path="/.autorelabel"```

#### Human Readable Output

### Snapshot File Request ID

|ID|Status|
|---|---|
| dummy_id | QUEUED |

### rubrik-gps-vm-livemount

***
Performs a live mount of a virtual machine snapshot.

Note: To know about the live mount status, use the "rubrik-gps-async-result" command.

#### Base Command

`rubrik-gps-vm-livemount`

#### Input

| **Argument Name** | **Description**                                                                                                                                                                             | **Required** |
| --- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- |
| snappable_id | The snappable ID.                                                                                                                                                                           | Required |
| should_recover_tags | Whether to keep vSphere tags associated with the VM or not.<br/><br/>Possible values are: "True", "False". Default is True.                                                                 | Optional |
| power_on | Whether to power on the mount or not.<br/><br/>Possible values are: "True", "False". Default is True.                                                                                       | Optional |
| keep_mac_addresses | Whether the mac addresses of network devices be removed or not.<br/><br/>Possible values are: "True", "False". Default is False.                                                            | Optional |
| remove_network_devices | Whether the network devices of the original VM be kept.<br/><br/>Possible values are: "True", "False". Default is False.                                                                    | Optional |
| host_id | The ID of the Vsphere ESXi host on which the new VM will be mounted.<br/><br/>Note: Users can get the list of host IDs by executing the "rubrik-gps-vm-host-list" command.                  | Optional |
| cluster_id | ID of the compute cluster where the new VM will be mounted.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command.               | Optional |
| resource_pool_id | ID of the resource pool where the new VM will be mounted.                                                                                                                                   | Optional |
| snapshot_fid | ID of the snapshot to recover.                                                                                                                                                              | Optional |
| vm_name | Name given to the VM that runs the snapshot. If not provided the name will be "&lt;Snapshot VM Name&gt; &lt;MM/DD of snapshot creation&gt; &lt;hh/mm of snapshot creation&gt; &lt;Num&gt;". | Optional |
| vnic_bindings | List of network bindings for vNIC of the VM.  <br/><br/> e.g. [{"networkDeviceInfo":{"key":2000,"name":"Network adapter"},"backingNetworkInfo":{"moid":"db68871d-0fbf-5551-97de-4c234885766b","name":"Router"}}]            | Optional |
| recovery_point | Point in time to recover to, e.g.: "2023-03-04T05:06:07.890".                                                                                                                               | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSVMLiveMount.id | String | ID of the Live mount request. |

#### Command Example

```!rubrik-gps-vm-livemount snapshot_id=d680b484-0084-5231-a05d-18e9cd5402fc vm_name=live-mount-demo```

#### Human Readable Output

### GPS VM Livemount

|VM Live Mount Request ID|
|---|
| dummy_id |

### rubrik-gps-vm-host-list

***
Retrieve the list of available Vsphere Hosts.

#### Base Command

`rubrik-gps-vm-host-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| name | The name of the host to search for. | Optional |
| cluster_id | To list hosts from the specific cluster.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command. | Optional |
| limit | Number of results to retrieve in the response. Maximum size allowed is 1000. Default is 50. | Optional |
| next_page_token | The next page cursor to retrieve the next set of results. | Optional |
| sort_by | Specify the field to use for sorting the response.<br/><br/>Note: Supported values are "ID" and "NAME" only. For any other values, the obtained result is sorted or not is not confirmed. Default is ID. | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "ASC", "DESC". Default is ASC. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSVMHost.id | String | ID of the Vsphere host. |
| RubrikPolaris.GPSVMHost.name | String | Name of the Vsphere host. |
| RubrikPolaris.GPSVMHost.physicalPath.fid | String | ID of a physical path of a node. |
| RubrikPolaris.GPSVMHost.physicalPath.name | String | Name of a physical path of a node. |
| RubrikPolaris.GPSVMHost.physicalPath.objectType | String | Type of a physical path of a node, for example, VSphereComputeCluster, VSphereDatacenter etc. |
| RubrikPolaris.PageToken.GPSVMHost.next_page_token | String | Next page token. |
| RubrikPolaris.PageToken.GPSVMHost.name | String | Name of the command. |
| RubrikPolaris.PageToken.GPSVMHost.has_next_page | Boolean | Whether the result has the next page or not. |

#### Command Example

```!rubrik-gps-vm-host-list```

#### Human Readable Output

### GPS VM Hosts

|VSphere Host ID|Name|Physical Host|
|---|---|---|
| f57bfebf-c7c9-5310-a5fd-1f0aeea5ba25 | sjc-40302-sand1-esx02.rubrikdemo.com | {'id': '72480b29-0eaa-57a9-8c5c-45b7e1c2c826', 'name': 'Sandbox-1 SJC Cluster', 'objectType': 'VSphereComputeCluster'},<br/>{'id': '3f3a92de-c7f3-57f7-989f-3731db83aeab', 'name': 'Sandbox-1 Datacenter', 'objectType': 'VSphereDatacenter'},<br/>{'id': '415859e2-fd22-53ea-8de1-041d99298fe3', 'name': 'sand1-vcsa.rubrikdemo.com', 'objectType': 'VSphereVCenter'} |

### rubrik-gps-vm-datastore-list

***
Retrieve the list of the available datastores on a Vsphere Host.

#### Base Command

`rubrik-gps-vm-datastore-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| name | The name of the datastore to search for. | Optional |
| host_id | The ID of a Vsphere host whose datastores are to be listed.<br/><br/>Note: Users can get the list of host IDs by executing the "rubrik-gps-vm-host-list" command. | Required |
| limit | Number of results to retrieve in the response. Maximum size allowed is 1000. Default is 50. | Optional |
| next_page_token | The next page cursor to retrieve the next set of results. | Optional |
| sort_by | Specify the field to use for sorting the response.<br/><br/>Note: Supported values are "ID" and "NAME" only. For any other values, the obtained result is sorted or not is not confirmed. Default is ID. | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "ASC", "DESC". Default is ASC. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSVMHost.id | String | ID of the Vsphere host. |
| RubrikPolaris.GPSVMHost.Datastore.id | String | ID of the Vsphere datastore. |
| RubrikPolaris.GPSVMHost.Datastore.name | String | Name of the Vsphere datastore. |
| RubrikPolaris.GPSVMHost.Datastore.capacity | Number | Datastore capacity in bytes. |
| RubrikPolaris.GPSVMHost.Datastore.isLocal | Boolean | Whether the datastore is local or remote. |
| RubrikPolaris.GPSVMHost.Datastore.freeSpace | Number | Free space on the datastore in bytes. |
| RubrikPolaris.GPSVMHost.Datastore.datastoreType | String | Type of datastore, for example, "NFS",  "VMFS" etc. |
| RubrikPolaris.PageToken.GPSVMHost.Datastore.next_page_token | String | Next page token. |
| RubrikPolaris.PageToken.GPSVMHost.Datastore.name | String | Name of the command. |
| RubrikPolaris.PageToken.GPSVMHost.Datastore.has_next_page | Boolean | Whether the result has the next page or not. |

#### Command Example

```!rubrik-gps-vm-datastore-list```

#### Human Readable Output

### GPS VM Datastores

|VSphere Datastore ID|Name|Capacity|Free Space|Datastore Type|
|---|---|---|---|---|
| dummy_datastore_id | dummy-repo | 0.53362190336 TB | 0.188318314496 TB | NFS |

### rubrik-event-list

***
Retrieve the list of events.

#### Base Command

`rubrik-event-list`

#### Input

| **Argument Name** | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | **Required** |
| --- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- |
| activity_status | Filter the events based on the provided activity statuses. Supports comma separated values.<br/><br/>Possible values are: "UNKNOWN_EVENT_STATUS", "SUCCESS", "FAILURE", "INFO", "CANCELED", "RUNNING", "WARNING", "CANCELING", "TASK_SUCCESS", "QUEUED", "TASK_FAILURE", "PARTIAL_SUCCESS".                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Optional |
| activity_type | Filter the events based on provided activity types. Supports comma separated values.<br/><br/>Possible values are: "UNKNOWN_EVENT_TYPE", "ARCHIVE", "AUTH_DOMAIN", "AWS_EVENT", "BACKUP", "CLASSIFICATION", "CLOUD_NATIVE_SOURCE", "CLOUD_NATIVE_VIRTUAL_MACHINE", "CLOUD_NATIVE_VM", "CONFIGURATION", "CONVERSION", "CONNECTION", "DIAGNOSTIC", "DISCOVERY", "DOWNLOAD", "FAILOVER", "FILESET", "HARDWARE", "HDFS", "HOST_EVENT", "HYPERV_SCVMM", "HYPERV_SERVER", "INDEX", "INSTANTIATE", "LEGAL_HOLD", "LOCAL_RECOVERY", "MAINTENANCE", "NUTANIX_CLUSTER", "RANSOMWARE_INVESTIGATION_ANALYSIS", "RECOVERY", "REPLICATION", "RESOURCE_OPERATIONS", "ANOMALY", "STORAGE", "STORAGE_ARRAY", "STORM_RESOURCE", "SUPPORT", "SYNC", "SYSTEM", "TEST_FAILOVER", "THREAT_HUNT", "TPR", "LOCK_SNAPSHOT", "UPGRADE", "VCENTER", "VCD", "VOLUME_GROUP", "EMBEDDED_EVENT", "ISOLATED_RECOVERY", "OWNERSHIP", "LOG_BACKUP", "K8S".                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Optional |
| severity | Filter the events based on provided severities. Supports comma separated values.<br/><br/>Possible values are: "SEVERITY_INFO", "SEVERITY_CRITICAL", "SEVERITY_WARNING".                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Optional |
| object_name | Filter out events based on object name.<br/><br/>Note: Users can get the object names by executing the "rubrik-polaris-vm-objects-list" or "rubrik-polaris-object-search" command.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Optional |
| object_type | Filter the events based on provided object types. Supports comma separated values.<br/><br/>Possible values are: "UNKNOWN_EVENT_OBJECT_TYPE", "RUBRIK_SAAS_ACCOUNT", "APP_BLUEPRINT", "APP_FLOWS", "OBJECT_TYPE_AUTH_DOMAIN", "AWS_ACCOUNT", "AWS_EVENT_TYPE", "AZURE_NATIVE_SUBSCRIPTION", "AZURE_NATIVE_VM", "AZURE_NATIVE_DISK", "AZURE_SQL_DATABASE", "AZURE_SQL_MANAGED_INSTANCE", "AZURE_SQL_DATABASE_SERVER", "AZURE_SQL_MANAGED_INSTANCE_DATABASE", "CAPACITY_BUNDLE", "OBJECT_TYPE_CLOUD_NATIVE_VIRTUAL_MACHINE", "OBJECT_TYPE_CLOUD_NATIVE_VM", "CERTIFICATE", "CLUSTER", "COMPUTE_INSTANCE", "DATA_LOCATION", "DB2_DATABASE", "DB2_INSTANCE", "EC2_INSTANCE", "ENVOY", "FAILOVER_CLUSTER_APP", "EXOCOMPUTE", "EXCHANGE_DATABASE", "OBJECT_TYPE_HDFS", "HOST", "OBJECT_TYPE_HYPERV_SCVMM", "OBJECT_TYPE_HYPERV_SERVER", "HYPERV_VM", "JOB_INSTANCE", "LDAP", "LINUX_FILESET", "LINUX_HOST", "MANAGED_VOLUME", "MSSQL", "NAS_FILESET", "WEBHOOK", "NAS_HOST", "NAS_SYSTEM", "OBJECT_TYPE_NUTANIX_CLUSTER", "NUTANIX_VM", "O365_CALENDAR", "O365_MAILBOX", "O365_ONEDRIVE", "O365_SITE", "O365_SHARE_POINT_DRIVE", "O365_SHARE_POINT_LIST", "O365_TEAM", "O365_ORGANIZATION", "O365_GROUP", "OBJECT_PROTECTION", "ORACLE", "ORACLE_DB", "ORACLE_HOST", "ORACLE_RAC", "AWS_NATIVE_ACCOUNT", "AWS_NATIVE_EBS_VOLUME", "AWS_NATIVE_EC2_INSTANCE", "RUBRIK_SAAS_EBS_VOLUME", "RUBRIK_SAAS_EC2_INSTANCE", "PUBLIC_CLOUD_MACHINE_INSTANCE", "SAML_SSO", "SAP_HANA_DB", "SAP_HANA_SYSTEM", "SHARE_FILESET", "SLA_DOMAIN", "SMB_DOMAIN", "SNAP_MIRROR_CLOUD", "OBJECT_TYPE_STORAGE_ARRAY", "STORAGE_ARRAY_VOLUME_GROUP", "STORAGE_LOCATION", "STORM", "SUPPORT_BUNDLE", "USER", "OBJECT_TYPE_UPGRADE", "OBJECT_TYPE_VCD", "VCD_VAPP", "OBJECT_TYPE_VCENTER", "VMWARE_COMPUTE_CLUSTER", "VMWARE_VM", "OBJECT_TYPE_VOLUME_GROUP", "WINDOWS_FILESET", "WINDOWS_HOST", "GCP_NATIVE_PROJECT", "AWS_NATIVE_RDS_INSTANCE", "GCP_NATIVE_GCE_INSTANCE", "GCP_NATIVE_DISK", "KUPR_CLUSTER", "KUPR_NAMESPACE", "CASSANDRA_COLUMN_FAMILY", "CASSANDRA_KEYSPACE", "CASSANDRA_SOURCE", "MONGODB_COLLECTION", "MONGODB_DATABASE", "MONGODB_SOURCE", "CLOUD_DIRECT_NAS_EXPORT", "MONGO_COLLECTION", "MONGO_DATABASE", "MONGO_SOURCE", "CERTIFICATE_MANAGEMENT", "AWS_NATIVE_S3_BUCKET", "AZURE_STORAGE_ACCOUNT", "K8S_CLUSTER", "K8S_RESOURCE_SET", "AZURE_AD_TENANT". | Optional |
| cluster_id | Filter the events based on provided cluster IDs. Supports comma separated values.<br/><br/>Note: Users can get the list of cluster IDs by executing the "rubrik-gps-cluster-list" command.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Optional |
| start_date | The start date to fetch updated events from.<br/><br/>Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Optional |
| end_date | The end date to fetch updated events until.<br/><br/>Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Optional |
| limit | Number of results to retrieve in the response. Maximum size allowed is 1000. Default is 50.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Optional |
| next_page_token | The next page cursor to retrieve the next set of results.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Optional |
| sort_by | Specify the field to use for sorting the response.<br/><br/>Note: Possible values are: "LAST_UPDATED", "LOCATION", "OBJECT_TYPE", "CLUSTER_NAME", "OBJECT_NAME", "START_TIME", "ACTIVITY_TYPE", "SEVERITY", "ACTIVITY_STATUS". Default is LAST_UPDATED.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "ASC","DESC". Default is DESC.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.Event.id | Number | ID of the event. |
| RubrikPolaris.Event.startTime | String | Start time of the event. |
| RubrikPolaris.Event.fid | String | FID of the event. |
| RubrikPolaris.Event.activitySeriesId | String | Activity Series ID of the event. |
| RubrikPolaris.Event.lastUpdated | String | Date time when the event was last updated. |
| RubrikPolaris.Event.lastActivityType | String | Last Activity Type of the event. |
| RubrikPolaris.Event.lastActivityStatus | String | Last Activity Status of the event. |
| RubrikPolaris.Event.location | String | Location of the event. |
| RubrikPolaris.Event.objectId | String | ID of the object. |
| RubrikPolaris.Event.objectName | String | Name of the object. |
| RubrikPolaris.Event.objectType | String | Type of the object. |
| RubrikPolaris.Event.severity | String | Severity of the event. |
| RubrikPolaris.Event.progress | String | Progress of the event. |
| RubrikPolaris.Event.cluster.id | String | The ID of the cluster. |
| RubrikPolaris.Event.cluster.name | String | The name of the cluster. |
| RubrikPolaris.Event.activityConnection.nodes.id | String | ID of the activity connection. |
| RubrikPolaris.Event.activityConnection.nodes.message | String | Message of the activity connection. |
| RubrikPolaris.Event.activityConnection.nodes.severity | String | Severity of the activity connection. |
| RubrikPolaris.Event.activityConnection.nodes.time | String | Date time when the activity connection was last updated. |
| RubrikPolaris.PageToken.Event.next_page_token | String | Next page token. |
| RubrikPolaris.PageToken.Event.name | String | Name of the command. |
| RubrikPolaris.PageToken.Event.has_next_page | Boolean | Whether the result has the next page or not. |

#### Command Example

```!rubrik-event-list limit=1```

#### Human Readable Output

### Events

|Event ID|Activity Series ID|Cluster ID|Object ID|Object Name|Severity|Start Time|Last Updated|Last Activity Type|Last Activity Status|
|---|---|---|---|---|---|---|---|---|---|
| 7739500 | 422d17c0-737d-44df-98a0-a7fa9f714c0d | cc19573c-db6c-418a-9d48-067a256543ba | Fileset:::f2666679-5b94-4116-9cbf-6ab69e575522 | AllTheThings | Info | 2021-10-25T12:15:36.911Z | 2021-10-25T12:16:10.212Z | Index | Success |

 Note: To retrieve the next set of results use, "next_page_token" = xyz

### rubrik-polaris-object-list

***
Retrieve the list of Rubrik objects, based on the provided filters.

#### Base Command

`rubrik-polaris-object-list`

#### Input

| **Argument Name** | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | **Required** |
| --- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- |
| type_filter | Filter the objects based on the provided object types. Supports comma separated values.<br/><br/>Possible values are: "MONGODB_DATABASE", "FilesetTemplate", "VcdOrgVdc", "ShareFileset", "KuprNamespace", "O365Group", "AwsNativeEbsVolume", "OracleDatabase", "O365Mailbox", "MONGO_DB", "AzureNativeResourceGroup", "AZURE_SQL_MANAGED_INSTANCE_DB", "Db2Database", "HOST_FAILOVER_CLUSTER", "VolumeGroup", "AzureNativeVm", "VcdOrg", "Db2Instance", "PhysicalHost", "AwsNativeRdsInstance", "AzureSqlManagedInstanceServer", "O365Site", "VmwareVirtualMachine", "O365User", "ORACLE_DATA_GUARD_GROUP", "AwsNativeEc2Instance", "MssqlInstance", "NutanixVirtualMachine", "CASSANDRA_COLUMN_FAMILY", "MONGO_COLLECTION", "O365Org", "OracleHost", "NAS_FILESET", "SapHanaDatabase", "AllSubHierarchyType", "AWS_NATIVE_S3_BUCKET", "NasSystem", "O365Teams", "VSphereFolder", "VSphereResourcePool", "GcpNativeDisk", "AwsNativeAccount", "VSphereDatacenter", "AZURE_STORAGE_ACCOUNT", "VSphereComputeCluster", "HypervCluster", "CASSANDRA_SOURCE", "VSphereTag", "VcdVapp", "RubrikEbsVolume", "NasVolume", "NasNamespace", "Vcd", "VcdVimServer", "AZURE_SQL_DATABASE_DB", "VSPHERE_VIRTUAL_DISK", "MssqlDatabaseBatchMaintenance", "EXCHANGE_SERVER", "CLOUD_DIRECT_NAS_EXPORT", "VcdCatalog", "O365File", "HypervSCVMM", "Blueprint", "AzureSqlDatabaseServer", "FeldsparSite", "CloudNativeTagRule", "Mssql", "MONGO_SOURCE", "HostShare", "SnapMirrorCloud", "O365Calendar", "O365SharePointDrive", "VSphereNetwork", "Fileset", "SapHanaSystem", "O365Onedrive", "Hdfs", "Ec2Instance", "WindowsCluster", "GcpNativeProject", "MONGODB_COLLECTION", "MONGO_DATABASE", "VSphereDatastore", "AZURE_AD_TENANT", "HypervServer", "VSphereHost", "AppBlueprint", "MssqlAvailabilityGroup", "LinuxFileset", "MANAGED_VOLUME_EXPORT", "CASSANDRA_KEYSPACE", "HypervVirtualMachine", "GcpNativeGCEInstance", "StorageArrayVolumeGroup", "O365SharePointList", "ExchangeDatabase", "NutanixCluster", "AzureNativeManagedDisk", "AzureNativeSubscription", "VSPHERE_DATASTORE_CLUSTER", "ManagedVolume", "FAILOVER_CLUSTER_APP", "VSphereVCenter", "NasShare", "EXCHANGE_DAG", "KuprCluster", "OracleRac", "MONGODB_SOURCE", "ORCHESTRATED_APPLICATION_RECOVERY_BLUEPRINT", "VSphereTagCategory", "ORCHESTRATED_APPLICATION_RECOVERY_PLAN", "WindowsVolumeGroup", "RubrikEc2Instance", "WindowsFileset". | Required |
| cluster_id | Filter the objects based on the provided cluster IDs. Supports comma separated values.<br/><br/>Note: Users can get the list of cluster IDs by executing the "rubrik-gps-cluster-list" command.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Optional |
| limit | Number of results to retrieve in the response. Maximum size allowed is 1000. Default is 50.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Optional |
| next_page_token | The next page cursor to retrieve the next set of results.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Optional |
| sort_by | Specify the field to use for sorting the response.<br/><br/>Note: Supported values are "ID" and "NAME" only. For any other values, the obtained result is sorted or not is not confirmed. Default is ID.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "ASC", "DESC". Default is ASC.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.Object.id | String | ID of the object. |
| RubrikPolaris.Object.effectiveSlaDomain.name | String | Name of the SLA domain of the object. |
| RubrikPolaris.Object.effectiveSlaDomain.id | String | ID of the SLA domain of the object. |
| RubrikPolaris.Object.effectiveSlaDomain.description | String | Description of the SLA domain of the object. |
| RubrikPolaris.Object.effectiveSlaDomain.cluster.id | String | Cluster ID of effective SLA domain of the object. |
| RubrikPolaris.Object.effectiveSlaDomain.cluster.name | String | Cluster name of effective SLA domain of the object. |
| RubrikPolaris.Object.effectiveSlaDomain.fid | String | FID of effective SLA domain of the object. |
| RubrikPolaris.Object.isPassthrough | Boolean | Whether the object is passthrough or not. |
| RubrikPolaris.Object.cluster.id | String | Cluster ID of the object. |
| RubrikPolaris.Object.cluster.name | String | Cluster name of the object. |
| RubrikPolaris.Object.primaryClusterLocation.id | String | ID of the primary cluster location of the object. |
| RubrikPolaris.Object.logicalPath.name | String | Name of the logical path of the object. |
| RubrikPolaris.Object.logicalPath.objectType | String | Object Type of the logical path of the object. |
| RubrikPolaris.Object.physicalPath.name | String | Name of the physical path of the object. |
| RubrikPolaris.Object.physicalPath.objectType | String | Object Type of the physical path of the object. |
| RubrikPolaris.Object.name | String | Name of the object. |
| RubrikPolaris.Object.objectType | String | Type of the object. |
| RubrikPolaris.PageToken.Object.has_next_page | Boolean | Whether the result has the next page or not. |
| RubrikPolaris.PageToken.Object.name | String | Name of the command. |
| RubrikPolaris.PageToken.Object.next_page_token | String | Next page token. |

#### Command Example

```!rubrik-polaris-object-list limit=1```

#### Human Readable Output

### Objects

|Object ID|Object Name|Object Type|Location|Cluster Name|SLA Domain Name|
|---|---|---|---|---|---|
| 0014037c-70ae-4c53-b1cf-df6926b88968 | Christian LeCorre | O365User | Rubrik Demo\EMEA Users\AMER Users | x | UNPROTECTED |

 Note: To retrieve the next set of results use, "next_page_token" = xyz

### rubrik-polaris-object-snapshot-list

***
Retrieve Rubrik snapshot(s) of an object, based on the provided object ID.

#### Base Command

`rubrik-polaris-object-snapshot-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| object_id | The object ID for which the snapshots are to be searched.<br/><br/>Note: Users can get the list of the object IDs by executing the "rubrik-polaris-object-list" command. | Required |
| start_date | The start date to get snapshots from.<br/><br/>Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.<br/><br/>Note: start_date and end_date both or none must be initialized. | Optional |
| end_date | The end date to get snapshots until.<br/><br/>Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.<br/><br/>Note: start_date and end_date both or none must be initialized. | Optional |
| limit | Number of results to retrieve in the response. Maximum size allowed is 1000. Default is 50. | Optional |
| next_page_token | The next page cursor to retrieve the next set of results. | Optional |
| snapshot_type | List of snapshot types to filter snapshots. Supports comma separated values.<br/><br/>Possible values are: "SCHEDULED", "ON_DEMAND", "DOWNLOADED". | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "Asc", "Desc". Default is Asc. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.Object.id | String | ID of the object. |
| RubrikPolaris.Object.Snapshot.id | String | ID of the snapshot. |
| RubrikPolaris.Object.Snapshot.date | String | Date of the snapshot. |
| RubrikPolaris.Object.Snapshot.isArchivalCopy | Boolean | Whether the snapshot is an archival copy or not. |
| RubrikPolaris.Object.Snapshot.isReplica | Boolean | Whether the snapshot is a replica or not. |
| RubrikPolaris.Object.Snapshot.isOnDemandSnapshot | Boolean | Whether the snapshot is on demand or not. |
| RubrikPolaris.Object.Snapshot.isDownloadedSnapshot | Boolean | Whether the snapshot is downloaded or not. |
| RubrikPolaris.Object.Snapshot.cluster.id | String | Cluster ID of the snapshot. |
| RubrikPolaris.Object.Snapshot.cluster.name | String | Cluster name of the snapshot. |
| RubrikPolaris.Object.Snapshot.cluster.version | String | Cluster version of the snapshot. |
| RubrikPolaris.Object.Snapshot.cluster.status | String | Cluster status of the snapshot. |
| RubrikPolaris.Object.Snapshot.slaDomain.name | String | Name of the SLA domain of the snapshot. |
| RubrikPolaris.Object.Snapshot.slaDomain.fid | String | FID of the SLA domain of the snapshot. |
| RubrikPolaris.Object.Snapshot.slaDomain.cluster.id | String | Cluster ID of the SLA domain of the snapshot. |
| RubrikPolaris.Object.Snapshot.slaDomain.cluster.name | String | Cluster name of the SLA domain of the snapshot. |
| RubrikPolaris.Object.Snapshot.slaDomain.id | String | ID of the SLA domain of the snapshot. |
| RubrikPolaris.Object.Snapshot.snapshotRetentionInfo.archivalInfos.name | String | Archival name of snapshot retention of the snapshot. |
| RubrikPolaris.Object.Snapshot.snapshotRetentionInfo.archivalInfos.isExpirationDateCalculated | String | Whether archival expiration date of snapshot retention of the snapshot is calculated or not. |
| RubrikPolaris.Object.Snapshot.snapshotRetentionInfo.archivalInfos.expirationTime | String | Archival expiration time of snapshot retention of the snapshot. |
| RubrikPolaris.Object.Snapshot.snapshotRetentionInfo.localInfo.name | String | Name of snapshot retention of the snapshot. |
| RubrikPolaris.Object.Snapshot.snapshotRetentionInfo.localInfo.isExpirationDateCalculated | Boolean | Whether the expiration date is calculated or not. |
| RubrikPolaris.Object.Snapshot.snapshotRetentionInfo.localInfo.expirationTime | String | Expiration time of snapshot retention of the snapshot. |
| RubrikPolaris.PageToken.Object.Snapshot.has_next_page | Boolean | Whether the result has the next page or not. |
| RubrikPolaris.PageToken.Object.Snapshot.name | String | Name of the command. |
| RubrikPolaris.PageToken.Object.Snapshot.next_page_token | String | Next Page Token. |

#### Command Example

```!rubrik-polaris-object-snapshot-list object_id=06515737-388a-57aa-9c8e-54b3f1ee5d8b limit=1```

#### Human Readable Output

### Object Snapshots

|Snapshot ID|Creation Date|Cluster Name|SLA Domain Name|
|---|---|---|---|
| a7adc499-b896-5ad6-bfc2-0aae0ed99459 | 2021-10-28T19:35:52.000Z | sand2-rbk01 | 12hr-30d-AWS |

 Note: To retrieve the next set of results use, "next_page_token" = xyz

### rubrik-radar-ioc-scan

***
Triggers an IOC scan of a system.

Note: To know the results of the scan use the "rubrik-radar-ioc-scan-results" command and to list the running/completed IOC scans on a cluster use the "rubrik-radar-ioc-scan-list" command.

#### Base Command

`rubrik-radar-ioc-scan`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| cluster_id | ID of the cluster on which to perform a scan.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command. | Required |
| object_id | Object ID of the system on which to perform the scan. Supports comma separated values.<br/><br/>Note: Users can get the list of object IDs by executing the "rubrik-polaris-vm-objects-list" command. | Required |
| scan_name | Name of the scan. Default is PAXSOAR-1.1.0.| Optional |
| ioc_type | The type of the indicator to scan for.<br/><br/>Possible values are: "INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME", "INDICATOR_OF_COMPROMISE_TYPE_HASH", "INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE".<br/><br/>Note: To provide multiple IOCs use the argument "advance_ioc". | Optional |
| ioc_value | Value of the indicator to scan for.<br/><br/>Note: To provide multiple IOCs use the argument "advance_ioc". | Optional |
| advance_ioc | Json encoded Indicators Of Compromise to scan. Json keys signify the type of IOC and the corresponding list of values are the values of the IOC's. If provided, will ignore the ioc_type and ioc_value arguments.<br/><br/>Possible keys to indicate type of indicator: <br/>INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME, INDICATOR_OF_COMPROMISE_TYPE_HASH, INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE<br/><br/>Format Accepted:<br/>{<br/>"&lt;ioc_type1&gt;": ["&lt;ioc_value1&gt;", "&lt;ioc_value2&gt;"],<br/>"&lt;ioc_type2&gt;": "&lt;ioc_value2&gt;"<br/>}<br/><br/>Example:<br/>{<br/>"INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME": ["C:\Users\Malware_Executible.ps1", "\bin\Malware_Executible"],<br/>"INDICATOR_OF_COMPROMISE_TYPE_HASH": ["e5c1b9c44be582f895eaea3d3738c5b4", "f541b9844be897f895eaea3d3738cfb2"],<br/>"INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE": "rule match_everything {condition:true}"<br/>}. | Optional |
| start_date | Filter the snapshots from the provided date. Any snapshots taken before the provided date-time will be excluded.<br/><br/>Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.<br/><br/>Examples of more supported values can be found at https://dateparser.readthedocs.io/en/latest/#relative-dates. | Optional |
| end_date | Filter the snapshots until the provided date. Any snapshots taken after the provided date-time will be excluded.<br/><br/>Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.<br/><br/>Examples of more supported values can be found at https://dateparser.readthedocs.io/en/latest/#relative-dates. | Optional |
| max_snapshots_per_object | Maximum number of snapshots to scan per object. | Optional |
| max_file_size | Maximum size of the file in bytes that will be included in the scan. The maximum allowed size is 15000000 bytes. Default is 5000000. | Optional |
| snapshot_id | Provide comma separated snapshot IDs on which to perform a scan separated by colon for each object ID (in the same order). Supports comma separated values.<br/><br/>Format accepted:<br/>object_1_snapshot_id_1, object_1_snapshot_id_2: object_2_snapshot_id_1<br/><br/>Example:<br/>B405e8c0-1fcd-401c-a6f6-42f758aad6df, e179eb47-534b-4624-b155-f33d188902e2: 1e1681bf-4479-4339-a4bb-59901598caa5<br/><br/>Note: Users can retrieve the list of snapshot IDs by executing the "rubrik-polaris-vm-object-snapshot-list" command.<br/><br/>Note: Do not provide "snapshot_start_date", "snapshot_end_date" and, "max_snapshots_per_object" arguments if snapshot ID is provided. | Optional |
| paths_to_include | Paths to include in the scan. Supports comma separated values.<br/><br/>Format accepted:<br/>path_to_include_1, path_to_include_2. | Optional |
| paths_to_exclude | Paths to exclude from the scan. Supports comma separated values.<br/><br/>Format accepted:<br/>path_to_exclude_1, path_to_exclude_2. | Optional |
| paths_to_exempt | Paths to exempt from exclusion. Supports comma separated values.<br/><br/>Format accepted:<br/>path_to_exempt_1, path_to_exempt_2. | Optional |
| requested_hash_types | The type of hash values of the matched files to return in the result. Supports comma separated values.<br/><br/>Possible values are: "HASH_TYPE_M_D5", "HASH_TYPE_SH_A1", "HASH_TYPE_SH_A256". | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.RadarIOCScan.id | String | ID of the IOC scan. |
| RubrikPolaris.RadarIOCScan.status | String | Status of the IOC scan trigger request. |

#### Command Example

```!rubrik-radar-ioc-scan scan_name="Revil Ransomware Scan" ioc_type="INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME" ioc_value="revil.exe" cluster_id="052bf7af-93a3-44e9-a7d7-bc8dad4d6b43" object_id="868aa03d-4145-4cb1-808b-e10c4f7a3741"```

#### Human Readable Output

### Radar IOC Scan

|Scan ID|Status|
|---|---|
| dummy-ioc-id | RUNNING |

### rubrik-radar-ioc-scan-results

***
Retrieves the results of IOC scan of a system.

Note: To initiate a scan use the "rubrik-radar-ioc-scan" command and to list the running/completed scans on a cluster use the "rubrik-radar-ioc-scan-list" command.

#### Base Command

`rubrik-radar-ioc-scan-results`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| scan_id | ID of the IOC scan whose results are to be retrieved.<br/><br/>Note: Users can get the scan ID by executing the "rubrik-radar-ioc-scan" command. | Required |
| cluster_id | ID of the cluster on which the scan was performed.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.RadarIOCScan.id | String | ID of the IOC scan. |
| RubrikPolaris.RadarIOCScan.status | String | Overall status of the scan. |
| RubrikPolaris.RadarIOCScan.indicatorsOfCompromise.iocType | String | Type of IOC that was scanned. |
| RubrikPolaris.RadarIOCScan.indicatorsOfCompromise.iocValue | String | Value of the IOC that was scanned. |
| RubrikPolaris.RadarIOCScan.results.objectId | String | ID of the system that was scanned. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.status | String | Status of the scan on the snapshot. Values: MALWARE_SCAN_IN_SNAPSHOT_STATUS_PENDING, MALWARE_SCAN_IN_SNAPSHOT_STATUS_FINISHED, MALWARE_SCAN_IN_SNAPSHOT_STATUS_ERROR. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.snapshotDate | String | The date-time at which the snapshot was taken. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.snapshotId | String | ID of the snapshot that was scanned. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.scanStats.numFiles | Number | Number of files encountered during scan. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.scanStats.numFilesScanned | Number | Number of files that were scanned on that snapshot. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.scanStats.totalFilesScannedSizeBytes | Number | The total file size of the files scanned. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.indicatorIndex | Number | Index of indicator in inputs for the scan. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.paths.aclDetails | String | JSON encoded file access control list \(ACL\) information. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.paths.creationTime | String | File creation date-time. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.paths.modificationTime | String | File modification date-time. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.paths.path | String | File path that matched the malware Indicator Of Compromise. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.paths.yaraMatchDetails.name | String | The name of the matching YARA rule. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.paths.yaraMatchDetails.tags | Unknown | Optional YARA tags. Described in https://yara.readthedocs.io/en/latest/writingrules.html\#rule-tags. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.paths.requestedHashDetails.hashType | String | Hash algorithm type. |
| RubrikPolaris.RadarIOCScan.results.snapshotResults.matches.paths.requestedHashDetails.hashValue | String | Hash value of the content at path. |

#### Command Example

```!rubrik-radar-ioc-scan-results scan_id="bf687fcf-84d7-47f6-8bd1-54e8cf439680" cluster_id="052bf7af-93a3-44e9-a7d7-bc8dad4d6b43"```

#### Human Readable Output

### Radar IOC Scan Results

Scan ID: bf687fcf-84d7-47f6-8bd1-54e8cf439680
Status: FINISHED

|Snapshot ID|Snapshot Date|Object ID|Snapshot Scan Status|Scan Statistics|Matches|
|---|---|---|---|---|---|
| b7d6b871-796e-4e7c-99cf-328007c9d5c1 | 2021-10-29T07:03:30.669Z | VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-81407 | MALWARE_SCAN_IN_SNAPSHOT_STATUS_FINISHED | Number of Files: 142630, Number of Files Scanned: 0, Total Files Scanned In Bytes: 0 | 1 |
| 3779a895-94bf-437e-b63a-61e73e215901 | 2021-10-28T07:00:09.297Z | VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-81407 | MALWARE_SCAN_IN_SNAPSHOT_STATUS_FINISHED | Number of Files: 142630, Number of Files Scanned: 0, Total Files Scanned In Bytes: 0 | 1 |
| a871683f-f4fa-475f-806c-58f06e6782dc | 2021-10-26T07:04:07.139Z | VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-81407 | MALWARE_SCAN_IN_SNAPSHOT_STATUS_FINISHED | Number of Files: 142630, Number of Files Scanned: 0, Total Files Scanned In Bytes: 0 | 1 |
| 129f22f4-0359-4e7d-aa53-9edf4e33cff1 | 2021-10-29T12:01:43.383Z | VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-72277 | MALWARE_SCAN_IN_SNAPSHOT_STATUS_FINISHED | Number of Files: 142138, Number of Files Scanned: 0, Total Files Scanned In Bytes: 0 | 1 |
| b9264942-c71c-4b91-b9a7-74a7ba0f6166 | 2021-10-29T08:01:39.388Z | VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-72277 | MALWARE_SCAN_IN_SNAPSHOT_STATUS_FINISHED | Number of Files: 142138, Number of Files Scanned: 0, Total Files Scanned In Bytes: 0 | 1 |
| 9f12b533-b740-4fb9-af94-4411b0aee01d | 2021-10-29T00:01:04.357Z | VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-72277 | MALWARE_SCAN_IN_SNAPSHOT_STATUS_FINISHED | Number of Files: 142139, Number of Files Scanned: 0, Total Files Scanned In Bytes: 0 | 1 |

### rubrik-gps-async-result

***
Retrieve the result of an asynchronous request. This command will retrieve the result of requests made by commands "rubrik-gps-snapshot-files-download", "rubrik-gps-vm-livemount", "rubrik-gps-vm-export", "rubrik-gps-vm-snapshot-create", and "rubrik-gps-vm-recover-files".

#### Base Command

`rubrik-gps-async-result`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| request_id | ID of the request.<br/><br/>Note: Users can get the request ID by executing any of the commands that make a request. Possible commands are mentioned in the command description. | Required |
| cluster_id | ID of the cluster on which request was made.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command. | Required |
| cluster_ip_address | IP address of the cluster node to access the download link. Only required to retrieve the results of the command "rubrik-gps-snapshot-files-download".<br/><br/>Note: Users can retrieve the list of the IP addresses by executing the "rubrik-gps-cluster-list" command. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSAsyncResult.id | String | The ID of the request. |
| RubrikPolaris.GPSAsyncResult.status | String | Status of the request. |
| RubrikPolaris.GPSAsyncResult.nodeId | String | ID of the node. |
| RubrikPolaris.GPSAsyncResult.progress | Number | Progress of the request in range 0 to 100. |
| RubrikPolaris.GPSAsyncResult.error.message | String | JSON stringified message object when an error occurs. |
| RubrikPolaris.GPSAsyncResult.links.href | String | Link to a resource. |
| RubrikPolaris.GPSAsyncResult.links.rel | String | Type of the resource pointed by the link. |

#### Command Example

```!rubrik-gps-async-result request_id="EXPORT_VMWARE_SNAPSHOT_6e101218-141f-4101-b334-3c1bf440bfee_466b7d74-0d13-4e54-9a57-2ea4d7b00a0c:::0" cluster_id="052bf7af-93a3-44e9-a7d7-bc8dad4d6b43"```

#### Human Readable Output

### GPS Asynchronous Request Result

|ID|Status|Node ID|Links|
|---|---|---|---|
| dummy_id | FAILED | cluster:::RVMHM219S004941 | [self](https://www.example.com/)<br/> |

### rubrik-gps-cluster-list

***
Retrieve the list of the available rubrik clusters.

#### Base Command

`rubrik-gps-cluster-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| type | Filter out clusters based on their type. Supports comma separated values.<br/><br/>Possible values are: "Cloud", "Robo", "ExoCompute", "OnPrem", "Polaris", "Unknown". | Optional |
| name | Filter out clusters based on name. Supports comma separated values. | Optional |
| sort_by | Specify the field to use for sorting the response.<br/><br/>Possible values are: "ClusterName", "ClusterType", "RegisteredAt", "ESTIMATED_RUNWAY". Default is ClusterName. | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "Asc", "Desc". Default is Asc. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSCluster.id | String | ID of the cluster. |
| RubrikPolaris.GPSCluster.name | String | Name of the cluster. |
| RubrikPolaris.GPSCluster.type | String | Type of the cluster. Values are Cloud, Robo, ExoCompute, OnPrem, Unknown, Polaris. |
| RubrikPolaris.GPSCluster.status | String | Status of the cluster. Values are Connected, Disconnected, Initializing. |
| RubrikPolaris.GPSCluster.version | String | Version of the cluster. |
| RubrikPolaris.GPSCluster.defaultAddress | String | Default address assigned to the cluster. |
| RubrikPolaris.GPSCluster.cdmUpgradeInfo.clusterStatus.message | String | Message about the cluster upgrade/current condition. |
| RubrikPolaris.GPSCluster.cdmUpgradeInfo.clusterStatus.status | String | Upgrade/current status of the cluster. It provides information like -- upgrading, upgrade scheduled, stable, downloading packages, pre-checks running and many more. |
| RubrikPolaris.GPSCluster.cdmUpgradeInfo.overallProgress | Number | Progress \(in percentage\) of an upgrade, if running. |
| RubrikPolaris.GPSCluster.cdmUpgradeInfo.scheduleUpgradeAt | String | Shows the date-time of a scheduled upgrade. |
| RubrikPolaris.GPSCluster.cdmUpgradeInfo.downloadedVersion | String | The version that was downloaded but not yet installed. |
| RubrikPolaris.GPSCluster.cdmUpgradeInfo.version | String | The current version of the cluster. |
| RubrikPolaris.GPSCluster.productType | String | The product type. Values are CDM, DATOS, POLARIS. |
| RubrikPolaris.GPSCluster.estimatedRunway | Number | Estimated number of days remaining before additional data storage space is required on the cluster. |
| RubrikPolaris.GPSCluster.snapshotCount | Number | The total number of snapshots that are taken of different objects in the cluster. |
| RubrikPolaris.GPSCluster.geoLocation.address | String | Geological address of the cluster. |
| RubrikPolaris.GPSCluster.lastConnectionTime | String | Time when the cluster was last polled. |
| RubrikPolaris.GPSCluster.metric.totalCapacity | Number | Total storage capacity of the cluster in Bytes. |
| RubrikPolaris.GPSCluster.metric.availableCapacity | Number | Available storage capacity of the cluster in Bytes. |
| RubrikPolaris.GPSCluster.snappableConnection.count | Number | The number of objects in the cluster whose snapshots can be taken. |
| RubrikPolaris.GPSCluster.state.connectedState | String | Status of the cluster. Values are Connected, Disconnected, Initializing. |
| RubrikPolaris.GPSCluster.state.clusterRemovalState | String | State of the cluster when it is being removed from the platform. Values are DATA_DELETING, WAITING_FOR_DATA_DELETION, UNREGISTERED, FAILED, DISCONNECTING, REGISTERED. |
| RubrikPolaris.GPSCluster.clusterNodeConnection.nodes.id | String | ID of a node in a cluster. |
| RubrikPolaris.GPSCluster.clusterNodeConnection.nodes.status | String | Status of a node in a cluster. |
| RubrikPolaris.GPSCluster.clusterNodeConnection.nodes.ipAddress | String | IP Address of a node in a cluster. |
| RubrikPolaris.GPSCluster.passesConnectivityCheck | Boolean | Whether the cluster passes the connectivity check. |
| RubrikPolaris.GPSCluster.globalManagerConnectivityStatus.urls.url | String | URL of a global manager of the cluster. |
| RubrikPolaris.GPSCluster.globalManagerConnectivityStatus.urls.isReachable | Boolean | Whether the global manager is reachable. |
| RubrikPolaris.GPSCluster.connectivityLastUpdated | String | The date-time of when the cluster was last polled for connectivity. |
| RubrikPolaris.GPSCluster.lambdaFeatureHistory.wasRadarEverEnabled | Boolean | Whether Polaris Radar was ever enabled on the cluster. |
| RubrikPolaris.GPSCluster.lambdaFeatureHistory.wasSonarEverEnabled | Boolean | Whether Polaris Sonar was ever enabled on the cluster. |

#### Command Example

```!rubrik-gps-cluster-list name="sand1"```

#### Human Readable Output

### GPS Clusters

|Cluster ID|Cluster Name|Connection Status|Cluster Location|Total Capacity|Free Space|Protected Objects|Cluster Version|IP Address|
|---|---|---|---|---|---|---|---|---|
| cc19573c-db6c-418a-9d48-067a256543ba | sand1-rbk01 | Connected | San Francisco, CA, USA | 52.605821063168 TB | 45.484602130432 TB | 205 | 7.0.0-EA1-14307 | X.X.X.X, X.X.X.X |

### rubrik-radar-ioc-scan-list

***
Lists the running/completed IOC scans on a cluster.

Note: To know the results of the scan use the "rubrik-radar-ioc-scan-results" command. To initiate a scan use the "rubrik-radar-ioc-scan" command.

#### Base Command

`rubrik-radar-ioc-scan-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| cluster_id | ID of the cluster whose IOC scans are to be listed.<br/><br/>Note: Users can retrieve the list of the cluster IDs by executing the "rubrik-gps-cluster-list" command. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.RadarIOCScan.id | String | ID of the IOC scan. |
| RubrikPolaris.RadarIOCScan.startTime | String | Start time of the scan. |
| RubrikPolaris.RadarIOCScan.endTime | String | End time of the scan. |
| RubrikPolaris.RadarIOCScan.snapshots.id | String | Object ID of the system. |
| RubrikPolaris.RadarIOCScan.snapshots.snapshots | Unknown | List of snapshot IDs that are included in the scan. |

#### Command Example

```!rubrik-radar-ioc-scan-list cluster_id="052bf7af-93a3-44e9-a7d7-bc8dad4d6b43"```

#### Human Readable Output

### Radar IOC Scans

|Scan ID|Start Time|End Time|Scanned Objects|
|---|---|---|---|
| fcac511b-20b4-472d-9b65-9198cff8cd49 | 2021-10-12T04:52:08.777Z | Not Finished | VirtualMachine:::90da5ffb-432f-4dac-8c73-39260ff5493e-vm-5952003d-f95c-4ae0-bf9b-b5a80b210935 |
| ad435ff1-617b-468a-b5d3-736fa0e278b0 | 2021-10-28T06:05:53.059Z | 2021-10-28T07:16:16.715Z | VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-72277, VirtualMachine:::868aa03d-4145-4cb1-808b-e10c4f7a3741-vm-72279 |

### rubrik-gps-vm-recover-files

***
Recovers files from a snapshot backup, back into a system.

Note: To know about the recovery status, use the "rubrik-gps-async-result" command.

#### Base Command

`rubrik-gps-vm-recover-files`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| cluster_id | ID of the cluster where the snapshot resides.<br/><br/>Note: Users can get the cluster ID by executing the "rubrik-gps-cluster-list" command. | Required |
| snapshot_id | ID of the snapshot from which to recover files.<br/><br/>Note: Users can get the snapshot ID by executing the "rubrik-polaris-vm-object-snapshot-list" command. | Required |
| paths_to_recover | Comma separated paths of files and directories that will be recovered from the snapshot.<br/><br/>Note: Users can get the list of paths in a snapshot by executing the "rubrik-gps-snapshot-files-list" command. | Required |
| restore_path | Path on the destination object on which recovery will be done. | Required |
| destination_object_id | ID of the object where the files will be restored into. If not provided, Rubrik will use the snapshots object.<br/><br/>Note: Users can get the object ID by executing the "rubrik-polaris-vm-objects-list" command. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.GPSVMRecoverFiles.id | String | Recover files request ID. |

#### Command Example

```!rubrik-gps-vm-recover-files cluster_id="052bf7af-93a3-44e9-a7d7-bc8dad4d6b43" snapshot_id="e2a0ffa8-82a3-518b-8532-0608a0e7380f" path_to_recover="/bin,/boot" restore_path="/tmp/backup1"```

#### Human Readable Output

### GPS VM Recover Files

|Recover Files Request ID|
|---|
| dummy_id |

### rubrik-sonar-user-access-list

***
Retrieve the user access information.

#### Base Command

`rubrik-sonar-user-access-list`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| user_name | The name of the user to search for. | Optional |
| user_email | The email or the UPN of the user to search for. | Optional |
| search_time_period | Specify the search time period to look for user access.<br/><br/>Supported formats: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.<br/><br/>For example: 01 May 2023, 01 Mar 2023 04:45:33, 2023-04-17T14:05:44Z. Default is 7 days. | Optional |
| risk_levels | The comma-separated list of risk levels.<br/><br/>Supported values are: UNKNOWN_RISK, HIGH_RISK, MEDIUM_RISK, LOW_RISK, NO_RISK.<br/><br/>Note: For any other values, whether the obtained result is filtered or not, is not confirmed. | Optional |
| group_id | Specify the group ID to filter with. | Optional |
| include_whitelisted_results | The boolean indicates to include the whitelisted results.<br/><br/>Possible values are: "True", "False". Default is False. | Optional |
| principal_summary_category | Specify the principal summary category to filter with.<br/><br/>Supported values are: PRINCIPAL_SUMMARY_CATEGORY_UNSPECIFIED, USERS_WITH_SENSITIVE_ACCESS, NEW_USERS_WITH_SENSITIVE_ACCESS, USERS_WITH_RISK_LEVEL_INCREASE. Default is USERS_WITH_SENSITIVE_ACCESS.<br/><br/>Note: For any other values, whether the obtained result is filtered or not, is not confirmed. | Optional |
| limit | Number of results to retrieve in the response. The maximum allowed size is 1000. Default is 50. | Optional |
| page_number | Specify the page number to get the particular page of results in the response. Default is 1.<br/><br/>Note: This argument is only applicable when provided with the "user_email" argument. | Optional |
| sort_by | Specify the field to use for sorting the response.<br/><br/>Supported values are: RISK_LEVEL, RISK_SENSITIVE_FILES, RISK_SENSITIVE_HITS, TOTAL_SENSITIVE_HITS, TOTAL_SENSITIVE_FILES, SID, TOTAL_SENSITIVE_OBJECTS. Default is RISK_LEVEL.<br/><br/>Note: For any other values, whether the obtained result is filtered or not, is not confirmed. | Optional |
| sort_order | Specify the order to sort the data in.<br/><br/>Possible values are: "ASC", "DESC". Default is DESC. | Optional |
| next_page_token | The next page cursor to retrieve the next set of results. | Optional |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| RubrikPolaris.UserAccess.principalId | String | The ID of the user. |
| RubrikPolaris.UserAccess.fullName | String | The full name of the user. |
| RubrikPolaris.UserAccess.upn | String | The user principal name. |
| RubrikPolaris.UserAccess.riskLevel | String | The risk level of the user. |
| RubrikPolaris.UserAccess.sensitiveFiles.highRiskFileCount.totalCount | Number | The total number of high-risk files. |
| RubrikPolaris.UserAccess.sensitiveFiles.highRiskFileCount.violatedCount | Number | The number of high-risk files that violate policies. |
| RubrikPolaris.UserAccess.sensitiveFiles.highRiskFileCount.__typename | String | The high-risk file count field type. |
| RubrikPolaris.UserAccess.sensitiveFiles.mediumRiskFileCount.totalCount | Number | Total number of medium-risk files. |
| RubrikPolaris.UserAccess.sensitiveFiles.mediumRiskFileCount.violatedCount | Number | The number of medium-risk files that violate policies. |
| RubrikPolaris.UserAccess.sensitiveFiles.mediumRiskFileCount.__typename | String | The type of the medium risk file count field. |
| RubrikPolaris.UserAccess.sensitiveFiles.lowRiskFileCount.totalCount | Number | The total number of low-risk files. |
| RubrikPolaris.UserAccess.sensitiveFiles.lowRiskFileCount.violatedCount | Number | The number of low-risk files that violate policies. |
| RubrikPolaris.UserAccess.sensitiveFiles.lowRiskFileCount.__typename | String | The type of the low-risk file count field. |
| RubrikPolaris.UserAccess.sensitiveFiles.__typename | String | The type of the sensitive files field. |
| RubrikPolaris.UserAccess.totalSensitiveHits.totalHits | Number | The total number of sensitive hits. |
| RubrikPolaris.UserAccess.totalSensitiveHits.violatedHits | Number | The number of sensitive hits that violate policies. |
| RubrikPolaris.UserAccess.totalSensitiveHits.__typename | String | The type of the total sensitive hits field. |
| RubrikPolaris.UserAccess.sensitiveObjectCount.totalCount | Number | The total number of sensitive objects. |
| RubrikPolaris.UserAccess.sensitiveObjectCount.violatedCount | Number | The Number of sensitive objects that violate policies. |
| RubrikPolaris.UserAccess.sensitiveObjectCount.__typename | String | The type of the sensitive object count field. |
| RubrikPolaris.UserAccess.numDescendants | Number | The number of descendant users associated with this user. |
| RubrikPolaris.UserAccess.domainName | String | The domain name associated with this user. |
| RubrikPolaris.UserAccess.__typename | String | The type of the User Access field. |
| RubrikPolaris.PageToken.UserAccess.name | String | Name of the command. |
| RubrikPolaris.PageToken.UserAccess.startCursor | String | The start cursor for the current page. |
| RubrikPolaris.PageToken.UserAccess.endCursor | String | The end cursor for the current page. |
| RubrikPolaris.PageToken.UserAccess.hasNextPage | Boolean | Whether the result has the next page or not. |
| RubrikPolaris.PageToken.UserAccess.hasPreviousPage | Boolean | Whether the result has the previous page or not. |
| RubrikPolaris.PageToken.UserAccess.next_upn_page_number | String | The next UPN page number. |
| RubrikPolaris.PageToken.UserAccess.has_next_upn_page | Boolean | Whether the result has the next UPN page or not. |

#### Command example

```!rubrik-sonar-user-access-list user_name="Demo Rubrik" user_email="demo@rubrik.com" limit="1"```

#### Context Example

```json
{
    "RubrikPolaris": {
        "PageToken": {
            "UserAccess": {
                "endCursor": "cursor_1",
                "hasNextPage": false,
                "hasPreviousPage": false,
                "has_next_upn_page": false,
                "name": "rubrik-sonar-user-access-list",
                "next_upn_page_number": 1,
                "startCursor": "cursor_1"
            }
        },
        "UserAccess": {
            "__typename": "PrincipalSummary",
            "domainName": "rubrik.com",
            "fullName": "Demo Rubrik",
            "numDescendants": 0,
            "principalId": "S-1-0-01-0000000000-0000000000-000000000-0001",
            "riskLevel": "HIGH_RISK",
            "sensitiveFiles": {
                "__typename": "SensitiveFiles",
                "highRiskFileCount": {
                    "__typename": "SummaryCount",
                    "totalCount": 0,
                    "violatedCount": 124
                },
                "lowRiskFileCount": {
                    "__typename": "SummaryCount",
                    "totalCount": 0,
                    "violatedCount": 0
                },
                "mediumRiskFileCount": {
                    "__typename": "SummaryCount",
                    "totalCount": 0,
                    "violatedCount": 0
                }
            },
            "sensitiveObjectCount": {
                "__typename": "SummaryCount",
                "totalCount": 0,
                "violatedCount": 1
            },
            "totalSensitiveHits": {
                "__typename": "SummaryHits",
                "totalHits": 0,
                "violatedHits": 86972
            },
            "upn": "demo@rubrik.com"
        }
    }
}

Human Readable Output

User Access (Showing Records 1-1 out of 1)

User ID User Full Name User Principal Name Risk Level Total Sensitive Objects Total Sensitive Files Total Sensitive Hits
S-1-0-01-0000000000-0000000000-000000000-0001 Demo Rubrik demo@rubrik.com HIGH_RISK 1 124 86972

Note: To retrieve the next set of results, use next_page_token = “cursor_2”.

If next_page_token is provided, then it will reset the record numbers. For the initial use of next_page_token, please avoid specifying the page_number.

rubrik-sonar-user-access-get


Retrieve the user access information based on the provided user ID.

Base Command

rubrik-sonar-user-access-get

Input

Argument Name Description Required
user_id Specify the user_id to retrieve the user access information.

Note: Users can get the list of the user IDs by executing the “rubrik-sonar-user-access-list” command.
Required
search_time_period Specify the search time period to look for user access. Default is 7 days.

Supported formats: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 May 2023, 01 Mar 2023 04:45:33, 2023-04-17T14:05:44Z.
Optional
historical_delta_days Specify the number of days in the past to collect delta for the sensitive hits. Default is 7. Optional
include_whitelisted_results The boolean indicates to include the whitelisted results. Default is False.

Possible values are: “True”, “False”.
Optional

Context Output

Path Type Description
RubrikPolaris.UserAccess.principalId String The ID of the user.
RubrikPolaris.UserAccess.fullName String The full name of the user.
RubrikPolaris.UserAccess.upn String The user principal name.
RubrikPolaris.UserAccess.riskLevel String The risk level of the user.
RubrikPolaris.UserAccess.policy_hits_summary.__typename String The type of object representing the policy hits summary.
RubrikPolaris.UserAccess.policy_hits_summary.policyId String The unique identifier of the policy associated with the hits summary.
RubrikPolaris.UserAccess.policy_hits_summary.policyName String The human-readable name of the policy associated with the hits summary.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.__typename String The type of object representing the analyzer hits for a specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.highRiskHits.__typename String The type of object representing high-risk hits for the analyzer.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.highRiskHits.totalHits Number The total number of high-risk hits detected by the analyzer.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.highRiskHits.violatedHits Number The number of high-risk hits that violated security policies.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.lowRiskHits.__typename String The type of object representing low-risk hits for the analyzer.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.lowRiskHits.totalHits Number The total number of low-risk hits detected by the analyzer.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.lowRiskHits.violatedHits Number The number of low-risk hits that violated security policies.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.mediumRiskHits.__typename String The type of object representing medium-risk hits for the analyzer.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.mediumRiskHits.totalHits Number The total number of medium-risk hits detected by the analyzer.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.mediumRiskHits.violatedHits Number The number of medium-risk hits that violated security policies.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.totalHits.__typename String The type of object representing the total number of hits for the analyzer.
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.totalHits.totalHits Number The total number of hits detected by the analyzer (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidAnalyzerHits.totalHits.violatedHits Number The number of hits detected by the analyzer that violated security policies (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.__typename String The type of object representing the difference in analyzer hits between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.highRiskHits.__typename String The type of object representing the difference in high-risk hits for the analyzer between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.highRiskHits.totalHits Number The difference in the total number of high-risk hits detected by the analyzer between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.highRiskHits.violatedHits Number The difference in the number of high-risk hits that violated security policies between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.lowRiskHits.__typename String The type of object representing the difference in low-risk hits for the analyzer between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.lowRiskHits.totalHits Number The difference in the total number of low-risk hits detected by the analyzer between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.lowRiskHits.violatedHits Number The difference in the number of low-risk hits that violated security policies between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.mediumRiskHits.__typename String The type of object representing the difference in medium-risk hits for the analyzer between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.mediumRiskHits.totalHits Number The difference in the total number of medium-risk hits detected by the analyzer between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.mediumRiskHits.violatedHits Number The difference in the number of medium-risk hits that violated security policies between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.totalHits.__typename String The type of object representing the total difference in hits for the analyzer between the current and previous periods (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.totalHits.totalHits Number The total difference in the number of hits detected by the analyzer between the current and previous periods (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaAnalyzerHits.totalHits.violatedHits Number The difference in the number of hits detected by the analyzer that violated security policies between the current and previous periods (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.__typename String The type of object representing the difference in risk hits between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.highRiskHits.__typename String The type of object representing the difference in high-risk hits between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.highRiskHits.totalHits Number The difference in the total number of high-risk hits detected between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.highRiskHits.violatedHits Number The difference in the number of high-risk hits that violated security policies between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.lowRiskHits.__typename String The type of object representing the difference in low-risk hits between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.lowRiskHits.totalHits Number The difference in the total number of low-risk hits detected between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.lowRiskHits.violatedHits Number The difference in the number of low-risk hits that violated security policies between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.mediumRiskHits.__typename String The type of object representing the difference in medium-risk hits between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.mediumRiskHits.totalHits Number The difference in the total number of medium-risk hits detected between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.mediumRiskHits.violatedHits Number The difference in the number of medium-risk hits that violated security policies between the current and previous periods.
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.totalHits.__typename String The type of object representing the total difference in risk hits between the current and previous periods (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.totalHits.totalHits Number The total difference in the number of risk hits detected between the current and previous periods (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidDeltaRiskHits.totalHits.violatedHits Number The difference in the number of risk hits detected that violated security policies between the current and previous periods (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.__typename String The type of object representing the risk hits for a specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.highRiskHits.__typename String The type of object representing high-risk hits for the risk engine.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.highRiskHits.totalHits Number The total number of high-risk hits detected by the risk engine for the specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.highRiskHits.violatedHits Number The number of high-risk hits that violated security policies for the specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.lowRiskHits.__typename String The type of object representing low-risk hits for the risk engine.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.lowRiskHits.totalHits Number The total number of low-risk hits detected by the risk engine for the specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.lowRiskHits.violatedHits Number The number of low-risk hits that violated security policies for the specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.mediumRiskHits.__typename String The type of object representing medium-risk hits for the risk engine.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.mediumRiskHits.totalHits Number The total number of medium-risk hits detected by the risk engine for the specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.mediumRiskHits.violatedHits Number The number of medium-risk hits that violated security policies for the specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.totalHits.__typename String The type of object representing the total number of risk hits for the specific SID (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.totalHits.totalHits Number The total number of risk hits detected by the risk engine for the specific SID (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidRiskHits.totalHits.violatedHits Number The number of risk hits detected by the risk engine that violated security policies for the specific SID (all risk levels combined).
RubrikPolaris.UserAccess.policy_hits_summary.sidSensitiveFiles.__typename String The type of object representing the sensitive files associated with the specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidSensitiveFiles.totalFileCount.__typename String The type of object representing the total number of sensitive files associated with the specific SID.
RubrikPolaris.UserAccess.policy_hits_summary.sidSensitiveFiles.totalFileCount.totalCount Number The total number of sensitive files associated with the specific SID, including both compliant and non-compliant files.
RubrikPolaris.UserAccess.policy_hits_summary.sidSensitiveFiles.totalFileCount.violatedCount Number The number of sensitive files associated with the specific SID that violate security policies.
RubrikPolaris.UserAccess.riskReasons.accessRiskReasons Unknown The reasons why the user’s access is considered risky.
RubrikPolaris.UserAccess.riskReasons.insecureReasons Unknown The reasons why the user’s access is considered insecure.
RubrikPolaris.UserAccess.riskReasons.__typename String The type of the risk reasons field.
RubrikPolaris.UserAccess.sensitiveFiles.highRiskFileCount.totalCount Number The total number of high-risk files.
RubrikPolaris.UserAccess.sensitiveFiles.highRiskFileCount.violatedCount Number The number of high-risk files that violate policies.
RubrikPolaris.UserAccess.sensitiveFiles.highRiskFileCount.__typename String The high-risk file count field type.
RubrikPolaris.UserAccess.sensitiveFiles.mediumRiskFileCount.totalCount Number Total number of medium-risk files.
RubrikPolaris.UserAccess.sensitiveFiles.mediumRiskFileCount.violatedCount Number The number of medium-risk files that violate policies.
RubrikPolaris.UserAccess.sensitiveFiles.mediumRiskFileCount.__typename String The type of the medium risk file count field.
RubrikPolaris.UserAccess.sensitiveFiles.lowRiskFileCount.totalCount Number The total number of low-risk files.
RubrikPolaris.UserAccess.sensitiveFiles.lowRiskFileCount.violatedCount Number The number of low-risk files that violate policies.
RubrikPolaris.UserAccess.sensitiveFiles.lowRiskFileCount.__typename String The type of the low-risk file count field.
RubrikPolaris.UserAccess.sensitiveFiles.__typename String The type of the sensitive files field.
RubrikPolaris.UserAccess.totalSensitiveHits.totalHits Number The total number of sensitive hits.
RubrikPolaris.UserAccess.totalSensitiveHits.violatedHits Number The number of sensitive hits that violate policies.
RubrikPolaris.UserAccess.totalSensitiveHits.__typename String The type of the total sensitive hits field.
RubrikPolaris.UserAccess.sensitiveObjectCount.totalCount Number The total number of sensitive objects.
RubrikPolaris.UserAccess.sensitiveObjectCount.violatedCount Number The Number of sensitive objects that violate policies.
RubrikPolaris.UserAccess.sensitiveObjectCount.__typename String The type of the sensitive object count field.
RubrikPolaris.UserAccess.numDescendants Number The number of descendant users associated with this user.
RubrikPolaris.UserAccess.domainName String The domain name associated with this user.
RubrikPolaris.UserAccess.directGroups.name String The name of the direct group.
RubrikPolaris.UserAccess.directGroups.sid String The security identifier (SID) of the direct group.
RubrikPolaris.UserAccess.directGroups.__typename String The type of the direct groups field.
RubrikPolaris.UserAccess.__typename String The type of the User Access field.

Command example

!rubrik-sonar-user-access-get user_id="S-1-0-01-0000000000-0000000000-000000000-0001"

Context Example

{
    "RubrikPolaris": {
        "UserAccess": {
            "__typename": "PrincipalSummary",
            "directGroups": [
                {
                    "__typename": "UserAccessGroup",
                    "name": "Domain Admins",
                    "sid": "S-1-0-01-0000000000-0000000000-000000000-002"
                },
                {
                    "__typename": "UserAccessGroup",
                    "name": "Domain Users",
                    "sid": "S-1-0-01-0000000000-0000000000-000000000-003"
                }
            ],
            "domainName": "rubrik.com",
            "fullName": "DemoRubrik",
            "numDescendants": 0,
            "principalId": "S-1-0-01-0000000000-0000000000-000000000-0001",
            "riskLevel": "HIGH_RISK",
            "policy_hits_summary": [
                {
                    "policyId": "00000000-0000-0000-0000-000000000001",
                    "policyName": "Policy 1",
                    "sidSensitiveFiles": {
                        "totalFileCount": {
                            "totalCount": 164,
                            "violatedCount": 164,
                            "__typename": "SummaryCount"
                        },
                        "__typename": "SensitiveFiles"
                    },
                    "sidAnalyzerHits": {
                        "highRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "mediumRiskHits": {
                            "totalHits": 138118,
                            "violatedHits": 138118,
                            "__typename": "SummaryHits"
                        },
                        "lowRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "totalHits": {
                            "totalHits": 138118,
                            "violatedHits": 138118,
                            "__typename": "SummaryHits"
                        },
                        "__typename": "SensitiveHits"
                    },
                    "sidDeltaAnalyzerHits": {
                        "highRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "mediumRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "lowRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "totalHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "__typename": "SensitiveHits"
                    },
                    "sidRiskHits": {
                        "highRiskHits": {
                            "totalHits": 138118,
                            "violatedHits": 138118,
                            "__typename": "SummaryHits"
                        },
                        "mediumRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "lowRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "totalHits": {
                            "totalHits": 138118,
                            "violatedHits": 138118,
                            "__typename": "SummaryHits"
                        },
                        "__typename": "SensitiveHits"
                    },
                    "sidDeltaRiskHits": {
                        "highRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "mediumRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "lowRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "totalHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "__typename": "SensitiveHits"
                    },
                    "__typename": "PolicyHitsSummary"
                },
                {
                    "policyId": "00000000-0000-0000-0000-000000000002",
                    "policyName": "Policy 2",
                    "sidSensitiveFiles": {
                        "totalFileCount": {
                            "totalCount": 130,
                            "violatedCount": 130,
                            "__typename": "SummaryCount"
                        },
                        "__typename": "SensitiveFiles"
                    },
                    "sidAnalyzerHits": {
                        "highRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "mediumRiskHits": {
                            "totalHits": 101434,
                            "violatedHits": 101434,
                            "__typename": "SummaryHits"
                        },
                        "lowRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "totalHits": {
                            "totalHits": 101434,
                            "violatedHits": 101434,
                            "__typename": "SummaryHits"
                        },
                        "__typename": "SensitiveHits"
                    },
                    "sidDeltaAnalyzerHits": {
                        "highRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "mediumRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "lowRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "totalHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "__typename": "SensitiveHits"
                    },
                    "sidRiskHits": {
                        "highRiskHits": {
                            "totalHits": 101434,
                            "violatedHits": 101434,
                            "__typename": "SummaryHits"
                        },
                        "mediumRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "lowRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "totalHits": {
                            "totalHits": 101434,
                            "violatedHits": 101434,
                            "__typename": "SummaryHits"
                        },
                        "__typename": "SensitiveHits"
                    },
                    "sidDeltaRiskHits": {
                        "highRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "mediumRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "lowRiskHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "totalHits": {
                            "totalHits": 0,
                            "violatedHits": 0,
                            "__typename": "SummaryHits"
                        },
                        "__typename": "SensitiveHits"
                    },
                    "__typename": "PolicyHitsSummary"
                }
            ],
            "riskReasons": {
                "__typename": "PrincipalRiskReasons",
                "accessRiskReasons": [
                    "MEDIUM_RISK_ANALYZER_HITS",
                    "OPEN_ACCESS"
                ],
                "insecureReasons": [
                    "PASSWORD_NEVER_EXPIRES"
                ]
            },
            "sensitiveFiles": {
                "__typename": "SensitiveFiles",
                "highRiskFileCount": {
                    "__typename": "SummaryCount",
                    "totalCount": 0,
                    "violatedCount": 250
                },
                "lowRiskFileCount": {
                    "__typename": "SummaryCount",
                    "totalCount": 0,
                    "violatedCount": 0
                },
                "mediumRiskFileCount": {
                    "__typename": "SummaryCount",
                    "totalCount": 0,
                    "violatedCount": 0
                }
            },
            "sensitiveObjectCount": {
                "__typename": "SummaryCount",
                "totalCount": 0,
                "violatedCount": 2
            },
            "totalSensitiveHits": {
                "__typename": "SummaryHits",
                "totalHits": 0,
                "violatedHits": 173954
            },
            "upn": "demo@rubrik.com"
        }
    }
}

Human Readable Output

User Access

User ID User Full Name User Principal Name Risk Level Access Risk Reason(s) Insecure Reason(s) Groups Total Sensitive Objects Total Sensitive Files Total Sensitive Hits
S-1-0-01-0000000000-0000000000-000000000-0001 DemoRubrik demo@rubrik.com HIGH_RISK MEDIUM_RISK_ANALYZER_HITS, OPEN_ACCESS PASSWORD_NEVER_EXPIRES Domain Admins, Domain Users 2 250 173954

Sensitive Hits

Policy Name Total Sensitive Files Total Sensitive Hits Sensitive Hits Delta High Risk Hits Medium Risk Hits Low Risk Hits
Policy 1 164 138118 0 0 138118 0
Policy 2 130 101434 0 0 101434 0

rubrik-sonar-file-context-list


Retrieve the context of the file, folder, or file share for the provided object and the file details.

Base Command

rubrik-sonar-file-context-list

Input

Argument Name Description Required
object_id The Object ID or the Snappable ID.

Note: Users can get the list of the object IDs by executing the “rubrik-polaris-object-list” command.
Required
snapshot_id The Snapshot ID of the object.

Note: Users can get the list of the snapshot IDs by executing the “rubrik-polaris-object-snapshot-list” command.
Required
file_name Specify the name of the file, folder, or file share object. Optional
file_path Specify the standard file path to filter with. Optional
user_id Specify the user ID to filter with.

Note: Users can get the list of the user IDs by executing the “rubrik-sonar-user-access-list” command.
Optional
include_whitelisted_results The boolean indicates to include the whitelisted results.

Possible values are: “True”, “False”. Default is False.
Optional
limit Number of results to retrieve in the response. The maximum allowed size is 1000. Default is 50. Optional
sort_by Specify the field to use for sorting the response.

Supported values are: HITS, NAME, DAILY_CHANGE, LAST_ACCESS_TIME, OPEN_ACCESS_TYPE, FILES_WITH_HITS, FILES_WITH_OPEN_ACCESS_HITS, STALE_FILES_WITH_HITS, CLUSTER, OBJECT_NAME, OBJECT_LOCATION, SNAPSHOT_TIME, NUM_ACTIVITIES, NUM_ACTIVITIES_DELTA, NATIVE_PATH. Default is HITS.

Note: For any other values, whether the obtained result is filtered or not, is not confirmed.
Optional
sort_order Specify the order to sort the data in.

Possible values are: “ASC”, “DESC”. Default is DESC.
Optional
next_page_token The next page cursor to retrieve the next set of results. Optional

Context Output

Path Type Description
RubrikPolaris.FileContext.nativePath String The native path of the file.
RubrikPolaris.FileContext.stdPath String The standardized path of the file.
RubrikPolaris.FileContext.filename String The filename.
RubrikPolaris.FileContext.mode String The file mode.
RubrikPolaris.FileContext.size Number The file size in bytes.
RubrikPolaris.FileContext.lastAccessTime Number The last access time of the file in milliseconds since the epoch.
RubrikPolaris.FileContext.lastModifiedTime Number The last modified time of the file in milliseconds since the epoch.
RubrikPolaris.FileContext.creationTime Number The creation time of the file in milliseconds since the epoch.
RubrikPolaris.FileContext.lastScanTime Number The last scan time of the file in milliseconds since the epoch.
RubrikPolaris.FileContext.directory String The value of Directory.
RubrikPolaris.FileContext.createdBy String The user who created the file.
RubrikPolaris.FileContext.modifiedBy String The user who last modified the file.
RubrikPolaris.FileContext.numDescendantFiles Number The number of descendant files of the file.
RubrikPolaris.FileContext.numDescendantErrorFiles Number The number of descendant files of the file that could not be processed.
RubrikPolaris.FileContext.numDescendantSkippedExtFiles Number The number of descendant files of the file that were skipped because of their file extension.
RubrikPolaris.FileContext.numDescendantSkippedSizeFiles Number The number of descendant files of the file that were skipped because of their file size.
RubrikPolaris.FileContext.errorCode String The error code, if any, for the file.
RubrikPolaris.FileContext.hits.totalHits Number The total number of hits for the file.
RubrikPolaris.FileContext.hits.violations Number The number of violations for the file.
RubrikPolaris.FileContext.hits.violationsDelta Number The change in the number of violations for the file since the last scan.
RubrikPolaris.FileContext.hits.totalHitsDelta Number The change in the total number of hits for the file since the last scan.
RubrikPolaris.FileContext.hits.__typename String The type of the hits field.
RubrikPolaris.FileContext.filesWithHits.totalHits Number The total number of files with hits.
RubrikPolaris.FileContext.filesWithHits.violations Number The number of files with violations.
RubrikPolaris.FileContext.filesWithHits.__typename String The type of the files with hits field.
RubrikPolaris.FileContext.openAccessFilesWithHits.totalHits Number The total number of open access files with hits.
RubrikPolaris.FileContext.openAccessFilesWithHits.violations Number The number of open access files with violations.
RubrikPolaris.FileContext.openAccessFilesWithHits.__typename String The type of the open access files with hits field.
RubrikPolaris.FileContext.staleFilesWithHits.totalHits Number The total number of stale files with hits.
RubrikPolaris.FileContext.staleFilesWithHits.violations Number The number of stale files with violations.
RubrikPolaris.FileContext.staleFilesWithHits.__typename String The type of the stale files with hits field.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerGroup.groupType String The type of the analyzer group.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerGroup.id String The ID of the analyzer group.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerGroup.name String The name of the analyzer group.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerGroup.__typename String The type of the analyzer group field.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerResults.hits.totalHits Number The total number of hits for the analyzer results.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerResults.hits.violations Number The number of violations for the analyzer results.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerResults.hits.__typename String The type of the hits field.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerResults.analyzer.id String The ID of the analyzer.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerResults.analyzer.name String The name of the analyzer.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerResults.analyzer.analyzerType String The type of the analyzer.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerResults.analyzer.__typename String The type of the analyzer field.
RubrikPolaris.FileContext.analyzerGroupResults.analyzerResults.__typename String The type of the analyzer results field.
RubrikPolaris.FileContext.analyzerGroupResults.hits.totalHits Number The total number of hits for the analyzer group results.
RubrikPolaris.FileContext.analyzerGroupResults.hits.violations Number The number of violations for the analyzer group results.
RubrikPolaris.FileContext.analyzerGroupResults.hits.violationsDelta Number The change in the number of violations for the analyzer group results since the last scan.
RubrikPolaris.FileContext.analyzerGroupResults.hits.totalHitsDelta Number The change in the total number of hits for the analyzer group results since the last scan.
RubrikPolaris.FileContext.analyzerGroupResults.hits.__typename String The type of the hits field.
RubrikPolaris.FileContext.analyzerGroupResults.__typename String The type of the analyzer group results field.
RubrikPolaris.FileContext.sensitiveFiles.highRiskFileCount.totalCount Number The total number of high-risk files for the policy object.
RubrikPolaris.FileContext.sensitiveFiles.highRiskFileCount.violatedCount Number The number of high-risk files for the policy object that violates policies.
RubrikPolaris.FileContext.sensitiveFiles.highRiskFileCount.__typename String The type of the high-risk file count field.
RubrikPolaris.FileContext.sensitiveFiles.mediumRiskFileCount.totalCount Number The total number of medium-risk files for the policy object.
RubrikPolaris.FileContext.sensitiveFiles.mediumRiskFileCount.violatedCount Number The number of medium-risk files for the policy object that violates policies.
RubrikPolaris.FileContext.sensitiveFiles.mediumRiskFileCount.__typename String The type of the medium risk file count field.
RubrikPolaris.FileContext.sensitiveFiles.lowRiskFileCount.totalCount Number The total number of low-risk files for the policy object.
RubrikPolaris.FileContext.sensitiveFiles.lowRiskFileCount.violatedCount Number The number of low-risk files for the policy object that violates policies.
RubrikPolaris.FileContext.sensitiveFiles.lowRiskFileCount.__typename String The type of the low-risk file count field.
RubrikPolaris.FileContext.sensitiveFiles.noRiskFileCount.totalCount Number The total number of no-risk files for the policy object.
RubrikPolaris.FileContext.sensitiveFiles.noRiskFileCount.violatedCount Number The number of no-risk files for the policy object that violates policies.
RubrikPolaris.FileContext.sensitiveFiles.noRiskFileCount.__typename String The type of the no-risk file count field.
RubrikPolaris.FileContext.sensitiveFiles.totalFileCount.totalCount Number The total number of files for the policy object.
RubrikPolaris.FileContext.sensitiveFiles.totalFileCount.violatedCount Number The number of files for the policy object that violates policies.
RubrikPolaris.FileContext.sensitiveFiles.totalFileCount.__typename String The type of the total file count field.
RubrikPolaris.FileContext.sensitiveFiles.__typename String The type of the sensitive files field.
RubrikPolaris.FileContext.sensitiveHits.highRiskHits.totalHits Number The total number of high-risk sensitive hits for the file.
RubrikPolaris.FileContext.sensitiveHits.highRiskHits.violatedHits Number The number of high-risk sensitive hits for the file that violates policies.
RubrikPolaris.FileContext.sensitiveHits.highRiskHits.__typename String The type of the high-risk hits field.
RubrikPolaris.FileContext.sensitiveHits.mediumRiskHits.totalHits Number The total number of medium-risk sensitive hits for the file.
RubrikPolaris.FileContext.sensitiveHits.mediumRiskHits.violatedHits Number The number of medium-risk sensitive hits for the file that violates policies.
RubrikPolaris.FileContext.sensitiveHits.mediumRiskHits.__typename String The type of the medium-risk hits field.
RubrikPolaris.FileContext.sensitiveHits.lowRiskHits.totalHits Number The total number of low-risk sensitive hits for the file.
RubrikPolaris.FileContext.sensitiveHits.lowRiskHits.violatedHits Number The number of low-risk sensitive hits for the file that violates policies.
RubrikPolaris.FileContext.sensitiveHits.lowRiskHits.__typename String The type of the low-risk hits field.
RubrikPolaris.FileContext.sensitiveHits.noRiskHits.totalHits Number The total number of no-risk sensitive hits for the file.
RubrikPolaris.FileContext.sensitiveHits.noRiskHits.violatedHits Number The number of no-risk sensitive hits for the file that violates policies.
RubrikPolaris.FileContext.sensitiveHits.noRiskHits.__typename String The type of the no-risk hits field.
RubrikPolaris.FileContext.sensitiveHits.__typename String The type of the sensitive hits field.
RubrikPolaris.FileContext.analyzerRiskHits.highRiskHits.totalHits Number The total number of high-risk analyzer hits for the file.
RubrikPolaris.FileContext.analyzerRiskHits.highRiskHits.violatedHits Number The number of high-risk analyzer hits for the file that violates policies.
RubrikPolaris.FileContext.analyzerRiskHits.highRiskHits.__typename String The type of the high-risk hits field.
RubrikPolaris.FileContext.analyzerRiskHits.mediumRiskHits.totalHits Number The total number of medium-risk analyzer hits for the file.
RubrikPolaris.FileContext.analyzerRiskHits.mediumRiskHits.violatedHits Number The number of medium-risk analyzer hits for the file that violates policies.
RubrikPolaris.FileContext.analyzerRiskHits.mediumRiskHits.__typename String The type of the medium-risk hits field.
RubrikPolaris.FileContext.analyzerRiskHits.lowRiskHits.totalHits Number The total number of low-risk analyzer hits for the file.
RubrikPolaris.FileContext.analyzerRiskHits.lowRiskHits.violatedHits Number The number of low-risk analyzer hits for the file that violates policies.
RubrikPolaris.FileContext.analyzerRiskHits.lowRiskHits.__typename String The type of the low-risk hits field.
RubrikPolaris.FileContext.analyzerRiskHits.noRiskHits.totalHits Number The total number of no-risk analyzer hits for the file.
RubrikPolaris.FileContext.analyzerRiskHits.noRiskHits.violatedHits Number The number of no-risk analyzer hits for the file that violates policies.
RubrikPolaris.FileContext.analyzerRiskHits.noRiskHits.__typename String The type of the no-risk hits field.
RubrikPolaris.FileContext.analyzerRiskHits.__typename String The type of the analyzer risk hits field.
RubrikPolaris.FileContext.analyzerResults.hits.totalHits Number The total number of hits for the analyzer results.
RubrikPolaris.FileContext.analyzerResults.hits.violations Number The number of violations for the analyzer results.
RubrikPolaris.FileContext.analyzerResults.hits.__typename String The type of the hits field.
RubrikPolaris.FileContext.analyzerResults.analyzer.id String The ID of the analyzer.
RubrikPolaris.FileContext.analyzerResults.analyzer.name String The name of the analyzer.
RubrikPolaris.FileContext.analyzerResults.analyzer.analyzerType String The type of the analyzer.
RubrikPolaris.FileContext.analyzerResults.analyzer.__typename String The type of the analyzer field.
RubrikPolaris.FileContext.analyzerResults.__typename String The type of the analyzer results field.
RubrikPolaris.FileContext.openAccessType String The open access type for the file.
RubrikPolaris.FileContext.stalenessType String The staleness type for the file.
RubrikPolaris.FileContext.numActivities Number The number of activities for the file.
RubrikPolaris.FileContext.numActivitiesDelta Number The change in the number of activities for the file since the last time it was checked.
RubrikPolaris.FileContext.exposureSummary.exposureType String The exposure type of the file.
RubrikPolaris.FileContext.exposureSummary.fileCount.totalCount Number The total number of files with this exposure type.
RubrikPolaris.FileContext.exposureSummary.fileCount.violatedCount Number The number of files with this exposure type that violates policies.
RubrikPolaris.FileContext.exposureSummary.fileCount.__typename String The type of the file count field.
RubrikPolaris.FileContext.exposureSummary.__typename String The type of the exposure summary field.
RubrikPolaris.FileContext.dbEntityType String The database entity type of the file.
RubrikPolaris.FileContext.mipLabelsSummary.mipLabel.siteId String The site ID of the MIP label.
RubrikPolaris.FileContext.mipLabelsSummary.mipLabel.labelName String The name of the MIP label.
RubrikPolaris.FileContext.mipLabelsSummary.mipLabel.labelId String The ID of the MIP label.
RubrikPolaris.FileContext.mipLabelsSummary.mipLabel.hasProtection Boolean Whether the MIP label has protection applied.
RubrikPolaris.FileContext.mipLabelsSummary.mipLabel.__typename String The type of the MIP label field.
RubrikPolaris.FileContext.mipLabelsSummary.filesCount.violatedCount Number The number of files with this MIP label that violates policies.
RubrikPolaris.FileContext.mipLabelsSummary.filesCount.totalCount Number The total number of files with this MIP label.
RubrikPolaris.FileContext.mipLabelsSummary.filesCount.__typename String The type of the files count field.
RubrikPolaris.FileContext.mipLabelsSummary.__typename String The type of the MIP labels summary field.
RubrikPolaris.FileContext.documentTypesSummary.id String The ID of the document type.
RubrikPolaris.FileContext.documentTypesSummary.name String The name of the document type.
RubrikPolaris.FileContext.documentTypesSummary.filesCount.totalCount Number The total number of files of this document type.
RubrikPolaris.FileContext.documentTypesSummary.filesCount.violatedCount Number The number of files of this document type that violates policies.
RubrikPolaris.FileContext.documentTypesSummary.filesCount.__typename String The type of the files count field.
RubrikPolaris.FileContext.documentTypesSummary.__typename String The type of the document types summary field.
RubrikPolaris.FileContext.__typename String The type of the file context field.
RubrikPolaris.PageToken.FileContext.name String Name of the command.
RubrikPolaris.PageToken.FileContext.startCursor String The start cursor for the current page.
RubrikPolaris.PageToken.FileContext.endCursor String The end cursor for the current page.
RubrikPolaris.PageToken.FileContext.hasNextPage Boolean Whether the result has the next page or not.
RubrikPolaris.PageToken.FileContext.hasPreviousPage Boolean Whether the result has the previous page or not.

Command example

!rubrik-sonar-file-context-list object_id="1" snapshot_id="1" limit="2"

Context Example

{
    "RubrikPolaris": {
        "FileContext": [
            {
                "__typename": "FileResult",
                "analyzerGroupResults": [
                    {
                        "__typename": "AnalyzerGroupResult",
                        "analyzerGroup": {
                            "__typename": "AnalyzerGroup",
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000001",
                            "name": "UK PII"
                        },
                        "analyzerResults": [
                            {
                                "__typename": "AnalyzerResult",
                                "analyzer": {
                                    "__typename": "Analyzer",
                                    "analyzerType": "UK_UTR",
                                    "id": "00000000-0000-0000-0000-000000000001",
                                    "name": "UK UTR"
                                },
                                "hits": {
                                    "__typename": "Hits",
                                    "totalHits": 0,
                                    "violations": 0
                                }
                            }
                        ],
                        "hits": {
                            "__typename": "Hits",
                            "totalHits": 0,
                            "totalHitsDelta": 0,
                            "violations": 2000,
                            "violationsDelta": 0
                        }
                    }
                ],
                "analyzerResults": [
                    {
                        "__typename": "AnalyzerResult",
                        "analyzer": {
                            "__typename": "Analyzer",
                            "analyzerType": "UK_UTR",
                            "id": "00000000-0000-0000-0000-000000000001",
                            "name": "UK UTR"
                        },
                        "hits": {
                            "__typename": "Hits",
                            "totalHits": 0,
                            "violations": 0
                        }
                    }
                ],
                "analyzerRiskHits": {
                    "__typename": "AnalyzerHits",
                    "highRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 1500
                    },
                    "lowRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 100
                    },
                    "mediumRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 400
                    },
                    "noRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 0
                    }
                },
                "createdBy": "admin",
                "creationTime": 1648099578,
                "dbEntityType": "NAS",
                "directory": "/C:/File Shares",
                "documentTypesSummary": [
                    {
                        "__typename": "DocumentTypeSummary",
                        "filesCount": {
                            "__typename": "SummaryCount",
                            "totalCount": 0,
                            "violatedCount": 1
                        },
                        "id": "00000000-0000-0000-0000-000000000003",
                        "name": "Spreadsheet"
                    }
                ],
                "errorCode": "NO_ERROR",
                "exposureSummary": [
                    {
                        "__typename": "ExposureSummary",
                        "exposureType": "OPEN_ACCESS",
                        "fileCount": {
                            "__typename": "SummaryCount",
                            "totalCount": 0,
                            "violatedCount": 1
                        }
                    }
                ],
                "filename": "uk_drivers_license_number.xlsx",
                "filesWithHits": {
                    "__typename": "Hits",
                    "totalHits": 0,
                    "violations": 1
                },
                "hits": {
                    "__typename": "Hits",
                    "totalHits": 0,
                    "totalHitsDelta": 0,
                    "violations": 2000,
                    "violationsDelta": 0
                },
                "lastAccessTime": 1648099578,
                "lastModifiedTime": 1648099578,
                "lastScanTime": 1648099578,
                "mipLabelsSummary": [
                    {
                        "__typename": "MipLabelSummary",
                        "filesCount": {
                            "__typename": "SummaryCount",
                            "totalCount": 0,
                            "violatedCount": 1
                        },
                        "mipLabel": {
                            "__typename": "MipLabel",
                            "hasProtection": true,
                            "labelId": "00000000-0000-0000-0000-000000000002",
                            "labelName": "Confidential",
                            "siteId": "00000000-0000-0000-0000-000000000001"
                        }
                    }
                ],
                "mode": "FILE",
                "modifiedBy": "admin",
                "nativePath": "/C:/File Shares/drivers_license_number.xlsx",
                "numActivities": 0,
                "numActivitiesDelta": 0,
                "numDescendantErrorFiles": 0,
                "numDescendantFiles": 0,
                "numDescendantSkippedExtFiles": 0,
                "numDescendantSkippedSizeFiles": 0,
                "openAccessFilesWithHits": {
                    "__typename": "Hits",
                    "totalHits": 0,
                    "violations": 1
                },
                "openAccessType": "INHERITED",
                "sensitiveFiles": {
                    "__typename": "SensitiveFiles",
                    "highRiskFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 1
                    },
                    "lowRiskFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 0
                    },
                    "mediumRiskFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 0
                    },
                    "noRiskFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 0
                    },
                    "totalFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 1
                    }
                },
                "sensitiveHits": {
                    "__typename": "SensitiveHits",
                    "highRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 1500,
                        "violatedHits": 1500
                    },
                    "lowRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 100,
                        "violatedHits": 100
                    },
                    "mediumRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 400,
                        "violatedHits": 400
                    },
                    "noRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 0
                    }
                },
                "size": 85708,
                "staleFilesWithHits": {
                    "__typename": "Hits",
                    "totalHits": 0,
                    "violations": 1
                },
                "stalenessType": "IS_STALE",
                "stdPath": "/C:/File Shares/uk_drivers_license_number.xlsx"
            },
            {
                "__typename": "FileResult",
                "analyzerGroupResults": [
                    {
                        "__typename": "AnalyzerGroupResult",
                        "analyzerGroup": {
                            "__typename": "AnalyzerGroup",
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000001",
                            "name": "UK PII"
                        },
                        "analyzerResults": [
                            {
                                "__typename": "AnalyzerResult",
                                "analyzer": {
                                    "__typename": "Analyzer",
                                    "analyzerType": "UK_NINO",
                                    "id": "00000000-0000-0000-0000-000000000001",
                                    "name": "UK NINO"
                                },
                                "hits": {
                                    "__typename": "Hits",
                                    "totalHits": 0,
                                    "violations": 0
                                }
                            }
                        ],
                        "hits": {
                            "__typename": "Hits",
                            "totalHits": 0,
                            "totalHitsDelta": 0,
                            "violations": 1712,
                            "violationsDelta": 0
                        }
                    }
                ],
                "analyzerResults": [
                    {
                        "__typename": "AnalyzerResult",
                        "analyzer": {
                            "__typename": "Analyzer",
                            "analyzerType": "UK_NINO",
                            "id": "00000000-0000-0000-0000-000000000001",
                            "name": "UK NINO"
                        },
                        "hits": {
                            "__typename": "Hits",
                            "totalHits": 0,
                            "violations": 0
                        }
                    }
                ],
                "analyzerRiskHits": {
                    "__typename": "AnalyzerHits",
                    "highRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 1712
                    },
                    "lowRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 0
                    },
                    "mediumRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 0
                    },
                    "noRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 0
                    }
                },
                "createdBy": "admin",
                "creationTime": 1648099580,
                "dbEntityType": "NAS",
                "directory": "/C:/File Shares",
                "documentTypesSummary": [
                    {
                        "__typename": "DocumentTypeSummary",
                        "filesCount": {
                            "__typename": "SummaryCount",
                            "totalCount": 0,
                            "violatedCount": 1
                        },
                        "id": "00000000-0000-0000-0000-000000000003",
                        "name": "Spreadsheet"
                    }
                ],
                "errorCode": "NO_ERROR",
                "exposureSummary": [
                    {
                        "__typename": "ExposureSummary",
                        "exposureType": "OPEN_ACCESS",
                        "fileCount": {
                            "__typename": "SummaryCount",
                            "totalCount": 0,
                            "violatedCount": 1
                        }
                    }
                ],
                "filename": "uk_national_insurance_number.csv",
                "filesWithHits": {
                    "__typename": "Hits",
                    "totalHits": 0,
                    "violations": 1
                },
                "hits": {
                    "__typename": "Hits",
                    "totalHits": 0,
                    "totalHitsDelta": 0,
                    "violations": 1712,
                    "violationsDelta": 0
                },
                "lastAccessTime": 1648099580,
                "lastModifiedTime": 1648099580,
                "lastScanTime": 1648099580,
                "mipLabelsSummary": [
                    {
                        "__typename": "MipLabelSummary",
                        "filesCount": {
                            "__typename": "SummaryCount",
                            "totalCount": 0,
                            "violatedCount": 1
                        },
                        "mipLabel": {
                            "__typename": "MipLabel",
                            "hasProtection": true,
                            "labelId": "00000000-0000-0000-0000-000000000002",
                            "labelName": "Confidential",
                            "siteId": "00000000-0000-0000-0000-000000000001"
                        }
                    }
                ],
                "mode": "FILE",
                "modifiedBy": "admin",
                "nativePath": "/C:/File Shares/uk_national_insurance_number.csv",
                "numActivities": 0,
                "numActivitiesDelta": 0,
                "numDescendantErrorFiles": 0,
                "numDescendantFiles": 0,
                "numDescendantSkippedExtFiles": 0,
                "numDescendantSkippedSizeFiles": 0,
                "openAccessFilesWithHits": {
                    "__typename": "Hits",
                    "totalHits": 0,
                    "violations": 1
                },
                "openAccessType": "INHERITED",
                "sensitiveFiles": {
                    "__typename": "SensitiveFiles",
                    "highRiskFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 1
                    },
                    "lowRiskFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 0
                    },
                    "mediumRiskFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 0
                    },
                    "noRiskFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 0
                    },
                    "totalFileCount": {
                        "__typename": "SummaryCount",
                        "totalCount": 0,
                        "violatedCount": 1
                    }
                },
                "sensitiveHits": {
                    "__typename": "SensitiveHits",
                    "highRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 1712,
                        "violatedHits": 1712
                    },
                    "lowRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 0
                    },
                    "mediumRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 0
                    },
                    "noRiskHits": {
                        "__typename": "SummaryHits",
                        "totalHits": 0,
                        "violatedHits": 0
                    }
                },
                "size": 120064,
                "staleFilesWithHits": {
                    "__typename": "Hits",
                    "totalHits": 0,
                    "violations": 1
                },
                "stalenessType": "IS_STALE",
                "stdPath": "/C:/File Shares/uk_national_insurance_number.csv"
            }
        ],
        "PageToken": {
            "FileContext": {
                "endCursor": "cursor_2",
                "hasNextPage": true,
                "hasPreviousPage": false,
                "name": "rubrik-sonar-file-context-list",
                "startCursor": "cursor_1"
            }
        }
    }
}

Human Readable Output

File Context

File Name File Size in Bytes Total Risk Hits Daily Hits Change High Risk Hits Medium Risk Hits Low Risk Hits No Risk Hits File Path Access Type Last Access Time Last Modified Time Data Categories
uk_drivers_license_number.xlsx 85708 2000 0 1500 400 100 0 /C:/File Shares/uk_drivers_license_number.xlsx INHERITED 2022-03-24T05:26:18Z 2022-03-24T05:26:18Z - id: 00000000-0000-0000-0000-000000000001
name: UK PII
totalViolatedHits: 2000
uk_national_insurance_number.csv 120064 1712 0 1712 0 0 0 /C:/File Shares/uk_national_insurance_number.csv INHERITED 2022-03-24T05:26:20Z 2022-03-24T05:26:20Z - id: 00000000-0000-0000-0000-000000000001
name: UK PII
totalViolatedHits: 1712

Note: To retrieve the next set of results use, “next_page_token” = cursor_2

rubrik-radar-suspicious-file-list


Retrieve the suspicious list of files for a snapshot ID with detected file anomalies.

Base Command

rubrik-radar-suspicious-file-list

Input

Argument Name Description Required
snapshot_id The Snapshot ID of the object or Activity Series ID.

Note: Users can get the list of the snapshot IDs by executing the “rubrik-polaris-object-snapshot-list” command. For the Activity Series ID, the users can execute the “rubrik-event-list” command with the “activity_type” argument set to “ANOMALY”.
Required

Context Output

Path Type Description
RubrikPolaris.SuspiciousFile.id String The anomaly result ID.
RubrikPolaris.SuspiciousFile.snapshotFid String The snapshot ID.
RubrikPolaris.SuspiciousFile.cluster.id String The cluster ID.
RubrikPolaris.SuspiciousFile.cluster.defaultAddress String The default address of the cluster.
RubrikPolaris.SuspiciousFile.cluster.systemStatusAffectedNodes.ipAddress String The IP address of the affected node.
RubrikPolaris.SuspiciousFile.cluster.name String The cluster name.
RubrikPolaris.SuspiciousFile.cluster.version String The cluster version.
RubrikPolaris.SuspiciousFile.cluster.status String The cluster status.
RubrikPolaris.SuspiciousFile.cluster.__typename String The type name of the cluster response.
RubrikPolaris.SuspiciousFile.cdmId String The snapshot CDM ID.
RubrikPolaris.SuspiciousFile.managedId String The managed object ID.
RubrikPolaris.SuspiciousFile.anomalyProbability Number The probability of the anomaly.
RubrikPolaris.SuspiciousFile.workloadId String The workload ID.
RubrikPolaris.SuspiciousFile.location String The location of the anomaly.
RubrikPolaris.SuspiciousFile.isAnomaly Boolean Indicates if the file is an anomaly.
RubrikPolaris.SuspiciousFile.objectType String The object type.
RubrikPolaris.SuspiciousFile.snappableNew.objectType String The object type of the snapshot.
RubrikPolaris.SuspiciousFile.severity String The severity of the anomaly.
RubrikPolaris.SuspiciousFile.detectionTime Date The detection time of the anomaly.
RubrikPolaris.SuspiciousFile.snapshotDate Date The snapshot date of the anomaly.
RubrikPolaris.SuspiciousFile.encryption String The encryption standard of the anomaly.
RubrikPolaris.SuspiciousFile.resolutionStatus String The resolution status of the anomaly.
RubrikPolaris.SuspiciousFile.anomalyType String The type of the anomaly.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.strainId String The ID of the Ransomware Strain.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.totalAffectedFiles Number The total number of affected files.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.totalRansomwareNotes Number The total number of ransomware notes.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.sampleAffectedFilesInfo.filePath String The path of the affected file.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.sampleAffectedFilesInfo.lastModified Date The last modified time of the affected file.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.sampleAffectedFilesInfo.fileSizeBytes Number The size of the affected file in bytes.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.sampleAffectedFilesInfo.__typename String The type name of the affected file response.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.sampleRansomwareNoteFilesInfo.filePath String The path of the ransomware note file.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.sampleRansomwareNoteFilesInfo.lastModified Date The last modified time of the ransomware note file.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.sampleRansomwareNoteFilesInfo.fileSizeBytes Number The size of the ransomware note file in bytes.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.sampleRansomwareNoteFilesInfo.__typename String The type name of the ransomware note file response.
RubrikPolaris.SuspiciousFile.anomalyInfo.strainAnalysisInfo.__typename String The type name of the strain analysis response.
RubrikPolaris.SuspiciousFile.anomalyInfo.__typename String The type name of the anomaly response.
RubrikPolaris.SuspiciousFile.__typename String The type name of the suspicious file response.

Command example

!rubrik-radar-suspicious-file-list snapshot_id="00000000-0000-0000-0000-000000000001"

Context Example

{
    "RubrikPolaris": {
      "SuspiciousFile": {
        "id": "00000000-0000-0000-0000-000000000001:::VirtualMachine:::00000000-0000-0000-0000-000000000001-vm-206:::00000000-0000-0000-0000-000000000001",
        "snapshotFid": "00000000-0000-0000-0000-000000000001",
        "cluster": {
          "id": "00000000-0000-0000-0000-000000000001",
          "defaultAddress": "cluster.rubrik",
          "systemStatusAffectedNodes": [
            {
              "ipAddress": "0.0.0.0"
            }
          ],
          "name": "Cluster_B",
          "version": "8.1.3",
          "status": "Connected",
          "__typename": "Cluster"
        },
        "snappableNew": {
          "objectType": "VmwareVirtualMachine"
        },
        "cdmId": "00000000-0000-0000-0000-000000000001",
        "managedId": "VirtualMachine:::00000000-0000-0000-0000-000000000001-vm-206",
        "anomalyProbability": 0.949999988079071,
        "workloadId": "00000000-0000-0000-0000-000000000001-vm-206",
        "location": "instance.rubrik",
        "isAnomaly": true,
        "severity": "Critical",
        "detectionTime": "2024-02-05T18:49:03.000Z",
        "snapshotDate": "2024-02-05T16:59:30.000Z",
        "encryption": "HIGH",
        "resolutionStatus": "UNRESOLVED",
        "anomalyType": "FILESYSTEM",
        "anomalyInfo": {
          "strainAnalysisInfo": [
            {
              "strainId": "LockBit",
              "totalAffectedFiles": 1,
              "totalRansomwareNotes": 1,
              "sampleAffectedFilesInfo": [
                {
                  "filePath": "/C:/Shares/Restore-My-Files.txt.lockbit",
                  "lastModified": "2024-02-05T16:00:44.000Z",
                  "fileSizeBytes": 2512,
                  "__typename": "SuspiciousFileInfo"
                }
              ],
              "sampleRansomwareNoteFilesInfo": [
                {
                  "filePath": "/C:/Users/Public/Desktop/Restore-My-Files.txt",
                  "lastModified": "2024-02-08T02:00:03.000Z",
                  "fileSizeBytes": 2484,
                  "__typename": "SuspiciousFileInfo"
                }
              ],
              "__typename": "StrainInfo"
            }
          ],
          "__typename": "AnomalyInfo"
        },
        "__typename": "GetAnomalyDetailsReply"
      }
    }
}

Human Readable Output

Anomaly Information

Anomaly ID Is Anomaly Anomaly Probability Severity Encryption Anomaly Anomaly Type Resolution Status Total Suspicious Files Total Ransomware Note Detection Time Snapshot Time
00000000-0000-0000-0000-000000000001:::VirtualMachine:::00000000-0000-0000-0000-000000000001-vm-206:::00000000-0000-0000-0000-000000000001 true 0.949999988079071 Critical HIGH LockBit FILESYSTEM UNRESOLVED 1 1 2024-02-05T18:49:03.000Z 2024-02-05T16:59:30.000Z

Suspicious Files

File Path Suspicious Activity File Size in Bytes Last Modified Time
/C:/Shares/Restore-My-Files.txt.lockbit Ransomware Encryption 2512 2024-02-05T16:00:44.000Z
/C:/Users/Public/Desktop/Restore-My-Files.txt Ransomware Note 2484 2024-02-08T02:00:03.000Z

ip


Retrieve the sensitive information available for the given IP address(es).

Base Command

ip

Input

Argument Name Description Required
ip The IP address(es) for which to retrieve sensitive information. Required

Context Output

Path Type Description
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.
IP.Address String IP address.
IP.Relationships.EntityA String The source of the relationship.
IP.Relationships.EntityB String The destination of the relationship.
IP.Relationships.Relationship String The name of the relationship.
IP.Relationships.EntityAType String The type of the source of the relationship.
IP.Relationships.EntityBType String The type of the destination of the relationship.
IP.ASN String The autonomous system name for the IP address, for example: “AS8948”.
IP.Hostname String The hostname that is mapped to this IP address.
IP.Geo.Location String The geolocation where the IP address is located, in the format: latitude:longitude.
IP.Geo.Country String The country in which the IP address is located.
IP.Geo.Description String Additional information about the location.
IP.DetectionEngines Number The total number of engines that checked the indicator.
IP.PositiveDetections Number The number of engines that positively detected the indicator as malicious.
IP.Malicious.Vendor String The vendor reporting the IP address as malicious.
IP.Malicious.Description String A description explaining why the IP address was reported as malicious.
IP.Tags Unknown Tags of the IP address.
IP.FeedRelatedIndicators.value String Indicators that are associated with the IP address.
IP.FeedRelatedIndicators.type String The type of the indicators that are associated with the IP address.
IP.FeedRelatedIndicators.description String The description of the indicators that are associated with the IP address.
IP.MalwareFamily String The malware family associated with the IP address.
IP.Organization.Name String The organization of the IP address.
IP.Organization.Type String The organization type of the IP address.
IP.ASOwner String The autonomous system owner of the IP address.
IP.Region String The region in which the IP address is located.
IP.Port String Ports that are associated with the IP address.
IP.Internal Boolean Whether the IP address is internal or external.
IP.UpdatedDate Date The date that the IP address was last updated.
IP.Registrar.Abuse.Name String The name of the contact for reporting abuse.
IP.Registrar.Abuse.Address String The address of the contact for reporting abuse.
IP.Registrar.Abuse.Country String The country of the contact for reporting abuse.
IP.Registrar.Abuse.Network String The network of the contact for reporting abuse.
IP.Registrar.Abuse.Phone String The phone number of the contact for reporting abuse.
IP.Registrar.Abuse.Email String The email address of the contact for reporting abuse.
IP.Campaign String The campaign associated with the IP address.
IP.TrafficLightProtocol String The Traffic Light Protocol (TLP) color that is suitable for the IP address.
IP.CommunityNotes.note String Notes on the IP address that were given by the community.
IP.CommunityNotes.timestamp Date The time in which the note was published.
IP.Publications.source String The source in which the article was published.
IP.Publications.title String The name of the article.
IP.Publications.link String A link to the original article.
IP.Publications.timestamp Date The time in which the article was published.
IP.ThreatTypes.threatcategory String The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc.
IP.ThreatTypes.threatcategoryconfidence String The confidence level provided by the vendor for the threat type category For example, a confidence of 90 for the threat type category ‘malware’ means that the vendor rates that this is 90% confidence of being a malware.
RubrikPolaris.IP.ip String IP address of the object.
RubrikPolaris.IP.generalInfo.fid String The foreign ID of the object.
RubrikPolaris.IP.generalInfo.name String The name of the object.
RubrikPolaris.IP.generalInfo.objectType String The type of the object.
RubrikPolaris.IP.generalInfo.protectionStatus String The protection status of the object.
RubrikPolaris.IP.generalInfo.lastSnapshot Date The timestamp of the last snapshot of the object.
RubrikPolaris.IP.generalInfo.redirectLink String The link to the object in the Rubrik UI.
RubrikPolaris.IP.sensitiveInfo.riskLevel String The risk level of the object.
RubrikPolaris.IP.sensitiveInfo.sensitiveFiles.mediumCount String The number of sensitive files of medium risk level.
RubrikPolaris.IP.sensitiveInfo.sensitiveHits Number The number of sensitive files.
RubrikPolaris.IP.sensitiveInfo.openAccessFiles Number The number of open access files.
RubrikPolaris.IP.sensitiveInfo.staleFiles Number The number of stale files.
RubrikPolaris.IP.sensitiveInfo.redirectLink String The link to the sensitive information in the Rubrik UI.
RubrikPolaris.IP.sensitiveInfo.policyNames String The names of the policies associated with the object.
RubrikPolaris.IP.anomalyInfo.severity String The severity of the anomaly.
RubrikPolaris.IP.anomalyInfo.detectionTime Date The timestamp of the anomaly detection.
RubrikPolaris.IP.anomalyInfo.createdFileCount String The number of created files.
RubrikPolaris.IP.anomalyInfo.deletedFileCount String The number of deleted files.
RubrikPolaris.IP.anomalyInfo.modifiedFileCount String The number of modified files.
RubrikPolaris.IP.anomalyInfo.suspiciousFileCount String The number of suspicious files.
RubrikPolaris.IP.anomalyInfo.redirectLink String The link to the anomaly information in the Rubrik UI.
RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.huntId String The ID of the latest threat hunt.
RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.huntStartTime Date The timestamp of the latest threat hunt.
RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.isMalicious String Whether the latest threat hunt is malicious.
RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.huntId String The ID of the latest malicious threat hunt.
RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.huntStartTime Date The timestamp of the latest malicious threat hunt.
RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.isMalicious String Whether the latest malicious threat hunt is malicious.
RubrikPolaris.IP.threatHuntInfo.redirectLink String The link to the threat hunt information in the Rubrik UI.
RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.snapshotFid String The foreign ID of the latest threat monitoring snapshot.
RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.monitoringScanTime Date The timestamp of the latest threat monitoring scan.
RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.isMalicious String Whether the latest threat monitoring snapshot is malicious.
RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.snapshotFid String The foreign ID of the latest malicious threat monitoring snapshot.
RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.monitoringScanTime Date The timestamp of the latest malicious threat monitoring scan.
RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.isMalicious String Whether the latest malicious threat monitoring snapshot is malicious.
RubrikPolaris.IP.threatMonitoringInfo.redirectLink String The link to the threat monitoring information in the Rubrik UI.

Command example

!ip ip="0.0.0.1"

Context Example

{
    "DBotScore": {
        "Indicator": "0.0.0.1",
        "Reliability": "A - Completely reliable",
        "Score": 2,
        "Type": "ip",
        "Vendor": "Rubrik Security Cloud"
    },
    "IP": {
        "Address": "0.0.0.1",
        "UpdatedDate": "2024-10-21T08:51:52Z"
    },
    "RubrikPolaris": {
        "IP": {
            "ip": "0.0.0.1",
            "generalInfo": {
                "fid": "12345678-1234-1234-1234-123456789012",
                "name": "DEMO-RADAR",
                "objectType": "Vsphere Virtual Machine",
                "protectionStatus": "Protected",
                "lastSnapshot": "2024-10-18T06:02:25Z",
                "redirectLink": "https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview"
            },
            "sensitiveInfo": {
                "riskLevel": "Medium",
                "sensitiveFiles": {
                    "mediumCount": "11"
                },
                "sensitiveHits": 2910,
                "openAccessFiles": 6,
                "staleFiles": 11,
                "redirectLink": "https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse",
                "policyNames": [
                    "U.S. PII"
                ]
            },
            "anomalyInfo": {
                "severity": "Critical",
                "detectionTime": "2024-10-14T17:57:06Z",
                "createdFileCount": "4487",
                "deletedFileCount": "4477",
                "modifiedFileCount": "32",
                "suspiciousFileCount": "4476",
                "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary"
            },
            "threatHuntInfo": {
                "latestThreatHunt": {
                    "huntId": "12345678-1234-1234-1234-123456789012",
                    "huntStartTime": "2024-10-11T09:23:26Z",
                    "isMalicious": "Matches Found"
                },
                "latestMaliciousThreatHunt": {
                    "huntId": "12345678-1234-1234-1234-123456789012",
                    "huntStartTime": "2024-10-11T09:23:26Z",
                    "isMalicious": "Matches Found"
                },
                "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details"
            },
            "threatMonitoringInfo": {
                "latestThreatMonitoring": {
                    "snapshotFid": "12345678-1234-1234-1234-123456789012",
                    "monitoringScanTime": "2024-10-18T05:51:31Z",
                    "isMalicious": "No Matches"
                },
                "latestMaliciousThreatMonitoring": {
                    "snapshotFid": "12345678-1234-1234-1234-123456789012",
                    "monitoringScanTime": "2024-10-14T04:41:15Z",
                    "isMalicious": "Matches Found"
                },
                "redirectLink": "https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90"
            }
        }
    }
}

Human Readable Output

General Information for the given medium risk IP: 0.0.0.1

Fid Last Snapshot Name Object Type Protection Status Redirect Link
12345678-1234-1234-1234-123456789012 2024-10-18T06:02:25Z DEMO-RADAR Vsphere Virtual Machine Protected https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview

Sensitive Information

Open Access Files Policy Names Redirect Link Risk Level Sensitive Files Sensitive Hits Stale Files
6 U.S. PII https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse Medium mediumCount: 11 2910 11

Anomaly Information

Created File Count Deleted File Count Detection Time Modified File Count Redirect Link Severity Suspicious File Count
4487 4477 2024-10-14T17:57:06Z 32 https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary Critical 4476

Threat Hunt Information

Latest Malicious Threat Hunt Latest Threat Hunt Redirect Link
huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found
huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found
https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details

Threat Monitoring Information

Latest Malicious Threat Monitoring Latest Threat Monitoring Redirect Link
snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-14T04:41:15Z
isMalicious: Matches Found
snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-18T05:51:31Z
isMalicious: No Matches
https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90

domain


Retrieve the sensitive information available for the given domain(s).

Base Command

domain

Input

Argument Name Description Required
domain The domain(s) for which to retrieve sensitive information. Required

Context Output

Path Type Description
DBotScore.Indicator String The indicator that was tested.
DBotScore.Type String The indicator type.
DBotScore.Vendor String The vendor used to calculate the score.
DBotScore.Score Number The actual score.
DBotScore.Reliability String Reliability of the source providing the intelligence data.
Domain.Name String The domain name, for example: “google.com”.
Domain.Relationships.EntityA string The source of the relationship.
Domain.Relationships.EntityB string The destination of the relationship.
Domain.Relationships.Relationship string The name of the relationship.
Domain.Relationships.EntityAType string The type of the source of the relationship.
Domain.Relationships.EntityBType string The type of the destination of the relationship.
Domain.DNS String A list of IP objects resolved by DNS.
Domain.DetectionEngines Number The total number of engines that checked the indicator.
Domain.PositiveDetections Number The number of engines that positively detected the indicator as malicious.
Domain.CreationDate Date The date that the domain was created.
Domain.UpdatedDate String The date that the domain was last updated.
Domain.ExpirationDate Date The expiration date of the domain.
Domain.DomainStatus Datte The status of the domain.
Domain.NameServers Unknown (List<String>) Name servers of the domain.
Domain.Organization String The organization of the domain.
Domain.Subdomains Unknown (List<String>) Subdomains of the domain.
Domain.Admin.Country String The country of the domain administrator.
Domain.Admin.Email String The email address of the domain administrator.
Domain.Admin.Name String The name of the domain administrator.
Domain.Admin.Phone String The phone number of the domain administrator.
Domain.Registrant.Country String The country of the registrant.
Domain.Registrant.Email String The email address of the registrant.
Domain.Registrant.Name String The name of the registrant.
Domain.Registrant.Phone String The phone number for receiving abuse reports.
Domain.Tags Unknown Tags of the domain.
Domain.FeedRelatedIndicators.value String Indicators that are associated with the domain.
Domain.FeedRelatedIndicators.type String The type of the indicators that are associated with the domain.
Domain.FeedRelatedIndicators.description String The description of the indicators that are associated with the domain.
Domain.MalwareFamily String The malware family associated with the domain.
Domain.WHOIS.DomainStatus String The status of the domain.
Domain.WHOIS.NameServers String (List<String>) Name servers of the domain.
Domain.WHOIS.CreationDate Date The date that the domain was created.
Domain.WHOIS.UpdatedDate Date The date that the domain was last updated.
Domain.WHOIS.ExpirationDate Date The expiration date of the domain.
Domain.WHOIS.Registrant.Name String The name of the registrant.
Domain.WHOIS.Registrant.Email String The email address of the registrant.
Domain.WHOIS.Registrant.Phone String The phone number of the registrant.
Domain.WHOIS.Registrar.Name String The name of the registrar, for example: “GoDaddy”.
Domain.WHOIS.Registrar.AbuseEmail String The email address of the contact for reporting abuse.
Domain.WHOIS.Registrar.AbusePhone String The phone number of contact for reporting abuse.
Domain.WHOIS.Admin.Name String The name of the domain administrator.
Domain.WHOIS.Admin.Email String The email address of the domain administrator.
Domain.WHOIS.Admin.Phone String The phone number of the domain administrator.
Domain.WHOIS/History String List of Whois objects.
Domain.Malicious.Vendor String The vendor reporting the domain as malicious.
Domain.Malicious.Description String A description explaining why the domain was reported as malicious.
Domain.DomainIDNName String The internationalized domain name (IDN) of the domain.
Domain.Port String Ports that are associated with the domain.
Domain.Internal Bool Whether or not the domain is internal or external.
Domain.Category String The category associated with the indicator.
Domain.Campaign String The campaign associated with the domain.
Domain.TrafficLightProtocol String The Traffic Light Protocol (TLP) color that is suitable for the domain.
Domain.ThreatTypes.threatcategory String The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc.
Domain.ThreatTypes.threatcategoryconfidence String Threat Category Confidence is the confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category ‘malware’ means that the vendor rates that this is 90% confidence of being a malware.
Domain.Geo.Location String The geolocation where the domain address is located, in the format: latitude:longitude.
Domain.Geo.Country String The country in which the domain address is located.
Domain.Geo.Description String Additional information about the location.
Domain.Tech.Country String The country of the domain technical contact.
Domain.Tech.Name String The name of the domain technical contact.
Domain.Tech.Organization String The organization of the domain technical contact.
Domain.Tech.Email String The email address of the domain technical contact.
Domain.CommunityNotes.note String Notes on the domain that were given by the community.
Domain.CommunityNotes.timestamp Date The time in which the note was published.
Domain.Publications.source String The source in which the article was published.
Domain.Publications.title String The name of the article.
Domain.Publications.link String A link to the original article.
Domain.Publications.timestamp Date The time in which the article was published.
Domain.Billing String The billing address of the domain.
RubrikPolaris.Domain.domain String The domain of the object.
RubrikPolaris.Domain.generalInfo.fid String The foreign ID of the object.
RubrikPolaris.Domain.generalInfo.name String The name of the object.
RubrikPolaris.Domain.generalInfo.objectType String The type of the object.
RubrikPolaris.Domain.generalInfo.protectionStatus String The protection status of the object.
RubrikPolaris.Domain.generalInfo.lastSnapshot Date The timestamp of the last snapshot of the object.
RubrikPolaris.Domain.generalInfo.redirectLink String The link to the object in the Rubrik UI.
RubrikPolaris.Domain.sensitiveInfo.riskLevel String The risk level of the object.
RubrikPolaris.Domain.sensitiveInfo.sensitiveFiles.mediumCount String The number of sensitive files of medium risk level.
RubrikPolaris.Domain.sensitiveInfo.sensitiveHits Number The number of sensitive files.
RubrikPolaris.Domain.sensitiveInfo.openAccessFiles Number The number of open access files.
RubrikPolaris.Domain.sensitiveInfo.staleFiles Number The number of stale files.
RubrikPolaris.Domain.sensitiveInfo.redirectLink String The link to the sensitive information in the Rubrik UI.
RubrikPolaris.Domain.sensitiveInfo.policyNames String The names of the policies associated with the object.
RubrikPolaris.Domain.anomalyInfo.severity String The severity of the anomaly.
RubrikPolaris.Domain.anomalyInfo.detectionTime Date The timestamp of the anomaly detection.
RubrikPolaris.Domain.anomalyInfo.createdFileCount String The number of created files.
RubrikPolaris.Domain.anomalyInfo.deletedFileCount String The number of deleted files.
RubrikPolaris.Domain.anomalyInfo.modifiedFileCount String The number of modified files.
RubrikPolaris.Domain.anomalyInfo.suspiciousFileCount String The number of suspicious files.
RubrikPolaris.Domain.anomalyInfo.redirectLink String The link to the anomaly information in the Rubrik UI.
RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.huntId String The ID of the latest threat hunt.
RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.huntStartTime Date The timestamp of the latest threat hunt.
RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.isMalicious String Whether the latest threat hunt is malicious.
RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.huntId String The ID of the latest malicious threat hunt.
RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.huntStartTime Date The timestamp of the latest malicious threat hunt.
RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.isMalicious String Whether the latest malicious threat hunt is malicious.
RubrikPolaris.Domain.threatHuntInfo.redirectLink String The link to the threat hunt information in the Rubrik UI.
RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.snapshotFid String The foreign ID of the latest threat monitoring snapshot.
RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.monitoringScanTime Date The timestamp of the latest threat monitoring scan.
RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.isMalicious String Whether the latest threat monitoring snapshot is malicious.
RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.snapshotFid String The foreign ID of the latest malicious threat monitoring snapshot.
RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.monitoringScanTime Date The timestamp of the latest malicious threat monitoring scan.
RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.isMalicious String Whether the latest malicious threat monitoring snapshot is malicious.
RubrikPolaris.Domain.threatMonitoringInfo.redirectLink String The link to the threat monitoring information in the Rubrik UI.

Command example

!domain domain="DEMO-RADAR" using-brand=RubrikPolaris

Context Example

{
    "DBotScore": {
        "Indicator": "DEMO-RADAR",
        "Reliability": "A - Completely reliable",
        "Score": 2,
        "Type": "domain",
        "Vendor": "Rubrik Security Cloud"
    },
    "Domain": {
        "Name": "DEMO-RADAR",
        "UpdatedDate": "2024-11-05T04:34:47Z",
        "WHOIS": {
            "UpdatedDate": "2024-11-05T04:34:47Z"
        }
    },
    "RubrikPolaris": {
        "Domain": {
            "domain": "DEMO-RADAR",
            "generalInfo": {
                "fid": "12345678-1234-1234-1234-123456789012",
                "name": "DEMO-RADAR",
                "objectType": "Vsphere Virtual Machine",
                "protectionStatus": "Protected",
                "lastSnapshot": "2024-10-18T06:02:25Z",
                "redirectLink": "https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview"
            },
            "anomalyInfo": {
                "severity": "Critical",
                "detectionTime": "2024-10-14T17:57:06Z",
                "createdFileCount": "4487",
                "deletedFileCount": "4477",
                "modifiedFileCount": "32",
                "suspiciousFileCount": "4476",
                "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary"
            },
            "sensitiveInfo": {
                "riskLevel": "Medium",
                "sensitiveFiles": {
                    "mediumCount": "11"
                },
                "sensitiveHits": 2910,
                "openAccessFiles": 6,
                "staleFiles": 11,
                "redirectLink": "https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse",
                "policyNames": [
                    "U.S. PII"
                ]
            },
            "threatHuntInfo": {
                "latestThreatHunt": {
                    "huntId": "12345678-1234-1234-1234-123456789012",
                    "huntStartTime": "2024-10-11T09:23:26Z",
                    "isMalicious": "Matches Found"
                },
                "latestMaliciousThreatHunt": {
                    "huntId": "12345678-1234-1234-1234-123456789012",
                    "huntStartTime": "2024-10-11T09:23:26Z",
                    "isMalicious": "Matches Found"
                },
                "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details"
            },
            "threatMonitoringInfo": {
                "latestThreatMonitoring": {
                    "snapshotFid": "12345678-1234-1234-1234-123456789012",
                    "monitoringScanTime": "2024-10-18T05:51:31Z",
                    "isMalicious": "No Matches"
                },
                "latestMaliciousThreatMonitoring": {
                    "snapshotFid": "12345678-1234-1234-1234-123456789012",
                    "monitoringScanTime": "2024-10-14T04:41:15Z",
                    "isMalicious": "Matches Found"
                },
                "redirectLink": "https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90"
            }
        }
    }
}

Human Readable Output

General Information for the given medium risk domain: DEMO-RADAR

Fid Last Snapshot Name Object Type Protection Status Redirect Link
12345678-1234-1234-1234-123456789012 2024-10-18T06:02:25Z DEMO-RADAR Vsphere Virtual Machine Protected https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview

Sensitive Information

Open Access Files Policy Names Redirect Link Risk Level Sensitive Files Sensitive Hits Stale Files
6 U.S. PII https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse Medium mediumCount: 11 2910 11

Anomaly Information

Created File Count Deleted File Count Detection Time Modified File Count Redirect Link Severity Suspicious File Count
4487 4477 2024-10-14T17:57:06Z 32 https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary Critical 4476

Threat Hunt Information

Latest Malicious Threat Hunt Latest Threat Hunt Redirect Link
huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found
huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found
https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details

Threat Monitoring Information

Latest Malicious Threat Monitoring Latest Threat Monitoring Redirect Link
snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-14T04:41:15Z
isMalicious: Matches Found
snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-18T05:51:31Z
isMalicious: No Matches
https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90

rubrik-radar-anomaly-status-update


Updates the status of the Anomaly detection.

Note: Run the “rubrik-radar-suspicious-file-list” command first to check the resolution status of the Anomaly Detection snapshot before executing this command.

Base Command

rubrik-radar-anomaly-status-update

Input

Argument Name Description Required
anomaly_type The type of the anomaly.

Note: For Anomaly Type, users can execute the “rubrik-radar-suspicious-file-list” command. Possible values are: FILESYSTEM, HYPERVISOR.
Required
anomaly_id The ID of the Anomaly or Activity Series ID.

Note: For Activity Series ID, users can execute the “rubrik-event-list” command with the “activity_type” argument set to “ANOMALY”.
Required
workload_id The workload ID (Snappable ID).

Note: Users can execute the “rubrik-event-list” command with the “activity_type” argument set to “ANOMALY” and get the value of “fid” from the context.
Required
false_positive_type The type for marking the anomaly as a false positive. Possible values are: FP_TYPE_UNSPECIFIED, OS_UPDATE, APPLICATION_UPDATE, LOG_ROTATION, OTHER, NFA_SCHEDULED_MAINTENANCE, NFA_UNSCHEDULED_MAINTENANCE. Optional
false_positive_reason The reason for marking the anomaly as a false positive when the “false_positive_type” argument is set to OTHER. Optional

Context Output

Path Type Description
RubrikPolaris.AnomalyStatus.command_name String The name of the command.
RubrikPolaris.AnomalyStatus.anomaly_type String The type of the Anomaly.
RubrikPolaris.AnomalyStatus.anomaly_id String The ID of the Anomaly.
RubrikPolaris.AnomalyStatus.workload_id String The workload ID.
RubrikPolaris.AnomalyStatus.is_resloved Boolean Whether the Anomaly is resolved.
RubrikPolaris.AnomalyStatus.false_positive_type String The type of the false positive.
RubrikPolaris.AnomalyStatus.false_positive_reason String The reason for marking the Anomaly detection snapshot as a false positive.

Command example

!rubrik-radar-anomaly-status-update anomaly_id=00000000-0000-0000-0000-000000000001 anomaly_type=FILESYSTEM workload_id=00000000-0000-0000-0000-000000000002

Context Example

{
    "RubrikPolaris": {
        "AnomalyStatus": {
            "anomaly_id": "00000000-0000-0000-0000-000000000001",
            "anomaly_type": "FILESYSTEM",
            "command_name": "rubrik-radar-anomaly-update-status",
            "is_resloved": true,
            "workload_id": "00000000-0000-0000-0000-000000000002"
        }
    }
}

Human Readable Output

Anomaly detection with the ID 00000000-0000-0000-0000-000000000001 resolved successfully

rubrik-threat-monitoring-matched-object-list


List the matched objects for Threat Monitoring.

Base Command

rubrik-threat-monitoring-matched-object-list

Input

Argument Name Description Required
cluster_id The unique ID of the cluster. Supports comma separated values.

Note: Users can retrieve the list of the cluster IDs by executing the “rubrik-gps-cluster-list” command.
Optional
object_type Filter the objects based on the provided object types. Supports comma separated values.

Note: Values not included in the predefined options can be found in the documentation.
Optional
object_name Filter objects by their name. Supports partial matches. Optional
match_type Filter the objects by the match type. Supports comma separated values.

Possible values are: INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME, INDICATOR_OF_COMPROMISE_TYPE_HASH, INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE.
Optional
start_time Filter the objects detected after this time.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 June 2025, 01 June 2025 04:45:33, 2025-06-17T14:05:44Z. Default is 7 days.
Optional
limit Number of results to retrieve in the response. The maximum allowed size is 1000. Optional
next_page_token The next page cursor to retrieve the next set of results. Optional

Context Output

Path Type Description
RubrikPolaris.ThreatMonitoring.objectFid String The unique identifier (FID) of the object.
RubrikPolaris.ThreatMonitoring.objectName String The name of the matched object.
RubrikPolaris.ThreatMonitoring.objectType String The type of the matched object.
RubrikPolaris.ThreatMonitoring.matchType Unknown A list of match types found for the object.
RubrikPolaris.ThreatMonitoring.filesMatched Number The number of files matched with the threat monitoring object.
RubrikPolaris.ThreatMonitoring.lastDetection Date The timestamp of the most recent detection.
RubrikPolaris.ThreatMonitoring.cluster.name String The name of the cluster the object belongs to.
RubrikPolaris.ThreatMonitoring.cluster.id String The unique identifier of the cluster.
RubrikPolaris.ThreatMonitoring.cluster.__typename String The GraphQL typename of the cluster object.
RubrikPolaris.ThreatMonitoring.__typename String The GraphQL typename of the matched object.
RubrikPolaris.PageToken.ThreatMonitoring.endCursor String The end cursor of the threat monitoring data.
RubrikPolaris.PageToken.ThreatMonitoring.hasNextPage Boolean A flag indicating if there is a next page of threat monitoring data.
RubrikPolaris.PageToken.ThreatMonitoring.hasPreviousPage Boolean A flag indicating if there is a previous page of threat monitoring data.
RubrikPolaris.PageToken.ThreatMonitoring.name String The name of the threat monitoring data.
RubrikPolaris.PageToken.ThreatMonitoring.total_matched_count Number The total number of matched objects.
RubrikPolaris.PageToken.ThreatMonitoring.startCursor String The start cursor of the threat monitoring data.

Command example

!rubrik-threat-monitoring-matched-object-list begin_time="3 days"

Context Example

{
    "RubrikPolaris": {
        "ThreatMonitoring": [
            {   
                "__typename": "dummy-typename",
                "cluster": {
                    "__typename": "dummy-typename",
                    "id": "dummy-cluster-id-123",
                    "name": "dummy-cluster-name"
                },
                "filesMatched": 1,
                "lastDetection": "2025-01-01T00:00:00.000Z",
                "matchType": [
                    "dummy-match-type"
                ],
                "objectFid": "dummy-fid-789012",
                "objectName": "dummy-object-name-456",
                "objectType": "dummy-object-type"
            }
        ],
        "PageToken": {
            "ThreatMonitoring": {
                "endCursor": "dummy-end-cursor",
                "hasNextPage": true,
                "hasPreviousPage": false,
                "name": "rubrik-threat-monitoring-matched-object-list",
                "startCursor": "dummy-start-cursor",
                "total_matched_count": 2
            }
        }
    }
}

Human Readable Output

Threat Monitoring Object List

Object ID Object Name Object Type Total Files Matched Match Types Last Detection Time Cluster ID Cluster Name
dummy-fid-789012 dummy-object-name-456 dummy-object-type 0 dummy-match-type 2025-01-01T00:00:00.000Z dummy-cluster-id-123 dummy-cluster-name

Note: To retrieve the next set of results use, “next_page_token” = dummy-end-cursor

rubrik-threat-monitoring-matched-object-get


Get the matched object for Threat Monitoring.

Base Command

rubrik-threat-monitoring-matched-object-get

Input

Argument Name Description Required
object_id The object ID for the threat monitoring object.

Note: Users can retrieve the object ID by executing the “rubrik-threat-monitoring-matched-object-list” command.
Required

Context Output

Path Type Description
RubrikPolaris.ThreatMonitoring.id String The ID of the threat monitoring data.
RubrikPolaris.ThreatMonitoring.name String The name of the threat monitoring data.
RubrikPolaris.ThreatMonitoring.objectType String The object type of the threat monitoring data.
RubrikPolaris.ThreatMonitoring.slaAssignment String The SLA assignment of the threat monitoring data.
RubrikPolaris.ThreatMonitoring.slaPauseStatus String The SLA pause status of the threat monitoring data.
RubrikPolaris.ThreatMonitoring.effectiveSlaDomain.id String The ID of the effective SLA domain.
RubrikPolaris.ThreatMonitoring.effectiveSlaDomain.name String The name of the effective SLA domain.
RubrikPolaris.ThreatMonitoring.effectiveSlaDomain.version String The version of the effective SLA domain.
RubrikPolaris.ThreatMonitoring.effectiveSlaDomain.__typename String The type name of the effective SLA domain.
RubrikPolaris.ThreatMonitoring.snapshotDistribution.id String The ID of the snapshot distribution.
RubrikPolaris.ThreatMonitoring.snapshotDistribution.totalCount Integer The total count of the snapshot distribution.
RubrikPolaris.ThreatMonitoring.snapshotDistribution.scheduledCount Integer The scheduled count of the snapshot distribution.
RubrikPolaris.ThreatMonitoring.snapshotDistribution.onDemandCount Integer The on-demand count of the snapshot distribution.
RubrikPolaris.ThreatMonitoring.snapshotDistribution.retrievedCount Integer The retrieved count of the snapshot distribution.
RubrikPolaris.ThreatMonitoring.snapshotDistribution.__typename String The type name of the snapshot distribution.
RubrikPolaris.ThreatMonitoring.effectiveRetentionSlaDomain.id String The ID of the effective retention SLA domain.
RubrikPolaris.ThreatMonitoring.effectiveRetentionSlaDomain.name String The name of the effective retention SLA domain.
RubrikPolaris.ThreatMonitoring.effectiveRetentionSlaDomain.version String The version of the effective retention SLA domain.
RubrikPolaris.ThreatMonitoring.effectiveRetentionSlaDomain.__typename String The type name of the effective retention SLA domain.
RubrikPolaris.ThreatMonitoring.configuredSlaDomain.id String The ID of the configured SLA domain.
RubrikPolaris.ThreatMonitoring.configuredSlaDomain.name String The name of the configured SLA domain.
RubrikPolaris.ThreatMonitoring.configuredSlaDomain.version String The version of the configured SLA domain.
RubrikPolaris.ThreatMonitoring.configuredSlaDomain.__typename String The type name of the configured SLA domain.
RubrikPolaris.ThreatMonitoring.effectiveSlaSourceObject.fid String The FID of the effective SLA source object.
RubrikPolaris.ThreatMonitoring.effectiveSlaSourceObject.name String The name of the effective SLA source object.
RubrikPolaris.ThreatMonitoring.effectiveSlaSourceObject.objectType String The object type of the effective SLA source object.
RubrikPolaris.ThreatMonitoring.effectiveSlaSourceObject.__typename String The type name of the effective SLA source object.
RubrikPolaris.ThreatMonitoring.logicalPath.fid String The FID of the logical path.
RubrikPolaris.ThreatMonitoring.logicalPath.name String The name of the logical path.
RubrikPolaris.ThreatMonitoring.logicalPath.objectType String The object type of the logical path.
RubrikPolaris.ThreatMonitoring.logicalPath.__typename String The type name of the logical path.
RubrikPolaris.ThreatMonitoring.physicalPath.fid String The FID of the physical path.
RubrikPolaris.ThreatMonitoring.physicalPath.name String The name of the physical path.
RubrikPolaris.ThreatMonitoring.physicalPath.objectType String The object type of the physical path.
RubrikPolaris.ThreatMonitoring.physicalPath.__typename String The type name of the physical path.
RubrikPolaris.ThreatMonitoring.numWorkloadDescendants Integer The number of workload descendants.
RubrikPolaris.ThreatMonitoring.allOrgs.id String The ID of the organization.
RubrikPolaris.ThreatMonitoring.allOrgs.name String The name of the organization.
RubrikPolaris.ThreatMonitoring.allOrgs.description String The description of the organization.
RubrikPolaris.ThreatMonitoring.allOrgs.mfaStatus String The MFA status of the organization.
RubrikPolaris.ThreatMonitoring.allOrgs.allUrls String The all URLs of the organization.
RubrikPolaris.ThreatMonitoring.allOrgs.__typename String The type name of the organization.
RubrikPolaris.ThreatMonitoring.securityMetadata.lowSensitiveHits Integer The low sensitive hits of the security metadata.
RubrikPolaris.ThreatMonitoring.securityMetadata.mediumSensitiveHits Integer The medium sensitive hits of the security metadata.
RubrikPolaris.ThreatMonitoring.securityMetadata.highSensitiveHits Integer The high sensitive hits of the security metadata.
RubrikPolaris.ThreatMonitoring.securityMetadata.sensitivityStatus String The sensitivity status of the security metadata.
RubrikPolaris.ThreatMonitoring.securityMetadata.isLaminarEnabled Boolean A flag indicating whether laminar is enabled for the security metadata.
RubrikPolaris.ThreatMonitoring.securityMetadata.dataTypeResults.id String The ID of the data type result.
RubrikPolaris.ThreatMonitoring.securityMetadata.dataTypeResults.name String The name of the data type result.
RubrikPolaris.ThreatMonitoring.securityMetadata.dataTypeResults.totalHits Integer The total hits of the data type result.
RubrikPolaris.ThreatMonitoring.securityMetadata.dataTypeResults.totalViolatedHits Integer The total violated hits of the data type result.
RubrikPolaris.ThreatMonitoring.securityMetadata.dataTypeResults.__typename String The type name of the data type result.
RubrikPolaris.ThreatMonitoring.securityMetadata.__typename String The type name of the security metadata.
RubrikPolaris.ThreatMonitoring.__typename String The type name of the threat monitoring data.

Command example

!rubrik-threat-monitoring-matched-object-get object_id="00000000-0000-0000-0000-000000000001"

Context Example

{
    "RubrikPolaris": {
        "ThreatMonitoring": {
            "id": "00000000-0000-0000-0000-000000000001",
            "name": "DUMMY-NAME",
            "objectType": "Dummy_Object_Type",
            "slaAssignment": "Dummy_Assignment",
            "slaPauseStatus": false,
            "effectiveSlaDomain": {
                "id": "dummy-sla-id",
                "name": "Dummy_SLA_Domain",
                "version": "v0",
                "__typename": "Global_Sla_Reply"
            },
            "Snapshot_Distribution": {
                "id": "dummy-snapshot-id",
                "totalCount": 0,
                "scheduledCount": 0,
                "onDemandCount": 0,
                "retrievedCount": 0,
                "__typename": "Snapshot_Distribution"
            },
            "effectiveRetentionSlaDomain": null,
            "configuredSlaDomain": {
                "id": "dummy-configured-sla-id",
                "name": "Dummy_Configured_SLA",
                "version": "v0",
                "__typename": "Global_Sla_Reply"
            },
            "effectiveSlaSourceObject": {
                "fid": "dummy-fid-001",
                "name": "DUMMY-SOURCE-NAME",
                "objectType": "Dummy_Source_Type",
                "__typename": "Path_Node"
            },
            "logicalPath": [
                {
                    "fid": "dummy-logical-fid-001",
                    "name": "Dummy_Logical_Name1",
                    "objectType": "Dummy_Logical_Type1",
                    "__typename": "Path_Node"
                },
                {
                    "fid": "dummy-logical-fid-002",
                    "name": "Dummy_Logical_Name2",
                    "objectType": "Dummy_Logical_Type2",
                    "__typename": "Path_Node"
                }
            ],
            "physicalPath": [
                {
                    "fid": "dummy-physical-fid-001",
                    "name": "Dummy_Physical_Name1",
                    "objectType": "Dummy_Physical_Type1",
                    "__typename": "Path_Node"
                },
                {
                    "fid": "dummy-physical-fid-002",
                    "name": "Dummy_Physical_Name2",
                    "objectType": "Dummy_Physical_Type2",
                    "__typename": "Path_Node"
                }
            ],
            "numWorkloadDescendants": 0,
            "allOrgs": [],
            "securityMetadata": null,
            "__typename": "Vsphere_Vm"
        }
    }
}

Human Readable Output

Threat Monitoring Object Details

ID Name Object Type SLA Assignment Effective SLA Domain SLA Pause Status Configured SLA Domain Effective SLA Source Object Logical Path Physical Path NumWorkload Descendants
dummy-id-001 DUMMY-NAME Dummy_Object_Type Dummy_Assignment id: dummy-sla-id
name: Dummy_SLA_Domain
version: v0
false id: dummy-configured-sla-id
name: Dummy_Configured_SLA
version: v0
fid: dummy-fid-001
name: DUMMY-SOURCE-NAME
objectType: Dummy_Source_Type
- fid: dummy-logical-fid-001
name: Dummy_Logical_Name1
objectType: Dummy_Logical_Type1
- fid: dummy-logical-fid-002
name: Dummy_Logical_Name2
objectType: Dummy_Logical_Type2
- fid: dummy-physical-fid-001
name: Dummy_Physical_Name1
objectType: Dummy_Physical_Type1
- fid: dummy-physical-fid-002
name: Dummy_Physical_Name2
objectType: Dummy_Physical_Type2
0

rubrik-threat-monitoring-matched-file-list


List the matched files for the Threat Monitoring object.

Base Command

rubrik-threat-monitoring-matched-file-list

Input

Argument Name Description Required
object_id The object ID for the threat monitoring object.

Note: Users can retrieve the object ID by executing the “rubrik-threat-monitoring-matched-object-list” command.
Required
file_name Filter files by their name. Supports partial matches. Optional
limit Number of results to retrieve in the response. The maximum allowed size is 1000. Default is 50. Optional
next_page_token The next page cursor to retrieve the next set of results. Optional

Context Output

Path Type Description
RubrikPolaris.ThreatMonitoringFile.filepath String The full path of the matched file.
RubrikPolaris.ThreatMonitoringFile.detectedTime Date The timestamp when the file was detected.
RubrikPolaris.ThreatMonitoringFile.fileName String The name of the matched file.
RubrikPolaris.ThreatMonitoringFile.fileSize Number The size of the matched file in bytes.
RubrikPolaris.ThreatMonitoringFile.matchedSnapshotDate Date The date of the snapshot where the match occurred.
RubrikPolaris.ThreatMonitoringFile.matchedSnapshotFid String The FID of the snapshot where the match occurred.
RubrikPolaris.ThreatMonitoringFile.isMatchedSnapshotExpired Boolean A flag indicating whether the matched snapshot has expired.
RubrikPolaris.ThreatMonitoringFile.isFirstObservedSnapshotExpired Boolean A flag indicating whether the first observed snapshot has expired.
RubrikPolaris.ThreatMonitoringFile.matchType String The type of indicator match.
RubrikPolaris.ThreatMonitoringFile.isQuarantinedInFirstObservedSnapshot Boolean A flag indicating whether the file is quarantined in the first observed snapshot.
RubrikPolaris.ThreatMonitoringFile.objectFid String The FID of the associated object.
RubrikPolaris.ThreatMonitoringFile.firstObservedSnapshotFid String The FID of the first observed snapshot.
RubrikPolaris.ThreatMonitoringFile.firstObservedSnapshotDate Date The date of the first observed snapshot.
RubrikPolaris.ThreatMonitoringFile.objectType String The type of the associated object.
RubrikPolaris.ThreatMonitoringFile.objectName String The name of the associated object.
RubrikPolaris.ThreatMonitoringFile.matchId Number The ID of the match event.
RubrikPolaris.ThreatMonitoringFile.__typename String The GraphQL typename of the file match object.
RubrikPolaris.PageToken.ThreatMonitoringFile.endCursor String The end cursor of the threat monitoring file data.
RubrikPolaris.PageToken.ThreatMonitoringFile.hasNextPage Boolean A flag indicating if there is a next page of threat monitoring file data.
RubrikPolaris.PageToken.ThreatMonitoringFile.hasPreviousPage Boolean A flag indicating if there is a previous page of threat monitoring file data.
RubrikPolaris.PageToken.ThreatMonitoringFile.name String The name of the threat monitoring file data.
RubrikPolaris.PageToken.ThreatMonitoringFile.total_matched_count Number The total number of matched files.
RubrikPolaris.PageToken.ThreatMonitoringFile.startCursor String The start cursor of the threat monitoring file data.

Command example

!rubrik-threat-monitoring-matched-file-list object_id="dummy-object-id"

Context Example

{
    "RubrikPolaris": {
        "ThreatMonitoringFile": [
            {
                "filepath": "/dummy/path/file1.txt",
                "detectedTime": "2025-01-01T00:00:00.000Z",
                "fileName": "file1.txt",
                "fileSize": 1234,
                "matchedSnapshotDate": "2025-01-02T00:00:00.000Z",
                "matchedSnapshotFid": "dummy-snapshot-fid-1",
                "isMatchedSnapshotExpired": false,
                "isFirstObservedSnapshotExpired": false,
                "matchType": "DUMMY_TYPE",
                "isQuarantinedInFirstObservedSnapshot": true,
                "objectFid": "dummy-object-id",
                "firstObservedSnapshotFid": "dummy-first-snapshot-fid-1",
                "firstObservedSnapshotDate": "2025-01-02T00:00:00.000Z",
                "objectType": "DummyObjectType",
                "objectName": "dummy-object-name-1",
                "matchId": 1111,
                "__typename": "FileMatch"
            },
            {
                "filepath": "/dummy/path/file2.txt",
                "detectedTime": "2025-01-03T00:00:00.000Z",
                "fileName": "file2.txt",
                "fileSize": 5678,
                "matchedSnapshotDate": "2025-01-04T00:00:00.000Z",
                "matchedSnapshotFid": "dummy-snapshot-fid-2",
                "isMatchedSnapshotExpired": true,
                "isFirstObservedSnapshotExpired": true,
                "matchType": "DUMMY_TYPE",
                "isQuarantinedInFirstObservedSnapshot": false,
                "objectFid": "dummy-object-id",
                "firstObservedSnapshotFid": "dummy-first-snapshot-fid-2",
                "firstObservedSnapshotDate": "2025-01-04T00:00:00.000Z",
                "objectType": "DummyObjectType",
                "objectName": "dummy-object-name-2",
                "matchId": 2222,
                "__typename": "FileMatch"
            }
        ],
        "PageToken": {
            "ThreatMonitoringFile": {
                "startCursor": "dummy-start-cursor",
                "endCursor": "dummy-end-cursor",
                "hasNextPage": true,
                "hasPreviousPage": false,
                "name": "rubrik-threat-monitoring-matched-file-list",
                "total_matched_count": 99
            }
        }
    }
}

Human Readable Output

Threat Monitoring File List

File Name File Path File Size Matched Snapshot ID Matched Snapshot Date Matched Snapshot Expired
file1.txt /dummy/path/file1.txt 1234 dummy-snapshot-fid-1 2025-01-02T00:00:00.000Z false
file2.txt /dummy/path/file2.txt 5678 dummy-snapshot-fid-2 2025-01-04T00:00:00.000Z true

Note: To retrieve the next set of results use, “next_page_token” = dummy-end-cursor

rubrik-threat-monitoring-matched-file-get


Get the matched file for the Threat Monitoring object.

Base Command

rubrik-threat-monitoring-matched-file-get

Input

Argument Name Description Required
matched_snapshot_id ID of the snapshot where the threat monitoring match was found.

Note: Users can retrieve the matched snapshot ID by executing the “rubrik-threat-monitoring-matched-file-list” command.
Required
file_path Path of the file.

Note: Users can retrieve the file path by executing the “rubrik-threat-monitoring-matched-file-list” command.
Required

Context Output

Path Type Description
RubrikPolaris.ThreatMonitoringFile.matchedFileMd5 String The MD5 hash of the matched file.
RubrikPolaris.ThreatMonitoringFile.matchedFileSha1 String The SHA1 hash of the matched file.
RubrikPolaris.ThreatMonitoringFile.matchedFileSha256 String The SHA256 hash of the matched file.
RubrikPolaris.ThreatMonitoringFile.iocDetails.matchType String The type of IOC match.
RubrikPolaris.ThreatMonitoringFile.iocDetails.intelFeedName String The name of the intelligence feed that provided the IOC.
RubrikPolaris.ThreatMonitoringFile.iocDetails.malwareName String The name of the malware associated with the IOC.
RubrikPolaris.ThreatMonitoringFile.iocDetails.iocRuleAuthor String The author of the IOC rule.
RubrikPolaris.ThreatMonitoringFile.iocDetails.malwareDescription String The description of the malware associated with the IOC.
RubrikPolaris.ThreatMonitoringFile.iocDetails.iocHashHex String The hash value of the IOC in hexadecimal format.
RubrikPolaris.ThreatMonitoringFile.iocDetails.iocStatus String The status of the IOC.
RubrikPolaris.ThreatMonitoringFile.iocDetails.__typename String The GraphQL typename of the IOC details.
RubrikPolaris.ThreatMonitoringFile.isQuarantinedInFirstObservedSnapshot Boolean A flag indicating whether the file was quarantined in the first observed snapshot.
RubrikPolaris.ThreatMonitoringFile.detectedSnapshotDate String The date when the file was detected in the snapshot.
RubrikPolaris.ThreatMonitoringFile.firstDetectedSnapshotFid String The ID of the first snapshot where the file was detected.
RubrikPolaris.ThreatMonitoringFile.filePath String The full path of the file.
RubrikPolaris.ThreatMonitoringFile.fileName String The name of the file.
RubrikPolaris.ThreatMonitoringFile.__typename String The GraphQL typename of the threat monitoring file.

Command example

!rubrik-threat-monitoring-matched-file-get matched_snapshot_id="test-id" file_path="/dummy/path/file1.txt"

Context Example

{
    "RubrikPolaris": {
        "ThreatMonitoringFile": {
            "matchedFileMd5": "00000000000000001",
            "matchedFileSha1": "0000000000000000000000001",
            "matchedFileSha256": "0000000000000000000000000000000000000000000000000000000000001",
            "iocDetails": [
                {
                    "matchType": "IOC_HASH",
                    "intelFeedName": "Dummy_Feed",
                    "malwareName": "Dummy_Malware",
                    "iocRuleAuthor": "Dummy_Author",
                    "malwareDescription": "Dummy description for testing purposes",
                    "iocHashHex": "00000000000000001",
                    "iocStatus": "ACTIVE",
                    "__typename": "IOCDetails"
                }
            ],
            "isQuarantinedInFirstObservedSnapshot": false,
            "detectedSnapshotDate": "2025-01-01T00:00:00.000Z",
            "firstDetectedSnapshotFid": "00000000-0000-0000-0000-000000000001",
            "filePath": "/dummy/path/file1.txt",
            "fileName": "dummyfile.com",
            "__typename": "ThreatMonitoringFileMatchDetailsV2"
        }
    }
}

Human Readable Output

Threat Monitoring File Details

File Name File Path File Hashes IOC Details First Detected Snapshot FID Detected Snapshot Date Quarantined In First Observed Snapshot
dummyfile.com /dummy/path/file1.txt MD5: 00000000000000001
SHA1: 0000000000000000000000001
SHA256: 0000000000000000000000000000000000000000000000000000000000001
- matchType: IOC_HASH
intelFeedName: Dummy_Feed
malwareName: Dummy_Malware
iocRuleAuthor: Dummy_Author
malwareDescription: Dummy description for testing purposes
iocHashHex: 00000000000000001
iocStatus: ACTIVE
00000000-0000-0000-0000-000000000001 2025-01-01T00:00:00.000Z false

rubrik-ioc-scan-list-v2


List details of the Turbo and Advance Threat Hunt.

Base Command

rubrik-ioc-scan-list-v2

Input

Argument Name Description Required
cluster_id The ID of the cluster whose IOC scans are to be listed. Supports comma separated values.

Note: Users can retrieve the list of the cluster IDs by executing the “rubrik-gps-cluster-list” command.
Optional
ioc_match Filter hunts on any matches.

Possible values are: MATCHES_FOUND, NO_MATCHES, UNSCANNED.
Optional
hunt_status Filter by hunt status.

Possible values are: ABORTED, CANCELED, CANCELING, FAILED, IN_PROGRESS, PARTIALLY_SUCCEEDED, PENDING, SUCCEEDED.
Optional
quarantine_status Filter by quarantine matches.

Possible values are: QUARANTINED_MATCHES, NO_QUARANTINED_MATCHES.
Optional
start_time Filter the threat hunts that started after this time.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 June 2025, 01 June 2025 04:45:33, 2025-06-17T14:05:44Z. Default is 7 days.
Optional
end_time Filter the threat hunts that ended before this time.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 June 2025, 01 June 2025 04:45:33, 2025-06-17T14:05:44Z.
Optional
limit Number of results to retrieve in the response. The maximum allowed size is 1000. Default is 50. Optional
next_page_token The next page cursor to retrieve the next set of results. Optional

Context Output

Path Type Description
RubrikPolaris.IOCScan.huntId string The unique identifier for the threat hunt.
RubrikPolaris.IOCScan.name string The name of the threat hunt.
RubrikPolaris.IOCScan.createdBy.id string The ID of the user who initiated the hunt.
RubrikPolaris.IOCScan.createdBy.username string The username of the user who initiated the hunt.
RubrikPolaris.IOCScan.createdBy.email string The email of the user who initiated the hunt.
RubrikPolaris.IOCScan.createdBy.__typename string The GraphQL typename of the user object.
RubrikPolaris.IOCScan.huntType string The type of the threat hunt.
RubrikPolaris.IOCScan.startTime date The start time of the threat hunt.
RubrikPolaris.IOCScan.status string The current status of the threat hunt.
RubrikPolaris.IOCScan.stats.totalProcessedSnapshots number The total number of processed snapshots.
RubrikPolaris.IOCScan.stats.totalAffectedObjects number The total number of affected objects.
RubrikPolaris.IOCScan.stats.totalAffectedSnapshots number The total number of affected snapshots.
RubrikPolaris.IOCScan.stats.totalUniqueMatchedPaths number The total number of unique matched file paths.
RubrikPolaris.IOCScan.stats.totalSucceededScans number The total number of successful scans.
RubrikPolaris.IOCScan.stats.totalSnapshotsScanned number The total number of snapshots scanned.
RubrikPolaris.IOCScan.stats.totalUniqueQuarantinedPaths number The total number of unique quarantined file paths.
RubrikPolaris.IOCScan.stats.totalObjectsScanned number The total number of objects scanned.
RubrikPolaris.IOCScan.stats.totalIocs number The total number of IOCs used in the scan.
RubrikPolaris.IOCScan.stats.__typename string The GraphQL typename of the stats object.
RubrikPolaris.IOCScan.huntDetails.startTime date The start time of the detailed threat hunt process.
RubrikPolaris.IOCScan.huntDetails.endTime date The end time of the detailed threat hunt process.
RubrikPolaris.IOCScan.huntDetails.cluster.id string The ID of the cluster used in the hunt.
RubrikPolaris.IOCScan.huntDetails.cluster.name string The name of the cluster used in the hunt.
RubrikPolaris.IOCScan.huntDetails.cluster.__typename string The GraphQL typename of the cluster object.
RubrikPolaris.IOCScan.huntDetails.config.name string The name of the configuration used in the hunt.
RubrikPolaris.IOCScan.huntDetails.config.indicatorsOfCompromise unknown The list of indicators of compromise.
RubrikPolaris.IOCScan.huntDetails.config.__typename string The GraphQL typename of the hunt config object.
RubrikPolaris.IOCScan.huntDetails.__typename string The GraphQL typename of the hunt details object.
RubrikPolaris.IOCScan.__typename string The GraphQL typename of the top-level threat hunt object.
RubrikPolaris.PageToken.IOCScan.endCursor string The end cursor of the IOC scan data.
RubrikPolaris.PageToken.IOCScan.hasNextPage boolean A flag indicating if there is a next page of IOC scan data.
RubrikPolaris.PageToken.IOCScan.hasPreviousPage boolean A flag indicating if there is a previous page of IOC scan data.
RubrikPolaris.PageToken.IOCScan.name string The name of the IOC scan data.
RubrikPolaris.PageToken.IOCScan.startCursor string The start cursor of the IOC scan data.
RubrikPolaris.PageToken.IOCScan.total_matched_count number The total number of matched IOC scans.

Command example

!rubrik-ioc-scan-list-v2 limit=1

Context Example

{
    "RubrikPolaris": {
        "IOCScan": [
            {
                "huntId": "dummy-hunt-id-0001",
                "name": "Dummy Threat Hunt",
                "createdBy": {
                    "id": "client|dummy-user-id",
                    "username": "dummyuser",
                    "email": "dummyuser@example.com",
                    "__typename": "User"
                },
                "huntType": "THREAT_HUNT_V2",
                "startTime": "2025-07-01T00:00:00.000Z",
                "status": "SUCCEEDED",
                "stats": {
                    "totalProcessedSnapshots": 10,
                    "totalAffectedObjects": 2,
                    "totalAffectedSnapshots": 1,
                    "totalUniqueMatchedPaths": 3,
                    "totalSucceededScans": 10,
                    "totalSnapshotsScanned": 12,
                    "totalUniqueQuarantinedPaths": 1,
                    "totalObjectsScanned": 20,
                    "totalIocs": 5,
                    "__typename": "ThreatHuntStats"
                },
                "huntDetails": {
                    "startTime": "2025-07-01T00:00:00.000Z",
                    "endTime": "2025-07-01T01:00:00.000Z",
                    "cluster": {
                        "id": "dummy-cluster-id",
                        "name": "Dummy Cluster",
                        "__typename": "Cluster"
                    },
                    "config": {
                        "name": "Dummy Hunt Config",
                        "indicatorsOfCompromise": [],
                        "__typename": "ThreatHuntConfig"
                    },
                    "__typename": "ThreatHuntDetails"
                },
                "__typename": "ThreatHunt"
            }
        ],
        "PageToken": {
            "IOCScan": {
                "endCursor": "dummy-end-cursor",
                "hasNextPage": true,
                "hasPreviousPage": false,
                "startCursor": "dummy-start-cursor",
                "name": "rubrik-ioc-scan-list-v2",
                "total_matched_count": 2
            }
        }
    }
}

Human Readable Output

IOC Scan List

Hunt ID Hunt Type Status Start Time
dummy-hunt-id-0001 THREAT_HUNT_V2 SUCCEEDED 2025-07-01T00:00:00.000Z

Note: To retrieve the next set of results use, “next_page_token” = dummy-end-cursor

rubrik-ioc-scan-results-v2


Retrieve details of the Turbo and Advance Threat Hunt.

Base Command

rubrik-ioc-scan-results-v2

Input

Argument Name Description Required
hunt_id The ID of the threat hunt.

Note: Users can retrieve the hunt ID by executing the “rubrik-ioc-scan-list-v2” command.
Required

Context Output

Path Type Description
RubrikPolaris.IOCScan.hunt_id string The ID of the threat hunt.
RubrikPolaris.IOCScan.totalObjectFids number The total number of object FIDs involved in the threat hunt.
RubrikPolaris.IOCScan.startTime date The start time of the threat hunt.
RubrikPolaris.IOCScan.endTime date The end time of the threat hunt.
RubrikPolaris.IOCScan.status string The current status of the threat hunt.
RubrikPolaris.IOCScan.totalMatchedSnapshots number The total number of matched snapshots.
RubrikPolaris.IOCScan.totalScannedSnapshots number The total number of scanned snapshots.
RubrikPolaris.IOCScan.totalUniqueFileMatches number The total number of unique file matches.
RubrikPolaris.IOCScan.clusters.id string The ID of the cluster.
RubrikPolaris.IOCScan.clusters.name string The name of the cluster.
RubrikPolaris.IOCScan.clusters.type string The type of the cluster.
RubrikPolaris.IOCScan.clusters.__typename string The GraphQL typename of the cluster object.
RubrikPolaris.IOCScan.baseConfig.name string The name of the base configuration used in the threat hunt.
RubrikPolaris.IOCScan.baseConfig.notes string The notes added to the hunt configuration.
RubrikPolaris.IOCScan.baseConfig.maxMatchesPerSnapshot number The maximum number of matches allowed per snapshot.
RubrikPolaris.IOCScan.baseConfig.threatHuntType string The type of the threat hunt.
RubrikPolaris.IOCScan.baseConfig.__typename string The GraphQL typename of the base configuration object.
RubrikPolaris.IOCScan.baseConfig.ioc.__typename string The GraphQL typename of the IOC object.
RubrikPolaris.IOCScan.baseConfig.ioc.iocList.__typename string The GraphQL typename of the IOC list container.
RubrikPolaris.IOCScan.baseConfig.ioc.iocList.indicatorsOfCompromise.iocKind string The type of IOC.
RubrikPolaris.IOCScan.baseConfig.ioc.iocList.indicatorsOfCompromise.iocValue string The value of the IOC indicator.
RubrikPolaris.IOCScan.baseConfig.ioc.iocList.indicatorsOfCompromise.__typename string The GraphQL typename of the IOC indicator.
RubrikPolaris.IOCScan.baseConfig.snapshotScanLimit.__typename string The GraphQL typename of the snapshot scan limit object.
RubrikPolaris.IOCScan.baseConfig.snapshotScanLimit.scanLimit.__typename string The GraphQL typename of the scan limit configuration.
RubrikPolaris.IOCScan.baseConfig.snapshotScanLimit.scanLimit.scanConfig.maxSnapshotsPerObject number The maximum snapshots to scan per object.
RubrikPolaris.IOCScan.baseConfig.snapshotScanLimit.scanLimit.scanConfig.startTime date The start time for the snapshot scan window.
RubrikPolaris.IOCScan.baseConfig.snapshotScanLimit.scanLimit.scanConfig.endTime date The end time for the snapshot scan window.
RubrikPolaris.IOCScan.baseConfig.snapshotScanLimit.scanLimit.scanConfig.__typename string The GraphQL typename of the scan limit configuration.
RubrikPolaris.IOCScan.baseConfig.snapshotScanLimit.scanLimit.objectSnapshotConfig string An object snapshot configuration.
RubrikPolaris.IOCScan.baseConfig.fileScanCriteria string A file scan criteria.
RubrikPolaris.IOCScan.threatHuntObjectMetrics.totalObjectsScanned number The total number of objects scanned during the hunt.
RubrikPolaris.IOCScan.threatHuntObjectMetrics.totalAffectedObjects number The total number of affected objects.
RubrikPolaris.IOCScan.threatHuntObjectMetrics.totalUnaffectedObjects number The total number of unaffected objects.
RubrikPolaris.IOCScan.threatHuntObjectMetrics.totalObjectsUnscannable number The total number of objects that couldn’t be scanned.
RubrikPolaris.IOCScan.threatHuntObjectMetrics.unaffectedObjectsFromDb number The number of clean objects retrieved from the database.
RubrikPolaris.IOCScan.threatHuntObjectMetrics.cleanRecoverableObjectLimit number The maximum number of clean recoverable objects allowed.
RubrikPolaris.IOCScan.threatHuntObjectMetrics.__typename string The GraphQL typename of the object metrics reply.
RubrikPolaris.IOCScan.__typename string The GraphQL typename of the root hunt details object.

Command example

!rubrik-ioc-scan-results-v2 hunt_id="test-hunt-id"

Context Example

{
    "RubrikPolaris": {
        "IOCScan": {
            "hunt_id": "test-hunt-id",
            "totalObjectFids": 100,
            "startTime": "2025-01-01T08:00:00.000Z",
            "endTime": "2025-01-01T09:00:00.000Z",
            "status": "SUCCEEDED",
            "totalMatchedSnapshots": 10,
            "totalScannedSnapshots": 200,
            "totalUniqueFileMatches": 3,
            "clusters": [
                {
                    "id": "dummy-cluster-id-123",
                    "name": "Dummy_Cluster",
                    "type": "DummyType",
                    "__typename": "Cluster"
                }
            ],
            "baseConfig": {
                "name": "Dummy Threat Hunt Config",
                "notes": "Dummy note here.",
                "maxMatchesPerSnapshot": 0,
                "threatHuntType": "TURBO_THREAT_HUNT",
                "ioc": {
                    "iocList": {
                        "indicatorsOfCompromise": [
                            {
                                "iocKind": "IOC_HASH",
                                "iocValue": "dummyhashvalue0000000000000000000001",
                                "__typename": "IndicatorOfCompromise"
                            },
                            {
                                "iocKind": "IOC_HASH",
                                "iocValue": "dummyhashvalue0000000000000000000002",
                                "__typename": "IndicatorOfCompromise"
                            }
                        ],
                        "__typename": "IndicatorOfCompromiseInputOutputListType"
                    },
                    "__typename": "Ioc"
                },
                "snapshotScanLimit": {
                    "scanLimit": {
                        "scanConfig": {
                            "maxSnapshotsPerObject": 5,
                            "startTime": "2025-01-01T00:00:00.000Z",
                            "endTime": "2025-01-10T00:00:00.000Z",
                            "__typename": "SnapshotScanConfig"
                        },
                        "__typename": "ScanLimit"
                    },
                    "__typename": "HuntScanSnapshotLimit"
                },
                "__typename": "ThreatHuntBaseConfig"
            },
            "__typename": "ThreatHuntDetailsV2",
            "threatHuntObjectMetrics": {
                "totalObjectsScanned": 100,
                "totalAffectedObjects": 5,
                "totalUnaffectedObjects": 95,
                "totalObjectsUnscannable": 0,
                "unaffectedObjectsFromDb": 95,
                "cleanRecoverableObjectLimit": 999,
                "__typename": "ThreatHuntObjectMetricsReply"
            }
        }
    }
}

Human Readable Output

IOC Scan Data

Hunt Name Hunt Type Status IOC Details Object Metrics Scan Metrics Start Time End Time
Dummy Threat Hunt Config TURBO_THREAT_HUNT SUCCEEDED - iocKind: IOC_HASH
iocValue: dummyhashvalue0000000000000000000001
- iocKind: IOC_HASH
iocValue: dummyhashvalue0000000000000000000002
totalObjectsScanned: 100
totalAffectedObjects: 5
totalUnaffectedObjects: 95
totalObjectsUnscannable: 0
unaffectedObjectsFromDb: 95
cleanRecoverableObjectLimit: 999
totalMatchedSnapshots: 10
totalScannedSnapshots: 200
totalUniqueFileMatches: 3
2025-01-01T08:00:00.000Z 2025-01-01T09:00:00.000Z

rubrik-turbo-ioc-scan


Start a new turbo threat hunt.

Base Command

rubrik-turbo-ioc-scan

Input

Argument Name Description Required
ioc The value of the indicator to scan for. Supports comma separated values.

Note: Users can retrieve the Md5, SHA1 or SHA256 by executing the “rubrik-threat-monitoring-matched-file-get” command.
Required
scan_name Name of the new turbo threat hunt scan. Default is PAXSOAR-1.6.0. Optional
cluster_id The ID of the cluster on which to perform a scan. If not provided, all the clusters will be scanned.

Note: Users can retrieve the list of the cluster IDs by executing the “rubrik-gps-cluster-list” command.
Optional
start_time Filter the snapshots from the provided date. Any snapshots taken before the provided date-time will be excluded.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.

For example: 01 June 2025, 01 June 2025 04:45:33, 2025-06-17T14:05:44Z.
Optional
end_time Filter the snapshots until the provided date. Any snapshots taken after the provided date-time will be excluded.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.

For example: 01 June 2025, 01 June 2025 04:45:33, 2025-06-17T14:05:44Z.
Optional
max_snapshots_per_object Maximum number of snapshots to scan per object. Optional

Context Output

Path Type Description
RubrikPolaris.TurboIOCScan.huntId String The ID of the new turbo threat hunt.
RubrikPolaris.TurboIOCScan.__typename String The type of the new turbo threat hunt.

Command example

!rubrik-turbo-ioc-scan ioc="00000000000000000001"

Context Example

{
    "RubrikPolaris": {
        "TurboIOCScan": {
            "huntId": "000000000-0000-0000-0000-000000001",
            "__typename": "StartTurboThreatHuntReply"
        }
    }
}

Human Readable Output

The new Turbo Threat Hunt started with ID: 000000000-0000-0000-0000-000000001

rubrik-advance-ioc-scan


Start a new advance threat hunt.

Base Command

rubrik-advance-ioc-scan

Input

Argument Name Description Required
object_id The Object ID of the system on which to perform the scan. Supports comma separated values.

Note: Users can get the list of object IDs by executing the “rubrik-polaris-object-list” command.
Required
ioc_type The type of the indicator to scan.

Note: To provide multiple IOCs use the argument “advance_ioc”. Possible values are: INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME, INDICATOR_OF_COMPROMISE_TYPE_HASH, INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE.
Optional
ioc_value The value of the indicator to scan.

Note: To provide multiple IOCs use the argument “advance_ioc”.
Optional
scan_name Name of the new advanced threat hunt scan. Default is PAXSOAR-1.6.0. Optional
advance_ioc Json encoded Indicators Of Compromise to scan. Json keys signify the type of IOC and the corresponding list of values are the values of the IOC’s. If provided, will ignore the ioc_type and ioc_value arguments.

Possible keys to indicate type of indicator:
INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME, INDICATOR_OF_COMPROMISE_TYPE_HASH, INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE

Format Accepted:
{
“<ioc_type1>”: [“<ioc_value1>”, “<ioc_value2>”],
“<ioc_type2>”: “<ioc_value3>“
}

Example:
{
“INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME”: [“C:\\Users\\Malware_Executible.ps1”, “\\bin\\Malware_Executible”],
“INDICATOR_OF_COMPROMISE_TYPE_HASH”: [“e5c1b9c44be582f895eaea3d3738c5b4”, “f541b9844be897f895eaea3d3738cfb2”],
“INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE”: “rule match_everything {condition:true}”
}.
Optional
max_matches_per_snapshot Maximum number of IOC matches allowed per snapshot. Optional
start_date Filter the snapshots from the provided date. Any snapshots taken before the provided date-time will be excluded.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.

For example: 01 June 2025, 01 June 2025 04:45:33, 2025-06-17T14:05:44Z.
Optional
end_date Filter the snapshots until the provided date. Any snapshots taken after the provided date-time will be excluded.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ, etc.

For example: 01 June 2025, 01 June 2025 04:45:33, 2025-06-17T14:05:44Z.
Optional
max_snapshots_per_object Maximum number of snapshots to scan per object. Optional
min_file_size Minimum size of the file in bytes that will be included in the scan. Optional
max_file_size Maximum size of the file in bytes that will be included in the scan. Optional
paths_to_include Paths to include in the scan. Supports comma separated values.

Format accepted: “path_to_include_1, path_to_include_2”.
Optional
paths_to_exclude Paths to exclude from the scan. Supports comma separated values.

Format accepted: “path_to_exclude_1, path_to_exclude_2”.
Optional
paths_to_exempt Paths to exempt from exclusion. Supports comma separated values.

Format accepted: “path_to_exempt_1, path_to_exempt_2”.
Optional

Context Output

Path Type Description
RubrikPolaris.AdvanceIOCScan.huntId string The ID of the new advance threat hunt.
RubrikPolaris.AdvanceIOCScan.huntName string The name or label of the advanced threat hunt.
RubrikPolaris.AdvanceIOCScan.config.huntType string The type of threat hunt configuration.
RubrikPolaris.AdvanceIOCScan.config.clusterUuids unknown The list of cluster UUIDs included in the hunt config.
RubrikPolaris.AdvanceIOCScan.config.objectFids unknown The list of object FIDs targeted by the hunt.
RubrikPolaris.AdvanceIOCScan.config.__typename string The GraphQL typename for the HuntConfig object.
RubrikPolaris.AdvanceIOCScan.status string The status of the threat hunt execution.
RubrikPolaris.AdvanceIOCScan.__typename string The GraphQL typename for the HuntResponse object.

Command example

!rubrik-advance-ioc-scan object_id="obj-123" ioc_type="INDICATOR_OF_COMPROMISE_TYPE_HASH" ioc_value="test-ioc-value"

Context Example

{
    "RubrikPolaris": {
        "AdvanceIOCScan": {
            "huntId": "hunt-abc",
            "huntName": "Test Hunt",
            "config": {
                "huntType": "THREAT_HUNT_V2",
                "clusterUuids": ["cluster-1"],
                "objectFids": ["obj-123"],
                "__typename": "HuntConfig"
            },
            "status": "HUNT_TRIGGER_SUCCEEDED",
            "__typename": "HuntResponse"
        }
    }
}

Human Readable Output

The new advance Threat Hunt started with ID: hunt-abc

rubrik-anomaly-csv-analysis-v2


Request for the analysis and directly download the anomaly CSV analyzed file.

Base Command

rubrik-anomaly-csv-analysis-v2

Input

Argument Name Description Required
cluster_id The unique ID of the cluster.

Note: Users can retrieve the list of the cluster IDs by executing the “rubrik-gps-cluster-list” command.
Required
snapshot_id The CDM snapshot ID.

Note: Use the “rubrik-radar-suspicious-file-list” command to retrieve the actual CDM ID from the Anomaly ID.
Example format to get the snapshot CDM ID from Anomaly ID: “<Cluster-ID>:::VirtualMachine:::<Snappable-ID>:::<CDM-ID>”.
Required
object_id The VM object ID (Snappable ID).

Note: Users can retrieve the list of Snappable IDs by executing the “rubrik-polaris-vm-objects-list” command.
Example format to get the Snappable ID: “VirtualMachine:::<Snappable-ID>”.
Required

Context Output

Path Type Description
RubrikPolaris.AnomalyCSVv2.clusterId String The ID of the cluster.
RubrikPolaris.AnomalyCSVv2.snapshotId String The ID of the snapshot.
RubrikPolaris.AnomalyCSVv2.objectId String The ID of the object.
RubrikPolaris.AnomalyCSVv2.externalId String The external ID of the CSV file.
RubrikPolaris.AnomalyCSVv2.isSuccessful Boolean Whether the CSV analysis was successful or not.
InfoFile.Name string FileName.
InfoFile.EntryID string The EntryID of the report.
InfoFile.Size number File Size.
InfoFile.Type string File type e.g. “PE”.
InfoFile.Info string Basic information of the file.

Command example

!rubrik-anomaly-csv-analysis-v2 cluster_id="00000000-0000-0000-0000-000000000000" snapshot_id="00000000-0000-0000-0000-000000000000" object_id="00000000-0000-0000-0000-000000000000-vm-000"

Context Example

{
    "InfoFile": {
        "EntryID": "10000@00000000-0000-0000-0000-000000000001",
        "Extension": "csv",
        "Info": "text/csv; charset=utf-8",
        "Name": "snapshot_00000000-0000-0000-0000-000000000000.csv",
        "Size": 1771317,
        "Type": "ASCII text, with very long lines"
    },
    "RubrikPolaris": {
        "AnomalyCSVv2": {
            "clusterId": "00000000-0000-0000-0000-000000000000",
            "externalId": "00000000-0000-0000-0000-000000000000",
            "isSuccessful": true,
            "objectId": "00000000-0000-0000-0000-000000000000-vm-000",
            "snapshotId": "00000000-0000-0000-0000-000000000000"
        }
    }
}

Human Readable Output

Successfully downloaded the analyzed CSV file

rubrik-data-security-violation-list


Retrieve the list of DSPM violations.

Base Command

rubrik-data-security-violation-list

Input

Argument Name Description Required
object_type Filter the violations based on object types. Supports comma separated values.

Note: Values not included in the options can be found in the documentation. Possible values are: AWS_NATIVE_DYNAMODB_TABLE, AWS_NATIVE_EBS_VOLUME, AWS_NATIVE_RDS_INSTANCE, AWS_NATIVE_S3_BUCKET, AZURE_MANAGED_DISK, AZURE_SQL_DATABASE_DB, AZURE_SQL_MANAGED_INSTANCE_DB, AZURE_STORAGE_ACCOUNT, AZURE_VIRTUAL_MACHINE, GCP_NATIVE_DISK, GCP_NATIVE_GCE_INSTANCE, HYPERV_VIRTUAL_MACHINE, K8S_PROTECTION_SET, K8S_VIRTUAL_MACHINE, LINUX_FILESET, NAS_FILESET, NUTANIX_VIRTUAL_MACHINE, O365_ONEDRIVE, O365_SITE, ORACLE_DATA_GUARD_GROUP, ORACLE_DATABASE, SHARE_FILESET, VOLUME_GROUP, VSPHERE_VIRTUAL_MACHINE, WINDOWS_FILESET.
Optional
detection_start_date Filter the violations detected after this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: detection_start_date and detection_end_date both or none of them should be initialized.
Optional
detection_end_date Filter the violations detected before this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: detection_start_date and detection_end_date both or none of them should be initialized.
Optional
resolved_start_date Filter the violations resolved after this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: resolved_start_date and resolved_end_date both or none of them should be initialized.
Optional
resolved_end_date Filter the violations resolved before this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: resolved_start_date and resolved_end_date both or none of them should be initialized.
Optional
category Filter the violations by category. Supports comma separated values. Possible values are: CATEGORY_UNSPECIFIED, MISPLACED, REDUNDANT, OVEREXPOSED, UNPROTECTED. Optional
status Filter the violations by status. Supports comma separated values. Possible values are: OPEN, IN_PROGRESS, REMEDIATED, DISMISSED, CLOSED. Optional
severity Filter the violations by severity level. Supports comma separated values. Possible values are: SEVERITY_UNSPECIFIED, LOW, MEDIUM, HIGH, CRITICAL. Optional
sensitivity Filter the violations by sensitivity level. Supports comma separated values. Possible values are: HIGH, MEDIUM, LOW, NO. Optional
limit Number of results to retrieve in the response. The maximum allowed size is 1000. Default is 50. Optional
next_page_token The next page cursor to retrieve the next set of results. Optional
sort_by Specify the field to use for sorting the response. Possible values are: SEVERITY, HITS, DETECTION_TIME, UPDATE_TIME, IDENTITY_TYPE, FILES_AT_RISK, TOTAL_HITS, ACCESSIBLE_OBJECTS, ORIGIN, EVENT_TIME, NAME, TYPE. Default is DETECTION_TIME. Optional
sort_order Specify the order to sort the data in. Possible values are: ASC, DESC. Default is DESC. Optional

Context Output

Path Type Description
RubrikPolaris.DSPMViolation.policyViolationId String The unique identifier for the policy violation.
RubrikPolaris.DSPMViolation.status String The current status of the policy violation.
RubrikPolaris.DSPMViolation.__typename String The GraphQL typename for the violation object.
RubrikPolaris.DSPMViolation.createdAt Date The date and time when the policy violation was created.
RubrikPolaris.DSPMViolation.lastUpdatedAt Date The date and time when the policy violation was last updated.
RubrikPolaris.DSPMViolation.policy.policyId String The unique identifier of the policy associated with the violation.
RubrikPolaris.DSPMViolation.policy.name String The name of the policy associated with the violation.
RubrikPolaris.DSPMViolation.policy.policySeverity String The severity level assigned to the policy.
RubrikPolaris.DSPMViolation.policy.__typename String The GraphQL typename for the policy object.
RubrikPolaris.DSPMViolation.resourceId String The unique identifier of the resource associated with the violation.
RubrikPolaris.DSPMViolation.resourceType String The type of the resource associated with the violation.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.name String The name of the resource where the violation occurred.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.objectType String The object type of the resource.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.platform String The platform of the resource.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.physicalHost String The physical host where the resource resides.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.cloudAccountInfo.accountName String The name of the associated cloud account.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.cloudAccountInfo.__typename String The GraphQL typename for the cloud account info object.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.__typename String The GraphQL typename for the resource metadata details object.
RubrikPolaris.DSPMViolation.resourceMetadata.__typename String The GraphQL typename for the resource metadata object.
RubrikPolaris.DSPMViolation.details.dataCategories.id String The ID of the data category.
RubrikPolaris.DSPMViolation.details.dataCategories.name String The name of the data category.
RubrikPolaris.DSPMViolation.details.dataCategories.totalViolatedHits Integer The total violated hits of the data category.
RubrikPolaris.DSPMViolation.details.dataCategories.__typename String The type name of the data category.
RubrikPolaris.DSPMViolation.details.dataTypes.id String The ID of the data type.
RubrikPolaris.DSPMViolation.details.dataTypes.name String The name of the data type.
RubrikPolaris.DSPMViolation.details.dataTypes.totalViolatedHits Integer The total violated hits of the data type.
RubrikPolaris.DSPMViolation.details.dataTypes.__typename String The type name of the data type.
RubrikPolaris.DSPMViolation.details.violatedNoRiskSensitiveHits Number The number of no-risk sensitive hits involved in the violation.
RubrikPolaris.DSPMViolation.details.violatedLowRiskSensitiveHits Number The number of low-risk sensitive hits involved in the violation.
RubrikPolaris.DSPMViolation.details.violatedMediumRiskSensitiveHits Number The number of medium-risk sensitive hits involved in the violation.
RubrikPolaris.DSPMViolation.details.violatedHighRiskSensitiveHits Number The number of high-risk sensitive hits involved in the violation.
RubrikPolaris.DSPMViolation.details.snapshotId String The ID of the snapshot associated with the violation details.
RubrikPolaris.DSPMViolation.details.__typename String The GraphQL typename for the violation details object.
RubrikPolaris.DSPMViolation.remediations.type String The type of the remediation action.
RubrikPolaris.DSPMViolation.remediations.state String The state of the remediation action.
RubrikPolaris.DSPMViolation.remediations.remediationDetails Unknown Detailed information about the remediation action.
RubrikPolaris.DSPMViolation.remediations.__typename String The GraphQL typename for the remediation object.
RubrikPolaris.DSPMViolation.remediations Unknown The list of remediations associated with the violation.
RubrikPolaris.PageToken.DSPMViolation.next_page_token String Next page token.
RubrikPolaris.PageToken.DSPMViolation.name String Name of the command.
RubrikPolaris.PageToken.DSPMViolation.has_next_page Boolean Whether the result has the next page or not.

Command example

!rubrik-data-security-violation-list status="OPEN" severity="MEDIUM" limit="50"

Context Example

{
    "RubrikPolaris": {
        "DSPMViolation": [
            {
                "policyViolationId": "00000000-0000-0000-0000-000000000001",
                "status": "POLICY_VIOLATION_STATUS_OPEN",
                "__typename": "PolicyViolation",
                "createdAt": "2026-03-06T06:30:45.000Z",
                "lastUpdatedAt": "2026-03-24T05:30:07.000Z",
                "name": "Secrets stored outside of vault",
                "violationSeverity": "MEDIUM",
                "policy": {
                    "policyId": "00000000-0000-0000-0000-000000000010",
                    "name": "Secrets stored outside of vault",
                    "policySeverity": "MEDIUM",
                    "policyCategory": "MISPLACED",
                    "description": "Detects secrets stored outside of vault",
                    "__typename": "DSPMPolicy"
                },
                "resourceId": "00000000-0000-0000-0000-000000000020",
                "resourceType": "RESOURCE_TYPE_OBJECT",
                "resourceMetadata": {
                    "metadata": {
                        "name": "DEMO-RADAR02",
                        "objectType": "VSPHERE_VIRTUAL_MACHINE",
                        "platform": "PLATFORM_DATA_CENTER",
                        "physicalHost": "rubrikdemo.com/Datacenters/Data Center/vm/Discovered virtual machine",
                        "__typename": "CommonAssetMetadata"
                    },
                    "__typename": "ResourceMetadata"
                },
                "details": {
                    "dataCategories": [
                        {
                            "__typename": "DataCategoryStats",
                            "id": "00000000-0000-0000-0000-000000000010",
                            "name": "",
                            "totalViolatedHits": 1
                        },
                        {
                            "__typename": "DataCategoryStats",
                            "id": "00000000-0000-0000-0000-000000000020",
                            "name": "",
                            "totalViolatedHits": 1
                        }
                    ],
                    "dataTypes": [
                        {
                            "__typename": "DataTypeStats",
                            "id": "00000000-0000-0000-0000-000000000010",
                            "name": "",
                            "totalViolatedHits": 1
                        },
                        {
                            "__typename": "DataTypeStats",
                            "id": "00000000-0000-0000-0000-000000000020",
                            "name": "",
                            "totalViolatedHits": 1
                        }
                    ],
                    "violatedNoRiskSensitiveHits": 37,
                    "violatedLowRiskSensitiveHits": 2,
                    "violatedMediumRiskSensitiveHits": 1,
                    "violatedHighRiskSensitiveHits": 0,
                    "snapshotId": "00000000-0000-0000-0000-000000000030",
                    "__typename": "DataGovViolationDetails"
                },
                "remediations": [
                    {
                        "type": "REMEDIATION_TYPE_EXPORT_ACTIONS_LOG_TO_CSV",
                        "state": "REMEDIATION_STATE_SUCCESS",
                        "__typename": "RemediationMetadata"
                    }
                ]
            },
            {
                "policyViolationId": "00000000-0000-0000-0000-000000000002",
                "status": "POLICY_VIOLATION_STATUS_OPEN",
                "__typename": "PolicyViolation",
                "createdAt": "2026-02-25T15:30:25.000Z",
                "lastUpdatedAt": "2026-03-23T16:30:05.000Z",
                "name": "Stale sensitive data",
                "violationSeverity": "LOW",
                "policy": {
                    "policyId": "00000000-0000-0000-0000-000000000011",
                    "name": "Stale sensitive data - not modified for over a year",
                    "policySeverity": "LOW",
                    "policyCategory": "REDUNDANT",
                    "description": "Detects stale sensitive data",
                    "__typename": "DSPMPolicy"
                },
                "resourceId": "00000000-0000-0000-0000-000000000021",
                "resourceType": "RESOURCE_TYPE_OBJECT",
                "resourceMetadata": {
                    "metadata": {
                        "name": "file-store",
                        "objectType": "AWS_NATIVE_S3_BUCKET",
                        "platform": "PLATFORM_AWS",
                        "physicalHost": "rubrik-lab/us-east-1",
                        "cloudAccountInfo": {
                            "accountName": "rubrik-lab",
                            "__typename": "CloudAccountInfo"
                        },
                        "__typename": "CommonAssetMetadata"
                    },
                    "__typename": "ResourceMetadata"
                },
                "details": {
                    "violatedNoRiskSensitiveHits": 83,
                    "violatedLowRiskSensitiveHits": 0,
                    "violatedMediumRiskSensitiveHits": 0,
                    "violatedHighRiskSensitiveHits": 7,
                    "snapshotId": "00000000-0000-0000-0000-000000000031",
                    "__typename": "DataGovViolationDetails"
                }
            }
        ]
    },
    "RubrikPolaris": {
        "PageToken": {
            "DSPMViolation": {
                "name": "rubrik-data-security-violation-list",
                "next_page_token": "hash_token",
                "has_next_page": true
            }
        }
    }
}

Human Readable Output

DSPM Violations List

ID Violation Name Severity Object Name Violation Status High Risk Hits Medium Risk Hits Low Risk Hits No Risk Hits Detection On
00000000-0000-0000-0000-000000000001 Secrets stored outside of vault Medium DEMO-RADAR02 Open 0 1 2 37 2026-03-06T06:30:45.000Z
00000000-0000-0000-0000-000000000002 Stale sensitive data - not modified for over a year Low file-store Open 7 0 0 83 2026-02-25T15:30:25.000Z

Note: To retrieve the next set of results use, “next_page_token” = hash_token

rubrik-data-security-violation-get


Retrieve the details of DSPM violation based on the provided violation ID.

Base Command

rubrik-data-security-violation-get

Input

Argument Name Description Required
violation_id The ID of the DSPM violation.

Note: Users can get the violation ID by executing the “rubrik-data-security-violation-list” command.
Required

Context Output

Path Type Description
RubrikPolaris.DSPMViolation.policyViolationId String The unique identifier for the policy violation.
RubrikPolaris.DSPMViolation.status String The current status of the policy violation.
RubrikPolaris.DSPMViolation.__typename String The GraphQL typename for the violation object.
RubrikPolaris.DSPMViolation.createdAt Date The date and time when the policy violation was created.
RubrikPolaris.DSPMViolation.lastUpdatedAt Date The date and time when the policy violation was last updated.
RubrikPolaris.DSPMViolation.policy.policyId String The unique identifier of the policy associated with the violation.
RubrikPolaris.DSPMViolation.policy.name String The name of the policy associated with the violation.
RubrikPolaris.DSPMViolation.policy.policySeverity String The severity level assigned to the policy.
RubrikPolaris.DSPMViolation.policy.__typename String The GraphQL typename for the policy object.
RubrikPolaris.DSPMViolation.resourceId String The unique identifier of the resource associated with the violation.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.name String The name of the resource where the violation occurred.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.objectType String The object type of the resource.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.platform String The platform of the resource.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.physicalHost String The physical host where the resource resides.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.cloudAccountInfo.accountName String The name of the associated cloud account.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.cloudAccountInfo.__typename String The GraphQL typename for the cloud account info object.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.__typename String The GraphQL typename for the resource metadata details object.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.clusterInfo.clusterName String The name of the cluster.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.clusterInfo.clusterUuid String The UUID of the cluster.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.clusterInfo.__typename String The GraphQL typename for the cluster info object.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.creationTime Number The creation time of the metadata.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.lastAccessTime Number The last access time of the metadata.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.snapshotTimestamp Number The snapshot timestamp.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.isDeleted Boolean Whether the resource is deleted.
RubrikPolaris.DSPMViolation.resourceMetadata.metadata.region String The region of the resource.
RubrikPolaris.DSPMViolation.resourceMetadata.__typename String The GraphQL typename for the resource metadata object.
RubrikPolaris.DSPMViolation.details.violatedNoRiskSensitiveHits Number The number of no-risk sensitive hits involved in the violation.
RubrikPolaris.DSPMViolation.details.violatedLowRiskSensitiveHits Number The number of low-risk sensitive hits involved in the violation.
RubrikPolaris.DSPMViolation.details.violatedMediumRiskSensitiveHits Number The number of medium-risk sensitive hits involved in the violation.
RubrikPolaris.DSPMViolation.details.violatedHighRiskSensitiveHits Number The number of high-risk sensitive hits involved in the violation.
RubrikPolaris.DSPMViolation.details.violatedSensitiveHits Number The total number of violated sensitive hits.
RubrikPolaris.DSPMViolation.details.dataTypes.id String The ID of the data type.
RubrikPolaris.DSPMViolation.details.dataTypes.name String The name of the data type.
RubrikPolaris.DSPMViolation.details.dataTypes.totalViolatedHits Number The total violated hits for the data type.
RubrikPolaris.DSPMViolation.details.dataTypes.__typename String The GraphQL typename for the data type stats.
RubrikPolaris.DSPMViolation.details.mipLabels Unknown The MIP labels associated with the details.
RubrikPolaris.DSPMViolation.details.documentTypes Unknown The document types associated with the details.
RubrikPolaris.DSPMViolation.details.dataCategories.id String The ID of the data category.
RubrikPolaris.DSPMViolation.details.dataCategories.name String The name of the data category.
RubrikPolaris.DSPMViolation.details.dataCategories.totalViolatedHits Number The total violated hits for the data category.
RubrikPolaris.DSPMViolation.details.dataCategories.__typename String The GraphQL typename for the data category stats.
RubrikPolaris.DSPMViolation.details.snapshotId String The ID of the snapshot associated with the violation details.
RubrikPolaris.DSPMViolation.details.__typename String The GraphQL typename for the violation details object.
RubrikPolaris.DSPMViolation.policy.description String The description of the policy.
RubrikPolaris.DSPMViolation.policy.policyCategory String The category of the policy.
RubrikPolaris.DSPMViolation.policy.containsAccessFilters Boolean Whether the policy contains access filters.
RubrikPolaris.DSPMViolation.remediations.state String The state of the remediation action.
RubrikPolaris.DSPMViolation.remediations.remediationId String The ID of the remediation.
RubrikPolaris.DSPMViolation.remediations.remediationDetails Unknown Detailed information about the remediation action.
RubrikPolaris.DSPMViolation.remediations.__typename String The GraphQL typename for the remediation object.

Command example

!rubrik-data-security-violation-get violation_id="00000000-0000-0000-0000-000000000001"

Context Example

{
    "RubrikPolaris": {
        "DSPMViolation": {
            "policyViolationId": "00000000-0000-0000-0000-000000000001",
            "status": "POLICY_VIOLATION_STATUS_OPEN",
            "violationSeverity": "MEDIUM",
            "createdAt": "2026-03-06T06:30:45.000Z",
            "lastUpdatedAt": "2026-03-24T05:30:07.000Z",
            "resourceId": "00000000-0000-0000-0000-000000000002",
            "__typename": "PolicyViolation",
            "policy": {
                "policyId": "00000000-0000-0000-0000-000000000003",
                "name": "Secrets stored outside of vault",
                "description": "Storing secrets outside vaults can lead to privilege escalation and unauthorized access. Store secrets in a secure vault to limit exposure.",
                "policyCategory": "MISPLACED",
                "policySeverity": "MEDIUM",
                "containsAccessFilters": false,
                "__typename": "DSPMPolicy"
            },
            "resourceMetadata": {
                "metadata": {
                    "name": "DEMO-RADAR02",
                    "objectType": "VSPHERE_VIRTUAL_MACHINE",
                    "platform": "PLATFORM_DATA_CENTER",
                    "physicalHost": "vcsa.rubrikdemo.com/Datacenters/Data Center/vm/Discovered virtual machine",
                    "clusterInfo": {
                        "clusterName": "Cluster_C",
                        "clusterUuid": "00000000-0000-0000-0000-000000000004",
                        "__typename": "ClusterInfo"
                    },
                    "creationTime": 0,
                    "lastAccessTime": 0,
                    "snapshotTimestamp": 1774329080131,
                    "isDeleted": false,
                    "region": "",
                    "cloudAccountInfo": {
                        "accountName": "",
                        "__typename": "CloudAccountInfo"
                    },
                    "__typename": "CommonAssetMetadata"
                },
                "__typename": "ResourceMetadata"
            },
            "details": {
                "snapshotId": "00000000-0000-0000-0000-000000000005",
                "violatedSensitiveHits": 40,
                "violatedNoRiskSensitiveHits": 37,
                "violatedLowRiskSensitiveHits": 2,
                "violatedMediumRiskSensitiveHits": 1,
                "violatedHighRiskSensitiveHits": 0,
                "__typename": "DataGovViolationDetails",
                "dataTypes": [
                    {
                        "id": "00000000-0000-0000-0000-000000000006",
                        "name": "Country",
                        "totalViolatedHits": 35,
                        "__typename": "DataTypeStats"
                    },
                    {
                        "id": "00000000-0000-0000-0000-000000000007",
                        "name": "US State",
                        "totalViolatedHits": 2,
                        "__typename": "DataTypeStats"
                    }
                ],
                "dataCategories": [
                    {
                        "id": "00000000-0000-0000-0000-000000000008",
                        "name": "Geographical",
                        "totalViolatedHits": 37,
                        "__typename": "DataCategoryStats"
                    }
                ]
            },
            "remediations": [
                {
                    "remediationId": "00000000-0000-0000-0000-000000000009",
                    "state": "REMEDIATION_STATE_SUCCESS",
                    "__typename": "RemediationMetadata"
                }
            ]
        }
    }
}

Human Readable Output

DSPM Violation Data

ID Violation Name Severity Violation Status Detection Time Last Updated Policy ID Policy Description Policy Category Policy Severity Total Risk Hits High Risk Hits Medium Risk Hits Low Risk Hits No Risk Hits Snapshot ID Object ID Object Name Object Type Object Location Object Platform Cluster ID Cluster Name Data Types Data Categories
00000000-0000-0000-0000-000000000001 Secrets stored outside of vault Medium Open 2026-03-06T06:30:45.000Z 2026-03-24T05:30:07.000Z 00000000-0000-0000-0000-000000000003 Storing secrets outside vaults can lead to privilege escalation and unauthorized access. Store secrets in a secure vault to limit exposure. MISPLACED Medium 40 0 1 2 37 00000000-0000-0000-0000-000000000005 00000000-0000-0000-0000-000000000002 DEMO-RADAR02 VSPHERE_VIRTUAL_MACHINE vcsa.rubrikdemo.com/Datacenters/Data Center/vm/Discovered virtual machine PLATFORM_DATA_CENTER 00000000-0000-0000-0000-000000000004 Cluster_C - id: 00000000-0000-0000-0000-000000000006
name: Country
totalViolatedHits: 35
- id: 00000000-0000-0000-0000-000000000007
name: US State
totalViolatedHits: 2
- id: 00000000-0000-0000-0000-000000000008
name: Geographical
totalViolatedHits: 37

rubrik-data-security-violation-status-update


Updates the status of the DSPM violation.

Base Command

rubrik-data-security-violation-status-update

Input

Argument Name Description Required
violation_id The ID of the DSPM violation.

Note: Users can get the violation ID by executing the “rubrik-data-security-violation-list” command.
Required
status The status to update for violation. Possible values are: OPEN, IN_PROGRESS, REMEDIATED, DISMISSED, CLOSED. Required

Context Output

Path Type Description
RubrikPolaris.DSPMViolation.policyViolationId String The ID of the violation.
RubrikPolaris.DSPMViolation.status String The status of the violation.

Command example

!rubrik-data-security-violation-status-update violation_id="00000000-0000-0000-0000-000000000001" status="IN_PROGRESS"

Context Example

{
    "RubrikPolaris": {
        "DSPMViolation": {
            "policyViolationId": "00000000-0000-0000-0000-000000000001",
            "status": "POLICY_VIOLATION_STATUS_IN_PROGRESS"
        }
    }
}

Human Readable Output

Successfully updated the DSPM violation status to In Progress

rubrik-data-security-violation-file-list


Retrieve the file information of data security violation based on the provided violation ID.

Base Command

rubrik-data-security-violation-file-list

Input

Argument Name Description Required
violation_id The ID of the DSPM violation.

Note: Users can get the violation ID by executing the “rubrik-data-security-violation-list” command.
Required
snapshot_id The snapshot ID.

Note: Users can get the snapshot ID by executing the “rubrik-polaris-object-snapshot-list” command.
Required
object_id The object ID.

Note: Users can get the Object ID by executing the “rubrik-polaris-objects-list” command.
Required
limit Number of results to retrieve in the response. The maximum allowed size is 1000. Default is 25. Optional
next_page_token The next page cursor to retrieve the next set of results. Optional
file_name Filter files by their name. Optional
last_access_start_date Filter files with last access after this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: last_access_start_date and last_access_end_date both or none of them should be initialized.
Optional
last_access_end_date Filter files with last access before this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: last_access_start_date and last_access_end_date both or none of them should be initialized.
Optional
last_modified_start_date Filter files with last modified after this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: last_modified_start_date and last_modified_end_date both or none of them should be initialized.
Optional
last_modified_end_date Filter files with last modified before this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: last_modified_start_date and last_modified_end_date both or none of them should be initialized.
Optional
creation_start_date Filter files created after this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: creation_date_start_date and creation_date_start_date both or none of them should be initialized.
Optional
creation_end_date Filter files created before this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: creation_date_start_date and creation_date_start_date both or none of them should be initialized.
Optional
last_scan_start_date Filter files with last scan after this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: last_scan_start_date and last_scan_end_date both or none of them should be initialized.
Optional
last_scan_end_date Filter files with last scan before this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: last_scan_start_date and last_scan_end_date both or none of them should be initialized.
Optional
sensitivity Filter files by sensitivity level. Supports comma separated values. Possible values are: HIGH, MEDIUM, LOW, NO. Optional
exposure Filter files by exposure type. Supports comma separated values. Possible values are: EXPLICIT, INHERITED, NOT_OPEN, PUBLIC. Optional
access_via Filter files by access type. Possible values are: ACCESS_TYPE_UNSPECIFIED, DIRECT, GROUP, ROLE. Default is ACCESS_TYPE_UNSPECIFIED. Optional
sort_order Specify the order to sort the data in. Possible values are: ASC, DESC. Default is DESC. Optional
sort_by Specify the field to use for sorting the response. Possible values are: CLUSTER, CREATION_TIME, DAILY_CHANGE, DATA_CATEGORY, DATA_TYPE, DOCUMENT_TYPE, EXPOSED_FILES, FILES_WITH_HITS, FILES_WITH_OPEN_ACCESS_HITS, HITS, HITS_BY_SENSITIVITY, LAST_ACCESS_TIME, LAST_MODIFIED, LAST_SCAN_TIME, NAME, NATIVE_PATH, NUM_ACTIVITIES, NUM_ACTIVITIES_DELTA, OBJECT_LOCATION, OBJECT_NAME, OPEN_ACCESS_TYPE, SNAPSHOT_TIME, STALE_FILES_WITH_HITS, TOTAL_SENSITIVE_HITS. Default is HITS. Optional

Context Output

Path Type Description
Rubrik.DSPMViolationFile.nativePath String The native path of the file.
Rubrik.DSPMViolationFile.stdPath String The standardized path of the file.
Rubrik.DSPMViolationFile.filename String The name of the file.
Rubrik.DSPMViolationFile.mode String The file mode.
Rubrik.DSPMViolationFile.size Number The file size in bytes.
Rubrik.DSPMViolationFile.lastAccessTime Number The last access time of the file.
Rubrik.DSPMViolationFile.lastModifiedTime Number The last modified time of the file.
Rubrik.DSPMViolationFile.creationTime Number The creation time of the file.
Rubrik.DSPMViolationFile.lastScanTime Number The last scan time of the file.
Rubrik.DSPMViolationFile.directory String The directory of the file.
Rubrik.DSPMViolationFile.createdBy String The user who created the file.
Rubrik.DSPMViolationFile.modifiedBy String The user who last modified the file.
Rubrik.DSPMViolationFile.numDescendantFiles Number The number of descendant files.
Rubrik.DSPMViolationFile.numDescendantErrorFiles Number The number of descendant files with errors.
Rubrik.DSPMViolationFile.numDescendantSkippedExtFiles Number The number of descendant files skipped due to extension.
Rubrik.DSPMViolationFile.numDescendantSkippedSizeFiles Number The number of descendant files skipped due to size.
Rubrik.DSPMViolationFile.errorCode String The error code.
Rubrik.DSPMViolationFile.hits.totalHits Number The total number of hits.
Rubrik.DSPMViolationFile.hits.violations Number The number of violations.
Rubrik.DSPMViolationFile.hits.violationsDelta Number The change in the number of violations.
Rubrik.DSPMViolationFile.hits.totalHitsDelta Number The change in the total number of hits.
Rubrik.DSPMViolationFile.hits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.filesWithHits.totalHits Number The total number of hits in files.
Rubrik.DSPMViolationFile.filesWithHits.violations Number The number of violations in files.
Rubrik.DSPMViolationFile.filesWithHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.openAccessFilesWithHits.totalHits Number The total number of hits in open access files.
Rubrik.DSPMViolationFile.openAccessFilesWithHits.violations Number The number of violations in open access files.
Rubrik.DSPMViolationFile.openAccessFilesWithHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.staleFilesWithHits.totalHits Number The total number of hits in stale files.
Rubrik.DSPMViolationFile.staleFilesWithHits.violations Number The number of violations in stale files.
Rubrik.DSPMViolationFile.staleFilesWithHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerGroup.groupType String The type of the analyzer group.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerGroup.id String The ID of the analyzer group.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerGroup.name String The name of the analyzer group.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerGroup.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerResults.hits.totalHits Number The total number of hits.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerResults.hits.violations Number The number of violations.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerResults.hits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerResults.analyzer.id String The ID of the analyzer.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerResults.analyzer.name String The name of the analyzer.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerResults.analyzer.analyzerType String The type of the analyzer.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerResults.analyzer.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerGroupResults.analyzerResults.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerGroupResults.hits.totalHits Number The total number of hits.
Rubrik.DSPMViolationFile.analyzerGroupResults.hits.violations Number The number of violations.
Rubrik.DSPMViolationFile.analyzerGroupResults.hits.violationsDelta Number The change in the number of violations.
Rubrik.DSPMViolationFile.analyzerGroupResults.hits.totalHitsDelta Number The change in the total number of hits.
Rubrik.DSPMViolationFile.analyzerGroupResults.hits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerGroupResults.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveFiles.highRiskFileCount.totalCount Number The total count of high risk files.
Rubrik.DSPMViolationFile.sensitiveFiles.highRiskFileCount.violatedCount Number The count of high risk files with violations.
Rubrik.DSPMViolationFile.sensitiveFiles.highRiskFileCount.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveFiles.mediumRiskFileCount.totalCount Number The total count of medium risk files.
Rubrik.DSPMViolationFile.sensitiveFiles.mediumRiskFileCount.violatedCount Number The count of medium risk files with violations.
Rubrik.DSPMViolationFile.sensitiveFiles.mediumRiskFileCount.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveFiles.lowRiskFileCount.totalCount Number The total count of low risk files.
Rubrik.DSPMViolationFile.sensitiveFiles.lowRiskFileCount.violatedCount Number The count of low risk files with violations.
Rubrik.DSPMViolationFile.sensitiveFiles.lowRiskFileCount.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveFiles.noRiskFileCount Unknown The count of files with no risk.
Rubrik.DSPMViolationFile.sensitiveFiles.totalFileCount.totalCount Number The total count of files.
Rubrik.DSPMViolationFile.sensitiveFiles.totalFileCount.violatedCount Number The count of files with violations.
Rubrik.DSPMViolationFile.sensitiveFiles.totalFileCount.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveFiles.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveHits.highRiskHits.totalHits Number The total number of high risk hits.
Rubrik.DSPMViolationFile.sensitiveHits.highRiskHits.violatedHits Number The number of violated high risk hits.
Rubrik.DSPMViolationFile.sensitiveHits.highRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveHits.mediumRiskHits.totalHits Number The total number of medium risk hits.
Rubrik.DSPMViolationFile.sensitiveHits.mediumRiskHits.violatedHits Number The number of violated medium risk hits.
Rubrik.DSPMViolationFile.sensitiveHits.mediumRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveHits.lowRiskHits.totalHits Number The total number of low risk hits.
Rubrik.DSPMViolationFile.sensitiveHits.lowRiskHits.violatedHits Number The number of violated low risk hits.
Rubrik.DSPMViolationFile.sensitiveHits.lowRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveHits.noRiskHits.totalHits Number The total number of no risk hits.
Rubrik.DSPMViolationFile.sensitiveHits.noRiskHits.violatedHits Number The number of violated no risk hits.
Rubrik.DSPMViolationFile.sensitiveHits.noRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.sensitiveHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerRiskHits.highRiskHits.totalHits Number The total number of high risk analyzer hits.
Rubrik.DSPMViolationFile.analyzerRiskHits.highRiskHits.violatedHits Number The number of violated high risk analyzer hits.
Rubrik.DSPMViolationFile.analyzerRiskHits.highRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerRiskHits.mediumRiskHits.totalHits Number The total number of medium risk analyzer hits.
Rubrik.DSPMViolationFile.analyzerRiskHits.mediumRiskHits.violatedHits Number The number of violated medium risk analyzer hits.
Rubrik.DSPMViolationFile.analyzerRiskHits.mediumRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerRiskHits.lowRiskHits.totalHits Number The total number of low risk analyzer hits.
Rubrik.DSPMViolationFile.analyzerRiskHits.lowRiskHits.violatedHits Number The number of violated low risk analyzer hits.
Rubrik.DSPMViolationFile.analyzerRiskHits.lowRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerRiskHits.noRiskHits.totalHits Number The total number of no risk analyzer hits.
Rubrik.DSPMViolationFile.analyzerRiskHits.noRiskHits.violatedHits Number The number of violated no risk analyzer hits.
Rubrik.DSPMViolationFile.analyzerRiskHits.noRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerRiskHits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerResults.hits.totalHits Number The total number of hits.
Rubrik.DSPMViolationFile.analyzerResults.hits.violations Number The number of violations.
Rubrik.DSPMViolationFile.analyzerResults.hits.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerResults.analyzer.id String The ID of the analyzer.
Rubrik.DSPMViolationFile.analyzerResults.analyzer.name String The name of the analyzer.
Rubrik.DSPMViolationFile.analyzerResults.analyzer.analyzerType String The type of the analyzer.
Rubrik.DSPMViolationFile.analyzerResults.analyzer.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.analyzerResults.__typename String The GraphQL type name.
Rubrik.DSPMViolationFile.openAccessType String The open access type.
Rubrik.DSPMViolationFile.stalenessType String The staleness type.
Rubrik.DSPMViolationFile.numActivities Number The number of activities.
Rubrik.DSPMViolationFile.numActivitiesDelta Number The change in the number of activities.
Rubrik.DSPMViolationFile.exposureSummary Unknown The exposure summary.
Rubrik.DSPMViolationFile.dbEntityType String The database entity type.
Rubrik.DSPMViolationFile.mipLabelsSummary Unknown The MIP labels summary.
Rubrik.DSPMViolationFile.documentTypesSummary Unknown The document types summary.
Rubrik.DSPMViolationFile.__typename String The GraphQL type name.

Command example

!rubrik-data-security-violation-file-list violation_id="00000000-0000-0000-0000-000000000001" snapshot_id="00000000-0000-0000-0000-000000010001" object_id="00000000-0000-0000-0000-000000000002"

Context Example

{
    "RubrikPolaris": {
        "DSPMViolationFile": [
            {
                "nativePath": "/Sales Department/fileName.txt",
                "stdPath": "/Sales Department/fileName.txt",
                "filename": "fileName.txt",
                "mode": "FILE",
                "size": 67615,
                "lastAccessTime": 0,
                "lastModifiedTime": 1684957676,
                "creationTime": 0,
                "lastScanTime": 1775406966,
                "directory": "/Sales Department",
                "createdBy": "",
                "modifiedBy": "",
                "numDescendantFiles": 0,
                "numDescendantErrorFiles": 0,
                "numDescendantSkippedExtFiles": 0,
                "numDescendantSkippedSizeFiles": 0,
                "errorCode": "NOERROR",
                "hits": {
                    "totalHits": 0,
                    "violations": 3022,
                    "violationsDelta": 0,
                    "totalHitsDelta": 0,
                    "__typename": "Hits"
                },
                "filesWithHits": {
                    "totalHits": 0,
                    "violations": 1,
                    "__typename": "Hits"
                },
                "openAccessFilesWithHits": {
                    "totalHits": 0,
                    "violations": 0,
                    "__typename": "Hits"
                },
                "staleFilesWithHits": {
                    "totalHits": 0,
                    "violations": 1,
                    "__typename": "Hits"
                },
                "analyzerGroupResults": [
                    {
                        "analyzerGroup": {
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000008",
                            "name": "Personal",
                            "__typename": "AnalyzerGroup"
                        },
                        "analyzerResults": [
                            {
                                "hits": {
                                    "totalHits": 0,
                                    "violations": 0,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000003",
                                    "name": "Italy Passport Number",
                                    "analyzerType": "UNDEFINED",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            },
                            {
                                "hits": {
                                    "totalHits": 0,
                                    "violations": 0,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000004",
                                    "name": "ITIN",
                                    "analyzerType": "US_ITIN",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            }
                        ],
                        "hits": {
                            "totalHits": 0,
                            "violations": 1533,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        },
                        "__typename": "AnalyzerGroupResult"
                    },
                    {
                        "analyzerGroup": {
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000007",
                            "name": "Geographical",
                            "__typename": "AnalyzerGroup"
                        },
                        "analyzerResults": [
                            {
                                "hits": {
                                    "totalHits": 0,
                                    "violations": 0,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000005",
                                    "name": "Country",
                                    "analyzerType": "UNDEFINED",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            },
                            {
                                "hits": {
                                    "totalHits": 0,
                                    "violations": 0,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000006",
                                    "name": "County",
                                    "analyzerType": "UNDEFINED",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            }
                        ],
                        "hits": {
                            "totalHits": 0,
                            "violations": 1489,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        },
                        "__typename": "AnalyzerGroupResult"
                    }
                ],
                "sensitiveFiles": {
                    "highRiskFileCount": {
                        "totalCount": 0,
                        "violatedCount": 0,
                        "__typename": "SummaryCount"
                    },
                    "mediumRiskFileCount": {
                        "totalCount": 0,
                        "violatedCount": 1,
                        "__typename": "SummaryCount"
                    },
                    "lowRiskFileCount": {
                        "totalCount": 0,
                        "violatedCount": 0,
                        "__typename": "SummaryCount"
                    },
                    "totalFileCount": {
                        "totalCount": 0,
                        "violatedCount": 0,
                        "__typename": "SummaryCount"
                    },
                    "__typename": "SensitiveFiles"
                },
                "sensitiveHits": {
                    "highRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "mediumRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 1533,
                        "__typename": "SummaryHits"
                    },
                    "lowRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "noRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 1489,
                        "__typename": "SummaryHits"
                    },
                    "__typename": "SensitiveHits"
                },
                "analyzerRiskHits": {
                    "highRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "mediumRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 1533,
                        "__typename": "SummaryHits"
                    },
                    "lowRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "noRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "__typename": "AnalyzerHits"
                },
                "analyzerResults": [
                    {
                        "hits": {
                            "totalHits": 0,
                            "violations": 758,
                            "__typename": "Hits"
                        },
                        "analyzer": {
                            "id": "00000000-0000-0000-0000-000000000013",
                            "name": "First Name",
                            "analyzerType": "UNDEFINED",
                            "__typename": "Analyzer"
                        },
                        "__typename": "AnalyzerResult"
                    },
                    {
                        "hits": {
                            "totalHits": 0,
                            "violations": 9,
                            "__typename": "Hits"
                        },
                        "analyzer": {
                            "id": "00000000-0000-0000-0000-000000000009",
                            "name": "EU Country",
                            "analyzerType": "UNDEFINED",
                            "__typename": "Analyzer"
                        },
                        "__typename": "AnalyzerResult"
                    },
                    {
                        "hits": {
                            "totalHits": 0,
                            "violations": 765,
                            "__typename": "Hits"
                        },
                        "analyzer": {
                            "id": "00000000-0000-0000-0000-000000000010",
                            "name": "City",
                            "analyzerType": "UNDEFINED",
                            "__typename": "Analyzer"
                        },
                        "__typename": "AnalyzerResult"
                    },
                    {
                        "hits": {
                            "totalHits": 0,
                            "violations": 715,
                            "__typename": "Hits"
                        },
                        "analyzer": {
                            "id": "00000000-0000-0000-0000-000000000011",
                            "name": "US State",
                            "analyzerType": "UNDEFINED",
                            "__typename": "Analyzer"
                        },
                        "__typename": "AnalyzerResult"
                    },
                    {
                        "hits": {
                            "totalHits": 0,
                            "violations": 775,
                            "__typename": "Hits"
                        },
                        "analyzer": {
                            "id": "00000000-0000-0000-0000-000000000012",
                            "name": "Last Name",
                            "analyzerType": "UNDEFINED",
                            "__typename": "Analyzer"
                        },
                        "__typename": "AnalyzerResult"
                    }
                ],
                "openAccessType": "UNKNOWN_ACCESS",
                "stalenessType": "IS_STALE",
                "numActivities": 0,
                "numActivitiesDelta": 0,
                "dbEntityType": "UNDEFINED_ENTITY",
                "__typename": "FileResult"
            },
            {
                "nativePath": "/Sales Department/fileName1.txt",
                "stdPath": "/Sales Department/fileName1.txt",
                "filename": "fileName1.txt",
                "mode": "FILE",
                "size": 25653,
                "lastAccessTime": 0,
                "lastModifiedTime": 1684957355,
                "creationTime": 0,
                "lastScanTime": 1775406966,
                "directory": "/Sales Department",
                "createdBy": "",
                "modifiedBy": "",
                "numDescendantFiles": 0,
                "numDescendantErrorFiles": 0,
                "numDescendantSkippedExtFiles": 0,
                "numDescendantSkippedSizeFiles": 0,
                "errorCode": "NOERROR",
                "hits": {
                    "totalHits": 0,
                    "violations": 790,
                    "violationsDelta": 0,
                    "totalHitsDelta": 0,
                    "__typename": "Hits"
                },
                "filesWithHits": {
                    "totalHits": 0,
                    "violations": 1,
                    "__typename": "Hits"
                },
                "openAccessFilesWithHits": {
                    "totalHits": 0,
                    "violations": 0,
                    "__typename": "Hits"
                },
                "staleFilesWithHits": {
                    "totalHits": 0,
                    "violations": 1,
                    "__typename": "Hits"
                },
                "analyzerGroupResults": [
                    {
                        "analyzerGroup": {
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000007",
                            "name": "Geographical",
                            "__typename": "AnalyzerGroup"
                        },
                        "analyzerResults": [
                            {
                                "hits": {
                                    "totalHits": 0,
                                    "violations": 21,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000005",
                                    "name": "Country",
                                    "analyzerType": "UNDEFINED",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            },
                            {
                                "hits": {
                                    "totalHits": 0,
                                    "violations": 0,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000006",
                                    "name": "County",
                                    "analyzerType": "UNDEFINED",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            }
                        ],
                        "hits": {
                            "totalHits": 0,
                            "violations": 397,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        },
                        "__typename": "AnalyzerGroupResult"
                    },
                    {
                        "analyzerGroup": {
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000008",
                            "name": "Personal",
                            "__typename": "AnalyzerGroup"
                        },
                        "analyzerResults": [
                            {
                                "hits": {
                                    "totalHits": 0,
                                    "violations": 0,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000003",
                                    "name": "Italy Passport Number",
                                    "analyzerType": "UNDEFINED",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            },
                            {
                                "hits": {
                                    "totalHits": 0,
                                    "violations": 0,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000004",
                                    "name": "ITIN",
                                    "analyzerType": "US_ITIN",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            }
                        ],
                        "hits": {
                            "totalHits": 0,
                            "violations": 393,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        },
                        "__typename": "AnalyzerGroupResult"
                    }
                ],
                "sensitiveFiles": {
                    "highRiskFileCount": {
                        "totalCount": 0,
                        "violatedCount": 0,
                        "__typename": "SummaryCount"
                    },
                    "mediumRiskFileCount": {
                        "totalCount": 0,
                        "violatedCount": 1,
                        "__typename": "SummaryCount"
                    },
                    "lowRiskFileCount": {
                        "totalCount": 0,
                        "violatedCount": 0,
                        "__typename": "SummaryCount"
                    },
                    "totalFileCount": {
                        "totalCount": 0,
                        "violatedCount": 0,
                        "__typename": "SummaryCount"
                    },
                    "__typename": "SensitiveFiles"
                },
                "sensitiveHits": {
                    "highRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "mediumRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 393,
                        "__typename": "SummaryHits"
                    },
                    "lowRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "noRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 397,
                        "__typename": "SummaryHits"
                    },
                    "__typename": "SensitiveHits"
                },
                "analyzerRiskHits": {
                    "highRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "mediumRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 393,
                        "__typename": "SummaryHits"
                    },
                    "lowRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "noRiskHits": {
                        "totalHits": 0,
                        "violatedHits": 0,
                        "__typename": "SummaryHits"
                    },
                    "__typename": "AnalyzerHits"
                },
                "analyzerResults": [
                    {
                        "hits": {
                            "totalHits": 0,
                            "violations": 192,
                            "__typename": "Hits"
                        },
                        "analyzer": {
                            "id": "00000000-0000-0000-0000-000000000010",
                            "name": "City",
                            "analyzerType": "UNDEFINED",
                            "__typename": "Analyzer"
                        },
                        "__typename": "AnalyzerResult"
                    }
                ],
                "openAccessType": "UNKNOWN_ACCESS",
                "stalenessType": "IS_STALE",
                "numActivities": 0,
                "numActivitiesDelta": 0,
                "dbEntityType": "UNDEFINED_ENTITY",
                "__typename": "FileResult"
            }
        ]
    },
    "RubrikPolaris": {
        "PageToken": {
            "DSPMViolationFile": {
                "name": "rubrik-data-security-violation-file-list",
                "next_page_token": "end_hash_cursor",
                "has_next_page": true
            }
        }
    }
}

Human Readable Output

DSPM Violation File List

File Path File Size in Bytes Total Risk Hits High Risk Hits Medium Risk Hits Low Risk Hits No Risk Hits Last Access Time Last Modified Time Data Categories
/Sales Department/fileName.txt 67615 3022 0 1533 0 1489 1970-01-01T00:00:00Z 2023-05-24T19:47:56Z - id: 00000000-0000-0000-0000-000000000008
name: Personal
totalViolatedHits: 1533
- id: 00000000-0000-0000-0000-000000000007
name: Geographical
totalViolatedHits: 1489
/Sales Department/fileName1.txt 25653 790 0 393 0 397 1970-01-01T00:00:00Z 2023-05-24T19:42:35Z - id: 00000000-0000-0000-0000-000000000007
name: Geographical
totalViolatedHits: 397
- id: 00000000-0000-0000-0000-000000000008
name: Personal
totalViolatedHits: 393

Note: To retrieve the next set of results use, “next_page_token” = end_hash_cursor

rubrik-data-security-violation-csv-download


Download all files at risk as CSV file for the specified data security violation.

Base Command

rubrik-data-security-violation-csv-download

Input

Argument Name Description Required
violation_id The ID of the DSPM violation.

Note: Users can get the violation ID by executing the “rubrik-data-security-violation-list” command.
Required
snapshot_id The snapshot ID.

Note: Users can retrieve the snapshot ID by executing the “rubrik-polaris-object-snapshot-list” command.
Required
object_id The object ID.

Note: Users can retrieve the object ID by executing the “rubrik-polaris-objects-list” command.
Required
object_name The object Name.

Note: If not specified command will retrieve it using the “rubrik-data-security-violation-get” command.
Optional

Context Output

Path Type Description
RubrikPolaris.DSPMViolationCSVDownload.violationId String The ID of the violation.
RubrikPolaris.DSPMViolationCSVDownload.snapshotId String The ID of the snapshot.
RubrikPolaris.DSPMViolationCSVDownload.objectId String The ID of the object.
RubrikPolaris.DSPMViolationCSVDownload.objectName String The Name of the object.
RubrikPolaris.DSPMViolationCSVDownload.externalId String The external ID of the CSV file.
RubrikPolaris.DSPMViolationCSVDownload.isSuccessful Boolean Whether the CSV analysis was successful or not.
InfoFile.Name string FileName.
InfoFile.EntryID string The EntryID of the report.
InfoFile.Size number File Size.
InfoFile.Type string File type e.g. “PE”.
InfoFile.Info string Basic information of the file.

Command example

!rubrik-data-security-violation-csv-download violation_id="00000000-0000-0000-0000-000000000001" snapshot_id="00000000-0000-0000-0000-000000010001" object_id="00000000-0000-0000-0000-000000000002"

Context Example

{
    "InfoFile": {
        "EntryID": "10000@00000000-0000-0000-0000-000000000001",
        "Extension": "csv",
        "Info": "text/csv; charset=utf-8",
        "Name": "test_object-violating-files_file_results_1775629027.csv",
        "Size": 1771317,
        "Type": "ASCII text, with very long lines"
    },
    "RubrikPolaris": {
        "DSPMViolationCSVDownload": {
            "violationId": "00000000-0000-0000-0000-000000000001",
            "objectId": "00000000-0000-0000-0000-000000000002",
            "snapshotId": "00000000-0000-0000-0000-000000010001",
            "objectName": "test_object",
            "externalId": "00000000-0000-0000-0000-000000000011",
            "isSuccessful": true
        }
    }
}

Human Readable Output

Successfully downloaded the Files at Risk CSV file

rubrik-data-security-violation-log-download


Download remediation logs as CSV file for the specified data security violation.

Base Command

rubrik-data-security-violation-log-download

Input

Argument Name Description Required
violation_id The ID of the DSPM violation.

Note: Users can get the violation ID by executing the “rubrik-data-security-violation-list” command.
Required
object_id The object ID.

Note: Users can retrieve the object ID by executing the “rubrik-polaris-objects-list” command.
Required
object_name The object Name.

Note: If not specified command will retrieve it using the “rubrik-data-security-violation-get” command.
Optional

Context Output

Path Type Description
RubrikPolaris.DSPMViolationRemediationLogDownload.violationId String The ID of the violation.
RubrikPolaris.DSPMViolationRemediationLogDownload.objectId String The ID of the object.
RubrikPolaris.DSPMViolationRemediationLogDownload.remediationId String The ID of the remediation.
RubrikPolaris.DSPMViolationRemediationLogDownload.objectName String The Name of the object.
RubrikPolaris.DSPMViolationRemediationLogDownload.externalId String The external ID of the file.
RubrikPolaris.DSPMViolationRemediationLogDownload.isSuccessful Boolean Whether the command was successful or not.
InfoFile.Name string FileName.
InfoFile.EntryID string The EntryID of the report.
InfoFile.Size number File Size.
InfoFile.Type string File type e.g. “PE”.
InfoFile.Info string Basic information of the file.

Command example

!rubrik-data-security-violation-log-download violation_id="00000000-0000-0000-0000-000000000001" object_id="00000000-0000-0000-0000-000000000002"

Context Example

{
    "InfoFile": {
        "EntryID": "10000@00000000-0000-0000-0000-000000000001",
        "Extension": "csv",
        "Info": "text/csv; charset=utf-8",
        "Name": "test_object actions log.csv",
        "Size": 1771317,
        "Type": "ASCII text, with very long lines"
    },
    "RubrikPolaris": {
        "DSPMViolationRemediationLogDownload": {
            "violationId": "00000000-0000-0000-0000-000000000001",
            "objectId": "00000000-0000-0000-0000-000000000002",
            "remediationId": "00000000-0000-0000-0000-000000010001",
            "externalId": "00000000-0000-0000-0000-000000000011",
            "objectName": "test_object",
            "isSuccessful": true
        }
    }
}

Human Readable Output

Successfully downloaded the Remediation Log file

rubrik-identity-resilience-violation-list


Retrieves the list of Identity Resilience (IR) violations.

Base Command

rubrik-identity-resilience-violation-list

Input

Argument Name Description Required
policy_type Filter the violations by policy type. Supports comma separated values. Possible values are: IDENTITY, IDP, IDENTITY_EVENT, CROWDSTRIKE, MICROSOFT_DEFENDER. Optional
detection_start_date Filter the violations detected after this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: detection_start_date and detection_end_date both or none of them should be initialized.
Optional
detection_end_date Filter the violations detected before this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: detection_start_date and detection_end_date both or none of them should be initialized.
Optional
resolved_start_date Filter the violations resolved after this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: resolved_start_date and resolved_end_date both or none of them should be initialized.
Optional
resolved_end_date Filter the violations resolved before this date.

Formats accepted: 2 minutes, 2 hours, 2 days, 2 weeks, 2 months, 2 years, yyyy-mm-dd, yyyy-mm-ddTHH:MM:SSZ.

For example: 01 Jan 2026, 01 Jan 2026 04:45:33, 2026-01-01T14:05:44Z.

Note: resolved_start_date and resolved_end_date both or none of them should be initialized.
Optional
category Filter the violations by category. Supports comma separated values. Possible values are: CATEGORY_UNSPECIFIED, AUTHENTICATION_AND_SECRET_MANAGEMENT, IDENTITY_HYGIENE, EXCESSIVE_IDENTITY_RIGHTS, IDENTITY_PROVIDER_SECURITY, PRIVILEGED_ACCOUNT_RISK, IDENTITY_RISK, INFRASTRUCTURE_SECURITY, CONFIGURATION_SECURITY, MEMBERSHIP_CHANGE, GPO_CHANGE. Optional
status Filter the violations by status. Supports comma separated values. Possible values are: OPEN, IN_PROGRESS, REMEDIATED, DISMISSED, CLOSED. Optional
severity Filter the violations by severity level. Supports comma separated values. Possible values are: SEVERITY_UNSPECIFIED, LOW, MEDIUM, HIGH, CRITICAL. Optional
identity_provider Filter the violations by identity provider type. Supports comma separated values. Possible values are: IDP_UNSPECIFIED, ON_PREM_AD, ENTRA_ID, AWS, LOCAL_AD, SHAREPOINT, SYSTEM, OKTA. Optional
identity_tag Filter the violations by identity tag. Supports comma separated values. Possible values are: IDENTITY_TAG_UNSPECIFIED, PRIVILEGED, AT_RISK, SENSITIVE. Optional
limit Number of results to retrieve in the response. The maximum allowed size is 1000. Default is 50. Optional
next_page_token The next page cursor to retrieve the next set of results. Optional
sort_by Specify the field to use for sorting the response. Possible values are: SEVERITY, HITS, DETECTION_TIME, UPDATE_TIME, IDENTITY_TYPE, TOTAL_HITS, EVENT_TIME, NAME, TYPE. Default is DETECTION_TIME. Optional
sort_order Specify the order to sort the data in. Possible values are: ASC, DESC. Default is DESC. Optional

Context Output

Path Type Description
RubrikPolaris.IRViolation.policyViolationId String The unique identifier for the policy violation.
RubrikPolaris.IRViolation.name String The name of the policy violation.
RubrikPolaris.IRViolation.violationSeverity String The severity level of the policy violation.
RubrikPolaris.IRViolation.status String The current status of the policy violation.
RubrikPolaris.IRViolation.createdAt Date The date and time when the policy violation was created.
RubrikPolaris.IRViolation.lastUpdatedAt Date The date and time when the policy violation was last updated.
RubrikPolaris.IRViolation.resourceId String The unique identifier of the resource associated with the violation.
RubrikPolaris.IRViolation.resourceType String The type of the resource associated with the violation.
RubrikPolaris.IRViolation.policy.policyId String The unique identifier of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.name String The name of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.description String The description of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.policySeverity String The severity level assigned to the policy.
RubrikPolaris.IRViolation.policy.policyCategory String The category of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.policyType String The type of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.frameworks String The compliance frameworks associated with the policy.
RubrikPolaris.IRViolation.policy.manualRemediationProcess String The manual remediation process recommended for the policy violation.
RubrikPolaris.IRViolation.details.domainUniqueId String The unique identifier of the domain associated with the violation details.
RubrikPolaris.IRViolation.details.detectionTime Date The time at which the threat was detected.
RubrikPolaris.IRViolation.details.startTime Date The start time of the alert event.
RubrikPolaris.IRViolation.details.endTime Date The end time of the alert event.
RubrikPolaris.IRViolation.details.mitreTactic String The MITRE ATT&CK tactic associated with the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.displayName String The display name of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.domainName String The domain name of the resource associated with the violation.
RubrikPolaris.IRViolation.resourceMetadata.metadata.domainUniqueId String The unique identifier of the domain of the resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.idpType String The identity provider type of the resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.principalType String The principal type of the identity resource (e.g. USER, COMPUTER).
RubrikPolaris.IRViolation.resourceMetadata.metadata.privilegeType String The privilege type of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.userPrincipalName String The user principal name of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.status String The status of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.title String The job title of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.source String The source of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.identityTags String The list of tags associated with the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.uniqueId String The unique identifier of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.nativeType String The native type of the identity resource (e.g. User).
RubrikPolaris.IRViolation.resourceMetadata.metadata.rootDomainName String The root domain name of the resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.rootDomainId String The unique identifier of the root domain of the resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorIdentityId String The unique identifier of the actor identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorIdentityName String The name of the actor identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorIdentityType String The type of the actor identity involved in the alert (e.g. USER).
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorPrivilegeType String The privilege type of the actor identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorState String The state of the actor identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.entityName String The name of the entity associated with the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.entityId String The unique identifier of the entity associated with the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentityUniqueIdentifier String The unique identifier of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentityName String The name of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentitySource String The source domain of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentityStatus String The status of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentityType String The type of the target identity involved in the alert (e.g. COMPUTER).
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdpType String The identity provider type of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetPrivilegeType String The privilege type of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.eventTime Date The time at which the identity event occurred.
RubrikPolaris.PageToken.IRViolation.next_page_token String The next page token.
RubrikPolaris.PageToken.IRViolation.name String The name of the command.
RubrikPolaris.PageToken.IRViolation.has_next_page Boolean Whether the result has the next page or not.

Command example

!rubrik-identity-resilience-violation-list limit=2

Context Example

{
    "RubrikPolaris": {
        "IRViolation": [
            {
                "policyViolationId": "00000000-0000-0000-0000-000000000001",
                "status": "POLICY_VIOLATION_STATUS_OPEN",
                "violationSeverity": "HIGH",
                "createdAt": "2026-03-25T09:29:55.000Z",
                "lastUpdatedAt": "2026-03-25T13:29:54.000Z",
                "resourceId": "00000000-0000-0000-0000-000000000101",
                "resourceType": "RESOURCE_TYPE_IDENTITY",
                "policy": {
                    "policyId": "00000000-0000-0000-0000-000000000201",
                    "name": "Excessive admin privileges",
                    "description": "Users with excessive admin privileges pose a risk of privilege escalation.",
                    "policySeverity": "HIGH",
                    "policyCategory": "IDENTITY_HYGIENE",
                    "policyType": "POLICY_TYPE_IDENTITY",
                    "frameworks": [
                        "MITRE ATT&CK: TA0006",
                        "CIS Controls: 14.2, 14.6",
                        "NIST CSF: PR.AC-1, PR.PT-3",
                        "NIST SP 800-53: AC-3, AC-6, IA-5",
                        "Regulations: GDPR, HIPAA, PCI DSS, SOC 2, CMMC"
                    ],
                    "manualRemediationProcess": "Disable delegation for privileged identities. For users, it's recommended to assign them to the \"Protected Users\" group. Alternatively, you can enable the setting \"This account is sensitive and can't be delegated\". For computers and service accounts, disable delegation by disabling the setting \"Trust this computer/user for delegation to any service\". If delegation is required, convert to constrained delegation that limits which services an identity can delegate to.",
                    "__typename": "IRPolicy"
                },
                "details": {
                    "domainUniqueId": "00000000-0000-0000-0000-000000000301",
                    "__typename": "IdentityViolationDetails"
                },
                "resourceMetadata": {
                    "metadata": {
                        "displayName": "John Doe",
                        "domainName": "rubrikdemo.com",
                        "idpType": "ENTRA_ID",
                        "principalType": "USER",
                        "privilegeType": "PRIVILEGED",
                        "userPrincipalName": "demo@rubrik.com",
                        "status": "ACTIVE",
                        "source": "ON_PREM_AD",
                        "identityTags": [
                            "PRIVILEGED"
                        ],
                        "uniqueId": "00000000-0000-0000-0000-000000000401",
                        "nativeType": "User",
                        "__typename": "IdentityMetadata"
                    },
                    "__typename": "ResourceMetadata"
                },
                "__typename": "PolicyViolation"
            },
            {
                "policyViolationId": "00000000-0000-0000-0000-000000000003",
                "status": "POLICY_VIOLATION_STATUS_OPEN",
                "name": "",
                "violationSeverity": "MEDIUM",
                "createdAt": "2026-03-25T16:45:30.000Z",
                "lastUpdatedAt": "2026-03-25T18:30:15.000Z",
                "resourceId": "00000000-0000-0000-0000-000000000103",
                "resourceType": "RESOURCE_TYPE_IDP",
                "policy": {
                    "policyId": "00000000-0000-0000-0000-000000000203",
                    "name": "Overly permissive IDP configuration",
                    "description": "Identity provider with overly permissive configuration.",
                    "policySeverity": "MEDIUM",
                    "policyCategory": "IDENTITY_PROVIDER_SECURITY",
                    "policyType": "POLICY_TYPE_IDP",
                    "frameworks": [
                        "MITRE ATT&CK: TA0006",
                        "CIS Controls: 6.7; NIST CSF: PR.AC-6",
                        "NIST SP 800-53: IA-5",
                        "Regulations: GDPR, HIPAA, PCI DSS, SOC 2, CMMC"
                    ],
                    "manualRemediationProcess": "Deploy a Conditional Access policy that enforces MFA for all users.",
                    "__typename": "IRPolicy"
                },
                "details": {
                    "domainUniqueId": "00000000-0000-0000-0000-000000000303",
                    "__typename": "IdpViolationDetails"
                },
                "resourceMetadata": {
                    "metadata": {
                        "domainName": "rubrikdemo.com",
                        "domainUniqueId": "00000000-0000-0000-0000-000000000303",
                        "idpType": "OKTA",
                        "rootDomainName": "rubrikdemo.com",
                        "rootDomainId": "00000000-0000-0000-0000-000000000501",
                        "__typename": "IdpMetadata"
                    },
                    "__typename": "ResourceMetadata"
                },
                "__typename": "PolicyViolation"
            }
        ],
        "PageToken": {
            "IRViolation": {
                "name": "rubrik-identity-resilience-violation-list",
                "next_page_token": "hash_token_ir",
                "has_next_page": true
            }
        }
    }
}

Human Readable Output

IR Violations List

ID Policy Name Display Name Domain Status Severity Policy Type Category Root Domain Detected On
00000000-0000-0000-0000-000000000001 Excessive admin privileges John Doe rubrikdemo.com Open High Identity Identity Hygiene   2026-03-25T09:29:55.000Z
00000000-0000-0000-0000-000000000003 Overly permissive IDP configuration   rubrikdemo.com Open Medium Idp Identity Provider Security rubrikdemo.com 2026-03-25T16:45:30.000Z

Note: To retrieve the next set of results use, “next_page_token” = hash_token_ir

rubrik-identity-resilience-violation-get


Retrieves the details of the Identity Resilience (IR) violation based on the provided violation ID.

Base Command

rubrik-identity-resilience-violation-get

Input

Argument Name Description Required
violation_id The ID of the IR violation.

Note: Users can get the violation ID by executing the “rubrik-identity-resilience-violation-list” command.
Required
policy_type The policy type of the IR violation. Possible values are: IDENTITY, IDP, IDENTITY_EVENT, CROWDSTRIKE, MICROSOFT_DEFENDER. Optional

Context Output

Path Type Description
RubrikPolaris.IRViolation.policyViolationId String The unique identifier for the policy violation.
RubrikPolaris.IRViolation.name String The name of the policy violation.
RubrikPolaris.IRViolation.violationSeverity String The severity level of the policy violation.
RubrikPolaris.IRViolation.status String The current status of the policy violation.
RubrikPolaris.IRViolation.createdAt Date The date and time when the policy violation was created.
RubrikPolaris.IRViolation.lastUpdatedAt Date The date and time when the policy violation was last updated.
RubrikPolaris.IRViolation.resourceId String The unique identifier of the resource associated with the violation.
RubrikPolaris.IRViolation.resourceType String The type of the resource associated with the violation.
RubrikPolaris.IRViolation.policy.policyId String The unique identifier of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.name String The name of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.description String The description of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.policySeverity String The severity level assigned to the policy.
RubrikPolaris.IRViolation.policy.policyCategory String The category of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.policyType String The type of the policy associated with the violation.
RubrikPolaris.IRViolation.policy.frameworks String The compliance frameworks associated with the policy.
RubrikPolaris.IRViolation.policy.manualRemediationProcess String The manual remediation process recommended for the policy violation.
RubrikPolaris.IRViolation.details.domainUniqueId String The unique identifier of the domain associated with the violation details.
RubrikPolaris.IRViolation.details.detectionTime Date The time at which the threat was detected.
RubrikPolaris.IRViolation.details.startTime Date The start time of the alert event.
RubrikPolaris.IRViolation.details.endTime Date The end time of the alert event.
RubrikPolaris.IRViolation.details.mitreTactic String The MITRE ATT&CK tactic associated with the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.displayName String The display name of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.domainName String The domain name of the resource associated with the violation.
RubrikPolaris.IRViolation.resourceMetadata.metadata.domainUniqueId String The unique identifier of the domain of the resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.idpType String The identity provider type of the resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.principalType String The principal type of the identity resource (e.g. USER, COMPUTER).
RubrikPolaris.IRViolation.resourceMetadata.metadata.privilegeType String The privilege type of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.userPrincipalName String The user principal name of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.status String The status of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.title String The job title of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.source String The source of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.identityTags String The list of tags associated with the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.uniqueId String The unique identifier of the identity resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.nativeType String The native type of the identity resource (e.g. User).
RubrikPolaris.IRViolation.resourceMetadata.metadata.rootDomainName String The root domain name of the resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.rootDomainId String The unique identifier of the root domain of the resource.
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorIdentityId String The unique identifier of the actor identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorIdentityName String The name of the actor identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorIdentityType String The type of the actor identity involved in the alert (e.g. USER).
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorPrivilegeType String The privilege type of the actor identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.actorState String The state of the actor identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.entityName String The name of the entity associated with the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.entityId String The unique identifier of the entity associated with the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentityUniqueIdentifier String The unique identifier of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentityName String The name of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentitySource String The source domain of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentityStatus String The status of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdentityType String The type of the target identity involved in the alert (e.g. COMPUTER).
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetIdpType String The identity provider type of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.targetPrivilegeType String The privilege type of the target identity involved in the alert.
RubrikPolaris.IRViolation.resourceMetadata.metadata.eventTime Date The time at which the identity event occurred.
RubrikPolaris.IRViolation.sensitiveHits.highRiskHits.violatedHits Number The number of high risk sensitive hits violated by the identity.
RubrikPolaris.IRViolation.sensitiveHits.mediumRiskHits.violatedHits Number The number of medium risk sensitive hits violated by the identity.
RubrikPolaris.IRViolation.sensitiveHits.lowRiskHits.violatedHits Number The number of low risk sensitive hits violated by the identity.
RubrikPolaris.IRViolation.sensitiveHits.noRiskHits.violatedHits Number The number of no risk sensitive hits violated by the identity.
RubrikPolaris.IRViolation.sensitiveHits.totalHits.violatedHits Number The total number of sensitive hits violated by the identity.
RubrikPolaris.IRViolation.dataCategoryResults.dataCategoryName String The name of the data category associated with the sensitive hits.
RubrikPolaris.IRViolation.dataCategoryResults.dataCategoryHits.dataCategoryId String The unique identifier of the data category.
RubrikPolaris.IRViolation.dataCategoryResults.dataCategoryHits.totalViolatedHits Number The total number of violated hits for the data category.

Command example

!rubrik-identity-resilience-violation-get violation_id="00000000-0000-0000-0000-000000000001" policy_type="IDENTITY"

Context Example

{
    "RubrikPolaris": {
        "IRViolation": {
            "policyViolationId": "00000000-0000-0000-0000-000000000001",
            "status": "POLICY_VIOLATION_STATUS_OPEN",
            "violationSeverity": "HIGH",
            "createdAt": "2026-03-25T09:29:55.000Z",
            "lastUpdatedAt": "2026-03-25T13:29:54.000Z",
            "resourceId": "00000000-0000-0000-0000-000000000101",
            "resourceType": "RESOURCE_TYPE_IDENTITY",
            "__typename": "PolicyViolation",
            "policy": {
                "policyId": "00000000-0000-0000-0000-000000000201",
                "name": "Excessive admin privileges",
                "description": "Users with excessive admin privileges pose a risk of privilege escalation.",
                "policyCategory": "IDENTITY_HYGIENE",
                "policySeverity": "HIGH",
                "policyType": "POLICY_TYPE_IDENTITY",
                "frameworks": [
                    "NIST",
                    "CIS"
                ],
                "manualRemediationProcess": "Review and revoke excess admin roles.",
                "__typename": "IRPolicy"
            },
            "details": {
                "domainUniqueId": "00000000-0000-0000-0000-000000000301",
                "mitreTactic": "Privilege Escalation",
                "__typename": "IdentityViolationDetails"
            },
            "resourceMetadata": {
                "metadata": {
                    "displayName": "John Doe",
                    "domainName": "rubrikdemo.com",
                    "idpType": "ENTRA_ID",
                    "principalType": "USER",
                    "privilegeType": "PRIVILEGED",
                    "userPrincipalName": "demo@rubrik.com",
                    "status": "ACTIVE",
                    "title": "Engineer",
                    "source": "ON_PREM_AD",
                    "nativeType": "User",
                    "__typename": "IdentityMetadata"
                },
                "__typename": "ResourceMetadata"
            },
            "identityTags": [
                "PRIVILEGED"
            ],
            "sensitiveHits": {
                "highRiskHits": {
                    "violatedHits": 5,
                    "__typename": "SensitiveHits"
                },
                "mediumRiskHits": {
                    "violatedHits": 3,
                    "__typename": "SensitiveHits"
                },
                "lowRiskHits": {
                    "violatedHits": 2,
                    "__typename": "SensitiveHits"
                },
                "noRiskHits": {
                    "violatedHits": 10,
                    "__typename": "SensitiveHits"
                },
                "totalHits": {
                    "violatedHits": 20,
                    "__typename": "SensitiveHits"
                },
                "__typename": "SensitiveHitsInfo"
            },
            "dataCategoryResults": [
                {
                    "dataCategoryName": "Financial",
                    "dataCategoryHits": {
                        "dataCategoryId": "00000000-0000-0000-0000-000000000601",
                        "totalViolatedHits": 8,
                        "__typename": "DataCategoryHits"
                    },
                    "__typename": "DataCategoryResult"
                }
            ]
        }
    }
}

Human Readable Output

IR Violation Information

ID Violation Name Severity Violation Status Detection Time Last Updated Policy ID Policy Name Policy Type Policy Description Policy Category Policy Severity Frameworks Manual Remediation Process Identity Status Resource ID Resource Type Title Display Name Domain Name Source Identity Provider Principal Type Privilege Type User Principal Name Identity Tags Native Type Domain Unique ID MITRE Tactic Total Risk Hits High Risk Hits Medium Risk Hits Low Risk Hits No Risk Hits Data Categories
00000000-0000-0000-0000-000000000001 Excessive admin privileges High Open 2026-03-25T09:29:55.000Z 2026-03-25T13:29:54.000Z 00000000-0000-0000-0000-000000000201 Excessive admin privileges Identity Users with excessive admin privileges pose a risk of privilege escalation. IDENTITY_HYGIENE High NIST,
CIS
Review and revoke excess admin roles. ACTIVE 00000000-0000-0000-0000-000000000101 Identity Engineer John Doe rubrikdemo.com ON_PREM_AD ENTRA_ID USER PRIVILEGED demo@rubrik.com PRIVILEGED User 00000000-0000-0000-0000-000000000301 Privilege Escalation 20 5 3 2 10 - id: 00000000-0000-0000-0000-000000000601
name: Financial
totalViolatedHits: 8

rubrik-identity-resilience-violation-status-update


Updates the status of the Identity Resilience (IR) violation.

Base Command

rubrik-identity-resilience-violation-status-update

Input

Argument Name Description Required
violation_id The ID of the IR violation.

Note: Users can get the violation ID by executing the “rubrik-identity-resilience-violation-list” command.
Required
status The status to update for the violation. Possible values are: OPEN, IN_PROGRESS, REMEDIATED, DISMISSED, CLOSED. Required

Context Output

Path Type Description
RubrikPolaris.IRViolation.policyViolationId String The ID of the violation.
RubrikPolaris.IRViolation.status String The status of the violation.

Command example

!rubrik-identity-resilience-violation-status-update violation_id="00000000-0000-0000-0000-000000000001" status="IN_PROGRESS"

Context Example

{
    "RubrikPolaris": {
        "IRViolation": {
            "policyViolationId": "00000000-0000-0000-0000-000000000001",
            "status": "POLICY_VIOLATION_STATUS_IN_PROGRESS"
        }
    }
}

Human Readable Output

Successfully updated the Identity Resilience violation status to In Progress

rubrik-sensitive-data-object-get


Retrieve the details of the object based on the provided object ID and snapshot ID.

Base Command

rubrik-sensitive-data-object-get

Input

Argument Name Description Required
object_id The ID of the object (snappable FID).

Note: Users can get the object ID by executing the “rubrik-polaris-object-list” command.
Required
snapshot_id The Snapshot ID of the object.

Note: Users can get the snapshot ID by executing the “rubrik-polaris-object-snapshot-list” command.
Required
include_whitelisted_results The boolean indicates to include the whitelisted results. Possible values are: True, False. Default is False. Optional

Context Output

Path Type Description
RubrikPolaris.SensitiveDataObject.id String The ID of the sensitive data object.
RubrikPolaris.SensitiveDataObject.snapshotFid String The FID of the snapshot associated with the object.
RubrikPolaris.SensitiveDataObject.snapshotTimestamp Number The timestamp of the snapshot.
RubrikPolaris.SensitiveDataObject.shareType String The share type of the object.
RubrikPolaris.SensitiveDataObject.riskLevel String The risk level of the object.
RubrikPolaris.SensitiveDataObject.osType String The OS type of the object.
RubrikPolaris.SensitiveDataObject.isUserAccessEnabledObject Boolean Whether user access is enabled for the object.
RubrikPolaris.SensitiveDataObject.__typename String The GraphQL type name of the sensitive data object.
RubrikPolaris.SensitiveDataObject.objectStatus.latestSnapshotResult.snapshotTime Number The time of the latest snapshot result.
RubrikPolaris.SensitiveDataObject.objectStatus.latestSnapshotResult.snapshotFid String The FID of the latest snapshot result.
RubrikPolaris.SensitiveDataObject.objectStatus.policyStatuses.status String The status of the policy for the object.
RubrikPolaris.SensitiveDataObject.objectStatus.__typename String The GraphQL type name of the object status.
RubrikPolaris.SensitiveDataObject.objectStatus.latestSnapshotResult.__typename String The GraphQL type name of the latest snapshot result.
RubrikPolaris.SensitiveDataObject.rootFileResult.hits.totalHits Number The total number of sensitive data hits in the object.
RubrikPolaris.SensitiveDataObject.rootFileResult.hits.violations Number The total number of violations in the object.
RubrikPolaris.SensitiveDataObject.rootFileResult.hits.violationsDelta Number The change in violations since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.hits.totalHitsDelta Number The change in total hits since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.__typename String The GraphQL type name of the root file result.
RubrikPolaris.SensitiveDataObject.rootFileResult.hits.__typename String The GraphQL type name of the root file result hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.analyzerGroup.groupType String The type of the analyzer group.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.analyzerGroup.id String The ID of the analyzer group.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.analyzerGroup.name String The name of the analyzer group.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.hits.totalHits Number The total hits for the analyzer group.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.hits.violations Number The violations for the analyzer group.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.hits.violationsDelta Number The change in violations for the analyzer group since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.hits.totalHitsDelta Number The change in total hits for the analyzer group since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.__typename String The GraphQL type name of the analyzer group result.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.analyzerGroup.__typename String The GraphQL type name of the analyzer group.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerGroupResults.hits.__typename String The GraphQL type name of the analyzer group hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerResults.analyzer.id String The ID of the analyzer.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerResults.analyzer.name String The name of the analyzer.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerResults.hits.totalHits Number The total hits for the analyzer.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerResults.hits.violations Number The violations for the analyzer.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerResults.hits.violationsDelta Number The change in violations for the analyzer since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerResults.hits.totalHitsDelta Number The change in total hits for the analyzer since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.analyzerResults.hits.__typename String The GraphQL type name of the analyzer result hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.filesWithHits.totalHits Number The total number of files with sensitive data hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.filesWithHits.violations Number The number of files with violations.
RubrikPolaris.SensitiveDataObject.rootFileResult.filesWithHits.violationsDelta Number The change in files with violations since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.filesWithHits.totalHitsDelta Number The change in files with hits since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.filesWithHits.__typename String The GraphQL type name of the files with hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFiles.totalHits Number The total number of open-access files.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFiles.violations Number The number of open-access files with violations.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFiles.violationsDelta Number The change in open-access files with violations since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFiles.totalHitsDelta Number The change in open-access files hits since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFiles.__typename String The GraphQL type name of the open access files.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFolders.totalHits Number The total number of open-access folders.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFolders.violations Number The number of open-access folders with violations.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFolders.violationsDelta Number The change in open-access folders with violations since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFolders.totalHitsDelta Number The change in open-access folders hits since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFolders.__typename String The GraphQL type name of the open access folders.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFilesWithHits.totalHits Number The total number of open-access files with sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFilesWithHits.violations Number The number of open-access files with hits and violations.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFilesWithHits.violationsDelta Number The change in open-access files with hits violations since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFilesWithHits.totalHitsDelta Number The change in open-access files with hits since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessFilesWithHits.__typename String The GraphQL type name of the open access files with hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFiles.totalHits Number The total number of stale files.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFiles.violations Number The number of stale files with violations.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFiles.violationsDelta Number The change in stale files with violations since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFiles.totalHitsDelta Number The change in stale files hits since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFiles.__typename String The GraphQL type name of the stale files.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFilesWithHits.totalHits Number The total number of stale files with sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFilesWithHits.violations Number The number of stale files with hits and violations.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFilesWithHits.violationsDelta Number The change in stale files with hits violations since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFilesWithHits.totalHitsDelta Number The change in stale files with hits since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.staleFilesWithHits.__typename String The GraphQL type name of the stale files with hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessStaleFiles.totalHits Number The total number of open-access stale files.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessStaleFiles.violations Number The number of open-access stale files with violations.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessStaleFiles.violationsDelta Number The change in open-access stale files with violations since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessStaleFiles.totalHitsDelta Number The change in open-access stale files hits since last scan.
RubrikPolaris.SensitiveDataObject.rootFileResult.openAccessStaleFiles.__typename String The GraphQL type name of the open access stale files.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.highRiskHits.totalHits Number The total high risk sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.highRiskHits.violatedHits Number The violated high risk sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.highRiskHits.__typename String The GraphQL type name of the high risk hits summary.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.mediumRiskHits.totalHits Number The total medium risk sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.mediumRiskHits.violatedHits Number The violated medium risk sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.mediumRiskHits.__typename String The GraphQL type name of the medium risk hits summary.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.lowRiskHits.totalHits Number The total low risk sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.lowRiskHits.violatedHits Number The violated low risk sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.lowRiskHits.__typename String The GraphQL type name of the low risk hits summary.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.noRiskHits.totalHits Number The total no-risk sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.noRiskHits.violatedHits Number The violated no-risk sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.noRiskHits.__typename String The GraphQL type name of the no-risk hits summary.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.totalHits.totalHits Number The total sensitive hits across all risk levels.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.totalHits.violatedHits Number The total violated sensitive hits across all risk levels.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.totalHits.__typename String The GraphQL type name of the total sensitive hits summary.
RubrikPolaris.SensitiveDataObject.rootFileResult.sensitiveHits.__typename String The GraphQL type name of the sensitive hits.
RubrikPolaris.SensitiveDataObject.rootFileResult.numActivities Number The number of activities associated with the file result.
RubrikPolaris.SensitiveDataObject.rootFileResult.numActivitiesDelta Number The change in number of activities since last scan.
RubrikPolaris.SensitiveDataObject.snappable.id String The ID of the snappable object.
RubrikPolaris.SensitiveDataObject.snappable.name String The name of the snappable object.
RubrikPolaris.SensitiveDataObject.snappable.objectType String The type of the snappable object.
RubrikPolaris.SensitiveDataObject.snappable.slaAssignment String The SLA assignment of the snappable object.
RubrikPolaris.SensitiveDataObject.snappable.logicalPath.fid String The FID of the logical path node.
RubrikPolaris.SensitiveDataObject.snappable.logicalPath.name String The name of the logical path node.
RubrikPolaris.SensitiveDataObject.snappable.logicalPath.objectType String The object type of the logical path node.
RubrikPolaris.SensitiveDataObject.snappable.logicalPath.__typename String The GraphQL type name of the logical path node.
RubrikPolaris.SensitiveDataObject.snappable.physicalPath.fid String The FID of the physical path node.
RubrikPolaris.SensitiveDataObject.snappable.physicalPath.name String The name of the physical path node.
RubrikPolaris.SensitiveDataObject.snappable.physicalPath.objectType String The object type of the physical path node.
RubrikPolaris.SensitiveDataObject.snappable.effectiveSlaDomain.id String The ID of the effective SLA domain.
RubrikPolaris.SensitiveDataObject.snappable.effectiveSlaDomain.name String The name of the effective SLA domain.
RubrikPolaris.SensitiveDataObject.snappable.effectiveSlaDomain.isRetentionLockedSla Boolean Whether the SLA domain has retention lock enabled.
RubrikPolaris.SensitiveDataObject.snappable.effectiveSlaDomain.retentionLockMode String The retention lock mode of the SLA domain.
RubrikPolaris.SensitiveDataObject.snappable.effectiveSlaDomain.description String The description of the effective SLA domain.
RubrikPolaris.SensitiveDataObject.snappable.effectiveSlaDomain.__typename String The GraphQL type name of the effective SLA domain.
RubrikPolaris.SensitiveDataObject.snappable.rscNativeObjectPendingSla.id String The ID of the pending SLA for the native object.
RubrikPolaris.SensitiveDataObject.snappable.rscNativeObjectPendingSla.name String The name of the pending SLA for the native object.
RubrikPolaris.SensitiveDataObject.snappable.__typename String The GraphQL type name of the snappable object.
RubrikPolaris.SensitiveDataObject.policySummaries.id String The ID of the classification policy.
RubrikPolaris.SensitiveDataObject.policySummaries.name String The name of the classification policy.
RubrikPolaris.SensitiveDataObject.policySummaries.colorEnum String The color enum of the classification policy.
RubrikPolaris.SensitiveDataObject.policySummaries.__typename String The GraphQL type name of the classification policy summary.

Context Example

{
    "RubrikPolaris": {
        "SensitiveDataObject": {
            "id": "00000000-0000-0000-0000-000000000001",
            "snapshotFid": "00000000-0000-0000-0000-000000000001",
            "snapshotTimestamp": 1782272126524,
            "shareType": "UNKNOWN_SHARE_TYPE",
            "riskLevel": "HIGH_RISK",
            "objectStatus": {
                "policyStatuses": [
                    {
                        "status": "UP_TO_DATE",
                        "__typename": "PolicyStatus"
                    },
                    {
                        "status": "UP_TO_DATE",
                        "__typename": "PolicyStatus"
                    }
                ],
                "latestSnapshotResult": {
                    "snapshotTime": 1782444911010,
                    "snapshotFid": "00000000-0000-0000-0000-000000000002",
                    "__typename": "SnapshotResult"
                },
                "__typename": "ObjectStatus"
            },
            "rootFileResult": {
                "hits": {
                    "totalHits": 40,
                    "violations": 40,
                    "violationsDelta": 0,
                    "totalHitsDelta": 0,
                    "__typename": "Hits"
                },
                "analyzerGroupResults": [
                    {
                        "analyzerGroup": {
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000003",
                            "name": "GLBA",
                            "__typename": "AnalyzerGroup"
                        },
                        "analyzerResults": [
                            {
                                "hits": {
                                    "totalHits": 2,
                                    "violations": 2,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000004",
                                    "name": "Bank Account Number",
                                    "analyzerType": "US_BANK_ACCT",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            }
                        ],
                        "hits": {
                            "totalHits": 2,
                            "violations": 2,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        },
                        "__typename": "AnalyzerGroupResult"
                    },
                    {
                        "analyzerGroup": {
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000005",
                            "name": "Financial",
                            "__typename": "AnalyzerGroup"
                        },
                        "analyzerResults": [
                            {
                                "hits": {
                                    "totalHits": 1,
                                    "violations": 1,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000006",
                                    "name": "ABA Routing Number",
                                    "analyzerType": "ABA_ROUTING_NUMBER",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            },
                            {
                                "hits": {
                                    "totalHits": 2,
                                    "violations": 2,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000004",
                                    "name": "Bank Account Number",
                                    "analyzerType": "US_BANK_ACCT",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            }
                        ],
                        "hits": {
                            "totalHits": 3,
                            "violations": 3,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        },
                        "__typename": "AnalyzerGroupResult"
                    },
                    {
                        "analyzerGroup": {
                            "groupType": "CUSTOM",
                            "id": "00000000-0000-0000-0000-000000000007",
                            "name": "U.S. Financials",
                            "__typename": "AnalyzerGroup"
                        },
                        "analyzerResults": [
                            {
                                "hits": {
                                    "totalHits": 1,
                                    "violations": 1,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000006",
                                    "name": "ABA Routing Number",
                                    "analyzerType": "ABA_ROUTING_NUMBER",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            },
                            {
                                "hits": {
                                    "totalHits": 2,
                                    "violations": 2,
                                    "__typename": "Hits"
                                },
                                "analyzer": {
                                    "id": "00000000-0000-0000-0000-000000000004",
                                    "name": "Bank Account Number",
                                    "analyzerType": "US_BANK_ACCT",
                                    "__typename": "Analyzer"
                                },
                                "__typename": "AnalyzerResult"
                            }
                        ],
                        "hits": {
                            "totalHits": 3,
                            "violations": 3,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        },
                        "__typename": "AnalyzerGroupResult"
                    }
                ],
                "filesWithHits": {
                    "totalHits": 11,
                    "violations": 11,
                    "violationsDelta": 0,
                    "totalHitsDelta": 0,
                    "__typename": "Hits"
                },
                "openAccessFilesWithHits": {
                    "totalHits": 0,
                    "violations": 0,
                    "violationsDelta": 0,
                    "totalHitsDelta": 0,
                    "__typename": "Hits"
                },
                "staleFilesWithHits": {
                    "totalHits": 8,
                    "violations": 8,
                    "violationsDelta": 0,
                    "totalHitsDelta": 0,
                    "__typename": "Hits"
                },
                "analyzerResults": [
                    {
                        "analyzer": {
                            "id": "00000000-0000-0000-0000-000000000004",
                            "name": "Bank Account Number"
                        },
                        "hits": {
                            "totalHits": 2,
                            "violations": 2,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        }
                    },
                    {
                        "analyzer": {
                            "id": "00000000-0000-0000-0000-000000000006",
                            "name": "ABA Routing Number"
                        },
                        "hits": {
                            "totalHits": 1,
                            "violations": 1,
                            "violationsDelta": 0,
                            "totalHitsDelta": 0,
                            "__typename": "Hits"
                        }
                    }
                ],
                "sensitiveHits": {
                    "highRiskHits": {
                        "totalHits": 20,
                        "violatedHits": 20,
                        "__typename": "SummaryHits"
                    },
                    "mediumRiskHits": {
                        "totalHits": 10,
                        "violatedHits": 10,
                        "__typename": "SummaryHits"
                    },
                    "lowRiskHits": {
                        "totalHits": 5,
                        "violatedHits": 5,
                        "__typename": "SummaryHits"
                    },
                    "noRiskHits": {
                        "totalHits": 5,
                        "violatedHits": 5,
                        "__typename": "SummaryHits"
                    },
                    "totalHits": {
                        "totalHits": 40,
                        "violatedHits": 40,
                        "__typename": "SummaryHits"
                    },
                    "__typename": "SensitiveHits"
                },
                "numActivities": 0,
                "numActivitiesDelta": 0,
                "__typename": "FileResult"
            },
            "snappable": {
                "id": "00000000-0000-0000-0000-000000000008",
                "name": "ran test",
                "objectType": "O365Site",
                "slaAssignment": "Direct",
                "logicalPath": [
                    {
                        "fid": "00000000-0000-0000-0000-000000000009",
                        "name": "Rubrik Inc",
                        "objectType": "O365Org",
                        "__typename": "PathNode"
                    },
                    {
                        "fid": "00000000-0000-0000-0000-000000000010",
                        "name": "rubrik-tme-lab",
                        "objectType": "AwsNativeAccount",
                        "__typename": "PathNode"
                    }
                ],
                "effectiveSlaDomain": {
                    "id": "00000000-0000-0000-0000-000000000001",
                    "name": "Silver",
                    "isRetentionLockedSla": false,
                    "retentionLockMode": "NO_MODE",
                    "__typename": "GlobalSlaReply",
                    "description": "Rubrik default Silver level SLA Domain policy"
                },
                "__typename": "O365Site"
            },
            "__typename": "PolicyObj",
            "osType": "NONE",
            "isUserAccessEnabledObject": true,
            "policySummaries": [
                {
                    "id": "00000000-0000-0000-0000-000000000003",
                    "name": "GLBA",
                    "colorEnum": "COLOR_003",
                    "__typename": "ClassificationPolicySummary"
                },
                {
                    "id": "00000000-0000-0000-0000-000000000005",
                    "name": "Financial",
                    "colorEnum": "COLOR_013",
                    "__typename": "ClassificationPolicySummary"
                },
                {
                    "id": "00000000-0000-0000-0000-000000000007",
                    "name": "Financials",
                    "colorEnum": "COLOR_005",
                    "__typename": "ClassificationPolicySummary"
                }
            ]
        }
    }
}

Human Readable Output

Sensitive Data Object

Object ID Object Name Object Type Risk Level OS Type Account Name Snapshot ID Snapshot Timestamp SLA Name Daily Hits Change Total Risk Hits High Risk Hits Medium Risk Hits Low Risk Hits No Risk Hits Total Files with Hits Stale Files with Hits Open Access Files with Hits Data Categories Data Types
00000000-0000-0000-0000-000000000001 ran test O365Site High NONE rubrik-tme-lab 00000000-0000-0000-0000-000000000001 2026-06-19T12:55:26Z Silver 0 40 20 10 5 5 11 8 0 - name: GLBA
totalViolatedHits: 2
- name: Financial
totalViolatedHits: 3
- name: U.S. Financials
totalViolatedHits: 3
- name: Bank Account Number
totalViolatedHits: 2
- name: ABA Routing Number
totalViolatedHits: 1

rubrik-sensitive-data-object-file-get


Retrieve the file information for the provided file path in the object.

Base Command

rubrik-sensitive-data-object-file-get

Input

Argument Name Description Required
object_id The ID of the object (snappable FID).

Note: Users can get the object ID by executing the “rubrik-polaris-object-list” command.
Required
snapshot_id The Snapshot ID of the object.

Note: Users can get the snapshot ID by executing the “rubrik-polaris-object-snapshot-list” command.
Required
file_path The full path of the file for which to retrieve information. Required
resolve_sids Whether to resolve SIDs to display names in the file response. Possible values are: True, False. Default is True. Optional

Context Output

Path Type Description
RubrikPolaris.SensitiveDataObjectFile.objectId String The unique identifier of the snappable object.
RubrikPolaris.SensitiveDataObjectFile.stdPath String The standard file path of the sensitive file.
RubrikPolaris.SensitiveDataObjectFile.secInfo.path String The full path of the sensitive file from the security descriptor.
RubrikPolaris.SensitiveDataObjectFile.secInfo.owner String The SID of the owner of the file.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.cn String The display name of the principal with file permissions.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.principalId String The SID or identifier of the principal with file permissions.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.principalOrigin String The origin of the principal.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.idpType String The identity provider type for the principal.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.principalType String The type of the principal.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.resolutionType String The resolution type of the principal SID.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.access String The access level granted to the principal.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.flags String The permission flags.
RubrikPolaris.SensitiveDataObjectFile.secInfo.permissions.accessMethodDetails.accessMethod String The access method used.
RubrikPolaris.SensitiveDataObjectFile.fileMetadata.createdBy.value String The value of the principal who created the file.
RubrikPolaris.SensitiveDataObjectFile.fileMetadata.creationTime Number The creation time of the file as a Unix timestamp.
RubrikPolaris.SensitiveDataObjectFile.fileMetadata.lastAccessTime Number The last access time of the file as a Unix timestamp.
RubrikPolaris.SensitiveDataObjectFile.fileMetadata.lastModifiedBy.value String The value of the principal who last modified the file.
RubrikPolaris.SensitiveDataObjectFile.fileMetadata.lastModifiedTime Number The last modified time of the file as a Unix timestamp.
RubrikPolaris.SensitiveDataObjectFile.fileMetadata.lastScanTime Number The last scan time of the file as a Unix timestamp.
RubrikPolaris.SensitiveDataObjectFile.fileMetadata.path String The full path of the file as recorded in the metadata.
RubrikPolaris.SensitiveDataObjectFile.fileMetadata.size Number The size of the file in bytes.
RubrikPolaris.SensitiveDataObjectFile.exposureSummary.exposureType String The exposure type of the file.
RubrikPolaris.SensitiveDataObjectFile.exposureSummary.fileCount.totalCount Number The total count of files in the exposure summary.
RubrikPolaris.SensitiveDataObjectFile.exposureSummary.fileCount.violatedCount Number The number of files with violations in the exposure summary.

Command Example

!rubrik-sensitive-data-object-file-get object_id="00000000-0000-0000-0000-000000000001" snapshot_id="00000000-0000-0000-0000-000000000002" file_path="/C:/DummyPath/DummyFile.xlsx"

Context Example

{
    "objectId": "00000000-0000-0000-0000-000000000001",
    "stdPath": "/C:/DummyPath/DummyFile.xlsx",
    "secInfo": [
        {
            "path": "/C:/DummyPath/DummyFile.xlsx",
            "owner": "S-1-5-21-0000000000-000000000-0000000000-0001",
            "permissions": [
                {
                    "cn": "John Doe",
                    "principalId": "S-1-5-21-0000000000-000000000-0000000000-0002",
                    "principalOrigin": "ORIGIN_INTERNAL",
                    "idpType": "ON_PREM_AD",
                    "principalType": "UNKNOWN",
                    "resolutionType": "RESOLVED_AD",
                    "access": "Full control",
                    "flags": [
                        "INHERITED"
                    ],
                    "accessMethodDetails": {
                        "accessMethod": "WINDOWS_ACL",
                        "__typename": "DatagovAccessMethodDetailsType"
                    },
                    "__typename": "SDDLPermission"
                },
                {
                    "cn": "Local System",
                    "principalId": "S-1-5-18",
                    "principalOrigin": "ORIGIN_INTERNAL",
                    "idpType": "ON_PREM_AD",
                    "principalType": "UNKNOWN",
                    "resolutionType": "WELL_KNOWN",
                    "access": "Full control",
                    "flags": [
                        "INHERITED"
                    ],
                    "accessMethodDetails": {
                        "accessMethod": "WINDOWS_ACL",
                        "__typename": "DatagovAccessMethodDetailsType"
                    },
                    "__typename": "SDDLPermission"
                },
                {
                    "cn": "Administrators",
                    "principalId": "S-1-5-32-000",
                    "principalOrigin": "ORIGIN_INTERNAL",
                    "idpType": "ON_PREM_AD",
                    "principalType": "UNKNOWN",
                    "resolutionType": "WELL_KNOWN",
                    "access": "Full control",
                    "flags": [
                        "INHERITED"
                    ],
                    "accessMethodDetails": {
                        "accessMethod": "WINDOWS_ACL",
                        "__typename": "DatagovAccessMethodDetailsType"
                    },
                    "__typename": "SDDLPermission"
                },
                {
                    "cn": "Users",
                    "principalId": "S-1-5-32-001",
                    "principalOrigin": "ORIGIN_INTERNAL",
                    "idpType": "ON_PREM_AD",
                    "principalType": "UNKNOWN",
                    "resolutionType": "WELL_KNOWN",
                    "access": "Read & execute",
                    "flags": [
                        "INHERITED"
                    ],
                    "accessMethodDetails": {
                        "accessMethod": "WINDOWS_ACL",
                        "__typename": "DatagovAccessMethodDetailsType"
                    },
                    "__typename": "SDDLPermission"
                }
            ],
            "__typename": "PathSecInfo"
        }
    ],
    "__typename": "SensitiveFileDetailsReply",
    "fileMetadata": {
        "createdBy": {
            "value": "admin@example.com",
            "__typename": "FilePrincipalIdentity"
        },
        "creationTime": 1768473000,
        "lastAccessTime": 1781945100,
        "lastModifiedBy": {
            "value": "admin@example.com",
            "__typename": "FilePrincipalIdentity"
        },
        "lastModifiedTime": 1773151200,
        "lastScanTime": 1782388800,
        "path": "/C:/DummyPath/DummyFile.xlsx",
        "size": 1665816,
        "__typename": "SensitiveFileMetadata"
    },
    "exposureSummary": [
        {
            "exposureType": "NOT_OPEN",
            "fileCount": {
                "totalCount": 1,
                "violatedCount": 0,
                "__typename": "SummaryCount"
            },
            "__typename": "ExposureSummary"
        }
    ]
}

Human Readable Output

File Information

File Path File Size in Bytes Owner Created By Last Modified By Create Time Last Modified Time Last Access Time Exposure Type File Count Permissions
/C:/DummyPath/DummyFile.xlsx 1665816 S-1-5-21-0000000000-000000000-0000000000-0001 admin@example.com admin@example.com 2026-01-15T10:30:00Z 2026-03-10T14:00:00Z 2026-06-20T08:45:00Z NOT_OPEN 1 - id: S-1-5-21-0000000000-000000000-0000000000-0002
name: John Doe
accessMethod: WINDOWS_ACL
access: Full control
- id: S-1-5-18
name: Local System
accessMethod: WINDOWS_ACL
access: Full control
- id: S-1-5-32-000
name: Administrators
accessMethod: WINDOWS_ACL
access: Full control
- id: S-1-5-32-001
name: Users
accessMethod: WINDOWS_ACL
access: Read & execute

Configuration parameters

  • service_account_json — Service Account JSON
  • url — Rubrik Account (e.g. ${rubrikAccount}.my.rubrik.com)
  • email — Email
  • isFetch — Fetch incidents
  • incidentType — Incident type
  • rsc_fetch_types — RSC Fetch Types
  • event_types — Event types to fetch as incidents
  • event_severities — Event severities to fetch as incidents
  • threat_monitoring_match_types — Threat Monitoring Match Types
  • threat_monitoring_object_types — Threat Monitoring Object Types
  • first_fetch — First fetch time
  • incidentFetchInterval — Incidents Fetch Interval
  • max_fetch — Fetch Limit (Maximum of 1000)
  • radar_critical_severity_mapping — Event Critical Severity Level Mapping
  • radar_warning_severity_mapping — Event Warning Severity Level Mapping
  • threat_monitoring_severity_mapping — Threat Monitoring Object Severity Level Mapping
  • dspm_violation_status — DSPM Violation Statuses
  • dspm_violation_sensitivity — DSPM Violation Sensitivity Levels
  • dspm_violation_severity — DSPM Violation Severity Levels
  • dspm_violation_category — DSPM Violation Categories
  • dspm_violation_object_type — DSPM Violation Object Types
  • ir_violation_policy_type — IR Violation Policy Types
  • ir_violation_status — IR Violation Statuses
  • ir_violation_severity — IR Violation Severity Levels
  • ir_violation_category — IR Violation Categories
  • ir_violation_identity_provider — IR Violation Identity Providers
  • ir_violation_identity_tag — IR Violation Identity Tags
  • sensitive_data_object_sensitivity — Sensitive Data Object Sensitivity Levels
  • sensitive_data_object_type — Sensitive Data Object Types
  • integration_reliability — Source Reliability
  • proxy — Use system proxy settings
  • insecure — Trust any certificate (not secure)

Commands (61)

  • domain

    Retrieve the sensitive information available for the given domain(s).

  • ip

    Retrieve the sensitive information available for the given IP address(es).

  • rubrik-advance-ioc-scan

    Start a new advance threat hunt.

  • rubrik-anomaly-csv-analysis-v2

    Request for the analysis and directly download the anomaly CSV analyzed file.

  • rubrik-cdm-cluster-connection-state

    Find the CDM Connection State of a CDM Cluster.

  • rubrik-cdm-cluster-location

    Find the CDM GeoLocation of a CDM Cluster.

  • rubrik-data-security-violation-csv-download

    Download all files at risk as CSV file for the specified data security violation.

  • rubrik-data-security-violation-file-list

    Retrieve the file information of data security violation based on the provided violation ID.

  • rubrik-data-security-violation-get

    Retrieve the details of DSPM violation based on the provided violation ID.

  • rubrik-data-security-violation-list

    Retrieve the list of DSPM violations.

  • rubrik-data-security-violation-log-download

    Download remediation logs as CSV file for the specified data security violation.

  • rubrik-data-security-violation-status-update

    Updates the status of the DSPM violation.

  • rubrik-event-list

    Retrieve the list of events.

  • rubrik-gps-async-result

    Retrieve the result of an asynchronous request. This command will retrieve the result of requests made by commands "rubrik-gps-snapshot-files-download", "rubrik-gps-vm-livemount", "rubrik-gps-vm-export", "rubrik-gps-vm-snapshot-create" and "rubrik-gps-vm-recover-files".

  • rubrik-gps-cluster-list

    Retrieve the list of the available rubrik clusters.

  • rubrik-gps-sla-domain-list

    Enumerates the available SLA Domains to apply to the on-demand snapshot as a retention policy.

  • rubrik-gps-snapshot-files-download

    Request to download the snapshot file from the backup. Note: To know about the file information and which file can be downloaded, use the "rubrik-gps-snapshot-files-list" command. To know about the status of the downloadable files, use the "rubrik-gps-async-result" command.

  • rubrik-gps-snapshot-files-list

    Retrieve the list of the available files that can be downloaded. Note: To initiate the file download request use the "rubrik-gps-snapshot-files-download" command.

  • rubrik-gps-vm-datastore-list

    Retrieve the list of the available datastores on a Vsphere Host.

  • rubrik-gps-vm-export

    Request to initiate an export of a snapshot of a virtual machine. Note: To know about the exported VM's status, use the "rubrik-gps-async-result" command.

  • rubrik-gps-vm-host-list

    Retrieve the list of available Vsphere Hosts.

  • rubrik-gps-vm-livemount

    Performs a live mount of a virtual machine snapshot. Note: To know about the live mount status, use the "rubrik-gps-async-result" command.

  • rubrik-gps-vm-recover-files

    Recovers files from a snapshot backup, back into a system. Note: To know about the recovery status, use the "rubrik-gps-async-result" command.

  • rubrik-gps-vm-snapshot-create

    Triggers an on-demand snapshot of a system. Note: To know about the status of the on-demand snapshot creation, use the "rubrik-gps-async-result" command.

  • rubrik-identity-resilience-violation-get

    Retrieves the details of the Identity Resilience (IR) violation based on the provided violation ID.

  • rubrik-identity-resilience-violation-list

    Retrieves the list of Identity Resilience (IR) violations.

  • rubrik-identity-resilience-violation-status-update

    Updates the status of the Identity Resilience (IR) violation.

  • rubrik-ioc-scan-list-v2

    List details of the Turbo and Advance Threat Hunt.

  • rubrik-ioc-scan-results-v2

    Retrieve details of the Turbo and Advance Threat Hunt.

  • rubrik-polaris-object-list

    Retrieve the list of Rubrik objects, based on the provided filters.

  • rubrik-polaris-object-search

    Search for Rubrik discovered objects of any type, return zero or more matches.

  • rubrik-polaris-object-snapshot-list

    Retrieve Rubrik snapshot(s) of an object, based on the provided object ID.

  • rubrik-polaris-vm-object-metadata-get

    Retrieve details for a Vsphere object based on the provided object ID.

  • rubrik-polaris-vm-object-snapshot-list

    Search for a Rubrik snapshot of an object based on the provided snapshot ID, exact timestamp, or specific value like earliest/latest, or closest before/after a timestamp.

  • rubrik-polaris-vm-objects-list

    Retrieve a list of all the objects of the Vsphere Vm known to the Rubrik.

  • rubrik-radar-analysis-status Deprecated

    Check the Radar Event for updates.

  • rubrik-radar-anomaly-csv-analysis

    Request for the analysis and retrieve the download link or directly download file for the Radar CSV analyzed file.

  • rubrik-radar-anomaly-status-update

    Updates the status of the Anomaly detection. Note: Run the "rubrik-radar-suspicious-file-list" command first to check the resolution status of the Anomaly Detection snapshot before executing this command.

  • rubrik-radar-ioc-scan

    Triggers an IOC scan of a system. Note: To know the results of the scan use the "rubrik-radar-ioc-scan-results" command and to list the running/completed IOC scans on a cluster use the "rubrik-radar-ioc-scan-list" command.

  • rubrik-radar-ioc-scan-list

    Lists the running/completed IOC scans on a cluster. Note: To know the results of the scan use the "rubrik-radar-ioc-scan-results" command. To initiate a scan use the "rubrik-radar-ioc-scan" command.

  • rubrik-radar-ioc-scan-results

    Retrieves the results of IOC scan of a system. Note: To initiate a scan use the "rubrik-radar-ioc-scan" command and to list the running/completed scans on a cluster use the "rubrik-radar-ioc-scan-list" command.

  • rubrik-radar-suspicious-file-list

    Retrieve the suspicious list of files for a snapshot ID with detected file anomalies.

  • rubrik-sensitive-data-object-file-get

    Retrieve the file information for the provided file path in the object.

  • rubrik-sensitive-data-object-get

    Retrieve the details of the object based on the provided object ID and snapshot ID.

  • rubrik-sonar-csv-download

    Request to download the Sonar CSV Snapshot results file. Note: To know the ID and status of the download, use the "rubrik-user-downloads-list" command. To download the file, use the "rubrik-sonar-csv-result-download" command.

  • rubrik-sonar-csv-result-download

    Retrieve the download link for the requested Sonar CSV Snapshot file.

  • rubrik-sonar-file-context-list

    Retrieve the context of the file, folder, or file share for the provided object and the file details.

  • rubrik-sonar-ondemand-scan

    Trigger an on-demand scan of a system. Supports "Vsphere VM" object type only. Note: To know the scan status use the "rubrik-sonar-ondemand-scan-status" command. To download the completed request use the "rubrik-sonar-ondemand-scan-result" command.

  • rubrik-sonar-ondemand-scan-result

    Retrieve the download link for the requested scanned file.

  • rubrik-sonar-ondemand-scan-status

    Retrieve the status of a scanned system. Note: To download the completed request use the "rubrik-sonar-ondemand-scan-result" command.

  • rubrik-sonar-policies-list

    Retrieve the list of all the available Sonar policies.

  • rubrik-sonar-policy-analyzer-groups-list

    List the analyzer group policies.

  • rubrik-sonar-sensitive-hits

    Find data classification hits on an object.

  • rubrik-sonar-user-access-get

    Retrieve the user access information based on the provided user ID.

  • rubrik-sonar-user-access-list

    Retrieve the user access information.

  • rubrik-threat-monitoring-matched-file-get

    Get the matched file for the Threat Monitoring object.

  • rubrik-threat-monitoring-matched-file-list

    List the matched files for the Threat Monitoring object.

  • rubrik-threat-monitoring-matched-object-get

    Get the matched object for Threat Monitoring.

  • rubrik-threat-monitoring-matched-object-list

    List the matched objects for Threat Monitoring.

  • rubrik-turbo-ioc-scan

    Start a new turbo threat hunt.

  • rubrik-user-downloads-list

    Retrieve the user downloads. This would return the current and past download history. Note: To download the requested Sonar CSV Snapshot results file use the "rubrik-sonar-csv-result-download" command.

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

"""Main file for RubrikPolaris Integration."""
import math
import re
import traceback
from collections.abc import Callable
from copy import deepcopy
from datetime import date

import jwt
import urllib3
from rubrik_polaris.exceptions import ProxyException
from rubrik_polaris.rubrik_polaris import PolarisClient

# Disable insecure warnings
urllib3.disable_warnings()

""" CONSTANTS """

INTEGRATION_NAME = "Rubrik Radar"
DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
HR_DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
HUMAN_READABLE_DATE_TIME_FORMAT = "%b %d, %Y at %I:%M:%S %p"
USER_ACCESS_HYPERLINK = "{}sonar/user_intelligence?redirected_user_id={}"
EVENT_HYPERLINK = '{}events/details/{}?clusterUuid="{}"'
THREAT_MONITORING_HYPERLINK = "{}radar/threat_monitoring/{}"
DSPM_VIOLATION_HYPERLINK = "{}sonar/data_risks/violations/{}/{}/{}/{}/details"
IR_VIOLATION_HYPERLINK = "{}identity_resilience/violations/{}?violation_id={}"
IR_ALERT_HYPERLINK = "{}identity_resilience/alerts/{}"
SENSITIVE_DATA_OBJECT_HYPERLINK = "{}sonar/objects/detail/{}/{}/browse"

DEFAULT_IS_FETCH = False
MAX_FETCH_MIN = 1
MAX_FETCH_MAX = 1000
DEFAULT_MAX_FETCH = 20
DEFAULT_LIMIT = 50
DEFAULT_SORT_BY = "ID"
DEFAULT_USER_ACCESS_SORT_BY = "RISK_LEVEL"
DEFAULT_FILE_CONTEXT_SORT_BY = "HITS"
ASCENDING_SORT_ORDER = "ASC"
DESCENDING_SORT_ORDER = "DESC"
DEFAULT_USER_ACCESS_SORT_ORDER = DESCENDING_SORT_ORDER
DEFAULT_FILE_CONTEXT_SORT_ORDER = DESCENDING_SORT_ORDER
DEFAULT_SORT_ORDER = "ASC"
DEFAULT_CLUSTER_CONNECTED = True
DEFAULT_SNAPSHOT_GROUP_BY = "Day"
DEFAULT_MISSED_SNAPSHOT_GROUP_BY = "DAY"
DEFAULT_EVENT_SORT_BY = "LAST_UPDATED"
DEFAULT_EVENT_SORT_ORDER = "DESC"
DEFAULT_SHOW_CLUSTER_SLA_ONLY = "True"
DEFAULT_SORT_BY_SLA_DOMAIN = "NAME"
DEFAULT_CLUSTER_SORT_BY = "ClusterName"
DEFAULT_REQUEST_NAME = f"PAXSOAR-{get_pack_version() or '1.7.0'}"
DEFAULT_PRINCIPAL_SUMMARY_CATEGORY = "USERS_WITH_SENSITIVE_ACCESS"
DEFAULT_RELIABILITY = "A - Completely reliable"
SCAN_ID = "Scan ID"
SNAPSHOT_ID = "Snapshot ID"
START_TIME = "Start Time"
LAST_ACCESS_TIME = "Last Access Time"
LAST_MODIFIED_TIME = "Last Modified Time"
CLUSTER_ID = "Cluster ID"
ACTIVITY_SERIES_ID = "Activity Series ID"
FREE_SPACE = "Free Space"
SLA_DOMAIN_NAME = "SLA Domain Name"
SNAPSHOT_IDS = "Snapshot IDs"
OBJECT_TYPE = "Object Type"
FILESET_OBJECT_TYPE = "FILESET"
VOLUME_GROUP_OBJECT_TYPE = "VOLUMEGROUP"
CLUSTER_NAME = "Cluster Name"
SNAPPABLE_ID = "Snappable ID"
SLA_DOMAIN = "SLA Domain"
OBJECT_NAME = "Object Name"
OBJECT_ID = "Object ID"
FILE_NAME = "File Name"
FILE_SIZE = "File Size in Bytes"
FILE_PATH = "File Path"
SUSPICIOUS_ACTIVITY = "Suspicious Activity"
ANOMALY_ID = "Anomaly ID"
IS_ANOMALY = "Is Anomaly"
ANOMALY_PROBABILITY = "Anomaly Probability"
SEVERITY = "Severity"
ENCRYPTION = "Encryption"
ANOMALY = "Anomaly"
ANOMALY_TYPE = "Anomaly Type"
TOTAL_SUSPICIOUS_FILES = "Total Suspicious Files"
TOTAL_RANSOMEWARE_NOTE = "Total Ransomware Note"
DETECTION_TIME = "Detection Time"
SNAPSHOT_TIME = "Snapshot Time"
ANOMALY_RESOLUTION_STATUS = "Resolution Status"
RANSOMEWARE_NOTE = "Ransomware Note"
RANSOMEWARE_ENCRYPTION = "Ransomware Encryption"
ACCESS_TYPE = "Access Type"
USER_ID = "User ID"
USER_FULL_NAME = "User Full Name"
USER_PRINCIPAL_NAME = "User Principal Name"
GROUPS = "Groups"
ACCESS_RISK_REASONS = "Access Risk Reason(s)"
INSECURE_REASONS = "Insecure Reason(s)"
RISK_LEVEL = "Risk Level"
TOTAL_SENSITIVE_FILES = "Total Sensitive Files"
TOTAL_SENSITIVE_HITS = "Total Sensitive Hits"
SENSITIVE_HITS_DELTA = "Sensitive Hits Delta"
TOTAL_SENSITIVE_OBJECTS = "Total Sensitive Objects"
HIGH_RISK_HITS = "High Risk Hits"
MEDIUM_RISK_HITS = "Medium Risk Hits"
LOW_RISK_HITS = "Low Risk Hits"
NO_RISK_HITS = "No Risk Hits"
TOTAL_RISK_HITS = "Total Risk Hits"
POLICY_NAME = "Policy Name"
VENDOR_NAME = "Rubrik Security Cloud"
GENERAL_INFO_KEY = "generalInfo"
SENSITIVE_INFO_KEY = "sensitiveInfo"
ANOMALY_INFO_KEY = "anomalyInfo"
THREAT_HUNT_INFO_KEY = "threatHuntInfo"
THREAT_MONITORING_INFO_KEY = "threatMonitoringInfo"

DAILY_HITS_CHANGE = "Daily Hits Change"
DEFAULT_EVENT_TYPES = ["ANOMALY", "THREAT_MONITORING"]
DEFAULT_ACTIVITY_STATUSES = ["SUCCESS", "PARTIAL_SUCCESS"]
DEFAULT_SEVERITIES = ["SEVERITY_CRITICAL"]
DEFAULT_EVENT_SEVERITIES = ["SEVERITY_CRITICAL", "SEVERITY_WARNING", "SEVERITY_INFO"]
START_CURSOR = "Start Cursor"
END_CURSOR = "End Cursor"
HAS_NEXT_PAGE = "Has Next Page"
HAS_PREVIOUS_PAGE = "Has Previous Page"
DEFAULT_FIRST_FETCH = "3 days"
DEFAULT_TIME_PERIOD = "7 days"
MAX_MATCHES_PER_OBJECT = 100
MAXIMUM_FILE_SIZE = 5000000
MAXIMUM_PAGINATION_LIMIT = 1000
DEFAULT_FETCH_TYPE = ["event", "threat monitoring object", "dspm violation", "ir violation", "sensitive data object"]
EVENT_FETCH_TYPE = "event"
THREAT_MONITORING_FETCH_TYPE = "threat monitoring object"
DSPM_VIOLATION_FETCH_TYPE = "dspm violation"
IR_VIOLATION_FETCH_TYPE = "ir violation"
SENSITIVE_DATA_OBJECT_FETCH_TYPE = "sensitive data object"
MAX_FETCH_APPLICABLE_FETCH_TYPES = [
    THREAT_MONITORING_FETCH_TYPE,
    DSPM_VIOLATION_FETCH_TYPE,
    IR_VIOLATION_FETCH_TYPE,
    SENSITIVE_DATA_OBJECT_FETCH_TYPE,
]
IOC_MATCHES = ["MATCHES_FOUND", "NO_MATCHES", "UNSCANNED"]
QUERANTINE_STATUS = ["QUARANTINED_MATCHES", "NO_QUARANTINED_MATCHES"]
HUNT_STATUSES = ["ABORTED", "CANCELED", "CANCELING", "FAILED", "IN_PROGRESS", "PARTIALLY_SUCCEEDED", "PENDING", "SUCCEEDED"]
MAX_INT_VALUE = 2**31 - 1
MAX_LONG_VALUE = 2**63 - 1 - 512
DEFAULT_POLLING_NEXT_RUN_IN_SECONDS = 30
DEFAULT_POLLING_TIMEOUT = 300
DEFAULT_DSPM_VIOLATION_STATUS = ["OPEN", "IN_PROGRESS"]
DSPM_VIOLATION_STATUS = ["OPEN", "REMEDIATED", "DISMISSED", "IN_PROGRESS", "CLOSED"]
DSPM_VIOLATION_SENSITIVITY = ["HIGH", "MEDIUM", "LOW", "NO"]
DSPM_VIOLATION_SEVERITY = ["SEVERITY_UNSPECIFIED", "LOW", "MEDIUM", "HIGH", "CRITICAL"]
DSPM_VIOLATION_CATEGORY = ["CATEGORY_UNSPECIFIED", "MISPLACED", "REDUNDANT", "OVEREXPOSED", "UNPROTECTED"]
DSPM_VIOLATION_OBJECT_TYPE = [
    "AWS_NATIVE_DYNAMODB_TABLE",
    "AWS_NATIVE_EBS_VOLUME",
    "AWS_NATIVE_RDS_INSTANCE",
    "AWS_NATIVE_S3_BUCKET",
    "AZURE_MANAGED_DISK",
    "AZURE_SQL_DATABASE_DB",
    "AZURE_SQL_MANAGED_INSTANCE_DB",
    "AZURE_STORAGE_ACCOUNT",
    "AZURE_VIRTUAL_MACHINE",
    "GCP_NATIVE_DISK",
    "GCP_NATIVE_GCE_INSTANCE",
    "HYPERV_VIRTUAL_MACHINE",
    "K8S_PROTECTION_SET",
    "K8S_VIRTUAL_MACHINE",
    "LINUX_FILESET",
    "NAS_FILESET",
    "NUTANIX_VIRTUAL_MACHINE",
    "O365_ONEDRIVE",
    "O365_SITE",
    "ORACLE_DATA_GUARD_GROUP",
    "ORACLE_DATABASE",
    "SHARE_FILESET",
    "VOLUME_GROUP",
    "VSPHERE_VIRTUAL_MACHINE",
    "WINDOWS_FILESET",
]
DSPM_VIOLATION_SORT_BY = [
    "SEVERITY",
    "HITS",
    "DETECTION_TIME",
    "UPDATE_TIME",
    "IDENTITY_TYPE",
    "FILES_AT_RISK",
    "TOTAL_HITS",
    "ACCESSIBLE_OBJECTS",
    "ORIGIN",
    "EVENT_TIME",
    "NAME",
    "TYPE",
]
DSPM_VIOLATION_FILE_LIST_SENSITIVITY = ["HIGH", "MEDIUM", "LOW", "NO"]
DSPM_VIOLATION_FILE_LIST_EXPOSURE = ["EXPLICIT", "INHERITED", "NOT_OPEN", "PUBLIC"]
DSPM_VIOLATION_FILE_LIST_ACCESS_VIA = ["ACCESS_TYPE_UNSPECIFIED", "DIRECT", "GROUP", "ROLE"]
DSPM_VIOLATION_FILE_LIST_SORT_BY = [
    "CLUSTER",
    "CREATION_TIME",
    "DAILY_CHANGE",
    "DATA_CATEGORY",
    "DATA_TYPE",
    "DOCUMENT_TYPE",
    "EXPOSED_FILES",
    "FILES_WITH_HITS",
    "FILES_WITH_OPEN_ACCESS_HITS",
    "HITS",
    "HITS_BY_SENSITIVITY",
    "LAST_ACCESS_TIME",
    "LAST_MODIFIED",
    "LAST_SCAN_TIME",
    "NAME",
    "NATIVE_PATH",
    "NUM_ACTIVITIES",
    "NUM_ACTIVITIES_DELTA",
    "OBJECT_LOCATION",
    "OBJECT_NAME",
    "OPEN_ACCESS_TYPE",
    "SNAPSHOT_TIME",
    "STALE_FILES_WITH_HITS",
    "TOTAL_SENSITIVE_HITS",
]
DEFAULT_IR_VIOLATION_STATUS = ["OPEN", "IN_PROGRESS"]
IR_VIOLATION_STATUS = ["OPEN", "REMEDIATED", "DISMISSED", "IN_PROGRESS", "CLOSED"]
IR_VIOLATION_SEVERITY = ["SEVERITY_UNSPECIFIED", "LOW", "MEDIUM", "HIGH", "CRITICAL"]
IR_VIOLATION_CATEGORY = [
    "CATEGORY_UNSPECIFIED",
    "AUTHENTICATION_AND_SECRET_MANAGEMENT",
    "IDENTITY_HYGIENE",
    "EXCESSIVE_IDENTITY_RIGHTS",
    "IDENTITY_PROVIDER_SECURITY",
    "PRIVILEGED_ACCOUNT_RISK",
    "IDENTITY_RISK",
    "INFRASTRUCTURE_SECURITY",
    "CONFIGURATION_SECURITY",
    "MEMBERSHIP_CHANGE",
    "GPO_CHANGE",
]
IR_VIOLATION_IDENTITY_PROVIDER = [
    "IDP_UNSPECIFIED",
    "ON_PREM_AD",
    "ENTRA_ID",
    "AWS",
    "LOCAL_AD",
    "SHAREPOINT",
    "SYSTEM",
    "OKTA",
]
IR_VIOLATION_IDENTITY_TAG = [
    "IDENTITY_TAG_UNSPECIFIED",
    "PRIVILEGED",
    "AT_RISK",
    "SENSITIVE",
]
IR_VIOLATION_POLICY_TYPE = ["IDENTITY", "IDP", "IDENTITY_EVENT", "CROWDSTRIKE", "MICROSOFT_DEFENDER"]
IR_ALERT_POLICY_TYPES = ["IDENTITY_EVENT", "CROWDSTRIKE", "MICROSOFT_DEFENDER"]
IR_VIOLATION_SORT_BY = [
    "SEVERITY",
    "HITS",
    "DETECTION_TIME",
    "UPDATE_TIME",
    "IDENTITY_TYPE",
    "TOTAL_HITS",
    "EVENT_TIME",
    "NAME",
    "TYPE",
]
SENSITIVE_DATA_OBJECT_CLASSIFICATION_MESSAGE = "Results available in the Objects page for the workload"
SENSITIVE_DATA_OBJECT_SENSITIVITY = ["HIGH", "MEDIUM", "LOW", "NO"]

MESSAGES = {
    "NO_RECORDS_FOUND": "No {} were found for the given argument(s).",
    "NO_RECORD_FOUND": "No {} was found for the given argument(s).",
    "NEXT_RECORD": 'Note: To retrieve the next set of results use, "next_page_token" =',
    "NEXT_PAGE_TOKEN": (
        'Note: To retrieve the next set of results, use **next_page_token** = "{}".'
        "\nIf **next_page_token** is provided, then it will reset the record numbers. "
        "For the initial use of **next_page_token**, please avoid specifying the **page_number**."
    ),
    "NO_RESPONSE": "No response was returned for the given argument(s).",
    "IP_NOT_FOUND": 'No details found for IP: "{}".',
    "DOMAIN_NOT_FOUND": 'No details found for domain: "{}".',
    "NO_OBJECT_FOUND": "No Objects Found",
    "INVALID_FETCH_EVENT_TYPE": f"Only the following event types are supported: {', '.join(DEFAULT_EVENT_TYPES)}",
    "INVALID_FETCH_TYPE": f"Only the following fetch types are supported: {', '.join(DEFAULT_FETCH_TYPE)}",
    "INVALID_FETCH_EVENT_SEVERITIES": f"Only the following event severities are supported: {', '.join(DEFAULT_EVENT_SEVERITIES)}",
}

OUTPUT_PREFIX = {
    "GLOBAL_SEARCH": "RubrikPolaris.GlobalSearchObject",
    "PAGE_TOKEN_GLOBAL_SEARCH": "RubrikPolaris.PageToken.GlobalSearchObject",
    "VM_OBJECT": "RubrikPolaris.VSphereVm",
    "PAGE_TOKEN_VM_OBJECT": "RubrikPolaris.PageToken.VSphereVm",
    "SONAR_POLICIES_LIST": "RubrikPolaris.SonarPolicy",
    "SONAR_ANALYZER_GROUP": "RubrikPolaris.SonarAnalyzerGroup",
    "SONAR_ON_DEMAND_SCAN": "RubrikPolaris.SonarOndemandScan",
    "RADAR_ANOMALY_CSV_ANALYSIS": "RubrikPolaris.RadarAnomalyCSV",
    "SONAR_CSV_DOWNLOAD": "RubrikPolaris.SonarCSVDownload",
    "GPS_SNAPSHOT_FILES": "RubrikPolaris.GPSSnapshotFile",
    "GPS_VM_EXPORT": "RubrikPolaris.GPSVMSnapshotExport",
    "USER_DOWNLOADS": "RubrikPolaris.UserDownload",
    "GPS_SLA_DOMAIN": "RubrikPolaris.GPSSLADomain",
    "GPS_SNAPSHOT_CREATE": "RubrikPolaris.GPSOndemandSnapshot",
    "GPS_SNAPSHOT_FILE_DOWNLOAD": "RubrikPolaris.GPSSnapshotFileDownload",
    "GPS_VM_LIVEMOUNT": "RubrikPolaris.GPSVMLiveMount",
    "GPS_VM_HOSTS": "RubrikPolaris.GPSVMHost",
    "PAGE_TOKEN_VM_HOSTS": "RubrikPolaris.PageToken.GPSVMHost",
    "CDM_CLUSTER": "Rubrik.CDM",
    "PAGE_TOKEN_GPS_SNAPSHOT_FILES": "RubrikPolaris.PageToken.GPSSnapshotFile",
    "RADAR_ANALYSIS_STATUS": "Rubrik.Radar",
    "EVENT": "RubrikPolaris.Event",
    "PAGE_TOKEN_EVENT": "RubrikPolaris.PageToken.Event",
    "SONAR_SENSITIVE_HITS": "Rubrik.Sonar",
    "OBJECT": "RubrikPolaris.Object",
    "PAGE_TOKEN_OBJECT": "RubrikPolaris.PageToken.Object",
    "RADAR_IOC_SCAN": "RubrikPolaris.RadarIOCScan",
    "GPS_ASYNC_RESULT": "RubrikPolaris.GPSAsyncResult",
    "GPS_CLUSTER": "RubrikPolaris.GPSCluster",
    "GPS_VM_RECOVER_FILES": "RubrikPolaris.GPSVMRecoverFiles",
    "USER_ACCESS": "RubrikPolaris.UserAccess",
    "PAGE_TOKEN_USER_ACCESS": "RubrikPolaris.PageToken.UserAccess",
    "FILE_CONTEXT": "RubrikPolaris.FileContext",
    "PAGE_TOKEN_FILE_CONTEXT": "RubrikPolaris.PageToken.FileContext",
    "SUSPICIOUS_FILE": "RubrikPolaris.SuspiciousFile",
    "IP": "RubrikPolaris.IP",
    "DOMAIN": "RubrikPolaris.Domain",
    "ANOMALY_UPDATE_STATUS": "RubrikPolaris.AnomalyStatus",
    "THREAT_MONITORING": "RubrikPolaris.ThreatMonitoring",
    "PAGE_TOKEN_THREAT_MONITORING": "RubrikPolaris.PageToken.ThreatMonitoring",
    "PAGE_TOKEN_THREAT_MONITORING_FILE": "RubrikPolaris.PageToken.ThreatMonitoringFile",
    "THREAT_MONITORING_FILE": "RubrikPolaris.ThreatMonitoringFile",
    "IOC_SCAN": "RubrikPolaris.IOCScan",
    "PAGE_TOKEN_IOC_SCAN": "RubrikPolaris.PageToken.IOCScan",
    "TURBO_IOC_SCAN": "RubrikPolaris.TurboIOCScan",
    "ADVANCE_IOC_SCAN": "RubrikPolaris.AdvanceIOCScan",
    "ANOMALY_CSV_ANALYSIS_V2": "RubrikPolaris.AnomalyCSVv2",
    "DSPM_VIOLATION": "RubrikPolaris.DSPMViolation",
    "PAGE_TOKEN_DSPM_VIOLATION": "RubrikPolaris.PageToken.DSPMViolation",
    "DSPM_VIOLATION_FILE": "RubrikPolaris.DSPMViolationFile",
    "PAGE_TOKEN_DSPM_VIOLATION_FILE": "RubrikPolaris.PageToken.DSPMViolationFile",
    "DSPM_VIOLATION_CSV_DOWNLOAD": "RubrikPolaris.DSPMViolationCSVDownload",
    "DSPM_VIOLATION_LOG_DOWNLOAD": "RubrikPolaris.DSPMViolationRemediationLogDownload",
    "IR_VIOLATION": "RubrikPolaris.IRViolation",
    "PAGE_TOKEN_IR_VIOLATION": "RubrikPolaris.PageToken.IRViolation",
    "SENSITIVE_DATA_OBJECT": "RubrikPolaris.SensitiveDataObject",
    "SENSITIVE_DATA_OBJECT_FILE": "RubrikPolaris.SensitiveDataObjectFile",
}

ERROR_MESSAGES = {
    "PROXY_ERROR": "Proxy Error: if the 'Use system proxy' checkbox in the integration configuration is selected, "
    "try clearing the checkbox, or check the provided proxies.",
    "INVALID_MAX_FETCH": f"The 'Fetch Limit' is not a valid integer."
    f" The minimum value is {MAX_FETCH_MIN} and the maximum is {MAX_FETCH_MAX}.",
    "INSECURE_NOT_SUPPORTED": f"Parameter 'Trust any certificate' is not supported by "
    f"integration {INTEGRATION_NAME}, please un-check it and try again. ",
    "MISSING_REQUIRED_FIELD": "'{}' field is required. Please provide correct input.",
    "NO_CREDENTIALS_PROVIDED": "Please provide either 'Service Account JSON' or "
    "'Rubrik Account'-'Email'-'Password' for authentication.",
    "SA_JSON_DECODE_ERR": "Unable to read 'Service Account JSON', please verify it's correctness.",
    "KEY_NOT_FOUND_IN_SA_JSON": "{} was not found in 'Service Account JSON', please verify it's correctness.",
    "INVALID_LIMIT": "'{}' is an invalid value for 'limit'. Value must be between 1 and 1000.",
    "INVALID_PAGE": "'{}' is an invalid value for 'page_number'. Value must be greater than zero.",
    "JSON_DECODE": "Failed to parse '{}' JSON string, please check it's format in the argument's help-text.",
    "INVALID_BOOLEAN": "'{}' is an invalid value for '{}'. Value must be in ['true', 'false'].",
    "INVALID_SORT_ORDER": "'{}' is an invalid value for 'sort_order'. Value must be 'ASC' or 'DESC'.",
    "INVALID_SELECT": "'{}' is an invalid value for '{}'. Value must be in {}.",
    "MISSING_EXPORT_DESTINATION": "host_id or host_compute_cluster_id must be provided.",
    "LEN_SNAPSHOT_NE_LEN_OBJECT": "'snapshot_id' for each 'snappable_id' should be provided separated by colon.",
    "NO_INDICATOR_SPECIFIED": "Please provide either 'ioc_type' and 'ioc_value' or 'advance_ioc' "
    "to specify the indicator to scan for.",
    "INVALID_FORMAT": "Invalid format for '{}', please check it's format in the argument's help-text. ",
    "IP_ADDRESS_REQUIRED": "IP Address is required for fetching snapshot files download results command",
    "FALSE_POSITIVE_REASON_ERROR": "Requires the {} argument when the {} argument is specified.",
    "FALSE_POSITIVE_TYPE_ERROR": "Requires the {} argument when {} argument is set to OTHER.",
    "FETCH_PARAM_REQUIRED": "Requires the '{}' parameter when fetch incidents is selected.",
    "MISSING_TWO_REQUIRED_FIELD": "Requires both '{}' and '{}' arguments. Please provide correct input.",
    "NEGATIVE_ARG_VALUE": "'{}' is an invalid value for '{}'. Value must be greater than zero.",
    "INVALID_INT_VALUE": "'{}' is an invalid value for '{}'. Value must be less than or equal to {}.",
    "INVALID_DATE_RANGE": "'{}' cannot be greater than '{}'. Please provide correct input.",
}

DBOT_SCORE_MAPPING = {
    "unknown": 0,  # Unknown
    "no risk": 1,  # Good
    "low": 1,  # Good
    "medium": 2,  # Suspicious
    "high": 3,  # Bad
}

TOKEN_EXPIRY_TIME_SPAN = 86400
TOKEN_EXPIRY_BUFFER_TIME = 30

IOC_TYPE_ENUM = [
    "INDICATOR_OF_COMPROMISE_TYPE_HASH",
    "INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE",
    "INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME",
]

ANOMALY_TYPE_ENUM = ["FILESYSTEM", "HYPERVISOR"]
FALSE_POSITIVE_TYPE_ENUM = [
    "FP_TYPE_UNSPECIFIED",
    "OS_UPDATE",
    "APPLICATION_UPDATE",
    "LOG_ROTATION",
    "OTHER",
    "NFA_SCHEDULED_MAINTENANCE",
    "NFA_UNSCHEDULED_MAINTENANCE",
]

IOC_TYPE_MAPPING = {
    "INDICATOR_OF_COMPROMISE_TYPE_HASH": "IOC_HASH",
    "INDICATOR_OF_COMPROMISE_TYPE_YARA_RULE": "IOC_YARA",
    "INDICATOR_OF_COMPROMISE_TYPE_PATH_OR_FILENAME": "IOC_FILE_PATTERN",
}

USER_ACCESS_QUERY = """query UserAccessPrincipalListQuery(
    $filter: PrincipalSummariesFilterInput,
    $timelineDate: String!,
    $sort: ListPrincipalsSummarySortInput,
    $first: Int, $after: String,
    $includeWhitelistedResults: Boolean) {
  principalSummaries(
    filter: $filter
    timelineDate: $timelineDate
    sort: $sort
    first: $first
    after: $after
    includeWhitelistedResults: $includeWhitelistedResults
  ) {
    edges {
      cursor
      node {
        principalId
        fullName
        upn
        riskLevel
        sensitiveFiles {
          ...SensitiveFilesTableCellFragment
          __typename
        }
        totalSensitiveHits {
          ...SummaryHitsFragment
          __typename
        }
        sensitiveObjectCount {
          ...SummaryCountFragment
          __typename
        }
        numDescendants
        domainName
        __typename
      }
      __typename
    }
    pageInfo {
      startCursor
      endCursor
      hasNextPage
      hasPreviousPage
      __typename
    }
    __typename
  }
}

fragment SensitiveFilesTableCellFragment on SensitiveFiles {
  highRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  mediumRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  lowRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  __typename
}

fragment SummaryCountFragment on SummaryCount {
  totalCount
  violatedCount
  __typename
}

fragment SummaryHitsFragment on SummaryHits {
  totalHits
  violatedHits
  __typename
}"""

USER_ACCESS_DETAIL_QUERY = """query UserAccessUserDetailsQuery(
    $sid: String!,
    $timelineDate: String!,
    $includeWhitelistedResults: Boolean) {
    principalDetails(
        sid: $sid
        timelineDate: $timelineDate
        includeWhitelistedResults: $includeWhitelistedResults
    ) {
        ...UserAccessUserSummaryFragment
        __typename
    }
}

fragment UserAccessUserSummaryFragment on PrincipalDetails {
    principalSummary {
        principalId
        fullName
        upn
        riskLevel
        riskReasons {
            accessRiskReasons
            insecureReasons
            __typename
        }
        sensitiveFiles {
            ...SensitiveFilesTableCellFragment
            __typename
        }
        totalSensitiveHits {
            ...SummaryHitsFragment
            __typename
        }
        sensitiveObjectCount {
            ...SummaryCountFragment
            __typename
        }
        numDescendants
        domainName
        __typename
    }
    directGroups {
        name
        sid
        __typename
    }
    __typename
}

fragment SensitiveFilesTableCellFragment on SensitiveFiles {
  highRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  mediumRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  lowRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  __typename
}

fragment SummaryCountFragment on SummaryCount {
  totalCount
  violatedCount
  __typename
}

fragment SummaryHitsFragment on SummaryHits {
  totalHits
  violatedHits
  __typename
}"""

POLICY_HITS_SUMMARY_CHART_QEURY = """query PrincipalPolicyHitsSummaryChartQuery(
    $sids: [String!]!,
    $day: String!,
    $historicalDeltaDays: Int!,
    $includeWhitelistedResults: Boolean) {
  sidsPolicyHitsSummary(
    sids: $sids
    day: $day
    historicalDeltaDays: $historicalDeltaDays
    includeWhitelistedResults: $includeWhitelistedResults
  ) {
    sidSummaries {
      principal
      summary {
        policyId
        policyName
        sidSensitiveFiles {
          totalFileCount {
            totalCount
            violatedCount
            __typename
          }
          __typename
        }
        sidAnalyzerHits {
          ...PrincipalSensitiveHitsFragment
          __typename
        }
        sidDeltaAnalyzerHits {
          ...PrincipalSensitiveHitsFragment
          __typename
        }
        sidRiskHits {
          ...PrincipalSensitiveHitsFragment
          __typename
        }
        sidDeltaRiskHits {
          ...PrincipalSensitiveHitsFragment
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
}

fragment PrincipalSensitiveHitsFragment on SensitiveHits {
  highRiskHits {
    ...SummaryHitsFragment
    __typename
  }
  mediumRiskHits {
    ...SummaryHitsFragment
    __typename
  }
  lowRiskHits {
    ...SummaryHitsFragment
    __typename
  }
  totalHits {
    ...SummaryHitsFragment
    __typename
  }
  __typename
}

fragment SummaryHitsFragment on SummaryHits {
  totalHits
  violatedHits
  __typename
}"""

FILE_CONTEXT_QUERY = """query CrawlsFileListQuery(
    $snappableFid: String!,
    $snapshotFid: String!,
    $first: Int!,
    $after: String,
    $filters: ListFileResultFiltersInput,
    $sort: FileResultSortInput,
    $timezone: String!) {
  policyObj(snappableFid: $snappableFid, snapshotFid: $snapshotFid) {
    id: snapshotFid
    fileResultConnection(first: $first, after: $after, filter: $filters, sort: $sort, timezone: $timezone) {
      edges {
        cursor
        node {
          ...DiscoveryFileFragment
          __typename
        }
        __typename
      }
      pageInfo {
        startCursor
        endCursor
        hasNextPage
        hasPreviousPage
        __typename
      }
      hasLatestData
      __typename
    }
    __typename
  }
}

fragment DiscoveryFileFragment on FileResult {
  nativePath
  stdPath
  filename
  mode
  size
  lastAccessTime
  lastModifiedTime
  creationTime
  lastScanTime
  directory
  createdBy
  modifiedBy
  numDescendantFiles
  numDescendantErrorFiles
  numDescendantSkippedExtFiles
  numDescendantSkippedSizeFiles
  errorCode
  hits {
    totalHits
    violations
    violationsDelta
    totalHitsDelta
    __typename
  }
  filesWithHits {
    totalHits
    violations
    __typename
  }
  openAccessFilesWithHits {
    totalHits
    violations
    __typename
  }
  staleFilesWithHits {
    totalHits
    violations
    __typename
  }
  analyzerGroupResults {
    ...AnalyzerGroupResultFragment
    __typename
  }
  sensitiveFiles {
    highRiskFileCount {
      totalCount
      violatedCount
      __typename
    }
    mediumRiskFileCount {
      totalCount
      violatedCount
      __typename
    }
    lowRiskFileCount {
      totalCount
      violatedCount
      __typename
    }
    noRiskFileCount {
      totalCount
      violatedCount
      __typename
    }
    totalFileCount {
      totalCount
      violatedCount
      __typename
    }
    __typename
  }
  sensitiveHits {
    highRiskHits {
      totalHits
      violatedHits
      __typename
    }
    mediumRiskHits {
      totalHits
      violatedHits
      __typename
    }
    lowRiskHits {
      totalHits
      violatedHits
      __typename
    }
    noRiskHits {
      totalHits
      violatedHits
      __typename
    }
    __typename
  }
  analyzerRiskHits {
    highRiskHits {
      totalHits
      violatedHits
      __typename
    }
    mediumRiskHits {
      totalHits
      violatedHits
      __typename
    }
    lowRiskHits {
      totalHits
      violatedHits
      __typename
    }
    noRiskHits {
      totalHits
      violatedHits
      __typename
    }
    __typename
  }
  analyzerResults {
    hits {
      totalHits
      violations
      __typename
    }
    analyzer {
      id
      name
      analyzerType
      __typename
    }
    __typename
  }
  openAccessType
  stalenessType
  numActivities
  numActivitiesDelta
  exposureSummary {
    exposureType
    fileCount {
      totalCount
      violatedCount
      __typename
    }
    __typename
  }
  dbEntityType
  mipLabelsSummary {
    ...ObjectInventoryMipColumnFragment
    __typename
  }
  documentTypesSummary {
    id
    name
    filesCount {
      totalCount
      violatedCount
      __typename
    }
    __typename
  }
  __typename
}

fragment AnalyzerGroupResultFragment on AnalyzerGroupResult {
  analyzerGroup {
    groupType
    id
    name
    __typename
  }
  analyzerResults {
    hits {
      totalHits
      violations
      __typename
    }
    analyzer {
      id
      name
      analyzerType
      __typename
    }
    __typename
  }
  hits {
    totalHits
    violations
    violationsDelta
    totalHitsDelta
    __typename
  }
  __typename
}

fragment ObjectInventoryMipColumnFragment on MipLabelSummary {
  mipLabel {
    siteId
    labelName
    labelId
    hasProtection
    __typename
  }
  filesCount {
    violatedCount
    totalCount
    __typename
  }
  __typename
}"""

SNAPPABLE_INVESTIGATIONS_QUERY = """query SnappableInvestigationsQuery($id: UUID!) {
  snapshot(snapshotFid: $id) {
    date
    cluster {
      id
      defaultAddress
      systemStatusAffectedNodes {
        ipAddress
      }
      name
      version
      status
      __typename
    }
    snappableNew {
      objectType
    }
    cdmId
    isQuarantined
    __typename
  }
}"""

ANOMALY_RESULT_QUERY = """query AnomalyResultQuery(
    $clusterUuid: UUID!, $snapshotId: String!) {
  anomalyResultOpt(clusterUuid: $clusterUuid, snapshotId: $snapshotId) {
    id
    snapshotFid
    managedId
    anomalyProbability
    workloadId
    location
    isAnomaly
    objectType
    severity
    detectionTime
    snapshotDate
    encryption
    resolutionStatus
    anomalyType
    anomalyInfo {
      strainAnalysisInfo {
        strainId
        totalAffectedFiles
        totalRansomwareNotes
        sampleAffectedFilesInfo {
          filePath
          lastModified
          fileSizeBytes
          __typename
        }
        sampleRansomwareNoteFilesInfo {
          filePath
          lastModified
          fileSizeBytes
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
}
"""

FILESET_DOWNLOAD_SNAPSHOT_FILES_MUTATION = """mutation PhysicalHostDownloadSnapshotFilesMutation(
    $config: FilesetDownloadFilesJobConfigInput!,
    $id: String!, $deltaTypeFilter: [DeltaType!],
    $nextSnapshotFid: UUID,
    $userNote: String) {
  filesetDownloadSnapshotFiles(
    input: {config: $config, id: $id, deltaTypeFilter: $deltaTypeFilter, nextSnapshotFid: $nextSnapshotFid, userNote: $userNote}
  ) {
    id
    status
    links {
      href
      rel
      __typename
    }
    __typename
  }
}"""

VOLUME_GROUP_DOWNLOAD_SNAPSHOT_FILES_MUTATION = """mutation RadarInvestigationVGDownloadFilesMutation(
    $input: DownloadVolumeGroupSnapshotFilesInput!) {
  downloadVolumeGroupSnapshotFiles(input: $input) {
    id
    status
    links {
      href
      rel
      __typename
    }
    __typename
  }
}
"""

ANOMALY_UPDATE_STATUS_MUTATION = """mutation AnomalyUpdateStatusMutation($input: ResolveAnomalyInput!) {
  resolveAnomaly(input: $input)
}"""

THREAT_MONITORING_MATCHED_OBJECT_LIST_QUERY = """query ThreatMonitoringMatchedObjectsQuery(
  $first: Int
  $after: String
  $last: Int
  $before: String
  $beginTime: DateTime
  $endTime: DateTime
  $clusterUuidFilter: [String!]
  $objectTypeFilter: [String!]
  $workloadNameSearch: String
  $matchTypeFilter: [IndicatorOfCompromiseKind!]
) {
  threatMonitoringMatchedObjects(
    first: $first
    after: $after
    last: $last
    before: $before
    beginTime: $beginTime
    endTime: $endTime
    clusterUuidFilter: $clusterUuidFilter
    objectTypeFilter: $objectTypeFilter
    workloadNameSearch: $workloadNameSearch
    matchTypeFilter: $matchTypeFilter
  ) {
    edges {
      cursor
      node {
        objectFid
        objectName
        objectType
        matchType
        filesMatched
        lastDetection
        cluster {
          id
          name
          __typename
        }
        __typename
      }
      __typename
    }
    stats {
      objectsWithMatches
      objectsWithNoMatches
      totalObjectsScanned
      __typename
    }
    pageInfo {
      startCursor
      endCursor
      hasNextPage
      hasPreviousPage
      __typename
    }
    __typename
  }
}
"""

THREAT_MONITORING_MATCHED_OBJECT_GET_QUERY = """query ThreatMonitoringObjectTypeQuery($fid: UUID!) {
  hierarchyObject(fid: $fid) {
    id
    name
    objectType
    slaAssignment
    slaPauseStatus
    effectiveSlaDomain {
      id
      name
      version
      __typename
    }
    snapshotDistribution {
      id
      totalCount
      scheduledCount
      onDemandCount
      retrievedCount
      __typename
    }
    effectiveRetentionSlaDomain {
      id
      name
      version
      __typename
    }
    configuredSlaDomain {
      id
      name
      version
      __typename
    }
    effectiveSlaSourceObject {
      fid
      name
      objectType
      __typename
    }
    logicalPath {
      fid
      name
      objectType
      __typename
    }
    physicalPath {
      fid
      name
      objectType
      __typename
    }
    numWorkloadDescendants
    allOrgs {
      id
      name
      description
      mfaStatus
      allUrls
      __typename
    }
    securityMetadata {
      lowSensitiveHits
      mediumSensitiveHits
      highSensitiveHits
      sensitivityStatus
      isLaminarEnabled
      dataTypeResults {
        id
        name
        totalHits
        totalViolatedHits
        __typename
      }
      __typename
    }
    __typename
  }
}
"""

DEPLOYMENT_VERSION_QUERY = """query DeploymentVersionQuery {
  deploymentVersion
}"""

THREAT_MONITORING_MATCHED_FILE_LIST_QUERY = """query ThreatMonitoringMatchedFiles(
  $first: Int
  $after: String
  $objectFid: UUID!
  $filenameSearchFilter: String
) {
  threatMonitoringMatchedFiles(
    first: $first
    after: $after
    objectFid: $objectFid
    filenameSearchFilter: $filenameSearchFilter
  ) {
    edges {
      cursor
      node {
        filepath
        detectedTime
        fileName
        fileSize
        matchedSnapshotDate
        matchedSnapshotFid
        isMatchedSnapshotExpired
        isFirstObservedSnapshotExpired
        matchType
        isQuarantinedInFirstObservedSnapshot
        objectFid
        firstObservedSnapshotFid
        firstObservedSnapshotDate
        objectType
        objectName
        matchId
        __typename
      }
      __typename
    }
    count
    pageInfo {
      startCursor
      endCursor
      hasNextPage
      hasPreviousPage
      __typename
    }
    __typename
  }
}
"""

THREAT_MONITORING_MATCHED_FILE_DETAILS_QUERY = """query ThreatMonitoringMatchedFileDetailsV2Query(
  $matchedSnapshotFid: UUID!,
  $filepath: String!
) {
  threatMonitoringMatchedFileDetailsV2(
    matchedSnapshotFid: $matchedSnapshotFid
    filepath: $filepath
  ) {
    matchedFileMd5
    matchedFileSha1
    matchedFileSha256
    iocDetails {
      matchType
      intelFeedName
      malwareName
      iocRuleAuthor
      malwareDescription
      iocHashHex
      iocStatus
      __typename
    }
    isQuarantinedInFirstObservedSnapshot
    detectedSnapshotDate
    firstDetectedSnapshotFid
    filePath
    fileName
    __typename
  }
}
"""

List_Threat_Hunts_Query = """
query ListThreatHuntsQuery(
  $clusterUuidFilter: [String!],
  $statusFilter: [ThreatHuntStatus!],
  $matchesFoundFilter: [ThreatHuntMatchesFound!],
  $quarantinedMatchesFilter: [ThreatHuntQuarantinedMatchType!],
  $beginTime: DateTime,
  $endTime: DateTime,
  $first: Int,
  $after: String
) {
  threatHunts(
    clusterUuidFilter: $clusterUuidFilter
    statusFilter: $statusFilter
    matchesFoundFilter: $matchesFoundFilter
    quarantinedMatchesFilter: $quarantinedMatchesFilter
    beginTime: $beginTime
    endTime: $endTime
    first: $first
    after: $after
  ) {
    edges {
      node {
        huntId
        name
        createdBy {
          id
          username
          email
          __typename
        }
        huntType
        startTime
        status
        stats {
          ...ThreatHuntStatsFragment
          __typename
        }
        huntDetails {
          startTime
          endTime
          cluster {
            id
            name
            __typename
          }
          config {
            name
            indicatorsOfCompromise {
              iocValue
              iocKind
              __typename
            }
            __typename
          }
          __typename
        }
        __typename
      }
      __typename
    }
    count
    pageInfo{
      endCursor
      hasNextPage
      hasPreviousPage
      startCursor
      __typename
    }
    __typename
  }
}

fragment ThreatHuntStatsFragment on ThreatHuntStats {
  totalProcessedSnapshots
  totalAffectedObjects
  totalAffectedSnapshots
  totalUniqueMatchedPaths
  totalSucceededScans
  totalSnapshotsScanned
  totalUniqueQuarantinedPaths
  totalObjectsScanned
  totalIocs
  __typename
}
"""

THREAT_HUNT_DETAILS_V2_QUERY = """query ThreatHuntDetailsV2Query($huntId: String!) {
  threatHuntObjectMetrics(huntId: $huntId) {
    totalObjectsScanned
    totalAffectedObjects
    totalUnaffectedObjects
    totalObjectsUnscannable
    unaffectedObjectsFromDb
    cleanRecoverableObjectLimit
    __typename
  }
  threatHuntDetailV2(huntId: $huntId) {
    totalObjectFids
    startTime
    endTime
    status
    totalMatchedSnapshots
    totalScannedSnapshots
    totalUniqueFileMatches
    clusters{
      id
      name
      type
      __typename
    }
    baseConfig {
      name
      notes
      maxMatchesPerSnapshot
      threatHuntType
      ioc {
        iocList {
          indicatorsOfCompromise {
            iocKind
            iocValue
            __typename
          }
          __typename
        }
        __typename
      }
      snapshotScanLimit {
        scanLimit {
          scanConfig {
            maxSnapshotsPerObject
            startTime
            endTime
            __typename
          }
          objectSnapshotConfig {
            objectFid
            snapshotFid
            __typename
          }
          __typename
        }
        __typename
      }
      fileScanCriteria {
        fileSizeLimits {
          maximumSizeInBytes
          minimumSizeInBytes
          __typename
        }
        fileTimeLimits {
          earliestCreationTime
          earliestModificationTime
          latestCreationTime
          latestModificationTime
          __typename
        }
        pathFilter {
          inclusions
          exclusions
          exemptions
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
}
"""

START_TURBO_THREAT_HUNT_MUTATION = """
mutation StartTurboThreatHunt($input: StartTurboThreatHuntInput!){
  startTurboThreatHunt(input: $input){
    huntId
    __typename
  }
}
"""

START_ADVANCE_THREAT_HUNT_MUTATION = """mutation StartAdvanceThreatHuntMutation($input: StartThreatHuntV2Input!) {
    startBulkThreatHunt(input: $input) {
        hunts {
            huntId
            huntName
            config {
                huntType
                clusterUuids
                objectFids
                __typename
            }
            status
            __typename
        }
        __typename
    }
}
"""

DOWNLOAD_ANOMALY_DETAILS_CSV_MUTATION = """
mutation DownloadAnomalyDetailsCsvMutation($input: DownloadAnomalyDetailsCsvInput!) {
    downloadAnomalyDetailsCsv(input: $input) {
        isSuccessful
        __typename
    }
}
"""

ALL_USER_DOWNLOADS_FILES_QUERY = """
query DownloadBarQuery {
  allUserFiles {
    downloads {
      externalId
      createdAt
      expiresAt
      completedAt
      creator
      filename
      type
      state
      __typename
    }
    __typename
  }
}
"""

DSPM_VIOLATION_GET_QUERY = """ query DataSecurityViolationGetQuery($violationId: String!) {
  policyViolation(
    violationId: $violationId
    policyTypes: [POLICY_TYPE_DATAGOV]
  ) {
    ...DataAtRiskPanelFragment
    status
    violationSeverity
    policyViolationId
    createdAt
    lastUpdatedAt
    resourceId
    policy {
      policyId
      name
      description
      policyCategory
      policySeverity
      containsAccessFilters
      __typename
    }
    remediations {
      remediationId
      state
      remediationDetails {
        details {
          ticketNumber
          ticketUrl
          __typename
        }
        __typename
      }
      __typename
    }
    resourceMetadata {
      metadata {
        ... on CommonAssetMetadata {
          platform
          cloudAccountInfo {
            accountName
            __typename
          }
          objectType
          clusterInfo {
            clusterName
            clusterUuid
            __typename
          }
          creationTime
          lastAccessTime
          snapshotTimestamp
          physicalHost
          name
          isDeleted
          region
          __typename
        }
      }
      __typename
    }
    __typename
  }
}

fragment SensitiveHitsChartFragment on DataGovViolationDetails {
  snapshotId
  violatedSensitiveHits
  violatedNoRiskSensitiveHits
  violatedLowRiskSensitiveHits
  violatedMediumRiskSensitiveHits
  violatedHighRiskSensitiveHits
  __typename
}

fragment DataAtRiskPanelFragment on PolicyViolation {
  details {
    ...SensitiveHitsChartFragment
    ... on DataGovViolationDetails {
      dataCategories {
        id
        name
        totalViolatedHits
        __typename
      }
      dataTypes {
        id
        name
        totalViolatedHits
        __typename
      }
      mipLabels {
        id
        totalViolatedHits
        name
        __typename
      }
      documentTypes {
        id
        name
        totalViolatedHits
        __typename
      }
      __typename
    }
    __typename
  }
  __typename
}
"""

DSPM_VIOLATIONS_LIST_QUERY = """query DataSecurityViolationsListQuery(
  $policyIds: [UUID!]
  $resourceIds: [String!]
  $statuses: [PolicyViolationStatus!]
  $severities: [Severity!]
  $categories: [Category!]
  $sensitivityLevels: [SensitivityLevel!]
  $detectionDate: TimeRangeInput
  $updateDate: TimeRangeInput
  $first: Int
  $after: String
  $sortBy: PolicyViolationSortField
  $sortOrder: SortOrder
  $resourceMetadataFilter: ResourceMetadataFiltersInput
  $dataCategoryIds: [String!]
  $dataTypeIds: [String!]
) {
  policyViolations(
    policyIds: $policyIds
    resourceIds: $resourceIds
    statuses: $statuses
    policySeverities: $severities
    policyCategories: $categories
    sensitivityLevels: $sensitivityLevels
    detectionDate: $detectionDate
    updateDate: $updateDate
    policyTypes: [POLICY_TYPE_DATAGOV]
    first: $first
    after: $after
    sortBy: $sortBy
    sortOrder: $sortOrder
    resourceMetadataFilter: $resourceMetadataFilter
    dataCategoryIds: $dataCategoryIds
    dataTypeIds: $dataTypeIds
  ) {
    edges {
      node {
        policyViolationId
        ...PolicyViolationStatusFragment
        createdAt
        lastUpdatedAt
        name
        violationSeverity
        policy {
          policyId
          name
          policySeverity
          policyCategory
          description
          __typename
        }
        resourceId
        resourceType
        resourceMetadata {
          metadata {
            ... on CommonAssetMetadata {
              name
              objectType
              platform
              physicalHost
              region
              creationTime
              lastAccessTime
              snapshotTimestamp
              clusterInfo {
                clusterName
                clusterUuid
                __typename
              }
              cloudAccountInfo {
                accountName
                __typename
              }
              __typename
            }
            __typename
          }
          __typename
        }
        ...PolicyViolationDetailsFragment
        remediations {
          type
          state
          remediationDetails {
            details {
              ticketNumber
              ticketUrl
              __typename
            }
            __typename
          }
          __typename
        }
        __typename
      }
      cursor
      __typename
    }
    pageInfo {
      startCursor
      endCursor
      hasNextPage
      hasPreviousPage
      __typename
    }
    count
    __typename
  }
}

fragment PolicyViolationStatusFragment on PolicyViolation {
  status
  __typename
}

fragment PolicyViolationDetailsFragment on PolicyViolation {
  policyViolationId
  details {
    ... on DataGovViolationDetails {
      violatedNoRiskSensitiveHits
      violatedLowRiskSensitiveHits
      violatedMediumRiskSensitiveHits
      violatedHighRiskSensitiveHits
      violatedSensitiveHits
      snapshotId
      dataTypes {
        id
        name
        totalViolatedHits
        __typename
      }
      dataCategories {
        id
        name
        totalViolatedHits
        __typename
      }
    }
    __typename
  }
  __typename
}
"""

DSPM_VIOLATION_STATUS_UPDATE_MUTATION = """mutation UpdatePolicyViolationsMutation($input: BulkUpdatePolicyViolationsInput!) {
  bulkUpdatePolicyViolations(input: $input)
}"""

DSPM_VIOLATION_FILE_LIST_QUERY = """query DSPMViolationFileListQuery(
  $first: Int!
  $after: String
  $snappableFid: String!
  $snapshotFid: String!
  $filters: ListFileResultFiltersInput
  $sort: FileResultSortInput
  $timezone: String!
) {
  policyObj(snappableFid: $snappableFid, snapshotFid: $snapshotFid) {
    id: snapshotFid
    fileResultConnection(
      first: $first
      after: $after
      filter: $filters
      sort: $sort
      timezone: $timezone
    ) {
      edges {
        cursor
        node {
          ...DiscoveryFileFragment
          __typename
        }
        __typename
      }
      pageInfo {
        startCursor
        endCursor
        hasNextPage
        hasPreviousPage
        __typename
      }
      hasLatestData
      __typename
    }
    __typename
  }
}

fragment DiscoveryFileFragment on FileResult {
  nativePath
  stdPath
  filename
  mode
  size
  lastAccessTime
  lastModifiedTime
  creationTime
  lastScanTime
  directory
  createdBy
  modifiedBy
  numDescendantFiles
  numDescendantErrorFiles
  numDescendantSkippedExtFiles
  numDescendantSkippedSizeFiles
  errorCode
  hits {
    totalHits
    violations
    violationsDelta
    totalHitsDelta
    __typename
  }
  filesWithHits {
    totalHits
    violations
    __typename
  }
  openAccessFilesWithHits {
    totalHits
    violations
    __typename
  }
  staleFilesWithHits {
    totalHits
    violations
    __typename
  }
  analyzerGroupResults {
    ...AnalyzerGroupResultFragment
    __typename
  }
  sensitiveFiles {
    ...SensitiveFilesTableCellFragment
    __typename
  }
  sensitiveHits {
    highRiskHits {
      totalHits
      violatedHits
      __typename
    }
    mediumRiskHits {
      totalHits
      violatedHits
      __typename
    }
    lowRiskHits {
      totalHits
      violatedHits
      __typename
    }
    noRiskHits {
      totalHits
      violatedHits
      __typename
    }
    __typename
  }
  analyzerRiskHits {
    highRiskHits {
      totalHits
      violatedHits
      __typename
    }
    mediumRiskHits {
      totalHits
      violatedHits
      __typename
    }
    lowRiskHits {
      totalHits
      violatedHits
      __typename
    }
    noRiskHits {
      totalHits
      violatedHits
      __typename
    }
    __typename
  }
  analyzerResults {
    hits {
      totalHits
      violations
      __typename
    }
    analyzer {
      id
      name
      analyzerType
      __typename
    }
    __typename
  }
  openAccessType
  stalenessType
  numActivities
  numActivitiesDelta
  exposureSummary {
    exposureType
    fileCount {
      totalCount
      violatedCount
      __typename
    }
    __typename
  }
  dbEntityType
  mipLabelsSummary {
    ...ObjectInventoryMipColumnFragment
    __typename
  }
  documentTypesSummary {
    id
    name
    filesCount {
      totalCount
      violatedCount
      __typename
    }
    __typename
  }
  __typename
}

fragment SensitiveFilesTableCellFragment on SensitiveFiles {
  highRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  mediumRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  lowRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  noRiskFileCount {
    ...SummaryCountFragment
    __typename
  }
  totalFileCount {
    ...SummaryCountFragment
    __typename
  }
  __typename
}

fragment SummaryCountFragment on SummaryCount {
  totalCount
  violatedCount
  __typename
}

fragment AnalyzerGroupResultFragment on AnalyzerGroupResult {
  analyzerGroup {
    groupType
    id
    name
    __typename
  }
  analyzerResults {
    hits {
      totalHits
      violations
      __typename
    }
    analyzer {
      id
      name
      analyzerType
      __typename
    }
    __typename
  }
  hits {
    totalHits
    violations
    violationsDelta
    totalHitsDelta
    __typename
  }
  __typename
}

fragment ObjectInventoryMipColumnFragment on MipLabelSummary {
  mipLabel {
    siteId
    labelName
    labelId
    hasProtection
    __typename
  }
  filesCount {
    violatedCount
    totalCount
    __typename
  }
  __typename
}
"""

DOWNLOAD_DSPM_VIOLATION_CSV_MUTATION = """mutation DownloadDSPMViolationCsvMutation(
  $filters: DownloadResultsCsvFiltersInput
  $snappableFid: String!
  $snapshotFid: String!
) {
  downloadSnapshotResultsCsv(
    snappableFid: $snappableFid
    snapshotFid: $snapshotFid
    downloadFilter: $filters
  ) {
    isSuccessful
    __typename
  }
}
"""

DOWNLOAD_DSPM_VIOLATION_REMEDIATION_LOG_MUTATION = """mutation DownloadDSPMViolationRemediationLogMutation(
  $input: CreateViolationRemediationInput!
) {
  createViolationRemediation(input: $input) {
    remediationId
    __typename
  }
}
"""

IR_VIOLATIONS_LIST_QUERY = """query IdentityResilienceViolationsListQuery(
  $policyIds: [UUID!]
  $resourceIds: [String!]
  $statuses: [PolicyViolationStatus!]
  $severities: [Severity!]
  $categories: [Category!]
  $policyTypes: [PolicyType!]!
  $detectionDate: TimeRangeInput
  $updateDate: TimeRangeInput
  $first: Int
  $after: String
  $sortBy: PolicyViolationSortField
  $sortOrder: SortOrder
  $resourceMetadataFilter: ResourceMetadataFiltersInput
) {
  policyViolations(
    policyIds: $policyIds
    resourceIds: $resourceIds
    statuses: $statuses
    policySeverities: $severities
    policyCategories: $categories
    detectionDate: $detectionDate
    updateDate: $updateDate
    policyTypes: $policyTypes
    first: $first
    after: $after
    sortBy: $sortBy
    sortOrder: $sortOrder
    resourceMetadataFilter: $resourceMetadataFilter
  ) {
    edges {
      node {
        policyViolationId
        violationSeverity
        name
        createdAt
        resourceId
        resourceType
        status
        lastUpdatedAt
        policy {
          policyId
          name
          description
          policySeverity
          policyCategory
          policyType
          frameworks
          manualRemediationProcess
          __typename
        }
        details {
          ... on IdentityViolationDetails {
            domainUniqueId
            __typename
          }
          ... on IdpViolationDetails {
            domainUniqueId
            __typename
          }
          ... on CrowdStrikeAlertViolationDetails {
            __typename
            detectionTime
            startTime
            endTime
            mitreTactic
          }
          ... on DefenderAlertViolationDetails {
            __typename
            detectionTime
            startTime
            endTime
            mitreTactic
          }
          __typename
        }
        resourceMetadata {
          metadata {
            ... on IdentityMetadata {
              displayName
              domainName
              idpType
              principalType
              privilegeType
              userPrincipalName
              status
              title
              source
              identityTags
              uniqueId
              nativeType
              __typename
            }
            ... on IdpMetadata {
              domainName
              idpType
              rootDomainName
              rootDomainId
              __typename
            }
            ... on IdentityEventMetadata {
              __typename
              eventTime
              idpType
              actorIdentityId
              actorIdentityName
              actorIdentityType
              actorPrivilegeType
              actorState
              targetIdentityUniqueIdentifier
              targetIdentityName
              targetIdentityType
              targetIdentitySource
              targetPrivilegeType
              entityName
              entityId
            }
            ... on CrowdStrikeAlertMetadata {
              __typename
              actorIdentityId
              actorIdentityName
              actorIdentityType
              actorPrivilegeType
              targetIdentityUniqueIdentifier
              targetIdentityName
              targetIdentitySource
              targetIdentityStatus
              targetIdentityType
              targetIdpType
              targetPrivilegeType
            }
            ... on DefenderAlertMetadata {
              __typename
              actorIdentityId
              actorIdentityName
              actorIdentityType
              actorPrivilegeType
              targetIdentityUniqueIdentifier
              targetIdentityName
              targetIdentitySource
              targetIdentityStatus
              targetIdentityType
              targetIdpType
              targetPrivilegeType
            }
            __typename
          }
          __typename
        }
        __typename
      }
      cursor
      __typename
    }
    pageInfo {
      startCursor
      endCursor
      hasNextPage
      hasPreviousPage
      __typename
    }
    count
    __typename
  }
}
"""

IR_VIOLATION_GET_QUERY = """query IdentityResilienceViolationsGetQuery(
  $violationId: String!
  $policyTypes: [PolicyType!]!
) {
  policyViolation(violationId: $violationId, policyTypes: $policyTypes) {
    policyViolationId
    violationSeverity
    name
    createdAt
    resourceId
    resourceType
    status
    lastUpdatedAt
    policy {
      policyId
      name
      description
      policyType
      policySeverity
      policyCategory
      frameworks
      manualRemediationProcess
      __typename
    }
    details {
      ... on IdentityViolationDetails {
        domainUniqueId
        principalUniqueId
        __typename
      }
      ... on IdpViolationDetails {
        domainUniqueId
        __typename
      }
      ... on CrowdStrikeAlertViolationDetails {
        __typename
        detectionTime
        startTime
        endTime
        mitreTactic
      }
      ... on DefenderAlertViolationDetails {
        __typename
        detectionTime
        startTime
        endTime
        mitreTactic
      }
      __typename
    }
    resourceMetadata {
      metadata {
        ... on IdentityMetadata {
          displayName
          domainName
          idpType
          principalType
          privilegeType
          userPrincipalName
          status
          title
          source
          identityTags
          uniqueId
          nativeType
          __typename
        }
        ... on IdpMetadata {
          domainName
          domainUniqueId
          idpType
          rootDomainName
          rootDomainId
          __typename
        }
        ... on IdentityEventMetadata {
          __typename
          eventTime
          idpType
          actorIdentityId
          actorIdentityName
          actorIdentityType
          actorPrivilegeType
          actorState
          targetIdentityUniqueIdentifier
          targetIdentityName
          targetIdentityType
          targetIdentitySource
          targetPrivilegeType
          entityName
          entityId
        }
        ... on CrowdStrikeAlertMetadata {
          __typename
          actorIdentityId
          actorIdentityName
          actorIdentityType
          actorPrivilegeType
          targetIdentityUniqueIdentifier
          targetIdentityName
          targetIdentitySource
          targetIdentityStatus
          targetIdentityType
          targetIdpType
          targetPrivilegeType
        }
        ... on DefenderAlertMetadata {
          __typename
          actorIdentityId
          actorIdentityName
          actorIdentityType
          actorPrivilegeType
          targetIdentityUniqueIdentifier
          targetIdentityName
          targetIdentitySource
          targetIdentityStatus
          targetIdentityType
          targetIdpType
          targetPrivilegeType
        }
        __typename
      }
      __typename
    }
    __typename
  }
}
"""

IR_VIOLATION_PRINCIPAL_SUMMARY_QUERY = """query GetPrincipalSummaryQuery($input: GetPrincipalSummaryReqInput!) {
  principalSummary(input: $input) {
    summary {
      identityTags
      sensitiveHits {
        highRiskHits {
          violatedHits
          __typename
        }
        mediumRiskHits {
          violatedHits
          __typename
        }
        lowRiskHits {
          violatedHits
          __typename
        }
        noRiskHits {
          violatedHits
          __typename
        }
        totalHits {
          violatedHits
          __typename
        }
        __typename
      }
      ...DataCategoryChipRowFragment
    }
    __typename
  }
}

fragment DataCategoryChipRowFragment on PrincipalSummary {
  dataCategoryResults {
    dataCategoryName
    dataCategoryHits {
      dataCategoryId
      totalViolatedHits
      __typename
    }
    __typename
  }
}
"""

IR_VIOLATION_STATUS_UPDATE_MUTATION = """mutation IdentityResilienceViolationsStatusUpdateMutation(
  $input: BulkUpdatePolicyViolationsInput!
) {
  bulkUpdatePolicyViolations(input: $input)
}
"""

SENSITIVE_DATA_OBJECT_EVENT_SERIES_LIST_QUERY = """query SensitiveDataObjectEventSeriesList(
  $after: String
  $filters: ActivitySeriesFilter
  $first: Int
  $sortBy: ActivitySeriesSortField
  $sortOrder: SortOrder
) {
  activitySeriesConnection(
    after: $after
    first: $first
    filters: $filters
    sortBy: $sortBy
    sortOrder: $sortOrder
  ) {
    edges {
      cursor
      node {
        id
        fid
        activitySeriesId
        startTime
        lastUpdated
        lastActivityType
        lastActivityStatus
        location
        objectName
        objectId
        objectType
        severity
        progress
        cluster {
          id
          name
        }
        activityConnection {
          nodes {
            id
            message
            severity
            time
            activityInfo
          }
        }
      }
    }
    pageInfo {
      endCursor
      hasNextPage
      hasPreviousPage
    }
  }
}
"""

SENSITIVE_OBJECT_DETAIL_QUERY = """query SensitiveObjectDetailQuery(
  $snappableFid: String!
  $snapshotFid: String!
  $includeWhitelistedResults: Boolean
) {
  policyObj(
    snappableFid: $snappableFid
    snapshotFid: $snapshotFid
    includeWhitelistedResults: $includeWhitelistedResults
  ) {
    ...SonarObjectDetailFragment
    policySummaries {
      ...PolicySummaryFragment
      __typename
    }
    __typename
  }
}

fragment SonarObjectDetailFragment on PolicyObj {
  ...PolicyObjFragment
  osType
  isUserAccessEnabledObject
  snappable {
    ... on VsphereVm {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    ... on LinuxFileset {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    ... on ShareFileset {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    ... on WindowsFileset {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    ... on NutanixVm {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    ... on HyperVVirtualMachine {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    ... on VolumeGroup {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    ... on MssqlDatabase {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    ... on NasFileset {
      cdmId
      cluster {
        id
        name
        version
        defaultAddress
        clusterNodeConnection(first: 1) {
          nodes {
            ipAddress
            __typename
          }
          __typename
        }
        datagovPreviewerConfig {
          enabled
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
  __typename
}

fragment PolicyObjFragment on PolicyObj {
  id
  snapshotFid
  snapshotTimestamp
  shareType
  riskLevel
  objectStatus {
    policyStatuses {
      status
      __typename
    }
    latestSnapshotResult {
      snapshotTime
      snapshotFid
      __typename
    }
    __typename
  }
  rootFileResult {
    hits {
      totalHits
      violations
      violationsDelta
      totalHitsDelta
      __typename
    }
    analyzerGroupResults {
      ...AnalyzerGroupResultFragment
      __typename
    }
    analyzerResults {
      analyzer {
        id
        name
      }
      hits {
        totalHits
        violations
        violationsDelta
        totalHitsDelta
        __typename
      }
    }
    filesWithHits {
      totalHits
      violations
      violationsDelta
      totalHitsDelta
      __typename
    }
    openAccessFiles {
      totalHits
      violations
      violationsDelta
      totalHitsDelta
      __typename
    }
    openAccessFolders {
      totalHits
      violations
      violationsDelta
      totalHitsDelta
      __typename
    }
    openAccessFilesWithHits {
      totalHits
      violations
      violationsDelta
      totalHitsDelta
      __typename
    }
    staleFiles {
      totalHits
      violations
      violationsDelta
      totalHitsDelta
      __typename
    }
    staleFilesWithHits {
      totalHits
      violations
      violationsDelta
      totalHitsDelta
      __typename
    }
    openAccessStaleFiles {
      totalHits
      violations
      violationsDelta
      totalHitsDelta
      __typename
    }
    sensitiveHits {
      highRiskHits {
        totalHits
        violatedHits
        __typename
      }
      mediumRiskHits {
        totalHits
        violatedHits
        __typename
      }
      lowRiskHits {
        totalHits
        violatedHits
        __typename
      }
      noRiskHits {
        totalHits
        violatedHits
        __typename
      }
      totalHits {
        totalHits
        violatedHits
        __typename
      }
      __typename
    }
    numActivities
    numActivitiesDelta
    __typename
  }
  snappable {
    ...SnappableFragment
    __typename
  }
  __typename
}

fragment AnalyzerGroupResultFragment on AnalyzerGroupResult {
  analyzerGroup {
    groupType
    id
    name
    __typename
  }
  hits {
    totalHits
    violations
    violationsDelta
    totalHitsDelta
    __typename
  }
  __typename
}

fragment SnappableFragment on HierarchyObject {
  id
  name
  objectType
  slaAssignment
  logicalPath {
    fid
    name
    objectType
    __typename
  }
  physicalPath {
    fid
    name
    objectType
    __typename
  }
  ...EffectiveSlaColumnFragment
  ... on VsphereVm {
    cluster {
      id
      name
      __typename
    }
    __typename
  }
  ... on LinuxFileset {
    cluster {
      id
      name
      __typename
    }
    __typename
  }
  ... on ShareFileset {
    cluster {
      id
      name
      __typename
    }
    __typename
  }
  ... on WindowsFileset {
    cluster {
      id
      name
      __typename
    }
    __typename
  }
  ... on NutanixVm {
    cluster {
      id
      name
      __typename
    }
    __typename
  }
  ... on HyperVVirtualMachine {
    cluster {
      id
      name
      __typename
    }
    __typename
  }
  ... on VolumeGroup {
    cluster {
      id
      name
      __typename
    }
    __typename
  }
  ... on O365Onedrive {
    userPrincipalName
    __typename
  }
  ... on O365SharepointDrive {
    url
    __typename
  }
  ... on AzureNativeVirtualMachine {
    region
    azureResourceGroupDetails {
      azureSubscriptionDetails {
        id
        name
        __typename
      }
      __typename
    }
    __typename
  }
  ... on AzureNativeManagedDisk {
    region
    azureResourceGroupDetails {
      azureSubscriptionDetails {
        id
        name
        __typename
      }
      __typename
    }
    __typename
  }
  ... on CloudDirectNasExport {
    exportPath
    __typename
  }
  ... on CloudDirectNasShare {
    exportPath
    __typename
  }
  ... on CloudDirectHierarchyObject {
    cluster {
      id
      name
      __typename
    }
    __typename
  }
  __typename
}

fragment EffectiveSlaColumnFragment on HierarchyObject {
  id
  effectiveSlaDomain {
    ...EffectiveSlaDomainFragment
    ... on GlobalSlaReply {
      description
      __typename
    }
    __typename
  }
  ... on CdmHierarchyObject {
    pendingSla {
      ...SLADomainFragment
      __typename
    }
    __typename
  }
  ... on CloudDirectHierarchyObject {
    pendingSla {
      ...SLADomainFragment
      __typename
    }
    __typename
  }
  ... on PolarisHierarchyObject {
    rscNativeObjectPendingSla {
      ...CompactSLADomainFragment
      __typename
    }
    __typename
  }
  __typename
}

fragment EffectiveSlaDomainFragment on SlaDomain {
  id
  name
  ... on GlobalSlaReply {
    isRetentionLockedSla
    retentionLockMode
    haPolicy {
      id
      __typename
    }
    __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 CompactSLADomainFragment on CompactSlaDomain {
  id
  name
  __typename
}

fragment PolicySummaryFragment on ClassificationPolicySummary {
  id
  name
  colorEnum
  __typename
}
"""

FILE_ACCESS_QUERY = """query FileAccessQuery(
  $snappableFid: String!
  $snapshotFid: String!
  $stdPath: String!
  $filters: SddlRequestFiltersInput
  $skipResolveSids: Boolean
) {
  datagovSecDesc(
    snappableFid: $snappableFid
    snapshotFid: $snapshotFid
    stdPath: $stdPath
    filters: $filters
    skipResolveSids: $skipResolveSids
  ) {
    secInfo {
      owner
      path
      permissions {
        cn
        principalId
        principalOrigin
        idpType
        principalType
        resolutionType
        access
        flags
        accessMethodDetails {
          accessMethod
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
}
"""

FILE_DETAILS_QUERY = """query FileDetailsQuery(
  $sensitiveFileInput: SensitiveFileMetadataInput!
) {
  sensitiveFileDetails(input: $sensitiveFileInput) {
    fileMetadata {
      createdBy {
        value
        __typename
      }
      creationTime
      lastAccessTime
      lastModifiedBy {
        value
        __typename
      }
      lastModifiedTime
      lastScanTime
      path
      size
      __typename
    }
    exposureSummary {
      exposureType
      fileCount {
        totalCount
        violatedCount
        __typename
      }
      __typename
    }
    __typename
  }
}
"""


class MyClient(PolarisClient):
    """Client class."""

    def auth(self):
        """Set access token for authorization."""
        self._access_token = self.get_api_token()
        if not self._access_token:
            self._access_token = self.authenticate()
            self.set_integration_context(self._access_token)

    @staticmethod
    def set_integration_context(access_token):
        """
        Set API token and expiry time in integration configuration context.

        Will raise value error if api-token is not found.
        """
        integration_context = {}
        api_token = jwt.decode(access_token, options={"verify_signature": False})
        integration_context["api_token"] = access_token
        integration_context["valid_until"] = (
            api_token.get("exp", int(time.time()) + TOKEN_EXPIRY_TIME_SPAN) - TOKEN_EXPIRY_BUFFER_TIME
        )
        set_integration_context(integration_context)

    @staticmethod
    def get_api_token() -> Any:
        """
        Retrieve API token from integration context.

        If API token is not found or expired it will return false
        """
        integration_context = get_integration_context()
        api_token = integration_context.get("api_token")
        valid_until = integration_context.get("valid_until")

        # Return API token from integration context, if found and not expired
        if api_token and valid_until and time.time() < valid_until:
            demisto.debug("[RubrikPolaris] Retrieved api-token from integration cache.")
            return api_token
        return False


""" HELPER FUNCTIONS """


def validate_required_arg(param_name, param_value):
    """
    Validate the required param is provided or not.

    Args:
        param_name: Name of the parameter to be validated
        param_value: Value of the required parameter

    Raises:
        ValueError if not provided
    Returns:
          Value of parameter
    """
    if not param_value:
        raise ValueError(ERROR_MESSAGES["MISSING_REQUIRED_FIELD"].format(param_name))
    else:
        return param_value


def convert_to_demisto_severity(severity: str = "XSOAR LOW") -> int:
    """
    Map the severity from the Rubrik Radar event to the user specified XSOAR severity level.

    :type severity: ``str``
    :param severity: XSOAR severity to map to

    :return: mapped incident severity level
    """
    demisto.info("SEVERITY TO CONVERT IS: " + severity)
    try:
        return {
            "XSOAR LOW": IncidentSeverity.LOW,
            "XSOAR MEDIUM": IncidentSeverity.MEDIUM,
            "XSOAR HIGH": IncidentSeverity.HIGH,
            "XSOAR CRITICAL": IncidentSeverity.CRITICAL,
        }[severity]
    except KeyError:
        raise ValueError(ERROR_MESSAGES["FETCH_PARAM_REQUIRED"].format("Event Critical Severity Level Mapping"))


def convert_severity_to_incident_severity(severity: str) -> int:
    """
    Map the severity level to XSOAR incident severity level.

    :type severity: ``str``
    :param severity: Severity level (CRITICAL, HIGH, MEDIUM, LOW)

    :return: mapped incident severity level
    :rtype: ``int``
    """
    return {
        "CRITICAL": IncidentSeverity.CRITICAL,
        "HIGH": IncidentSeverity.HIGH,
        "MEDIUM": IncidentSeverity.MEDIUM,
        "LOW": IncidentSeverity.LOW,
    }.get(severity.upper(), IncidentSeverity.UNKNOWN)


def process_activity_nodes(activity_nodes: list, processed_incident):
    """
    Update processed incident data.

    :param activity_nodes: List of activity connection nodes
    :type activity_nodes: list

    :param processed_incident: the processed incident with event details
    :type processed_incident: dict

    :return: updated processed incident
    """
    for activity_node in activity_nodes:
        # Convert time to friendly display format
        display_time = datetime.strptime(activity_node.get("time", ""), DATE_TIME_FORMAT)
        stringified_display_time = display_time.strftime(HUMAN_READABLE_DATE_TIME_FORMAT)

        processed_incident["message"].append(  # type: ignore
            {
                "message": activity_node.get("message", ""),
                "id": activity_node.get("id", ""),
                "severity": activity_node.get("severity", ""),
                "time": stringified_display_time,
            }
        )

        file_changes_match = re.search(
            r"File Change: ([0-9]+) Added, ([0-9]+) Modified, ([0-9]+) Removed", activity_node.get("message", "")
        )
        if file_changes_match is not None:
            try:
                processed_incident["radar_files_added"] = file_changes_match.group(1)
                processed_incident["radar_files_modified"] = file_changes_match.group(2)
                processed_incident["radar_files_deleted"] = file_changes_match.group(3)

            except KeyError:
                demisto.info("Error Parsing Radar Anomaly File Change attributes")

    return processed_incident


def calc_pages(total_count: int, per_page_count: int) -> int:
    """
    Calculates the number of pages required to display all the items,
    considering the number of items to be displayed per page

    Args:
        total_count (int): The total number of items.
        per_page_count (int): The count of items per page.

    Returns:
        int: The total number of pages.
    """
    return math.ceil(total_count / per_page_count)


def prepare_context_hr_object_search(response: dict):
    """
    Prepare context output and human readable response for rubrik-polaris-object-search command.

    :type response: ``dict``
    :param response: edges from the response received from the API

    :return: context output and human readable for the command
    """
    hr = []
    context = []
    for node in response:
        cluster_name = sla_domain_name = ""
        node = node.get("node", {})
        context.append(remove_empty_elements(node))

        if node.get("cluster"):
            cluster_name = node.get("cluster", {}).get("name", "")
        if node.get("effectiveSlaDomain"):
            sla_domain_name = node.get("effectiveSlaDomain", {}).get("name", "")

        hr.append(
            {
                OBJECT_ID: node.get("id", ""),
                OBJECT_NAME: node.get("name", ""),
                "Cluster": cluster_name,
                "Type": node.get("objectType", ""),
                SLA_DOMAIN: sla_domain_name,
            }
        )
    return context, hr


def prepare_context_hr_sonar_policies(nodes: list):
    """
    Prepare context output and human readable response for rubrik-sonar-policies-list command.

    :type nodes: ``dict``
    :param nodes: nodes from the response received from the API

    :return: context output and human readable for the command
    """
    hr_content = []
    nodes = remove_empty_elements(nodes)
    for node in nodes:
        hr_content.append(
            {
                "ID": node.get("id", ""),
                "Name": node.get("name", ""),
                "Description": node.get("description", ""),
                "Analyzers": node.get("numAnalyzers"),
                "Objects": node.get("totalObjects"),
                "Creator Email": node.get("creator", {}).get("email", ""),
            }
        )
    hr_headers = ["ID", "Name", "Description", "Analyzers", "Objects", "Creator Email"]
    hr = tableToMarkdown("Sonar Policies", hr_content, hr_headers, removeNull=True)
    return nodes, hr


def prepare_context_hr_sonar_policy_analyzer_groups(nodes: list):
    """
    Prepare context output and human readable response for rubrik-sonar-policy-analyzer-groups-list command.

    :type nodes: ``dict``
    :param nodes: nodes from the response received from the API

    :return: context output and human readable for the command
    """
    hr_content = []
    nodes = remove_empty_elements(nodes)

    def stringify_analyzer(analyzer_id, analyzer_name, analyzer_type):
        """Convert analyzer response into human readable string."""
        return f"id: {analyzer_id}, Name: {analyzer_name}, Analyzer Type: {analyzer_type}"

    for node in nodes:
        analyzers = node.get("analyzers", [])

        analyzers_str_rep = "\n\n".join(
            [
                stringify_analyzer(analyzer.get("id", "n/a"), analyzer.get("name", "n/a"), analyzer.get("analyzerType", "n/a"))
                for analyzer in analyzers
            ]
        )
        hr_content.append(
            {
                "ID": node.get("id", ""),
                "Name": node.get("name", ""),
                "Group Type": node.get("groupType", ""),
                "Analyzers": analyzers_str_rep,
            }
        )
    hr_headers = ["ID", "Name", "Group Type", "Analyzers"]
    hr = tableToMarkdown("Sonar Policy Analyzer Groups", hr_content, hr_headers, removeNull=True)
    return nodes, hr


def prepare_context_hr_vm_object_metadata(response: dict):
    """
    Prepare context and hr for rubrik-polaris-vm-object-metadata-get.

    :type response: ``dict``
    :param response: Response received from API

    :return: context output and human readable for the command
    """
    hr = []
    response = remove_empty_elements(response)
    object_id = response.get("id")
    context = {"id": object_id, "metadata": response}
    del context["metadata"]["id"]

    hr.append(
        {
            OBJECT_ID: object_id,
            "Name": response.get("name", ""),
            SNAPPABLE_ID: response.get("reportSnappable", {}).get("id"),
            SLA_DOMAIN: response.get("effectiveSlaDomain", {}).get("name", ""),
            CLUSTER_NAME: response.get("cluster", {}).get("name", ""),
            "Total Snapshots": response.get("totalSnapshots", {}).get("count", ""),
            "Oldest Snapshot Date": response.get("oldestSnapshot", {}).get("date", ""),
            "Latest Snapshot Date": response.get("newestSnapshot", {}).get("date", ""),
        }
    )

    return context, hr


def prepare_context_hr_vm_object_list(response: dict):
    """
    Prepare context output and human readable response for rubrik-polaris-vm-object-list command.

    :type response: ``dict``
    :param response: edges from the response received from the API

    :return: context output and human readable for the command
    """
    hr = []
    context = []
    for edge in response:
        node = edge.get("node")
        hr.append(
            {
                OBJECT_ID: node.get("id", ""),
                "Name": node.get("name", ""),
                SNAPPABLE_ID: node.get("reportSnappable", {}).get("id") if node.get("reportSnappable") else None,
                "Cluster": node.get("cluster", {}).get("name", "") if node.get("cluster") else None,
                OBJECT_TYPE: node.get("objectType", ""),
                SLA_DOMAIN: node.get("effectiveSlaDomain", {}).get("name", "") if node.get("effectiveSlaDomain") else None,
                "Assignment": node.get("slaAssignment", ""),
                "Snapshots": node.get("snapshotDistribution", {}).get("totalCount", "")
                if node.get("snapshotDistribution")
                else None,
                "RBS Status": node.get("agentStatus", {}).get("agentStatus", "") if node.get("agentStatus") else None,
                "Source Storage": convert_bytes(
                    node.get("reportSnappable", {}).get("archiveStorage", "")
                    if node.get("reportSnappable")  # type: ignore[arg-type]
                    else None
                ),
                "Archival Storage": convert_bytes(
                    node.get("reportSnappable", {}).get("physicalBytes", "")
                    if node.get("reportSnappable")  # type: ignore[arg-type]
                    else None
                ),
            }
        )
        context.append(remove_empty_elements(node))
    return context, hr


def convert_bytes(bytes_val: int):
    """
    Convert bytes to mega/giga/tera bytes.

    :type bytes_val: ``int``
    :param bytes_val: Bytes to convert

    :return: Converted value
    """
    if bytes_val is None:
        return None
    elif bytes_val == 0:
        return 0
    elif bytes_val > 0:

        def count_digit(val):
            count = 0
            while val != 0:
                val //= 10
                count += 1
            return count

        if count_digit(bytes_val) >= 12:
            return f"{bytes_val / (10**12)} TB"
        elif count_digit(bytes_val) >= 9:
            return f"{bytes_val / (10**9)} GB"
        elif count_digit(bytes_val) >= 6:
            return f"{bytes_val / (10**6)} MB"
        elif count_digit(bytes_val) >= 3:
            return f"{bytes_val / (10**3)} KB"
        else:
            return f"{bytes_val} B"
    return None


def prepare_context_hr_sonar_ondemand_scan_status(nodes: list, crawl_id: str):
    """
    Prepare context output and human readable response for rubrik-sonar-ondemand-scan-status command.

    :type nodes: ``dict``
    :param nodes: nodes from the response received from the API

    :type crawl_id: ``str``
    :param crawl_id: crawl_id received in response

    :return: context output and human readable for the command
    """
    hr_content = []
    nodes = remove_empty_elements(nodes)
    context = {"crawlId": crawl_id, "Status": nodes}
    final_status = None
    for object_scan in context["Status"]:
        object_scan_status = object_scan.get("status")
        hr_content.append(
            {
                OBJECT_ID: object_scan.get("snappable", {}).get("id", ""),
                OBJECT_NAME: object_scan.get("snappable", {}).get("name", ""),
                "Scan Status": object_scan_status,
            }
        )
        if not final_status and object_scan_status == "IN_PROGRESS":
            final_status = "IN_PROGRESS"
        if object_scan_status == "FAIL":
            final_status = "FAIL"
    if not final_status:
        final_status = "COMPLETE"

    hr_header = f"### Sonar On-Demand Scan Status\nFinal status of scan with crawl ID {crawl_id} is {final_status}\n\n"
    hr_table = tableToMarkdown("", hr_content, [OBJECT_ID, OBJECT_NAME, "Scan Status"], removeNull=True)
    return context, hr_header + hr_table


def prepare_context_hr_vm_object_snapshot(response: dict):
    """
    Prepare context and hr for rubrik-polaris-vm-object-snapshot-list.

    :type response: ``dict``
    :param response: Response received from API

    :return: context output and human readable for the command
    """
    hr = []
    if response.get("missedSnapshotGroupByConnection"):
        del response["missedSnapshotGroupByConnection"]
    response = remove_empty_elements(response)
    object_id = response.get("id")
    context = {"id": object_id, "Snapshot": response}
    del context["Snapshot"]["id"]

    if response.get("snapshotGroupByConnection", {}).get("nodes"):
        nodes = response.get("snapshotGroupByConnection", {}).get("nodes")
        for node in nodes:
            sub_nodes = node.get("snapshotConnection", {}).get("nodes") if node.get("snapshotConnection") else None
            hr_data = {
                "Snapshot Details": f"Total Snapshots: {node.get('snapshotConnection').get('count')}"
                f"\nDate Range: From {node.get('groupByInfo').get('start')} to"
                f" {node.get('groupByInfo').get('end')}",
                SNAPSHOT_IDS: [],
            }
            ids = []
            for sub_node in sub_nodes:  # type: ignore[union-attr]
                ids.append(sub_node.get("id"))
            hr_data[SNAPSHOT_IDS] = ids
            hr.append(hr_data)

    return context, hr


def prepare_context_hr_gps_snapshot_files(edges: list, snapshot_id: str):
    """
    Prepare context output and human readable response for rubrik_gps_snapshot_files_list_command.

    :type edges: ``dict``
    :param edges: Response received from API

    :type snapshot_id: ``str``
    :param snapshot_id: snapshot_id passed as input

    :return: context output and human readable for the command
    """
    context = []
    hr_content = []

    edges = remove_empty_elements(edges)

    for edge in edges:
        node = edge.get("node")
        hr_content.append(
            {
                "File Name": node.get("filename", ""),
                "Absolute Path": node.get("absolutePath", ""),
                "Path": node.get("path", ""),
                "File Mode": node.get("fileMode", ""),
                "Last Modified": node.get("lastModified", ""),
            }
        )
        context.append(node)

    context_data = {"snapshotId": snapshot_id.lower(), "node": context}

    hr = tableToMarkdown(
        "GPS Snapshot Files", hr_content, ["File Name", "Absolute Path", "Path", "File Mode", "Last Modified"], removeNull=True
    )
    return context_data, hr


def validate_boolean_argument(arg_value: Union[str, bool], arg_name: str):
    """
    To validate boolean argument for all commands.

    :param arg_value: the value to evaluate
    :type arg_value: ``string|bool``

    :param arg_name: Argument name
    :type arg_name: ``string``

    :return: a boolean representatation of 'arg_value'
    """
    try:
        result = argToBoolean(arg_value)
    except ValueError:
        raise ValueError(ERROR_MESSAGES["INVALID_BOOLEAN"].format(arg_value, arg_name))

    return result


def validate_vm_export_args(args: Dict[str, Any]):
    """
    To validate arguments of rubrik-gps-vm-export.

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: Validated arguments for rubrik-gps-vm-export
    """
    vm_name = args.get("vm_name")
    object_id = validate_required_arg("object_id", args.get("object_id", ""))
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id", ""))
    datastore_id = validate_required_arg("datastore_id", args.get("datastore_id", ""))
    host_id = args.get("host_id", None)
    host_compute_cluster_id = args.get("host_compute_cluster_id", None)

    if not host_id and not host_compute_cluster_id:
        raise ValueError(ERROR_MESSAGES["MISSING_EXPORT_DESTINATION"])
    power_on = args.get("power_on")
    if power_on:
        power_on = validate_boolean_argument(power_on, "power_on")

    keep_mac_addresses = args.get("keep_mac_addresses")
    if keep_mac_addresses:
        keep_mac_addresses = validate_boolean_argument(keep_mac_addresses, "keep_mac_addresses")

    remove_network_devices = args.get("remove_network_devices")
    if remove_network_devices:
        remove_network_devices = validate_boolean_argument(remove_network_devices, "remove_network_devices")

    recover_tags = args.get("recover_tags")
    if recover_tags:
        recover_tags = validate_boolean_argument(recover_tags, "recover_tags")

    disable_network = args.get("disable_network")
    if disable_network:
        disable_network = validate_boolean_argument(disable_network, "disable_network")

    config = {
        "datastoreId": datastore_id,
        "hostId": host_id,
        "clusterId": host_compute_cluster_id,
        "shouldRecoverTags": recover_tags,
        "mountExportSnapshotJobCommonOptionsV2": {
            "keepMacAddresses": keep_mac_addresses,
            "removeNetworkDevices": remove_network_devices,
            "vmName": vm_name,
            "powerOn": power_on,
            "disableNetwork": disable_network,
        },
        "requiredRecoveryParameters": {"snapshotId": snapshot_id},
    }

    return remove_empty_elements(config), object_id


def validate_user_access_list_command_args(limit: int, sort_order: str, page_number: Optional[int] = 1):
    """
    To validate arguments of rubrik-sonar-user-access-list.

    :type limit: ``int``
    :param limit: Number of records to return.

    :type sort_order: ``str``
    :param sort_order: Sort order argument.

    :type page_number: ``Optional[int]``
    :param page_number: Page number argument.
    """
    # Validate limit argument.
    if not limit or not 0 <= limit <= MAXIMUM_PAGINATION_LIMIT:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    # Validate sort_order argument.
    if sort_order not in (ASCENDING_SORT_ORDER, DESCENDING_SORT_ORDER):
        raise ValueError(ERROR_MESSAGES["INVALID_SORT_ORDER"].format(sort_order))

    # Validate page number if supplied.
    if isinstance(page_number, int) and page_number < 1:
        raise ValueError(ERROR_MESSAGES["INVALID_PAGE"].format(page_number))


def prepare_context_hr_user_downloads(nodes: list):
    """
    Prepare context output and human readable response for rubrik-user-downloads-get command.

    :type nodes: ``dict``
    :param nodes: nodes from the response received from the API

    :return: context output and human readable for the command
    """
    hr_content = []
    nodes = remove_empty_elements(nodes)
    for node in nodes:
        hr_content.append(
            {
                "Download ID": node.get("id", ""),
                "Name": node.get("name", ""),
                "Status": node.get("status", ""),
                "Identifier": node.get("identifier", ""),
                "Creation Time": node.get("createTime", ""),
                "Completion Time": node.get("completeTime", ""),
            }
        )
    return nodes, hr_content


def prepare_context_hr_sla_domains_list(nodes):
    """
    Prepare context output and human readable response for rubrik-sonar-policies-list command.

    :type nodes: ``dict``
    :param nodes: nodes from the response received from the API

    :return: context output and human readable for the command
    """
    nodes = remove_empty_elements(nodes)
    hr_content = []
    context = []
    for node in nodes:
        context.append(node)
        base_frequency = node.get("baseFrequency", {})
        replication_specs = node.get("replicationSpecsV2", [])
        replication_target_1 = ""
        replication_target_2 = ""
        if replication_specs and isinstance(replication_specs, list):
            replication_target_1 = replication_specs[0].get("cluster", {}).get("name", "")
            if len(replication_specs) > 1:
                replication_target_2 = replication_specs[1].get("cluster", {}).get("name", "")

        hr_content.append(
            {
                "SLA Domain ID": node.get("id", ""),
                SLA_DOMAIN_NAME: node.get("name", ""),
                "Base Frequency": f"{base_frequency.get('duration')} {base_frequency.get('unit', '').capitalize()}",
                "Protected Object Count": node.get("protectedObjectCount"),
                "Archival Location": node.get("archivalSpec", {}).get("archivalLocationName"),
                "Description": node.get("description", ""),
                "Replication Target 1": replication_target_1,
                "Replication Target 2": replication_target_2,
            }
        )
    hr = tableToMarkdown(
        "GPS SLA Domains",
        hr_content,
        headers=[
            "SLA Domain ID",
            SLA_DOMAIN_NAME,
            "Base Frequency",
            "Protected Object Count",
            "Archival Location",
            "Description",
            "Replication Target 1",
            "Replication Target 2",
        ],
        removeNull=True,
    )
    return context, hr


def prepare_context_hr_gps_snapshot_download(response: dict):
    """
    Prepare context and hr for rubrik-polaris-gps-snapshot-files-download.

    :type response: ``dict``
    :param response: Response received from API

    :return: context output and human readable for the command
    """
    response = remove_empty_elements(response)
    id_ = response.get("id")
    status = response.get("status")
    href = response.get("links")[0].get("href")
    rel = response.get("links")[0].get("rel")

    context = {"id": id_, "status": status, "links": {"href": href, "rel": rel}}

    hr = {"ID": id_, "Status": status}
    return context, hr


def prepare_context_hr_vm_host_list(edges):
    """
    Prepare context output and human readable response for rubrik-gps-vm-host-list command.

    :type edges: ``dict``
    :param edges: edges from the response received from the API

    :return: context output and human readable for the command
    """
    edges = remove_empty_elements(edges)
    hr_content = []
    context = []
    for edge in edges:
        node = edge.get("node")
        physical_host = []
        context.append(node)
        for path in node.get("physicalPath"):
            physical_host.append({"id": path.get("fid"), "name": path.get("name"), "objectType": path.get("objectType")})
        hr_content.append({"VSphere Host ID": node.get("id"), "Name": node.get("name"), "Physical Host": physical_host})
    return context, hr_content


def prepare_context_hr_vm_datastore_list(edges, host_id):
    """
    Prepare context output and human readable response for rubrik-gps-vm-datastore-list command.

    :type edges: ``dict``
    :param edges: edges from the response received from the API

    :type host_id: ``str``
    :param host_id: Host ID that was queried for.

    :return: context output and human readable for the command
    """
    edges = remove_empty_elements(edges)
    hr_content = []
    context = {"id": host_id, "Datastore": []}
    for edge in edges:
        node = edge.get("node")
        context["Datastore"].append(node)
        hr_content.append(
            {
                "VSphere Datastore ID": node.get("id", ""),
                "Name": node.get("name", ""),
                "Capacity": convert_bytes(node.get("capacity", "")),
                FREE_SPACE: convert_bytes(node.get("freeSpace")),
                "Datastore Type": node.get("datastoreType", ""),
            }
        )
    hr = tableToMarkdown(
        "GPS VM Datastores",
        hr_content,
        headers=["VSphere Datastore ID", "Name", "Capacity", FREE_SPACE, "Datastore Type"],
        removeNull=True,
    )
    return context, hr


def prepare_context_hr_radar_analysis_status(activity_series: dict, activity_series_id: str, cluster_id: str):
    """
    Prepare context output and human readable response for rubrik-radar-analysis-status command.

    :type activity_series: ``dict``
    :param activity_series: activity_series from the response received from the API

    :type activity_series_id: ``dict``
    :param activity_series_id: activity_series_id received from user

    :type cluster_id: ``dict``
    :param cluster_id: cluster_id received from user

    :return: context output and human readable for the command
    """
    messages = []
    nodes = activity_series["activityConnection"]["nodes"]
    for node in nodes:
        messages.append(remove_empty_elements(node))

    context = {
        "ActivitySeriesId": activity_series_id.lower(),
        "ClusterId": cluster_id,
        "Message": messages,
        "EventComplete": "True" if activity_series.get("lastActivityStatus") == "Success" else "False",
    }
    hr_content = {
        ACTIVITY_SERIES_ID: activity_series_id.lower(),
        CLUSTER_ID: cluster_id,
        "Message": messages[0].get("message", ""),
        "Event Complete": "True" if activity_series.get("lastActivityStatus") == "Success" else "False",
    }
    hr_headers = [ACTIVITY_SERIES_ID, CLUSTER_ID, "Message", "Event Complete"]
    hr = tableToMarkdown("Radar Analysis Status", hr_content, hr_headers, removeNull=True)
    return context, hr


def prepare_context_hr_event_list(edges):
    """
    Prepare context output and human readable response for rubrik-event-list command.

    :type edges: ``list``
    :param edges: edges from the response received from the API

    :return: context output and human readable for the command
    """
    hr_content = []
    context = []
    for edge in edges:
        node = edge.get("node")
        node = remove_empty_elements(node)
        context.append(node)
        hr_content.append(
            {
                "Event ID": node.get("id", ""),
                ACTIVITY_SERIES_ID: node.get("activitySeriesId", ""),
                CLUSTER_ID: node.get("cluster", "").get("id", ""),
                OBJECT_ID: node.get("objectId", ""),
                OBJECT_NAME: node.get("objectName", ""),
                "Severity": node.get("severity", ""),
                "Progress": node.get("progress", ""),
                START_TIME: node.get("startTime", ""),
                "Last Updated": node.get("lastUpdated", ""),
                "Last Activity Type": node.get("lastActivityType", ""),
                "Last Activity Status": node.get("lastActivityStatus", ""),
            }
        )
    hr = tableToMarkdown(
        "Events",
        hr_content,
        headers=[
            "Event ID",
            ACTIVITY_SERIES_ID,
            CLUSTER_ID,
            OBJECT_ID,
            OBJECT_NAME,
            "Severity",
            "Progress",
            START_TIME,
            "Last Updated",
            "Last Activity Type",
            "Last Activity Status",
        ],
        removeNull=True,
    )
    return context, hr


def prepare_context_hr_sonar_sensitive_hits(response):
    """
    Prepare context output and human readable response for rubrik-sonar-sensitive-hits command.

    :type response: ``dict``
    :param response: The response received from the API

    :return: context output and human readable for the command
    """
    hr = []
    context = []
    policy_hits = {}  # type: ignore
    for data in response.get("rootFileResult", {}).get("analyzerGroupResults", []):
        policy_name = data.get("analyzerGroup", {}).get("name", "")
        policy_hits[policy_name] = {}

        for analyzer in data.get("analyzerResults", []):
            analyzer_name = analyzer.get("analyzer", {}).get("name", "")
            analyzer_hits = str(analyzer.get("hits", {}).get("totalHits", ""))
            policy_hits[policy_name][analyzer_name] = analyzer_hits

    root = response.get("rootFileResult")
    context.append(
        remove_empty_elements(
            {
                "id": response.get("id", ""),
                "totalHits": root.get("hits", {}).get("totalHits", ""),
                "policy_hits": policy_hits,
                "filesWithHits": root.get("filesWithHits", {}).get("totalHits", ""),
                "openAccessFiles": root.get("openAccessFiles", {}).get("totalHits", ""),
                "openAccessFolders": root.get("openAccessFolders", {}).get("totalHits", ""),
                "openAccessFilesWithHits": root.get("openAccessFilesWithHits", {}).get("totalHits", ""),
                "staleFiles": root.get("staleFiles", {}).get("totalHits", ""),
                "staleFilesWithHits": root.get("staleFilesWithHits", {}).get("totalHits", ""),
                "openAccessStaleFiles": root.get("openAccessStaleFiles", {}).get("totalHits", ""),
            }
        )
    )

    hr.append({"ID": context[0].get("id"), "Total Hits": context[0].get("totalHits")})
    return context, hr


def prepare_context_hr_object_snapshot_list(edges, object_id):
    """
    Prepare context output and human readable response for rubrik-polaris-object-snapshot-list command.

    :type object_id: ``str``
    :param object_id: ObjectID to get snapshots of.
    :type edges: ``list``
    :param edges: edges from the response received from the API

    :return: context output and human readable for the command
    """
    hr_content = []
    context = {"id": object_id, "Snapshot": []}
    for edge in edges:
        node = edge.get("node")
        context["Snapshot"].append(remove_empty_elements(node))
        hr_content.append(
            {
                SNAPSHOT_ID: node.get("id"),
                "Creation Date": node.get("date"),
                CLUSTER_NAME: node.get("cluster", {}).get("name"),
                SLA_DOMAIN_NAME: node.get("slaDomain", {}).get("name"),
            }
        )
    hr = tableToMarkdown(
        "Object Snapshots", hr_content, headers=[SNAPSHOT_ID, "Creation Date", CLUSTER_NAME, SLA_DOMAIN_NAME], removeNull=True
    )
    return context, hr


def prepare_context_hr_object_list(edges):
    """
    Prepare context output and human readable response for rubrik-polaris-object-list command.

    :type edges: ``list``
    :param edges: edges from the response received from the API

    :return: context output and human readable for the command
    """
    hr_content = []
    context = []
    for edge in edges:
        node = edge.get("node")
        node = remove_empty_elements(node)
        context.append(node)
        logical_path_names = []
        location = ""
        for path in node.get("logicalPath", []):
            logical_path_names.append(path.get("name"))
        for name in logical_path_names:
            if location:
                location = name + "\\" + location
            else:
                location = name
        hr_content.append(
            {
                OBJECT_ID: node.get("id"),
                OBJECT_NAME: node.get("name"),
                OBJECT_TYPE: node.get("objectType"),
                "Location": location,
                CLUSTER_NAME: node.get("cluster", {}).get("name"),
                SLA_DOMAIN_NAME: node.get("effectiveSlaDomain", {}).get("name"),
            }
        )
    hr = tableToMarkdown(
        "Objects",
        hr_content,
        headers=[OBJECT_ID, OBJECT_NAME, OBJECT_TYPE, "Location", CLUSTER_NAME, SLA_DOMAIN_NAME],
        removeNull=True,
    )
    return context, hr


def prepare_context_hr_async_result(response, request_id, ip_address):
    """
    Prepare context output and human readable response for rubrik-gps-async-result command.

    :type ip_address: str
    :param ip_address: IP Address to append with hyperlink

    :type: request_id: str
    :param request_id: Request ID to get results

    :type response: ``dict``
    :param response: The response received from the API

    :return: context output and human readable for the command
    """
    context = remove_empty_elements(response)
    hyper_link = ""
    for data in response.get("links"):
        link = data.get("href", "")
        rel = data.get("rel", "")
        if "DOWNLOAD_SNAPPABLE_FILE" in request_id and response.get("status") == "SUCCEEDED" and rel == "result":
            link = urljoin(f"https://{ip_address}", link)  # noqa: E231
        hyper_link += f"[{rel}]({urllib3.util.parse_url(link)})\n"
    hr = {"ID": response.get("id"), "Status": response.get("status"), "Node ID": response.get("nodeId"), "Links": hyper_link}

    readable_output = tableToMarkdown(
        name="GPS Asynchronous Request Result", t=hr, headers=["ID", "Status", "Node ID", "Links"], removeNull=True
    )
    return context, readable_output


def prepare_advance_ioc(advance_ioc, ioc):
    """
    Prepare formatted advance IOC.

    :param ioc: ioc value
    :param advance_ioc: unformatted advance ioc
    :return: formatted advance ioc
    """
    if advance_ioc:
        if not isinstance(advance_ioc, dict):
            raise ValueError(ERROR_MESSAGES["INVALID_FORMAT"].format("advance_ioc"))
        ioc = []
        for advance_ioc_key, advance_ioc_value in advance_ioc.items():
            if not isinstance(advance_ioc_value, list):
                advance_ioc_value = [advance_ioc_value]
            ioc.extend([{"iocType": str(advance_ioc_key).strip(), "iocValue": value} for value in advance_ioc_value])

    return ioc


def validate_ioc_scan_args(args: Dict[str, Any]) -> dict:
    """
    To validate arguments of rubrik-radar-ioc-scan.

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: Validated arguments for rubrik-radar-ioc-scan
    """
    cluster_id = validate_required_arg("cluster_id", args.get("cluster_id"))
    object_id = argToList(validate_required_arg("object_id", args.get("object_id")))

    scan_name = args.get("scan_name", DEFAULT_REQUEST_NAME)
    ioc_type = args.get("ioc_type")
    ioc_value = args.get("ioc_value")
    advance_ioc = args.get("advance_ioc")

    start_date = args.get("start_date")
    end_date = args.get("end_date")
    max_snapshots_per_object = arg_to_number(args.get("max_snapshots_per_object"), "max_snapshots_per_object")
    snapshot_id = argToList(args.get("snapshot_id"), ":")

    paths_to_include = argToList(args.get("paths_to_include"))
    paths_to_exclude = argToList(args.get("paths_to_exclude"))
    paths_to_exempt = argToList(args.get("paths_to_exempt"))
    requested_hash_types = argToList(args.get("requested_hash_types"))

    ioc = []
    if ioc_type:
        if ioc_type not in IOC_TYPE_ENUM:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(ioc_type, "ioc_type", IOC_TYPE_ENUM))
        ioc.append({"iocType": ioc_type, "iocValue": ioc_value})
    if advance_ioc:
        try:
            advance_ioc = json.loads(advance_ioc)
        except json.JSONDecodeError:
            raise ValueError(ERROR_MESSAGES["JSON_DECODE"].format("advance_ioc"))

    if not ioc and not advance_ioc:
        raise ValueError(ERROR_MESSAGES["NO_INDICATOR_SPECIFIED"])

    ioc = prepare_advance_ioc(advance_ioc, ioc)
    snapshot_scan_limit = {}
    if start_date:
        start_date_ob = arg_to_datetime(validate_required_arg("start_date", args.get("start_date")), "start_date")
        snapshot_scan_limit["startTime"] = start_date_ob.strftime(DATE_TIME_FORMAT)  # type: ignore
    if end_date:
        end_date_ob = arg_to_datetime(validate_required_arg("end_date", args.get("end_date")), "end_date")
        snapshot_scan_limit["endTime"] = end_date_ob.strftime(DATE_TIME_FORMAT)  # type: ignore
    if max_snapshots_per_object:
        snapshot_scan_limit["maxSnapshotsPerObject"] = max_snapshots_per_object
    if snapshot_id:
        if len(snapshot_id) != len(object_id):
            raise ValueError(ERROR_MESSAGES["LEN_SNAPSHOT_NE_LEN_OBJECT"])
        snapshot_scan_limit["snapshotsToScanPerObject"] = [
            {"id": object_id[i], "snapshots": argToList(snapshot_id[i])} for i in range(len(snapshot_id))
        ]

    max_matches_per_snapshot = MAX_MATCHES_PER_OBJECT
    max_file_size = arg_to_number(args.get("max_file_size", MAXIMUM_FILE_SIZE), "max_file_size")
    return {
        "object_ids": object_id,
        "cluster_id": cluster_id,
        "indicators_of_compromise": ioc,
        "scan_name": scan_name,
        "snapshot_scan_limit": snapshot_scan_limit,
        "max_matches_per_snapshot": max_matches_per_snapshot,
        "path_to_include": paths_to_include,
        "path_to_exclude": paths_to_exclude,
        "path_to_exempt": paths_to_exempt,
        "maximum_file_size_to_scan": max_file_size,
        "requested_hash_types": requested_hash_types,
    }


def prepare_context_hr_radar_ioc_scan_results(data: dict):
    """
    Prepare context output and human readable response for rubrik-radar-ioc-scan-results command.

    :type data: ``dict``
    :param data: The data in response received from the API

    :return: context output and human readable for the command
    """
    outputs = remove_empty_elements(data)
    hr_content = []
    results = outputs.get("results", [])
    scan_status = "FINISHED"

    for result in results:
        object_id = result.get("objectId")
        for snapshot_result in result.get("snapshotResults", []):
            status = snapshot_result.get("status", "")
            if status == "MALWARE_SCAN_IN_SNAPSHOT_STATUS_ERROR":
                scan_status = "ERROR"
            if status == "MALWARE_SCAN_IN_SNAPSHOT_STATUS_PENDING" and scan_status != "ERROR":
                scan_status = "RUNNING"
            if not status and scan_status != "ERROR":
                scan_status = "UNKNOWN"

            scan_stats = snapshot_result.get("scanStats")
            scan_statistics = (
                f"Number of Files: {scan_stats.get('numFiles')}, "
                f"Number of Files Scanned: {scan_stats.get('numFilesScanned')}, "
                f"Total Files Scanned In Bytes: {scan_stats.get('totalFilesScannedSizeBytes')}"
            )
            hr_content.append(
                {
                    SNAPSHOT_ID: snapshot_result.get("snapshotId"),
                    "Snapshot Date": snapshot_result.get("snapshotDate"),
                    OBJECT_ID: object_id,
                    "Snapshot Scan Status": status,
                    "Scan Statistics": scan_statistics,
                    "Matches": len(snapshot_result.get("matches", [])),
                }
            )

    table_name = "Radar IOC Scan Results"
    metadata = f"Scan ID: {outputs.get('id')}\nStatus: {scan_status}"
    outputs["status"] = scan_status
    headers = [SNAPSHOT_ID, "Snapshot Date", OBJECT_ID, "Snapshot Scan Status", "Scan Statistics", "Matches"]
    readable_output = tableToMarkdown(table_name, hr_content, metadata=metadata, headers=headers, removeNull=True)

    return outputs, readable_output


def prepare_context_hr_cluster_list(nodes):
    """
    Prepare context output and human readable response for rubrik-gps-cluster-list command.

    :type nodes: ``list``
    :param nodes: nodes from the response received from the API

    :return: context output and human readable for the command
    """
    hr_content = []
    context = []
    for node in nodes:
        node = remove_empty_elements(node)
        context.append(node)
        ip_addresses = []
        for cluster_node in node.get("clusterNodeConnection", {}).get("nodes", []):
            ip_addresses.append(cluster_node.get("ipAddress"))
        hr_content.append(
            {
                CLUSTER_ID: node.get("id"),
                CLUSTER_NAME: node.get("name"),
                "Connection Status": node.get("status"),
                "Cluster Location": node.get("geoLocation", {}).get("address"),
                "Total Capacity": convert_bytes(node.get("metric", {}).get("totalCapacity")),
                FREE_SPACE: convert_bytes(node.get("metric", {}).get("availableCapacity")),
                "Protected Objects": node.get("snappableConnection", {}).get("count"),
                "Cluster Version": node.get("version"),
                "IP Address": ", ".join(ip_addresses),
            }
        )
    hr = tableToMarkdown(
        "GPS Clusters",
        hr_content,
        headers=[
            CLUSTER_ID,
            CLUSTER_NAME,
            "Connection Status",
            "Cluster Location",
            "Total Capacity",
            FREE_SPACE,
            "Protected Objects",
            "Cluster Version",
            "IP Address",
        ],
        removeNull=True,
    )
    return context, hr


def prepare_context_hr_ioc_scan_list(data: list):
    """
    Prepare the context output and human readable response for rubrik-radar-ioc-scan-list command.

    :type data: ``dict``
    :param data: data from response received from the API

    :return: context output and human readable for the command
    """
    hr_content = []
    for scan in data:
        hr_content.append(
            {
                SCAN_ID: scan.get("id", ""),
                START_TIME: scan.get("startTime", ""),
                "End Time": "Not Finished" if scan.get("endTime") is None else scan.get("endTime", ""),
                "Scanned Objects": ", ".join(
                    [snapshot.get("id", "") for snapshot in scan.get("snapshots", []) if isinstance(snapshot, dict)]
                ),
            }
        )
    hr = tableToMarkdown(
        "Radar IOC Scans", hr_content, headers=[SCAN_ID, START_TIME, "End Time", "Scanned Objects"], removeNull=True
    )
    return data, hr


def prepare_context_hr_user_access_list(
    edges: list,
    include_whitelisted_results: bool,
    user_email: str,
    base_url: str,
    page_number: int = 1,
    limit: int = DEFAULT_LIMIT,
) -> tuple[list[dict], str, int, set[str]]:
    """
    Prepare context output and human-readable response for rubrik-sonar-user-access-list command.

    :type edges: ``list``
    :param edges: Edges from the response received from the API.

    :type include_whitelisted_results: ``bool``
    :param include_whitelisted_results: Include whitelisted results in the API response.

    :type user_email: ``str``
    :param user_email: User email or user principal name.

    :type base_url: ``str``
    :param base_url: Base URL of the platform.

    :type page_number: ``int``
    :param page_number: The current page number.

    :type limit: ``int``
    :param limit: Limit the records for the output.

    :return: Context output, human-readable, the total pages and the risk levels for the command.
    """
    hr_content = []
    context: list[dict] = []
    risk_levels: set[str] = set()
    upn_match_count = 0
    for edge in edges:
        node = edge.get("node")
        node = remove_empty_elements(node)
        user_principal_name = node.get("upn")
        if user_email:
            if isinstance(user_principal_name, str) and user_email not in user_principal_name:
                continue
            # Found the match of the UPN with the user provide mail address.
            upn_match_count += 1
            # Skip the records as per the page number.
            if upn_match_count <= limit * (page_number - 1):
                continue
            # Limit the context and the HR output.
            if len(context) >= limit:
                continue
        context.append(node)
        sensitive_files = node.get("sensitiveFiles") or {}
        risk_level = node.get("riskLevel")
        if risk_level:
            risk_levels.add(risk_level)

        total_sensitive_files = 0
        # Go for totalHits if include_whitelisted_results is True else go for violatedHits.
        if include_whitelisted_results:
            sensitive_hits_key = "totalHits"
            sensitive_files_key = "totalCount"
        else:
            sensitive_hits_key = "violatedHits"
            sensitive_files_key = "violatedCount"

        for file_count in sensitive_files.values():
            if isinstance(file_count, dict):
                total_sensitive_files += file_count.get(sensitive_files_key) or 0

        user_id = node.get("principalId")
        hr_content.append(
            {
                USER_ID: f"[{user_id}]({USER_ACCESS_HYPERLINK.format(base_url, user_id)})",
                USER_FULL_NAME: node.get("fullName"),
                USER_PRINCIPAL_NAME: re.escape(node.get("upn") or ""),
                RISK_LEVEL: node.get("riskLevel"),
                TOTAL_SENSITIVE_OBJECTS: node.get("sensitiveObjectCount", {}).get(sensitive_files_key, 0),
                TOTAL_SENSITIVE_FILES: total_sensitive_files,
                TOTAL_SENSITIVE_HITS: node.get("totalSensitiveHits", {}).get(sensitive_hits_key) or 0,
            }
        )

    pages = calc_pages(per_page_count=limit, total_count=upn_match_count)  # type: ignore
    if user_email:
        record_start = limit * (page_number - 1) + 1
        record_end = record_start + len(context) - 1
        total_records = upn_match_count
    else:
        record_start = 1
        record_end = len(context)
        total_records = record_end
    hr = tableToMarkdown(
        f"User Access (Showing Records {record_start}-{record_end} out of {total_records})",
        hr_content,
        headers=[  # noqa: E225
            USER_ID,
            USER_FULL_NAME,
            USER_PRINCIPAL_NAME,
            RISK_LEVEL,
            TOTAL_SENSITIVE_OBJECTS,
            TOTAL_SENSITIVE_FILES,
            TOTAL_SENSITIVE_HITS,
        ],
        removeNull=True,  # noqa: E225
    )

    return context, hr, pages, risk_levels


def prepare_context_hr_dspm_violation_get(violation_data: Dict) -> tuple[Dict, str]:
    """
    Prepare context output and human-readable response for rubrik-data-security-violation-get command.

    :type violation_data: ``Dict``
    :param violation_data: Policy violation data from the API response.

    :return: Context output and human-readable for the command.
    """
    context = remove_empty_elements(violation_data)

    metadata = demisto.get(violation_data, "resourceMetadata.metadata", {})
    policy = demisto.get(violation_data, "policy", {})
    details = demisto.get(violation_data, "details", {})
    status = violation_data.get("status", "")
    display_status = status.replace("POLICY_VIOLATION_STATUS_", "").replace("_", " ").title() if status else ""

    severity = violation_data.get("violationSeverity", "")
    display_severity = severity.title() if severity else ""

    data_types = demisto.get(details, "dataTypes", [])
    data_types_data = [
        {"id": dt.get("id"), "name": dt.get("name"), "totalViolatedHits": dt.get("totalViolatedHits")} for dt in data_types
    ]

    data_categories = demisto.get(details, "dataCategories", [])
    data_categories_data = [
        {"id": dc.get("id"), "name": dc.get("name"), "totalViolatedHits": dc.get("totalViolatedHits")} for dc in data_categories
    ]

    hr_content = {
        "ID": violation_data.get("policyViolationId"),
        "Violation Name": policy.get("name"),
        SEVERITY: display_severity,
        "Violation Status": display_status,
        DETECTION_TIME: violation_data.get("createdAt"),
        "Last Updated": violation_data.get("lastUpdatedAt"),
        "Policy ID": policy.get("policyId"),
        "Policy Description": policy.get("description"),
        "Policy Category": policy.get("policyCategory"),
        "Policy Severity": policy.get("policySeverity").title() if policy.get("policySeverity") else "",
        TOTAL_RISK_HITS: details.get("violatedSensitiveHits"),
        HIGH_RISK_HITS: details.get("violatedHighRiskSensitiveHits"),
        MEDIUM_RISK_HITS: details.get("violatedMediumRiskSensitiveHits"),
        LOW_RISK_HITS: details.get("violatedLowRiskSensitiveHits"),
        NO_RISK_HITS: details.get("violatedNoRiskSensitiveHits"),
        SNAPSHOT_ID: details.get("snapshotId"),
        OBJECT_ID: violation_data.get("resourceId"),
        OBJECT_NAME: metadata.get("name"),
        OBJECT_TYPE: metadata.get("objectType"),
        "Object Location": metadata.get("physicalHost"),
        "Object Account name": demisto.get(metadata, "cloudAccountInfo.accountName"),
        "Object Platform": metadata.get("platform"),
        "Object Region": metadata.get("region"),
        CLUSTER_ID: demisto.get(metadata, "clusterInfo.clusterUuid"),
        CLUSTER_NAME: demisto.get(metadata, "clusterInfo.clusterName"),
        "Data Types": data_types_data,
        "Data Categories": data_categories_data,
    }

    hr = tableToMarkdown(
        "DSPM Violation Data",
        hr_content,
        removeNull=True,
        sort_headers=False,
        json_transform_mapping={"Data Types": JsonTransformer(), "Data Categories": JsonTransformer()},
    )

    return context, hr


def prepare_context_hr_user_access_get(
    principal_summary: Dict, policy_hits_context: list, base_url: str, include_whitelisted_results: bool
) -> tuple[list, str, str]:
    """
    Prepare context output and human-readable response for rubrik-sonar-user-access-get command.

    :type principal_summary: ``Dict``
    :param principal_summary: Edges from the response received from the API.

    :type policy_hits_context: ``list``
    :param policy_hits_context: Summary of the policy hits for the user.

    :type base_url: ``str``
    :param base_url: Base URL of the platform.

    :type include_whitelisted_results: ``bool``
    :param include_whitelisted_results: Include whitelisted results in the API response.

    :return: Context output and human-readable for the command.
    """
    access_hr_content = []
    policy_hits_hr_content: list = []
    context = []
    principal_summary = remove_empty_elements(principal_summary)
    policy_hits_context = remove_empty_elements(policy_hits_context)
    principal_summary["policy_hits_summary"] = policy_hits_context
    context.append(principal_summary)
    sensitive_files = principal_summary.get("sensitiveFiles") or {}

    total_sensitive_files = 0
    # Go for totalHits if include_whitelisted_results is True else go for violatedHits.
    if include_whitelisted_results:
        sensitive_hits_key = "totalHits"
        sensitive_files_key = "totalCount"
    else:
        sensitive_hits_key = "violatedHits"
        sensitive_files_key = "violatedCount"

    for file_count in sensitive_files.values():
        if isinstance(file_count, dict):
            total_sensitive_files += file_count.get(sensitive_files_key) or 0

    groups = [group.get("name") for group in principal_summary.get("directGroups", [])]
    access_risk_reasons = principal_summary.get("riskReasons", {}).get("accessRiskReasons", [])
    insecure_reasons = principal_summary.get("riskReasons", {}).get("insecureReasons", [])

    user_id = principal_summary.get("principalId")
    access_hr_content.append(
        {
            USER_ID: f"[{user_id}]({USER_ACCESS_HYPERLINK.format(base_url, user_id)})",
            USER_FULL_NAME: principal_summary.get("fullName"),
            USER_PRINCIPAL_NAME: re.escape(principal_summary.get("upn") or ""),
            RISK_LEVEL: principal_summary.get("riskLevel"),
            ACCESS_RISK_REASONS: ", ".join(access_risk_reasons),
            INSECURE_REASONS: ", ".join(insecure_reasons),
            GROUPS: ", ".join(groups),
            TOTAL_SENSITIVE_OBJECTS: principal_summary.get("sensitiveObjectCount", {}).get(sensitive_files_key, 0),
            TOTAL_SENSITIVE_FILES: total_sensitive_files,
            TOTAL_SENSITIVE_HITS: principal_summary.get("totalSensitiveHits", {}).get(sensitive_hits_key) or 0,
        }
    )

    access_hr = tableToMarkdown(
        "User Access",
        access_hr_content,
        headers=[
            USER_ID,
            USER_FULL_NAME,
            USER_PRINCIPAL_NAME,
            RISK_LEVEL,
            ACCESS_RISK_REASONS,
            INSECURE_REASONS,
            GROUPS,
            TOTAL_SENSITIVE_OBJECTS,
            TOTAL_SENSITIVE_FILES,
            TOTAL_SENSITIVE_HITS,
        ],
        removeNull=True,
    )

    for policy_hits in policy_hits_context:
        total_file_count_dict = policy_hits.get("sidSensitiveFiles", {}).get("totalFileCount", {})
        risk_hits_dict = policy_hits.get("sidAnalyzerHits", {})
        delta_risk_hits_dict = policy_hits.get("sidDeltaAnalyzerHits", {})

        policy_hits_hr_content.append(
            {
                POLICY_NAME: policy_hits.get("policyName") or "",
                TOTAL_SENSITIVE_FILES: total_file_count_dict.get(sensitive_files_key) or 0,
                TOTAL_SENSITIVE_HITS: risk_hits_dict.get("totalHits", {}).get(sensitive_hits_key) or 0,
                SENSITIVE_HITS_DELTA: delta_risk_hits_dict.get("totalHits", {}).get(sensitive_hits_key) or 0,
                HIGH_RISK_HITS: risk_hits_dict.get("highRiskHits", {}).get(sensitive_hits_key) or 0,
                MEDIUM_RISK_HITS: risk_hits_dict.get("mediumRiskHits", {}).get(sensitive_hits_key) or 0,
                LOW_RISK_HITS: risk_hits_dict.get("lowRiskHits", {}).get(sensitive_hits_key) or 0,
            }
        )

    policy_hits_hr = tableToMarkdown(
        "Sensitive Hits",
        policy_hits_hr_content,
        headers=[
            POLICY_NAME,
            TOTAL_SENSITIVE_FILES,
            TOTAL_SENSITIVE_HITS,
            SENSITIVE_HITS_DELTA,
            HIGH_RISK_HITS,
            MEDIUM_RISK_HITS,
            LOW_RISK_HITS,
        ],
        removeNull=True,
    )

    return context, access_hr, policy_hits_hr


def prepare_context_hr_file_context_list(edges: list, include_whitelisted_results: bool) -> tuple[list, str]:
    """
    Prepare context output and human-readable response for rubrik-sonar-file-context-list command.

    :type edges: ``list``
    :param edges: Edges from the response received from the API.

    :type include_whitelisted_results: ``bool``
    :param include_whitelisted_results: Include whitelisted results in the API response.

    :return: Context output and human-readable for the command.
    """
    hr_content = []
    context = []
    for edge in edges:
        node = edge.get("node")
        node = remove_empty_elements(node)
        context.append(node)
        last_access_time = node.get("lastAccessTime")
        last_access_time_str = (
            datetime.fromtimestamp(last_access_time, tz=timezone.utc).strftime(HR_DATE_TIME_FORMAT)
            if last_access_time is not None
            else ""
        )
        last_modified_time = node.get("lastModifiedTime")
        last_modified_time_str = (
            datetime.fromtimestamp(last_modified_time, tz=timezone.utc).strftime(HR_DATE_TIME_FORMAT)
            if last_modified_time is not None
            else ""
        )

        # Go for totalHits if include_whitelisted_results is True else go for violatedHits.
        if include_whitelisted_results:
            total_sensitive_hits = node.get("hits", {}).get("totalHits") or 0
            daily_hits_change = node.get("hits", {}).get("totalHitsDelta") or 0
            high_risk_hits = demisto.get(node, "sensitiveHits.highRiskHits.totalHits") or 0
            medium_risk_hits = demisto.get(node, "sensitiveHits.mediumRiskHits.totalHits") or 0
            low_risk_hits = demisto.get(node, "sensitiveHits.lowRiskHits.totalHits") or 0
            no_risk_hits = demisto.get(node, "sensitiveHits.noRiskHits.totalHits") or 0
        else:
            total_sensitive_hits = node.get("hits", {}).get("violations") or 0
            daily_hits_change = node.get("hits", {}).get("violationsDelta") or 0
            high_risk_hits = demisto.get(node, "sensitiveHits.highRiskHits.violatedHits") or 0
            medium_risk_hits = demisto.get(node, "sensitiveHits.mediumRiskHits.violatedHits") or 0
            low_risk_hits = demisto.get(node, "sensitiveHits.lowRiskHits.violatedHits") or 0
            no_risk_hits = demisto.get(node, "sensitiveHits.noRiskHits.violatedHits") or 0

        data_categories = [
            {
                "id": demisto.get(result, "analyzerGroup.id", ""),
                "name": demisto.get(result, "analyzerGroup.name", ""),
                "totalViolatedHits": demisto.get(result, "hits.violations") or 0,
            }
            for result in node.get("analyzerGroupResults", [])
        ]

        hr_content.append(
            {
                FILE_NAME: node.get("filename"),
                FILE_SIZE: node.get("size"),
                TOTAL_RISK_HITS: total_sensitive_hits,
                DAILY_HITS_CHANGE: daily_hits_change,
                HIGH_RISK_HITS: high_risk_hits,
                MEDIUM_RISK_HITS: medium_risk_hits,
                LOW_RISK_HITS: low_risk_hits,
                NO_RISK_HITS: no_risk_hits,
                "Data Categories": data_categories,
                FILE_PATH: node.get("stdPath"),
                ACCESS_TYPE: node.get("openAccessType"),
                LAST_ACCESS_TIME: last_access_time_str,
                LAST_MODIFIED_TIME: last_modified_time_str,
            }
        )

    hr = tableToMarkdown(
        "File Context",
        hr_content,
        headers=[
            FILE_NAME,
            FILE_SIZE,
            TOTAL_RISK_HITS,
            DAILY_HITS_CHANGE,
            HIGH_RISK_HITS,
            MEDIUM_RISK_HITS,
            LOW_RISK_HITS,
            NO_RISK_HITS,
            FILE_PATH,
            ACCESS_TYPE,
            LAST_ACCESS_TIME,
            LAST_MODIFIED_TIME,
            "Data Categories",
        ],
        removeNull=True,
        json_transform_mapping={"Data Categories": JsonTransformer()},
    )

    return context, hr


def prepare_context_hr_suspicious_file_list(snappable_investigations_data: dict, suspicious_file_data: dict) -> tuple[dict, str]:
    """
    Prepare context output and human-readable response for rubrik-radar-suspicious-file-list command.

    :type snappable_investigations_data: ``dict``
    :param snappable_investigations_data: Snappable investigations response received from the API.

    :type suspicious_file_data: ``dict``
    :param suspicious_file_data: Suspicious file data response received from the API.

    :return: Context output and human-readable for the command.
    """
    context = {}
    anomaly_information_hr_content = []
    suspicious_file_hr_content = []
    snappable_investigations_data = remove_empty_elements(snappable_investigations_data)
    suspicious_file_data = remove_empty_elements(suspicious_file_data)
    context.update(suspicious_file_data)
    cluster_data = snappable_investigations_data.get("cluster", {})
    if cluster_data:
        context["cluster"] = cluster_data
    snapshot_cdm_id = snappable_investigations_data.get("cdmId")
    if snapshot_cdm_id:
        context["cdmId"] = snapshot_cdm_id
    snappable_new = snappable_investigations_data.get("snappableNew", {})
    if snappable_new:
        context["snappableNew"] = snappable_new

    anomaly_information = {
        ANOMALY_ID: context.get("id"),
        IS_ANOMALY: context.get("isAnomaly"),
        ANOMALY_PROBABILITY: context.get("anomalyProbability"),
        SEVERITY: context.get("severity"),
        ENCRYPTION: context.get("encryption"),
        DETECTION_TIME: context.get("detectionTime"),
        SNAPSHOT_TIME: context.get("snapshotDate"),
        ANOMALY_RESOLUTION_STATUS: context.get("resolutionStatus"),
        ANOMALY_TYPE: context.get("anomalyType"),
    }

    anomaly_info_list: list = context.get("anomalyInfo", {}).get("strainAnalysisInfo", [])
    if not anomaly_info_list or not isinstance(anomaly_info_list, list):
        anomaly_information_hr_content.append(anomaly_information)
    else:
        anomaly_info: dict = anomaly_info_list[0]
        anomaly_information.update(
            {
                ANOMALY: anomaly_info.get("strainId"),
                TOTAL_SUSPICIOUS_FILES: anomaly_info.get("totalAffectedFiles"),
                TOTAL_RANSOMEWARE_NOTE: anomaly_info.get("totalRansomwareNotes"),
            }
        )
        anomaly_information_hr_content.append(anomaly_information)
        affected_files: list = anomaly_info.get("sampleAffectedFilesInfo", [])
        ransomeware_note_files: list = anomaly_info.get("sampleRansomwareNoteFilesInfo", [])
        if affected_files and isinstance(affected_files, list):
            for affected_file in affected_files:
                suspicious_file = {
                    FILE_PATH: affected_file.get("filePath"),
                    SUSPICIOUS_ACTIVITY: RANSOMEWARE_ENCRYPTION,
                    FILE_SIZE: affected_file.get("fileSizeBytes"),
                    LAST_MODIFIED_TIME: affected_file.get("lastModified"),
                }
                suspicious_file_hr_content.append(suspicious_file)
        if ransomeware_note_files and isinstance(ransomeware_note_files, list):
            for ransomeware_note_file in ransomeware_note_files:
                suspicious_file = {
                    FILE_PATH: ransomeware_note_file.get("filePath"),
                    SUSPICIOUS_ACTIVITY: RANSOMEWARE_NOTE,
                    FILE_SIZE: ransomeware_note_file.get("fileSizeBytes"),
                    LAST_MODIFIED_TIME: ransomeware_note_file.get("lastModified"),
                }
                suspicious_file_hr_content.append(suspicious_file)

    anomaly_hr = tableToMarkdown(
        "Anomaly Information",
        anomaly_information_hr_content,
        headers=[
            ANOMALY_ID,
            IS_ANOMALY,
            ANOMALY_PROBABILITY,
            SEVERITY,
            ENCRYPTION,
            ANOMALY,
            ANOMALY_TYPE,
            ANOMALY_RESOLUTION_STATUS,
            TOTAL_SUSPICIOUS_FILES,
            TOTAL_RANSOMEWARE_NOTE,
            DETECTION_TIME,
            SNAPSHOT_TIME,
        ],
        removeNull=True,
    )

    suspicious_file_hr = tableToMarkdown(
        "Suspicious Files",
        suspicious_file_hr_content,
        headers=[FILE_PATH, SUSPICIOUS_ACTIVITY, FILE_SIZE, LAST_MODIFIED_TIME],
        removeNull=True,
    )

    return context, f"{anomaly_hr}\n\n{suspicious_file_hr}"


def prepare_score_and_hr_for_reputation_command(response: dict, indicator_value: str, indicator_type: str) -> tuple[int, str]:
    """
    Prepare severity score and human-readable response for generic reputation command.

    :type response: ``dict``
    :param response: IP response received from the API.

    :type indicator_value: ``str``
    :param indicator_value: Indicator value.

    :type indicator_type: ``str``
    :param indicator_type: Indicator type.

    :return: Severity score and human-readable for the command.
    """
    sensitive_info = response.get(SENSITIVE_INFO_KEY, {})
    severity_str = sensitive_info.get("riskLevel", "unknown").lower()
    if "none" in severity_str:
        severity_str = "unknown"
    severity_score: int = DBOT_SCORE_MAPPING.get(severity_str, 0)
    general_info = response.get(GENERAL_INFO_KEY, {})
    severity_str = severity_str.replace(" risk", "")
    human_readable = tableToMarkdown(
        f"General Information for the given {severity_str} risk {indicator_type}: {indicator_value}",
        general_info,
        removeNull=True,
        headerTransform=pascalToSpace,
        url_keys=["redirectLink"],
    )
    human_readable += (
        "\n"
        + tableToMarkdown(
            "Sensitive Information", sensitive_info, headerTransform=pascalToSpace, removeNull=True, url_keys=["redirectLink"]
        )
        if sensitive_info
        else ""
    )
    anomalies_info = response.get(ANOMALY_INFO_KEY, {})
    human_readable += (
        "\n"
        + tableToMarkdown(
            "Anomaly Information", anomalies_info, headerTransform=pascalToSpace, removeNull=True, url_keys=["redirectLink"]
        )
        if anomalies_info
        else ""
    )
    threat_hunt_info = response.get(THREAT_HUNT_INFO_KEY, {})
    human_readable += (
        "\n"
        + tableToMarkdown(
            "Threat Hunt Information", threat_hunt_info, headerTransform=pascalToSpace, removeNull=True, url_keys=["redirectLink"]
        )
        if threat_hunt_info
        else ""
    )
    threat_monitoring_info = response.get(THREAT_MONITORING_INFO_KEY, {})
    human_readable += (
        "\n"
        + tableToMarkdown(
            "Threat Monitoring Information",
            threat_monitoring_info,
            headerTransform=pascalToSpace,
            removeNull=True,
            url_keys=["redirectLink"],
        )
        if threat_monitoring_info
        else ""
    )

    return severity_score, human_readable


def validate_ip_addresses(ips_list: List[str]) -> tuple[List[str], List[str]]:
    """
    Given a list of IP addresses, returns the invalid and valid ips.

    :type ips_list: ``List[str]``
    :param ips_list: List of ip addresses.

    :return: invalid_ip_addresses and valid_ip_addresses.
    :rtype: ``Tuple[List[str], List[str]]``
    """
    invalid_ip_addresses = []
    valid_ip_addresses = []
    for ip in ips_list:
        if is_ip_valid(ip, accept_v6_ips=True):
            valid_ip_addresses.append(ip)
        else:
            invalid_ip_addresses.append(ip)
    return invalid_ip_addresses, valid_ip_addresses


def validate_anomaly_status_update_command_args(
    anomaly_type: str, false_positive_type: Optional[str], false_positive_reason: Optional[str]
):
    """
    Validate the arguments of the rubrik_radar_anomaly_status_update_command.

    :type anomaly_type: ``str``
    :param anomaly_type: The type of the anomaly.

    :type false_positive_type: ``Optional[str]``
    :param false_positive_type: The type of the false positive.

    :type false_positive_reason: ``Optional[str]``
    :param false_positive_reason: The reason for marking the anomaly as a false positive.
    """

    if anomaly_type.upper() not in ANOMALY_TYPE_ENUM:
        raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(anomaly_type, "anomaly_type", ANOMALY_TYPE_ENUM))

    if false_positive_reason and not false_positive_type:
        raise ValueError(ERROR_MESSAGES["FALSE_POSITIVE_REASON_ERROR"].format("false_positive_type", "false_positive_reason"))

    if false_positive_type and false_positive_type.upper() not in FALSE_POSITIVE_TYPE_ENUM:
        raise ValueError(
            ERROR_MESSAGES["INVALID_SELECT"].format(false_positive_type, "false_positive_type", FALSE_POSITIVE_TYPE_ENUM)
        )

    if false_positive_type and false_positive_type.upper() == "OTHER" and not false_positive_reason:
        raise ValueError(ERROR_MESSAGES["FALSE_POSITIVE_TYPE_ERROR"].format("false_positive_reason", "false_positive_type"))


def validate_threat_monitoring_matched_object_list_command_args(
    start_time_obj: Optional[datetime], limit: Optional[int], match_types: list
):
    """
    Validate the arguments of the rubrik-threat-monitoring-matched-object-list command.

    :type start_time_obj: ``Optional[datetime]``
    :param start_time_obj: The start time of the query.

    :type limit: ``Optional[int]``
    :param limit: The number of results to return.

    :type match_types: ``list``
    :param match_types: The match types to filter by.
    """
    start_time_obj = validate_required_arg("start_time", start_time_obj)
    if not limit or not 1 <= limit <= MAXIMUM_PAGINATION_LIMIT:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    for match_type in match_types:
        if match_type not in IOC_TYPE_ENUM:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(match_type, "match_type", IOC_TYPE_ENUM))


def prepare_context_hr_threat_monitoring_matched_object_list(edges: list) -> tuple:
    """
    Prepare human readable response and context for rubrik-threat-monitoring-matched-object-list.

    :type edges: ``list``
    :param edges: edges from the response received from the API.

    :return: human readable and context for the command.
    :rtype: ``tuple``
    """
    hr_content = []
    context = []
    for edge in edges:
        node = edge.get("node", {})
        node = remove_empty_elements(node)
        context.append(node)
        hr_content.append(
            {
                "Object ID": node.get("objectFid"),
                "Object Name": node.get("objectName"),
                "Object Type": node.get("objectType"),
                "Total Files Matched": node.get("filesMatched"),
                "Match Types": node.get("matchType"),
                "Last Detection Time": node.get("lastDetection"),
                "Cluster ID": node.get("cluster", {}).get("id"),
                "Cluster Name": node.get("cluster", {}).get("name"),
            }
        )
    hr = tableToMarkdown(
        "Threat Monitoring Object List",
        hr_content,
        headers=[
            "Object ID",
            "Object Name",
            "Object Type",
            "Total Files Matched",
            "Match Types",
            "Last Detection Time",
            "Cluster ID",
            "Cluster Name",
        ],
        removeNull=True,
    )
    return context, hr


def remove_typename(data: Union[dict, list]) -> Union[dict, list]:
    """
    Recursively remove "__typename" key from all the dict and list types.

    :type data: ``dict`` or ``list``
    :param data: The data which "__typename" key needs to be removed.

    :return: The data with "__typename" key removed.
    :rtype: ``dict`` or ``list``
    """
    if isinstance(data, dict):
        if "__typename" in data:
            data.pop("__typename")
        for key, value in data.items():
            if isinstance(value, (dict, list)):
                data[key] = remove_typename(value)
    elif isinstance(data, list):
        for index, value in enumerate(data):
            if isinstance(value, (dict, list)):
                data[index] = remove_typename(value)
    return data


def prepare_hr_threat_monitoring_matched_objects_get(threat_monitoring_data: dict) -> str:
    """
    Prepare human readable response for rubrik-threat-monitoring-matched-object-get command.

    :type threat_monitoring_data: ``dict``
    :param threat_monitoring_data: The response received from the API.

    :return: human readable for the command.
    :rtype: ``str``
    """
    threat_monitoring_data_copy = deepcopy(threat_monitoring_data)

    threat_monitoring_data_copy: dict = remove_typename(threat_monitoring_data_copy)  # type: ignore

    hr_content = {
        "ID": threat_monitoring_data.get("id"),
        "Name": threat_monitoring_data.get("name"),
        "Object Type": threat_monitoring_data.get("objectType"),
        "SLA Assignment": threat_monitoring_data.get("slaAssignment"),
        "Effective SLA Domain": threat_monitoring_data_copy.get("effectiveSlaDomain"),
        "SLA Pause Status": threat_monitoring_data.get("slaPauseStatus"),
        "Snapshot Distribution": threat_monitoring_data_copy.get("snapshotDistribution"),
        "Effective Retention SLA Domain": threat_monitoring_data_copy.get("effectiveRetentionSlaDomain"),
        "Configured SLA Domain": threat_monitoring_data_copy.get("configuredSlaDomain"),
        "Effective SLA Source Object": threat_monitoring_data_copy.get("effectiveSlaSourceObject"),
        "Logical Path": threat_monitoring_data_copy.get("logicalPath"),
        "Physical Path": threat_monitoring_data_copy.get("physicalPath"),
        "NumWorkload Descendants": threat_monitoring_data.get("numWorkloadDescendants"),
        "All Orgs": threat_monitoring_data_copy.get("allOrgs"),
        "Security Metadata": threat_monitoring_data_copy.get("securityMetadata"),
    }

    hr = tableToMarkdown(
        "Threat Monitoring Object Details",
        hr_content,
        headers=[
            "ID",
            "Name",
            "Object Type",
            "SLA Assignment",
            "Effective SLA Domain",
            "SLA Pause Status",
            "Snapshot Distribution",
            "Effective Retention SLA Domain",
            "Configured SLA Domain",
            "Effective SLA Source Object",
            "Logical Path",
            "Physical Path",
            "NumWorkload Descendants",
            "All Orgs",
            "Security Metadata",
        ],
        json_transform_mapping={
            "Effective SLA Domain": JsonTransformer(is_nested=True),
            "Snapshot Distribution": JsonTransformer(is_nested=True),
            "Effective Retention SLA Domain": JsonTransformer(is_nested=True),
            "Configured SLA Domain": JsonTransformer(is_nested=True),
            "Effective SLA Source Object": JsonTransformer(is_nested=True),
            "Logical Path": JsonTransformer(is_nested=True),
            "Physical Path": JsonTransformer(is_nested=True),
            "All Orgs": JsonTransformer(is_nested=True),
            "Security Metadata": JsonTransformer(is_nested=True),
        },
        removeNull=True,
    )
    return hr


def validate_threat_monitoring_matched_file_list_command_args(object_id: Optional[Any], limit: Optional[int]):
    """
    Validate the arguments of the rubrik-threat-monitoring-matched-file-list command.

    :type object_id: ``Optional[Any]``
    :param object_id: The object ID for the threat monitoring object.

    :type limit: ``Optional[int]``
    :param limit: The number of results to return.
    """
    validate_required_arg("object_id", object_id)
    if not limit or not 1 <= limit <= MAXIMUM_PAGINATION_LIMIT:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))


def prepare_context_hr_threat_monitoring_matched_file_list(edges: list) -> tuple[list, str]:
    """
    Prepare context and human-readable output for matched file list.

    :type edges: ``list``
    :param edges: edges from the response received from the API.

    :return: context and human-readable for the command.
    :rtype: ``tuple[list, str]``
    """
    context = []
    hr_rows = []
    for edge in edges:
        node = edge.get("node", {})
        context.append(remove_empty_elements(node))
        hr_rows.append(
            {
                "File Name": node.get("fileName"),
                "File Path": node.get("filepath"),
                "File Size": node.get("fileSize"),
                "Matched Snapshot ID": node.get("matchedSnapshotFid"),
                "Matched Snapshot Date": node.get("matchedSnapshotDate"),
                "Matched Snapshot Expired": node.get("isMatchedSnapshotExpired"),
            }
        )
    hr = tableToMarkdown(
        "Threat Monitoring File List",
        hr_rows,
        headers=[
            "File Name",
            "File Path",
            "File Size",
            "Matched Snapshot ID",
            "Matched Snapshot Date",
            "Matched Snapshot Expired",
        ],
        removeNull=True,
    )
    return context, hr


def validate_threat_monitoring_matched_file_get_command_args(matched_snapshot_id: str, file_path: str):
    """
    Validate the arguments of the rubrik-threat-monitoring-matched-file-get command.

    :type matched_snapshot_id: ``str``
    :param matched_snapshot_id: The ID of the snapshot to search for.

    :type file_path: ``str``
    :param file_path: The path of the file to search for.
    """
    if not matched_snapshot_id and not file_path:
        raise ValueError(ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("matched_snapshot_id", "file_path"))
    validate_required_arg("matched_snapshot_id", matched_snapshot_id)
    validate_required_arg("file_path", file_path)


def prepare_context_hr_threat_monitoring_matched_file_get(file_details: Dict[str, Any]) -> str:
    """
    Prepare context and human-readable output for rubrik-threat-monitoring-matched-file-get command.

    :type file_details: ``Dict[str, Any]``
    :param file_details: File details from the API response.

    :return: A human-readable output.
    :rtype: ``str``
    """
    file_hashes = {
        "MD5": file_details.get("matchedFileMd5"),
        "SHA1": file_details.get("matchedFileSha1"),
        "SHA256": file_details.get("matchedFileSha256"),
    }

    # Add IOC Details if available
    ioc_details = deepcopy(file_details.get("iocDetails", []))
    ioc_details = remove_typename(ioc_details)

    # Prepare human readable output
    hr_content = {
        "File Name": file_details.get("fileName"),
        "File Path": file_details.get("filePath"),
        "File Hashes": file_hashes,
        "IOC Details": ioc_details,
        "First Detected Snapshot FID": file_details.get("firstDetectedSnapshotFid"),
        "Detected Snapshot Date": file_details.get("detectedSnapshotDate"),
        "Quarantined In First Observed Snapshot": file_details.get("isQuarantinedInFirstObservedSnapshot"),
    }

    hr = tableToMarkdown(
        "Threat Monitoring File Details",
        hr_content,
        headers=[
            "File Name",
            "File Path",
            "File Hashes",
            "IOC Details",
            "First Detected Snapshot FID",
            "Detected Snapshot Date",
            "Quarantined In First Observed Snapshot",
        ],
        json_transform_mapping={
            "File Hashes": JsonTransformer(is_nested=True),
            "IOC Details": JsonTransformer(is_nested=True),
        },
        removeNull=True,
    )

    return hr


def validate_comman_fetch_params(max_fetch: Optional[int], fetch_types: list):
    """
    Validate the arguments of the fetch commands.

    :type max_fetch: ``Optional[int]``
    :param max_fetch: The maximum number of incidents to fetch.

    :type fetch_type: ``list``
    :param fetch_type: The type of incidents to fetch.

    :return: None
    """
    if any(fetch_type not in DEFAULT_FETCH_TYPE for fetch_type in fetch_types):
        raise ValueError(MESSAGES["INVALID_FETCH_TYPE"])

    if set(MAX_FETCH_APPLICABLE_FETCH_TYPES) & set(fetch_types) and (
        not max_fetch or not MAX_FETCH_MIN <= max_fetch <= MAX_FETCH_MAX
    ):
        raise ValueError(ERROR_MESSAGES["INVALID_MAX_FETCH"])


def validate_dspm_violation_fetch_params(
    violation_statuses: list, violation_severities: list, violation_sensitivities: list, is_fetch: bool = True
) -> tuple:
    """
    Validate and transform DSPM violation fetch parameters to API enum format.

    :param violation_statuses: List of violation statuses to validate.
    :type violation_statuses: list

    :param violation_severities: List of violation severities to validate.
    :type violation_severities: list

    :param violation_sensitivities: List of violation sensitivities to validate.
    :type violation_sensitivities: list

    :param is_fetch: Whether this is called from fetch (True) or list command (False).
    :type is_fetch: bool

    :return: Tuple of (statuses, severities, sensitivities) transformed to API enum format.
    :rtype: tuple
    :raises ValueError: If any parameter value is not in the allowed values.
    """
    statuses = []
    status_arg_name = "dspm_violation_status" if is_fetch else "status"
    severity_arg_name = "dspm_violation_severity" if is_fetch else "severity"
    sensitivity_arg_name = "dspm_violation_sensitivity" if is_fetch else "sensitivity"

    for status in violation_statuses:
        if status.upper() not in DSPM_VIOLATION_STATUS:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(status, status_arg_name, DSPM_VIOLATION_STATUS))

        statuses.append(f"POLICY_VIOLATION_STATUS_{status.upper()}")

    severities = []
    for severity in violation_severities:
        if severity.upper() not in DSPM_VIOLATION_SEVERITY:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(severity, severity_arg_name, DSPM_VIOLATION_SEVERITY))

        severities.append(severity.upper())

    sensitivities = []
    for sensitivity in violation_sensitivities:
        if sensitivity.upper() not in DSPM_VIOLATION_SENSITIVITY:
            raise ValueError(
                ERROR_MESSAGES["INVALID_SELECT"].format(sensitivity, sensitivity_arg_name, DSPM_VIOLATION_SENSITIVITY)
            )

        sensitivities.append(f"{sensitivity.upper()}_SENSITIVITY")

    return statuses, severities, sensitivities


def validate_ir_violation_fetch_params(
    violation_statuses: list,
    violation_severities: list,
    violation_policy_types: list,
    violation_identity_providers: list,
    violation_identity_tags: list,
    is_fetch: bool = True,
) -> tuple:
    """
    Validate and transform IR violation fetch parameters to API enum format.

    :param violation_statuses: List of violation statuses to validate.
    :type violation_statuses: list

    :param violation_severities: List of violation severities to validate.
    :type violation_severities: list

    :param violation_policy_types: List of policy types to validate.
    :type violation_policy_types: list

    :param violation_identity_providers: List of identity providers to validate.
    :type violation_identity_providers: list

    :param violation_identity_tags: List of identity tags to validate.
    :type violation_identity_tags: list

    :param is_fetch: Whether this is called from fetch (True) or list command (False).
    :type is_fetch: bool

    :return: Tuple of (statuses, severities, policy_types, identity_providers, identity_tags) transformed to API enum format.
    :rtype: tuple
    :raises ValueError: If any parameter value is not in the allowed values.
    """
    status_arg_name = "ir_violation_status" if is_fetch else "status"
    severity_arg_name = "ir_violation_severity" if is_fetch else "severity"
    policy_type_arg_name = "ir_violation_policy_type" if is_fetch else "policy_type"
    identity_provider_arg_name = "ir_violation_identity_provider" if is_fetch else "identity_provider"
    identity_tag_arg_name = "ir_violation_identity_tag" if is_fetch else "identity_tag"

    statuses = []
    for status in violation_statuses:
        if status.upper() not in IR_VIOLATION_STATUS:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(status, status_arg_name, IR_VIOLATION_STATUS))
        statuses.append(f"POLICY_VIOLATION_STATUS_{status.upper()}")

    severities = []
    for severity in violation_severities:
        if severity.upper() not in IR_VIOLATION_SEVERITY:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(severity, severity_arg_name, IR_VIOLATION_SEVERITY))
        severities.append(severity.upper())

    policy_types = []
    for policy_type in violation_policy_types:
        if policy_type.upper() not in IR_VIOLATION_POLICY_TYPE:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(policy_type, policy_type_arg_name, IR_VIOLATION_POLICY_TYPE))
        policy_types.append(f"POLICY_TYPE_{policy_type.upper()}")

    identity_providers = []
    for identity_provider in violation_identity_providers:
        if identity_provider.upper() not in IR_VIOLATION_IDENTITY_PROVIDER:
            raise ValueError(
                ERROR_MESSAGES["INVALID_SELECT"].format(
                    identity_provider, identity_provider_arg_name, IR_VIOLATION_IDENTITY_PROVIDER
                )
            )
        identity_providers.append(identity_provider.upper())

    identity_tags = []
    for identity_tag in violation_identity_tags:
        if identity_tag.upper() not in IR_VIOLATION_IDENTITY_TAG:
            raise ValueError(
                ERROR_MESSAGES["INVALID_SELECT"].format(identity_tag, identity_tag_arg_name, IR_VIOLATION_IDENTITY_TAG)
            )
        identity_tags.append(identity_tag.upper())

    return statuses, severities, policy_types, identity_providers, identity_tags


def validate_sensitive_data_object_fetch_params(sensitivities: list) -> list:
    """
    Validate and transform sensitivity levels for sensitive data object fetch.

    :param sensitivities: List of sensitivity levels.
    :type sensitivities: list

    :return: List of validated risk level strings.
    :rtype: list
    :raises ValueError: If any sensitivity value is not in the allowed values.
    """
    valid_sensitivities = []
    for sensitivity in sensitivities:
        if sensitivity.upper() not in SENSITIVE_DATA_OBJECT_SENSITIVITY:
            raise ValueError(
                ERROR_MESSAGES["INVALID_SELECT"].format(
                    sensitivity, "sensitive_data_object_sensitivity", SENSITIVE_DATA_OBJECT_SENSITIVITY
                )
            )
        valid_sensitivities.append(f"{sensitivity.upper()}_RISK")
    return valid_sensitivities


def get_ir_violation_resource_display_name(node: dict) -> str:
    """
    Extract the available resource/entity display name from an IR violation.

    Tries multiple metadata fields in priority order, and appends the target identity
    name if present to form a combined display name.

    :type node: ``dict``
    :param node: A single IR violation node from the API response.

    :rtype: ``str``
    :return: The resolved display name for the violation's resource/entity.
    """
    resource_name = (
        demisto.get(node, "resourceMetadata.metadata.displayName", "")
        or demisto.get(node, "resourceMetadata.metadata.domainName", "")
        or demisto.get(node, "resourceMetadata.metadata.entityName", "")
        or demisto.get(node, "resourceMetadata.metadata.actorIdentityName", "")
    )
    target_entity_name = demisto.get(node, "resourceMetadata.metadata.targetIdentityName", "")
    if target_entity_name:
        resource_name = f"{resource_name} - {target_entity_name}" if resource_name else target_entity_name
    return resource_name


def validate_date_range(start_time: Optional[datetime], start_time_arg: str, end_time: Optional[datetime], end_time_arg: str):
    """
    Validate that start time is not greater than end time.

    :type start_time: ``Optional[datetime]``
    :param start_time: The start time value.

    :type start_time_arg: ``str``
    :param start_time_arg: The argument name for start time (used in error messages).

    :type end_time: ``Optional[datetime]``
    :param end_time: The end time value.

    :type end_time_arg: ``str``
    :param end_time_arg: The argument name for end time (used in error messages).

    :raises ValueError: If start time is greater than end time.
    """
    if start_time and end_time and start_time > end_time:
        raise ValueError(ERROR_MESSAGES["INVALID_DATE_RANGE"].format(start_time_arg, end_time_arg))


def validate_data_security_violation_list_command_args(
    limit: Optional[int],
    sort_by: Optional[str],
    sort_order: str,
    detection_start_date: Optional[datetime],
    detection_end_date: Optional[datetime],
    resolved_start_date: Optional[datetime],
    resolved_end_date: Optional[datetime],
):
    """
    Validate the arguments of the rubrik-data-security-violation-list command.

    :type limit: ``Optional[int]``
    :param limit: The number of results to return.

    :type sort_by: ``Optional[str]``
    :param sort_by: The field to sort by.

    :type sort_order: ``str``
    :param sort_order: The sort order (ASC or DESC).

    :type detection_start_date: ``Optional[datetime]``
    :param detection_start_date: The detection start date.

    :type detection_end_date: ``Optional[datetime]``
    :param detection_end_date: The detection end date.

    :type resolved_start_date: ``Optional[datetime]``
    :param resolved_start_date: The resolved start date.

    :type resolved_end_date: ``Optional[datetime]``
    :param resolved_end_date: The resolved end date.

    :raises ValueError: If any parameter value is not valid.
    """
    if not limit or not 1 <= limit <= MAXIMUM_PAGINATION_LIMIT:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    if sort_by and sort_by.upper() not in DSPM_VIOLATION_SORT_BY:
        raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(sort_by, "sort_by", DSPM_VIOLATION_SORT_BY))

    if sort_order.upper() not in (ASCENDING_SORT_ORDER, DESCENDING_SORT_ORDER):
        raise ValueError(ERROR_MESSAGES["INVALID_SORT_ORDER"].format(sort_order))

    if bool(detection_start_date) != bool(detection_end_date):
        raise ValueError(ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("detection_start_date", "detection_end_date"))

    if bool(resolved_start_date) != bool(resolved_end_date):
        raise ValueError(ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("resolved_start_date", "resolved_end_date"))

    validate_date_range(detection_start_date, "detection_start_date", detection_end_date, "detection_end_date")
    validate_date_range(resolved_start_date, "resolved_start_date", resolved_end_date, "resolved_end_date")


def prepare_context_hr_data_security_violation_list(edges: list) -> tuple:
    """
    Prepare context and human readable output for the rubrik-data-security-violation-list command.

    :type edges: ``list``
    :param edges: List of violation edges from the GraphQL response.

    :return: Tuple of (context, human_readable)
    :rtype: ``tuple``
    """
    hr_content = []
    context = []
    for edge in edges:
        node = edge.get("node", {})
        node = remove_empty_elements(node)
        context.append(node)

        status = node.get("status", "")
        display_status = status.replace("POLICY_VIOLATION_STATUS_", "").replace("_", " ").title() if status else ""

        severity = demisto.get(node, "policy.policySeverity", "")
        display_severity = severity.title() if severity else ""

        hr_content.append(
            {
                "ID": node.get("policyViolationId"),
                "Violation Name": demisto.get(node, "policy.name"),
                "Severity": display_severity,
                "Object Name": demisto.get(node, "resourceMetadata.metadata.name"),
                "Violation Status": display_status,
                "High Risk Hits": demisto.get(node, "details.violatedHighRiskSensitiveHits"),
                "Medium Risk Hits": demisto.get(node, "details.violatedMediumRiskSensitiveHits"),
                "Low Risk Hits": demisto.get(node, "details.violatedLowRiskSensitiveHits"),
                "No Risk Hits": demisto.get(node, "details.violatedNoRiskSensitiveHits"),
                "Detection On": node.get("createdAt"),
            }
        )

    hr = tableToMarkdown(
        "DSPM Violations List",
        hr_content,
        headers=[
            "ID",
            "Violation Name",
            "Severity",
            "Object Name",
            "Violation Status",
            "High Risk Hits",
            "Medium Risk Hits",
            "Low Risk Hits",
            "No Risk Hits",
            "Detection On",
        ],
        removeNull=True,
    )
    return context, hr


def validate_ioc_scan_list_v2_command_args(
    limit: Optional[int], ioc_match: Optional[list], quarantine_status: Optional[list], hunt_status: Optional[list]
):
    """
    Validate the arguments of the IOC scan list v2 command.

    :type limit: ``Optional[int]``
    :param limit: Limit value.

    :type ioc_match: ``Optional[list]``
    :param ioc_match: List of IOC match values.

    :type quarantine_status: ``Optional[list]``
    :param quarantine_status: List of quarantine status values.

    :type hunt_status: ``Optional[list]``
    :param hunt_status: List of hunt status values.

    :return: None
    :raises ValueError: If any argument is invalid.
    """
    if not limit or not 1 <= limit <= MAXIMUM_PAGINATION_LIMIT:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    if ioc_match:
        for i_match in ioc_match:
            if i_match not in IOC_MATCHES:
                raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(i_match, "ioc_match", IOC_MATCHES))

    if quarantine_status:
        for q_status in quarantine_status:
            if q_status not in QUERANTINE_STATUS:
                raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(q_status, "quarantine_status", QUERANTINE_STATUS))

    if hunt_status:
        for h_status in hunt_status:
            if h_status not in HUNT_STATUSES:
                raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(h_status, "hunt_status", HUNT_STATUSES))


def prepare_context_hr_ioc_scan_v2_list(edges: list) -> tuple:
    """
    Prepare context and human readable output for IOC scan list.

    :type edges: ``list``
    :param edges: List of edges from GraphQL response.

    :return: Tuple of context and human readable output.
    """
    hr_content = []
    context = []

    for edge in edges:
        node = edge.get("node", {})
        node = remove_empty_elements(node)
        context.append(node)
        hr_content.append(
            {
                "Hunt ID": node.get("huntId"),
                "Hunt Name": node.get("huntName"),
                "Hunt Type": node.get("huntType"),
                "Status": node.get("status"),
                "Start Time": node.get("startTime"),
            }
        )

    hr = tableToMarkdown(
        "IOC Scan List",
        hr_content,
        headers=[
            "Hunt ID",
            "Hunt Name",
            "Hunt Type",
            "Status",
            "Start Time",
        ],
        removeNull=True,
    )

    return context, hr


def prepare_hr_ioc_scan_results_v2(ioc_scan_data: dict) -> str:
    """
    Prepare human readable response for rubrik-ioc-scan-results-v2.

    :type ioc_scan_data: ``dict``
    :param ioc_scan_data: ioc scan data from the response received from the API.

    :return: human readable for the command.
    :rtype: ``str``
    """
    hr_content = []
    ioc_scan_data = deepcopy(ioc_scan_data)
    basic_config = ioc_scan_data.get("baseConfig", {})

    ioc_details = remove_typename(basic_config.get("ioc", {}).get("iocList", {}).get("indicatorsOfCompromise", []))
    object_metric = remove_typename(ioc_scan_data.get("threatHuntObjectMetrics", {}))
    scan_metric = {
        "totalMatchedSnapshots": ioc_scan_data.get("totalMatchedSnapshots"),
        "totalScannedSnapshots": ioc_scan_data.get("totalScannedSnapshots"),
        "totalUniqueFileMatches": ioc_scan_data.get("totalUniqueFileMatches"),
    }

    hr_content.append(
        {
            "Hunt Name": basic_config.get("name"),
            "Hunt Type": basic_config.get("threatHuntType"),
            "Status": ioc_scan_data.get("status"),
            "IOC Details": ioc_details,
            "Object Metrics": object_metric,
            "Scan Metrics": scan_metric,
            "Start Time": ioc_scan_data.get("startTime"),
            "End Time": ioc_scan_data.get("endTime"),
        }
    )
    hr = tableToMarkdown(
        "IOC Scan Data",
        hr_content,
        headers=[
            "Hunt Name",
            "Hunt Type",
            "Status",
            "IOC Details",
            "Object Metrics",
            "Scan Metrics",
            "Start Time",
            "End Time",
        ],
        json_transform_mapping={
            "IOC Details": JsonTransformer(is_nested=True),
            "Object Metrics": JsonTransformer(is_nested=True),
            "Scan Metrics": JsonTransformer(is_nested=True),
        },
        removeNull=True,
    )
    return hr


def validate_turbo_ioc_scan_command_args(ioc: list, max_snapshots_per_object: Optional[int]):
    """
    Validate the arguments of the turbo ioc scan command.

    :type ioc: ``list``
    :param ioc: list of IOC values.

    :type max_snapshots_per_object: ``Optional[int]``
    :param max_snapshots_per_object: The max snapshots per object value.

    :return: None
    """
    if not ioc:
        raise ValueError(ERROR_MESSAGES["MISSING_REQUIRED_FIELD"].format("ioc"))
    if max_snapshots_per_object is not None and max_snapshots_per_object < 1:
        raise ValueError(ERROR_MESSAGES["NEGATIVE_ARG_VALUE"].format(max_snapshots_per_object, "max_snapshots_per_object"))
    if max_snapshots_per_object is not None and max_snapshots_per_object > MAX_INT_VALUE:
        raise ValueError(
            ERROR_MESSAGES["INVALID_INT_VALUE"].format(max_snapshots_per_object, "max_snapshots_per_object", MAX_INT_VALUE)
        )


def prepare_ioc_and_validate_advance_ioc_scan_args(
    ioc_type: Any,
    ioc_value: Any,
    advance_ioc: Any,
    max_matches_per_snapshot: Optional[int],
    max_snapshots_per_object: Optional[int],
    min_file_size: Optional[int],
    max_file_size: Optional[int],
) -> list:
    """
    Prepare and validate the arguments of the advance ioc scan command.

    :type ioc_type: ``Any``
    :param ioc_type: Type of IOC.

    :type ioc_value: ``Any``
    :param ioc_value: Value of IOC.

    :type advance_ioc: ``Any``
    :param advance_ioc: Advance IOC.

    :type max_matches_per_snapshot: ``Optional[int]``
    :param max_matches_per_snapshot: Maximum matches per snapshot.

    :type max_snapshots_per_object: ``Optional[int]``
    :param max_snapshots_per_object: Maximum snapshots per object.

    :type min_file_size: ``Optional[int]``
    :param min_file_size: Minimum file size.

    :type max_file_size: ``Optional[int]``
    :param max_file_size: Maximum file size.

    :return: List of IOCs.
    :rtype: ``list``
    """
    if ioc_type and ioc_type not in IOC_TYPE_ENUM:
        raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(ioc_type, "ioc_type", IOC_TYPE_ENUM))

    if not (ioc_type and ioc_value) and not advance_ioc:
        raise ValueError(ERROR_MESSAGES["NO_INDICATOR_SPECIFIED"])

    if max_matches_per_snapshot is not None and max_matches_per_snapshot < 1:
        raise ValueError(ERROR_MESSAGES["NEGATIVE_ARG_VALUE"].format(max_matches_per_snapshot, "max_matches_per_snapshot"))
    if max_matches_per_snapshot is not None and max_matches_per_snapshot > MAX_INT_VALUE:
        raise ValueError(
            ERROR_MESSAGES["INVALID_INT_VALUE"].format(max_matches_per_snapshot, "max_matches_per_snapshot", MAX_INT_VALUE)
        )
    if max_snapshots_per_object is not None and max_snapshots_per_object < 1:
        raise ValueError(ERROR_MESSAGES["NEGATIVE_ARG_VALUE"].format(max_snapshots_per_object, "max_snapshots_per_object"))
    if max_snapshots_per_object is not None and max_snapshots_per_object > MAX_INT_VALUE:
        raise ValueError(
            ERROR_MESSAGES["INVALID_INT_VALUE"].format(max_snapshots_per_object, "max_snapshots_per_object", MAX_INT_VALUE)
        )
    if min_file_size is not None and min_file_size < 1:
        raise ValueError(ERROR_MESSAGES["NEGATIVE_ARG_VALUE"].format(min_file_size, "min_file_size"))
    if min_file_size is not None and min_file_size > MAX_LONG_VALUE:
        raise ValueError(ERROR_MESSAGES["INVALID_INT_VALUE"].format(min_file_size, "min_file_size", MAX_LONG_VALUE))
    if max_file_size is not None and max_file_size < 1:
        raise ValueError(ERROR_MESSAGES["NEGATIVE_ARG_VALUE"].format(max_file_size, "max_file_size"))
    if max_file_size is not None and max_file_size > MAX_LONG_VALUE:
        raise ValueError(ERROR_MESSAGES["INVALID_INT_VALUE"].format(max_file_size, "max_file_size", MAX_LONG_VALUE))

    iocs = []
    if advance_ioc:
        try:
            advance_ioc_dict = json.loads(advance_ioc)
            for ioc_type, ioc_values in advance_ioc_dict.items():
                if isinstance(ioc_values, list):
                    for value in ioc_values:
                        iocs.append({"iocKind": IOC_TYPE_MAPPING.get(ioc_type), "iocValue": value})
                else:
                    iocs.append({"iocKind": IOC_TYPE_MAPPING.get(ioc_type), "iocValue": ioc_values})
        except json.JSONDecodeError:
            raise ValueError(ERROR_MESSAGES["JSON_DECODE"].format("advance_ioc"))
    else:
        iocs.append({"iocKind": IOC_TYPE_MAPPING.get(ioc_type), "iocValue": ioc_value})

    return iocs


def check_empty(x: Any) -> bool:
    """
    Check if input is empty (None, empty dict, empty list, or empty string).

    :param x: Input to check.
    :type x: Any
    :return: True if x is empty, False otherwise.
    :rtype: bool
    """
    return x is None or x == {} or x == [] or x == ""


def remove_empty_elements_for_fetch(d: Any) -> Any:
    """
    Recursively remove empty lists, empty dicts, or None elements from a dictionary or list.
    :param d: Input dictionary or list.
    :return: Dictionary or list with all empty lists, and empty dictionaries removed.
    """
    if not isinstance(d, dict | list):
        return d
    elif isinstance(d, list):
        return [v for v in (remove_empty_elements_for_fetch(v) for v in d) if not check_empty(v)]
    return {k: v for k, v in ((k, remove_empty_elements_for_fetch(v)) for k, v in d.items()) if not check_empty(v)}


def remove_empty_elements_for_hr(d: Any) -> Any:
    """
    Recursively remove empty lists, empty dicts, or None elements from a dictionary or list.
    Non-collection scalar values (int, float, bool) are converted to strings so that
    falsy values like 0 and False are preserved in human-readable output.

    :type d: Any
    :param d: Input dictionary or list.

    :return: Dictionary or list with empty elements removed and scalars stringified.
    :rtype: Any
    """
    if not isinstance(d, dict | list):
        return str(d) if isinstance(d, int | float | bool) else d
    elif isinstance(d, list):
        return [v for v in (remove_empty_elements_for_hr(v) for v in d) if not check_empty(v)]
    return {k: v for k, v in ((k, remove_empty_elements_for_hr(v)) for k, v in d.items()) if not check_empty(v)}


def validate_data_security_violation_file_list_command_args(
    limit: Optional[int],
    sort_by: str,
    sort_order: str,
    sensitivities: list,
    exposures: list,
    access_via: str,
    last_access_start_date: Optional[datetime],
    last_access_end_date: Optional[datetime],
    last_modified_start_date: Optional[datetime],
    last_modified_end_date: Optional[datetime],
    creation_start_date: Optional[datetime],
    creation_end_date: Optional[datetime],
    last_scan_start_date: Optional[datetime],
    last_scan_end_date: Optional[datetime],
):
    """
    Validate the arguments of the rubrik-data-security-violation-file-list command.

    :type limit: ``Optional[int]``
    :param limit: The number of results to return.

    :type sort_by: ``Optional[str]``
    :param sort_by: The field to sort by.

    :type sort_order: ``str``
    :param sort_order: The sort order (ASC or DESC).

    :type sensitivities: ``list``
    :param sensitivities: The list of file sensitivites.

    :type exposures: ``list``
    :param exposures: The list of file exposures.

    :type access_via: ``str``
    :param access_via: The file access via type.

    :type last_access_start_date: ``Optional[datetime]``
    :param last_access_start_date: The file access start date.

    :type last_access_end_date: ``Optional[datetime]``
    :param last_access_end_date: The file access end date.

    :type last_modified_start_date: ``Optional[datetime]``
    :param last_modified_start_date: The file modified start date.

    :type last_modified_end_date: ``Optional[datetime]``
    :param last_modified_end_date: The file modified end date.

    :type creation_start_date: ``Optional[datetime]``
    :param creation_start_date: The file create start date.

    :type creation_end_date: ``Optional[datetime]``
    :param creation_end_date: The file create end date.

    :type last_scan_start_date: ``Optional[datetime]``
    :param last_scan_start_date: The file scan start date.

    :type last_scan_end_date: ``Optional[datetime]``
    :param last_scan_end_date: The file scan end date.

    :raises ValueError: If any parameter value is not valid.
    """
    if not limit or not 1 <= limit <= MAXIMUM_PAGINATION_LIMIT:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    if sort_by and sort_by.upper() not in DSPM_VIOLATION_FILE_LIST_SORT_BY:
        raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(sort_by, "sort_by", DSPM_VIOLATION_FILE_LIST_SORT_BY))

    if sort_order.upper() not in (ASCENDING_SORT_ORDER, DESCENDING_SORT_ORDER):
        raise ValueError(ERROR_MESSAGES["INVALID_SORT_ORDER"].format(sort_order))

    for sensitivity in sensitivities:
        if sensitivity.upper() not in DSPM_VIOLATION_FILE_LIST_SENSITIVITY:
            raise ValueError(
                ERROR_MESSAGES["INVALID_SELECT"].format(sensitivity, "sensitivity", DSPM_VIOLATION_FILE_LIST_SENSITIVITY)
            )

    for exposure in exposures:
        if exposure.upper() not in DSPM_VIOLATION_FILE_LIST_EXPOSURE:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(exposure, "exposure", DSPM_VIOLATION_FILE_LIST_EXPOSURE))

    if access_via and access_via.upper() not in DSPM_VIOLATION_FILE_LIST_ACCESS_VIA:
        raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(access_via, "access_via", DSPM_VIOLATION_FILE_LIST_ACCESS_VIA))

    if bool(last_access_start_date) != bool(last_access_end_date):
        raise ValueError(ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("last_access_start_date", "last_access_end_date"))

    if bool(last_modified_start_date) != bool(last_modified_end_date):
        raise ValueError(
            ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("last_modified_start_date", "last_modified_end_date")
        )

    if bool(creation_start_date) != bool(creation_end_date):
        raise ValueError(ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("creation_start_date", "creation_end_date"))

    if bool(last_scan_start_date) != bool(last_scan_end_date):
        raise ValueError(ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("last_scan_start_date", "last_scan_end_date"))

    validate_date_range(last_access_start_date, "last_access_start_date", last_access_end_date, "last_access_end_date")
    validate_date_range(last_modified_start_date, "last_modified_start_date", last_modified_end_date, "last_modified_end_date")
    validate_date_range(creation_start_date, "creation_start_date", creation_end_date, "creation_end_date")
    validate_date_range(last_scan_start_date, "last_scan_start_date", last_scan_end_date, "last_scan_end_date")


def prepare_context_hr_data_security_violation_file_list(edges: list) -> tuple:
    """
    Prepare context and human readable output for the rubrik-data-security-violation-file-list command.

    :type edges: ``list``
    :param edges: List of files edges from the GraphQL response.

    :return: Tuple of (context, human_readable)
    :rtype: ``tuple``
    """
    hr_content = []
    context = []
    for edge in edges:
        node = edge.get("node", {})
        node = remove_empty_elements(node)
        context.append(node)
        last_access_time = node.get("lastAccessTime")
        last_access_time_str = (
            datetime.fromtimestamp(last_access_time, tz=timezone.utc).strftime(HR_DATE_TIME_FORMAT)
            if last_access_time is not None
            else ""
        )
        last_modified_time = node.get("lastModifiedTime")
        last_modified_time_str = (
            datetime.fromtimestamp(last_modified_time, tz=timezone.utc).strftime(HR_DATE_TIME_FORMAT)
            if last_modified_time is not None
            else ""
        )
        total_risk_hits = demisto.get(node, "hits.violations") or 0
        high_risk_hits = demisto.get(node, "sensitiveHits.highRiskHits.violatedHits") or 0
        medium_risk_hits = demisto.get(node, "sensitiveHits.mediumRiskHits.violatedHits") or 0
        low_risk_hits = demisto.get(node, "sensitiveHits.lowRiskHits.violatedHits") or 0
        no_risk_hits = demisto.get(node, "sensitiveHits.noRiskHits.violatedHits") or 0
        data_categories = [
            {
                "id": demisto.get(result, "analyzerGroup.id", ""),
                "name": demisto.get(result, "analyzerGroup.name", ""),
                "totalViolatedHits": demisto.get(result, "hits.violations") or 0,
            }
            for result in node.get("analyzerGroupResults", [])
        ]

        hr_content.append(
            {
                FILE_PATH: node.get("stdPath"),
                FILE_SIZE: node.get("size"),
                TOTAL_RISK_HITS: total_risk_hits,
                HIGH_RISK_HITS: high_risk_hits,
                MEDIUM_RISK_HITS: medium_risk_hits,
                LOW_RISK_HITS: low_risk_hits,
                NO_RISK_HITS: no_risk_hits,
                "Data Categories": data_categories,
                LAST_ACCESS_TIME: last_access_time_str,
                LAST_MODIFIED_TIME: last_modified_time_str,
            }
        )

    hr = tableToMarkdown(
        "DSPM Violation File List",
        hr_content,
        headers=[
            FILE_PATH,
            FILE_SIZE,
            TOTAL_RISK_HITS,
            HIGH_RISK_HITS,
            MEDIUM_RISK_HITS,
            LOW_RISK_HITS,
            NO_RISK_HITS,
            LAST_ACCESS_TIME,
            LAST_MODIFIED_TIME,
            "Data Categories",
        ],
        removeNull=True,
        json_transform_mapping={"Data Categories": JsonTransformer()},
    )
    return context, hr


def validate_ir_violation_list_command_args(
    limit: Optional[int],
    sort_by: Optional[str],
    sort_order: str,
    detection_start_date: Optional[datetime],
    detection_end_date: Optional[datetime],
    resolved_start_date: Optional[datetime],
    resolved_end_date: Optional[datetime],
):
    """
    Validate the arguments of the rubrik-identity-resilience-violation-list command.

    :type limit: ``Optional[int]``
    :param limit: The number of results to return.

    :type sort_by: ``Optional[str]``
    :param sort_by: The field to sort by.

    :type sort_order: ``str``
    :param sort_order: The sort order (ASC or DESC).

    :type detection_start_date: ``Optional[datetime]``
    :param detection_start_date: The detection start date.

    :type detection_end_date: ``Optional[datetime]``
    :param detection_end_date: The detection end date.

    :type resolved_start_date: ``Optional[datetime]``
    :param resolved_start_date: The resolved start date.

    :type resolved_end_date: ``Optional[datetime]``
    :param resolved_end_date: The resolved end date.

    :raises ValueError: If any parameter value is not valid.
    """
    if not limit or not 1 <= limit <= MAXIMUM_PAGINATION_LIMIT:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    if sort_by and sort_by.upper() not in IR_VIOLATION_SORT_BY:
        raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(sort_by, "sort_by", IR_VIOLATION_SORT_BY))

    if sort_order.upper() not in (ASCENDING_SORT_ORDER, DESCENDING_SORT_ORDER):
        raise ValueError(ERROR_MESSAGES["INVALID_SORT_ORDER"].format(sort_order))

    if bool(detection_start_date) != bool(detection_end_date):
        raise ValueError(ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("detection_start_date", "detection_end_date"))

    if bool(resolved_start_date) != bool(resolved_end_date):
        raise ValueError(ERROR_MESSAGES["MISSING_TWO_REQUIRED_FIELD"].format("resolved_start_date", "resolved_end_date"))

    validate_date_range(detection_start_date, "detection_start_date", detection_end_date, "detection_end_date")
    validate_date_range(resolved_start_date, "resolved_start_date", resolved_end_date, "resolved_end_date")


def prepare_context_hr_identity_resilience_violation_list(edges: list) -> tuple:
    """
    Prepare context and human readable output for the rubrik-identity-resilience-violation-list command.

    :type edges: ``list``
    :param edges: List of violation edges from the GraphQL response.

    :return: Tuple of (context, human_readable)
    :rtype: ``tuple``
    """
    hr_content = []
    context = []
    for edge in edges:
        node = edge.get("node", {})
        node = remove_empty_elements(node)
        context.append(node)

        status = node.get("status", "")
        display_status = status.replace("POLICY_VIOLATION_STATUS_", "").replace("_", " ").title() if status else ""

        severity = node.get("violationSeverity", "")
        display_severity = severity.title() if severity else ""

        metadata = demisto.get(node, "resourceMetadata.metadata") or {}

        display_name = metadata.get("displayName")
        domain = metadata.get("domainName")
        actor_name = metadata.get("actorIdentityName")
        target_name = metadata.get("targetIdentityName")
        title = metadata.get("title")
        root_domain = metadata.get("rootDomainName")
        event_time = metadata.get("eventTime")
        detected_on = node.get("createdAt")

        policy_type = demisto.get(node, "policy.policyType", "")
        display_policy_type = policy_type.replace("POLICY_TYPE_", "").replace("_", " ").title() if policy_type else ""

        policy_category = demisto.get(node, "policy.policyCategory", "")
        display_category = policy_category.replace("_", " ").title() if policy_category else ""

        hr_content.append(
            {
                "ID": node.get("policyViolationId"),
                "Policy Name": demisto.get(node, "policy.name"),
                "Display Name": display_name,
                "Domain": domain,
                "Actor Name": actor_name,
                "Target Name": target_name,
                "Status": display_status,
                "Severity": display_severity,
                "Policy Type": display_policy_type,
                "Category": display_category,
                "Title": title,
                "Root Domain": root_domain,
                "Event Time": event_time,
                "Detected On": detected_on,
            },
        )

    hr = tableToMarkdown(
        "IR Violations List",
        hr_content,
        headers=[
            "ID",
            "Policy Name",
            "Display Name",
            "Domain",
            "Actor Name",
            "Target Name",
            "Status",
            "Severity",
            "Policy Type",
            "Category",
            "Title",
            "Root Domain",
            "Event Time",
            "Detected On",
        ],
        removeNull=True,
    )
    return context, hr


def prepare_context_hr_ir_violation_get(violation_data: Dict) -> tuple[Dict, str]:
    """
    Prepare context output and human-readable response for rubrik-identity-resilience-violation-get command.

    :type violation_data: ``Dict``
    :param violation_data: Policy violation data from the API response.

    :return: Context output and human-readable for the command.
    """
    context = remove_empty_elements(violation_data)

    metadata = demisto.get(violation_data, "resourceMetadata.metadata") or {}
    policy = demisto.get(violation_data, "policy") or {}
    details = demisto.get(violation_data, "details") or {}

    status = violation_data.get("status", "")
    display_status = status.replace("POLICY_VIOLATION_STATUS_", "").replace("_", " ").title() if status else ""

    severity = violation_data.get("violationSeverity", "")
    display_severity = severity.title() if severity else ""

    policy_type = demisto.get(violation_data, "policy.policyType", "")
    display_policy_type = policy_type.replace("POLICY_TYPE_", "").replace("_", " ").title() if policy_type else ""

    resource_type = violation_data.get("resourceType", "")
    display_resource_type = resource_type.replace("RESOURCE_TYPE_", "").replace("_", " ").title() if resource_type else ""

    data_categories = violation_data.get("dataCategoryResults", [])
    data_categories_data = [
        {
            "id": demisto.get(dc, "dataCategoryHits.dataCategoryId", ""),
            "name": dc.get("dataCategoryName"),
            "totalViolatedHits": demisto.get(dc, "dataCategoryHits.totalViolatedHits", ""),
        }
        for dc in data_categories
    ]
    sensitive_hits = violation_data.get("sensitiveHits") or {}

    hr_data = {
        "ID": violation_data.get("policyViolationId"),
        "Violation Name": violation_data.get("name"),
        SEVERITY: display_severity,
        "Violation Status": display_status,
        DETECTION_TIME: violation_data.get("createdAt"),
        "Last Updated": violation_data.get("lastUpdatedAt"),
        "Policy ID": policy.get("policyId"),
        "Policy Name": policy.get("name"),
        "Policy Type": display_policy_type,
        "Policy Description": policy.get("description"),
        "Policy Category": policy.get("policyCategory"),
        "Policy Severity": policy.get("policySeverity", "").title() if policy.get("policySeverity") else "",
        "Frameworks": policy.get("frameworks"),
        "Manual Remediation Process": policy.get("manualRemediationProcess"),
        "Identity Status": metadata.get("status"),
        "Resource ID": violation_data.get("resourceId"),
        "Resource Type": display_resource_type,
        "Title": metadata.get("title"),
        "Display Name": metadata.get("displayName"),
        "Domain Name": metadata.get("domainName"),
        "Source": metadata.get("source"),
        "Identity Provider": metadata.get("idpType"),
        "Principal Type": metadata.get("principalType"),
        "Privilege Type": metadata.get("privilegeType"),
        "User Principal Name": metadata.get("userPrincipalName"),
        "Identity Tags": violation_data.get("identityTags"),
        "Native Type": metadata.get("nativeType"),
        "Root Domain Name": metadata.get("rootDomainName"),
        "Entity Name": metadata.get("entityName"),
        "Actor Identity Name": metadata.get("actorIdentityName"),
        "Actor Identity Type": metadata.get("actorIdentityType"),
        "Actor Privilege Type": metadata.get("actorPrivilegeType"),
        "Actor State": metadata.get("actorState"),
        "Target Identity Name": metadata.get("targetIdentityName"),
        "Target Identity Type": metadata.get("targetIdentityType"),
        "Target Identity Source": metadata.get("targetIdentitySource"),
        "Target Identity Status": metadata.get("targetIdentityStatus"),
        "Target Identity Provider": metadata.get("targetIdpType"),
        "Target Privilege Type": metadata.get("targetPrivilegeType"),
        "Event Time": metadata.get("eventTime"),
        "Domain Unique ID": details.get("domainUniqueId"),
        "MITRE Tactic": details.get("mitreTactic"),
        TOTAL_RISK_HITS: demisto.get(sensitive_hits, "totalHits.violatedHits"),
        HIGH_RISK_HITS: demisto.get(sensitive_hits, "highRiskHits.violatedHits"),
        MEDIUM_RISK_HITS: demisto.get(sensitive_hits, "mediumRiskHits.violatedHits"),
        LOW_RISK_HITS: demisto.get(sensitive_hits, "lowRiskHits.violatedHits"),
        NO_RISK_HITS: demisto.get(sensitive_hits, "noRiskHits.violatedHits"),
        "Data Categories": data_categories_data,
    }

    hr = tableToMarkdown(
        "IR Violation Information",
        hr_data,
        removeNull=True,
        sort_headers=False,
        json_transform_mapping={"Data Categories": JsonTransformer()},
    )

    return context, hr


def prepare_context_hr_sensitive_data_object_get(object_data: dict) -> tuple[dict, str]:
    """
    Prepare context output and human-readable response for rubrik-sensitive-data-object-get command.

    :type object_data: ``dict``
    :param object_data: Object detail data from the API response.

    :return: Context output and human-readable for the command.
    """
    analyzer_group_results = demisto.get(object_data, "rootFileResult.analyzerGroupResults") or []
    data_categories = [
        {
            "name": demisto.get(result, "analyzerGroup.name", ""),
            "totalViolatedHits": demisto.get(result, "hits.violations") or 0,
        }
        for result in analyzer_group_results
    ]

    data_type_results = demisto.get(object_data, "rootFileResult.analyzerResults") or []
    data_types = [
        {
            "name": demisto.get(result, "analyzer.name") or "",
            "totalViolatedHits": demisto.get(result, "hits.violations") or 0,
        }
        for result in data_type_results
    ]

    context = remove_empty_elements(object_data)

    logical_paths = demisto.get(object_data, "snappable.logicalPath") or []
    region = ""
    account = ""
    for path in logical_paths:
        object_type = path.get("objectType", "")
        if "Region" in object_type:
            region = path.get("name")
        elif "Account" in object_type:
            account = path.get("name")

    risk_level = object_data.get("riskLevel", "")
    display_risk_level = risk_level.replace("_RISK", "").title() if risk_level else ""

    snapshot_time = object_data.get("snapshotTimestamp")
    snapshot_time_str = ""
    if snapshot_time:
        snapshot_time_str = arg_to_datetime(snapshot_time).strftime(HR_DATE_TIME_FORMAT)  # type: ignore

    hr_data = {
        OBJECT_ID: object_data.get("id"),
        OBJECT_NAME: demisto.get(object_data, "snappable.name"),
        OBJECT_TYPE: demisto.get(object_data, "snappable.objectType"),
        "Risk Level": display_risk_level,
        "OS Type": object_data.get("osType"),
        "Account Name": account,
        "Region": region,
        SNAPSHOT_ID: object_data.get("snapshotFid"),
        "Snapshot Timestamp": snapshot_time_str,
        "SLA Name": demisto.get(object_data, "snappable.effectiveSlaDomain.name"),
        CLUSTER_ID: demisto.get(object_data, "snappable.cluster.id"),
        CLUSTER_NAME: demisto.get(object_data, "snappable.cluster.name"),
        DAILY_HITS_CHANGE: demisto.get(object_data, "rootFileResult.hits.totalHitsDelta"),
        TOTAL_RISK_HITS: demisto.get(object_data, "rootFileResult.sensitiveHits.totalHits.totalHits"),
        HIGH_RISK_HITS: demisto.get(object_data, "rootFileResult.sensitiveHits.highRiskHits.totalHits"),
        MEDIUM_RISK_HITS: demisto.get(object_data, "rootFileResult.sensitiveHits.mediumRiskHits.totalHits"),
        LOW_RISK_HITS: demisto.get(object_data, "rootFileResult.sensitiveHits.lowRiskHits.totalHits"),
        NO_RISK_HITS: demisto.get(object_data, "rootFileResult.sensitiveHits.noRiskHits.totalHits"),
        "Total Files with Hits": demisto.get(object_data, "rootFileResult.filesWithHits.totalHits"),
        "Stale Files with Hits": demisto.get(object_data, "rootFileResult.staleFilesWithHits.totalHits"),
        "Open Access Files with Hits": demisto.get(object_data, "rootFileResult.openAccessFilesWithHits.totalHits"),
        "Data Categories": data_categories,
        "Data Types": data_types,
    }

    hr = tableToMarkdown(
        "Sensitive Data Object",
        remove_empty_elements_for_hr(hr_data),
        removeNull=True,
        sort_headers=False,
        is_auto_json_transform=True,
    )

    return context, hr


def prepare_context_hr_sensitive_data_object_file_get(
    file_access_data: dict, file_details: dict, object_id: str = "", std_path: str = ""
) -> tuple[dict, str]:
    """
    Prepare context output and human-readable response for rubrik-sensitive-data-object-file-get command.

    :type file_access_data: ``dict``
    :param file_access_data: File security descriptor data from the API response.

    :type file_details: ``dict``
    :param file_details: Sensitive file metadata and exposure summary from the API response.

    :type object_id: ``str``
    :param object_id: Unique identifier of the snappable object. Used as a deduplication key in context output.

    :type std_path: ``str``
    :param std_path: Standard file path of the sensitive file. Used as a deduplication key in context output.

    :return: Context output and human-readable for the command.
    """
    sec_info_list = file_access_data.get("secInfo") or []
    file_metadata = demisto.get(file_details, "fileMetadata") or {}
    sec_info = sec_info_list[0] if sec_info_list else {}

    combined_data: dict = {**file_access_data, **file_details, "stdPath": std_path, "objectId": object_id}
    context = remove_empty_elements(combined_data)

    permissions = []
    owner = sec_info.get("owner", "")
    for perm in sec_info.get("permissions") or []:
        access_method = demisto.get(perm, "accessMethodDetails.accessMethod") or ""
        permissions.append(
            {
                "id": perm.get("principalId", ""),
                "name": perm.get("cn", ""),
                "accessMethod": access_method,
                "access": perm.get("access", ""),
            }
        )

    exposure_summary = file_details.get("exposureSummary") or []
    first_exposure = exposure_summary[0] if exposure_summary else {}
    exposure_type = first_exposure.get("exposureType", "")
    file_count = (first_exposure.get("fileCount") or {}).get("totalCount", 0)

    creation_time = file_metadata.get("creationTime")
    creation_time_str = (
        datetime.fromtimestamp(creation_time, tz=timezone.utc).strftime(HR_DATE_TIME_FORMAT) if creation_time is not None else ""
    )
    last_modified_time = file_metadata.get("lastModifiedTime")
    last_modified_time_str = (
        datetime.fromtimestamp(last_modified_time, tz=timezone.utc).strftime(HR_DATE_TIME_FORMAT)
        if last_modified_time is not None
        else ""
    )
    last_access_time = file_metadata.get("lastAccessTime")
    last_access_time_str = (
        datetime.fromtimestamp(last_access_time, tz=timezone.utc).strftime(HR_DATE_TIME_FORMAT)
        if last_access_time is not None
        else ""
    )

    hr_data = {
        FILE_PATH: file_metadata.get("path"),
        FILE_SIZE: file_metadata.get("size"),
        "Owner": owner,
        "Created By": demisto.get(file_metadata, "createdBy.value"),
        "Last Modified By": demisto.get(file_metadata, "lastModifiedBy.value"),
        "Create Time": creation_time_str,
        LAST_MODIFIED_TIME: last_modified_time_str,
        LAST_ACCESS_TIME: last_access_time_str,
        "Exposure Type": exposure_type,
        "File Count": file_count,
        "Permissions": permissions,
    }

    hr = tableToMarkdown(
        "File Information",
        remove_empty_elements_for_hr(hr_data),
        removeNull=True,
        sort_headers=False,
        is_auto_json_transform=True,
    )

    return context, hr


""" COMMAND FUNCTIONS """


def test_module(client: PolarisClient, params: Dict[str, Any]) -> str:
    """Tests validity of provided parameters'.

    Returning 'ok' indicates that the integration works like it is supposed to.
    Connection to the service is successful.
    Raises exceptions if something goes wrong.

    :type client: ``PolarisClient``
    :param client: Rubrik polaris client to use

    :type params: ``dict``
    :param params: params obtained from demisto.params()

    :return: 'ok' if test passed, anything else will fail the test.
    :rtype: ``str``
    """
    is_fetch = params.get("isFetch", DEFAULT_IS_FETCH)

    client._query_raw(raw_query=DEPLOYMENT_VERSION_QUERY, operation_name="DeploymentVersionQuery", variables={}, timeout=60)
    if is_fetch:
        fetch_incidents(client, {}, params)

    return "ok"


def fetch_events(client: PolarisClient, last_run: dict, params: dict, max_fetch: Optional[int]) -> tuple[dict, list]:
    """
    Fetch Rubrik Anomaly incidents.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type last_run: ``dict``
    :param last_run: last run object obtained from demisto.getLastRun()

    :type params: ``dict``
    :param params: arguments obtained from demisto.params()

    :type max_fetch: ``Optional[int]``
    :param max_fetch: The maximum number of incidents to fetch.

    :return: tuple of next run object and list of incidents
    :rtype: ``tuple[dict, list]``
    """
    event_types = argToList(params.get("event_types"), transform=lambda s: s.strip())
    event_severities = argToList(params.get("event_severities"), transform=lambda s: s.strip())

    event_types = [event_type.upper() for event_type in event_types if event_type]
    event_severities = [event_severity.upper() for event_severity in event_severities if event_severity]

    if not event_types:
        event_types = DEFAULT_EVENT_TYPES
    elif any(event_type not in DEFAULT_EVENT_TYPES for event_type in event_types):
        raise ValueError(MESSAGES["INVALID_FETCH_EVENT_TYPE"])

    if not event_severities:
        event_severities = DEFAULT_SEVERITIES
    elif any(event_severity not in DEFAULT_EVENT_SEVERITIES for event_severity in event_severities):
        raise ValueError(MESSAGES["INVALID_FETCH_EVENT_SEVERITIES"])

    event_last_run = last_run
    last_run_time = event_last_run.get("last_fetch", None)
    next_page_token = event_last_run.get("next_page_token", "")

    evnet_next_run = event_last_run.copy()

    if last_run_time is None:
        # if the last run has not been set (i.e on the first run)
        # check to see if a first_fetch value has been provided. If it hasn't
        # return the current time
        first_fetch = params.get("first_fetch", DEFAULT_FIRST_FETCH)
        first_fetch = arg_to_datetime(first_fetch, "First fetch time")
        last_run_time = first_fetch.strftime(DATE_TIME_FORMAT)  # type: ignore
        evnet_next_run["last_fetch"] = last_run_time
    # removed manual fetch interval as this feature is built in XSOAR 6.0.0 and onwards

    filters = {"lastActivityStatus": DEFAULT_ACTIVITY_STATUSES, "severity": event_severities}

    events = client.list_event_series(
        activity_type=",".join(event_types),
        start_date=last_run_time,
        sort_order="ASC",
        first=max_fetch,
        after=next_page_token,
        filters=filters,
    )

    activity_series_connection = events.get("data", {}).get("activitySeriesConnection", {})

    new_next_page_token = activity_series_connection.get("pageInfo", {}).get("endCursor", "")
    if new_next_page_token:
        evnet_next_run["next_page_token"] = new_next_page_token

    incidents = []

    edges = activity_series_connection.get("edges", [])
    for event in edges:
        processed_incident = {"incidentClassification": "RubrikRadar", "message": [], "severity": IncidentSeverity.UNKNOWN}
        node = event.get("node", {})

        processed_incident.update(node)
        processed_incident["eventCompleted"] = "True" if node.get("lastActivityStatus", "") == "Success" else False
        activity_connection = node.get("activityConnection", {})
        activity_nodes = activity_connection.get("nodes", [])
        processed_incident = process_activity_nodes(activity_nodes, processed_incident)

        base_url = str(client._baseurl).removesuffix("api")
        activity_series_id = node.get("activitySeriesId", "")
        cluster_id = node.get("cluster", {}).get("id", "")
        processed_incident["incident_link"] = EVENT_HYPERLINK.format(base_url, activity_series_id, cluster_id)

        # Map Severity Level
        severity = node.get("severity", "")
        if severity == "Critical" or severity == "Warning":
            if params.get(f"radar_{severity.lower()}_severity_mapping"):
                severity_mapping = params.get(f"radar_{severity.lower()}_severity_mapping", "XSOAR LOW")
            else:
                severity_mapping = "XSOAR LOW"

            processed_incident["severity"] = convert_to_demisto_severity(severity_mapping)

        else:
            processed_incident["severity"] = IncidentSeverity.LOW

        incidents.append(
            {
                "name": f"Rubrik Radar Anomaly - {processed_incident.get('objectName', '')}",
                "occurred": processed_incident.get("lastUpdated", ""),
                "rawJSON": json.dumps(processed_incident),
                "severity": processed_incident["severity"],
            }
        )
    demisto.debug(f"Checkpoint for Events: Next page token = {evnet_next_run.get('next_page_token')}")
    return evnet_next_run, incidents


def fetch_threat_monitoring_objects(
    client: PolarisClient, last_run: dict, params: dict, max_fetch: Optional[int]
) -> tuple[dict, list]:
    """
    Fetch Rubrik threat monitoring objects as incidents.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type last_run: ``dict``
    :param last_run: last run object obtained from demisto.getLastRun()

    :type params: ``dict``
    :param params: arguments obtained from demisto.params()

    :type max_fetch: ``Optional[int]``
    :param max_fetch: The maximum number of incidents to fetch.

    :return: tuple of next run object and list of incidents
    :rtype: ``tuple[dict, list]``
    """
    match_types = argToList(params.get("threat_monitoring_match_types"), transform=lambda s: s.strip())
    object_types = argToList(params.get("threat_monitoring_object_types"), transform=lambda s: s.strip())

    threat_monitoring_last_run = last_run.get("threat_monitoring", {})
    last_run_time = threat_monitoring_last_run.get("last_fetch", None)
    next_page_token = threat_monitoring_last_run.get("next_page_token", "")
    match_type_filter = threat_monitoring_last_run.get("match_type_filter", [])
    object_type_filter = threat_monitoring_last_run.get("object_type_filter", [])
    already_fetched = threat_monitoring_last_run.get("already_fetched", [])

    threat_monitoring_next_run = threat_monitoring_last_run.copy()

    if last_run_time is None:
        # if the last run has not been set (i.e on the first run)
        # check to see if a first_fetch value has been provided. If it hasn't
        # return the current time
        first_fetch = params.get("first_fetch", DEFAULT_FIRST_FETCH)
        first_fetch = arg_to_datetime(first_fetch, "First fetch time")
        last_run_time = first_fetch.strftime(DATE_TIME_FORMAT)  # type: ignore
        threat_monitoring_next_run["last_fetch"] = last_run_time

    for match_type in match_types:
        if match_type not in IOC_TYPE_ENUM:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(match_type, "match_type", IOC_TYPE_ENUM))

    ioc_match_type = []
    for match_type in match_types:
        ioc_match_type.append(IOC_TYPE_MAPPING.get(match_type))

    ioc_match_type.sort()
    if isinstance(object_types, list):
        object_types.sort()
    if ioc_match_type != match_type_filter or object_types != object_type_filter:
        next_page_token = ""

    threat_monitoring_filters = {
        "matchTypeFilter": ioc_match_type,
        "objectTypeFilter": object_types,
        "after": next_page_token,
        "beginTime": last_run_time,
        "first": max_fetch,
    }

    remove_nulls_from_dictionary(threat_monitoring_filters)

    threat_monitoring_response = client._query_raw(
        raw_query=THREAT_MONITORING_MATCHED_OBJECT_LIST_QUERY,
        operation_name="ThreatMonitoringMatchedObjectsQuery",
        variables=threat_monitoring_filters,
        timeout=60,
    )

    edges = []
    page_info = {}
    threat_monitoring_data = threat_monitoring_response.get("data", {})
    if threat_monitoring_data is not None:
        edges = threat_monitoring_data.get("threatMonitoringMatchedObjects", {}).get("edges", [])
        page_info = threat_monitoring_data.get("threatMonitoringMatchedObjects", {}).get("pageInfo", {})

    page_cursor = remove_empty_elements(page_info)
    new_next_page_token = page_cursor.get("endCursor")
    if new_next_page_token:
        threat_monitoring_next_run["next_page_token"] = new_next_page_token

    if params.get("threat_monitoring_severity_mapping"):
        severity_mapping = params.get("threat_monitoring_severity_mapping", "XSOAR HIGH")
    else:
        severity_mapping = "XSOAR HIGH"

    incident_severity = convert_to_demisto_severity(severity_mapping)

    incidents = []

    for threat_object in edges:
        node = threat_object.get("node", {})

        if node.get("objectFid") in already_fetched:
            continue
        already_fetched.append(node.get("objectFid"))

        processed_incident = {
            "incidentClassification": "RubrikThreatMonitoringObject",
            "message": [],
            "severity": incident_severity,
        }
        processed_incident.update(node)

        base_url = str(client._baseurl).removesuffix("api")
        processed_incident["incident_link"] = THREAT_MONITORING_HYPERLINK.format(base_url, node.get("objectFid", ""))

        incidents.append(
            {
                "name": f"Rubrik Radar Threat Monitoring Object - {processed_incident.get('objectName', '')}",
                "occurred": processed_incident.get("lastDetection", ""),
                "rawJSON": json.dumps(processed_incident),
                "severity": processed_incident.get("severity"),
            }
        )

    threat_monitoring_next_run["match_type_filter"] = ioc_match_type
    threat_monitoring_next_run["object_type_filter"] = object_types
    threat_monitoring_next_run["already_fetched"] = already_fetched
    demisto.debug(
        f"Checkpoint for Threat monitoring objects: Next page token = {threat_monitoring_next_run.get('next_page_token')}, "
        f"Match Type = {threat_monitoring_next_run.get('match_type_filter')}, "
        f"Object Type = {threat_monitoring_next_run.get('object_type_filter')}"
    )
    return threat_monitoring_next_run, incidents


def fetch_dspm_violations(client: PolarisClient, last_run: dict, params: dict, max_fetch: Optional[int]) -> tuple[dict, list]:
    """
    Fetch Rubrik DSPM violations as incidents.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type last_run: ``dict``
    :param last_run: last run object obtained from demisto.getLastRun().

    :type params: ``dict``
    :param params: arguments obtained from demisto.params().

    :type max_fetch: ``Optional[int]``
    :param max_fetch: The maximum number of incidents to fetch.

    :return: tuple of next run object and list of incidents.
    :rtype: ``tuple[dict, list]``
    """
    # Get configuration parameters
    violation_statuses = argToList(
        params.get("dspm_violation_status", DEFAULT_DSPM_VIOLATION_STATUS), transform=lambda s: s.strip()
    )
    violation_severities = argToList(params.get("dspm_violation_severity"), transform=lambda s: s.strip())
    violation_sensitivities = argToList(params.get("dspm_violation_sensitivity"), transform=lambda s: s.strip())
    violation_categories = argToList(params.get("dspm_violation_category"), transform=lambda s: s.strip().upper())
    violation_object_types = argToList(params.get("dspm_violation_object_type"), transform=lambda s: s.strip().upper())
    current_time = arg_to_datetime("now").strftime(DATE_TIME_FORMAT)  # type: ignore

    # Get last run state for DSPM violations
    dspm_last_run = last_run.get("dspm_violation", {})
    last_run_time = dspm_last_run.get("last_fetch", None)
    next_page_token = dspm_last_run.get("next_page_token", "")
    already_fetched = dspm_last_run.get("already_fetched", [])

    dspm_next_run = dspm_last_run.copy()

    # Initialize last_run_time if this is the first fetch
    if last_run_time is None:
        first_fetch = params.get("first_fetch", DEFAULT_FIRST_FETCH)
        first_fetch = arg_to_datetime(first_fetch, "First fetch time")
        last_run_time = first_fetch.strftime(DATE_TIME_FORMAT)  # type: ignore
        dspm_next_run["last_fetch"] = last_run_time

    # Map configuration values to API enum values
    statuses, severities, sensitivities = validate_dspm_violation_fetch_params(
        violation_statuses, violation_severities, violation_sensitivities
    )
    # Prepare GraphQL query variables
    dspm_filters = {
        "statuses": statuses,
        "severities": severities,
        "sensitivityLevels": sensitivities,
        "categories": violation_categories,
        "detectionDate": {
            "start": last_run_time,
            "end": current_time,
        },
        "first": max_fetch,
        "after": next_page_token,
        "sortBy": "SORT_DETECTION_TIME",
        "sortOrder": ASCENDING_SORT_ORDER,
    }
    if violation_object_types:
        dspm_filters["resourceMetadataFilter"] = {"managedObjectTypes": violation_object_types}

    # Remove None values
    remove_nulls_from_dictionary(dspm_filters)

    # Execute GraphQL query
    dspm_response = client._query_raw(
        raw_query=DSPM_VIOLATIONS_LIST_QUERY,
        operation_name="DataSecurityViolationsListQuery",
        variables=dspm_filters,
        timeout=60,
    )

    edges = []
    page_info = {}
    dspm_data = dspm_response.get("data", {})
    if dspm_data is not None:
        edges = demisto.get(dspm_data, "policyViolations.edges", [])
        page_info = demisto.get(dspm_data, "policyViolations.pageInfo", {})

    # Update next page token
    page_cursor = remove_empty_elements(page_info)
    new_next_page_token = page_cursor.get("endCursor")
    if new_next_page_token:
        dspm_next_run["next_page_token"] = new_next_page_token

    incidents = []
    duplicate_violation_ids = []

    for violation in edges:
        node = violation.get("node", {})
        violation_id = node.get("policyViolationId")

        # Skip if already fetched (deduplication)
        if violation_id in already_fetched:
            duplicate_violation_ids.append(violation_id)
            continue

        already_fetched.append(violation_id)

        # Prepare incident data
        processed_incident: dict[str, Any] = {
            "incidentClassification": "RubrikDSPMViolation",
        }
        processed_incident.update(node)

        # Create incident link
        base_url = str(client._baseurl).removesuffix("api")
        resource_id = node.get("resourceId", "")
        policy_id = demisto.get(node, "policy.policyId", "")
        snapshot_id = demisto.get(node, "details.snapshotId", "")

        # Build the violation details URL
        if violation_id and resource_id and policy_id and snapshot_id:
            processed_incident["incident_link"] = DSPM_VIOLATION_HYPERLINK.format(
                base_url, violation_id, resource_id, policy_id, snapshot_id
            )

        # Map severity to XSOAR severity
        violation_severity = node.get("violationSeverity", "")
        processed_incident["severity"] = convert_severity_to_incident_severity(violation_severity)

        # Get resource name for incident title
        resource_name = demisto.get(node, "resourceMetadata.metadata.name", "")
        policy_name = demisto.get(node, "policy.name", "")

        incidents.append(
            {
                "name": f"Rubrik DSPM Violation - {policy_name} - {resource_name}",
                "occurred": processed_incident.get("createdAt", ""),
                "rawJSON": json.dumps(remove_empty_elements_for_fetch(processed_incident)),
                "severity": processed_incident.get("severity"),
            }
        )

    dspm_next_run["already_fetched"] = already_fetched

    if duplicate_violation_ids:
        demisto.debug(
            f"DSPM Violation: Skipped {len(duplicate_violation_ids)} duplicate DSPM violation(s): {duplicate_violation_ids}"
        )

    demisto.debug(f"Checkpoint for DSPM Violation: Next page token = {dspm_next_run.get('next_page_token')}")
    return dspm_next_run, incidents


def fetch_ir_violations(client: PolarisClient, last_run: dict, params: dict, max_fetch: Optional[int]) -> tuple[dict, list]:
    """
    Fetch Rubrik IR violations as incidents.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type last_run: ``dict``
    :param last_run: last run object obtained from demisto.getLastRun().

    :type params: ``dict``
    :param params: arguments obtained from demisto.params().

    :type max_fetch: ``Optional[int]``
    :param max_fetch: The maximum number of incidents to fetch.

    :return: tuple of next run object and list of incidents.
    :rtype: ``tuple[dict, list]``
    """
    # Get configuration parameters
    violation_statuses = argToList(
        params.get("ir_violation_status", DEFAULT_IR_VIOLATION_STATUS), transform=lambda s: s.strip().upper()
    )
    violation_severities = argToList(params.get("ir_violation_severity"), transform=lambda s: s.strip().upper())
    violation_categories = argToList(params.get("ir_violation_category"), transform=lambda s: s.strip().upper())
    violation_policy_types = argToList(
        params.get("ir_violation_policy_type", IR_VIOLATION_POLICY_TYPE), transform=lambda s: s.strip().upper()
    )
    violation_identity_providers = argToList(params.get("ir_violation_identity_provider"), transform=lambda s: s.strip().upper())
    violation_identity_tags = argToList(params.get("ir_violation_identity_tag"), transform=lambda s: s.strip().upper())
    current_time = arg_to_datetime("now").strftime(DATE_TIME_FORMAT)  # type: ignore

    # Get last run state for IR violations
    ir_last_run = last_run.get("ir_violation", {})
    last_run_time = ir_last_run.get("last_fetch", None)
    next_page_token = ir_last_run.get("next_page_token", "")
    already_fetched = ir_last_run.get("already_fetched", [])

    ir_next_run = ir_last_run.copy()

    # Initialize last_run_time if this is the first fetch
    if last_run_time is None:
        first_fetch = params.get("first_fetch", DEFAULT_FIRST_FETCH)
        first_fetch = arg_to_datetime(first_fetch, "First fetch time")
        last_run_time = first_fetch.strftime(DATE_TIME_FORMAT)  # type: ignore
        ir_next_run["last_fetch"] = last_run_time

    # Map configuration values to API enum values
    statuses, severities, policy_types, identity_providers, identity_tags = validate_ir_violation_fetch_params(
        violation_statuses,
        violation_severities,
        violation_policy_types,
        violation_identity_providers,
        violation_identity_tags,
    )

    resource_metadata_filter: dict = {}
    if identity_providers:
        resource_metadata_filter["idpTypes"] = identity_providers
    if identity_tags:
        resource_metadata_filter["identityTags"] = identity_tags

    # Prepare GraphQL query variables
    ir_filters = {
        "statuses": statuses,
        "severities": severities,
        "categories": violation_categories,
        "policyTypes": policy_types,
        "detectionDate": {
            "start": last_run_time,
            "end": current_time,
        },
        "first": max_fetch,
        "after": next_page_token,
        "sortBy": "SORT_DETECTION_TIME",
        "sortOrder": ASCENDING_SORT_ORDER,
        "resourceMetadataFilter": resource_metadata_filter,
    }

    # Remove None values
    remove_nulls_from_dictionary(ir_filters)

    # Execute GraphQL query
    ir_response = client._query_raw(
        raw_query=IR_VIOLATIONS_LIST_QUERY,
        operation_name="IdentityResilienceViolationsListQuery",
        variables=ir_filters,
        timeout=60,
    )

    edges = []
    page_info = {}
    ir_violation_data = ir_response.get("data", {})
    if ir_violation_data is not None:
        edges = demisto.get(ir_violation_data, "policyViolations.edges", [])
        page_info = demisto.get(ir_violation_data, "policyViolations.pageInfo", {})

    # Update next page token
    page_cursor = remove_empty_elements(page_info)
    new_next_page_token = page_cursor.get("endCursor")
    if new_next_page_token:
        ir_next_run["next_page_token"] = new_next_page_token

    incidents = []
    duplicate_violation_ids = []

    for violation in edges:
        node = violation.get("node", {})
        violation_id = node.get("policyViolationId")

        # Skip if already fetched (deduplication)
        if violation_id in already_fetched:
            duplicate_violation_ids.append(violation_id)
            continue

        already_fetched.append(violation_id)

        # Prepare incident data
        processed_incident: dict[str, Any] = {
            "incidentClassification": "RubrikIRViolation",
        }
        processed_incident.update(node)

        # Create incident link
        base_url = str(client._baseurl).removesuffix("api")
        policy_id = demisto.get(node, "policy.policyId", "")
        policy_type = demisto.get(node, "policy.policyType", "").removeprefix("POLICY_TYPE_")
        if violation_id:
            if policy_type in IR_ALERT_POLICY_TYPES:
                processed_incident["incident_link"] = IR_ALERT_HYPERLINK.format(base_url, violation_id)
            elif policy_id:
                processed_incident["incident_link"] = IR_VIOLATION_HYPERLINK.format(base_url, policy_id, violation_id)

        # Map severity to XSOAR severity
        violation_severity = node.get("violationSeverity", "")
        processed_incident["severity"] = convert_severity_to_incident_severity(violation_severity)

        # Get resource name for incident title
        resource_name = get_ir_violation_resource_display_name(node)

        policy_name = demisto.get(node, "policy.name", "")
        incident_name = node.get("name", "") or f"{policy_name} - {resource_name}"

        incidents.append(
            {
                "name": f"Rubrik IR Violation - {incident_name}",
                "occurred": processed_incident.get("createdAt", ""),
                "rawJSON": json.dumps(remove_empty_elements_for_fetch(processed_incident)),
                "severity": processed_incident.get("severity"),
            }
        )

    ir_next_run["already_fetched"] = already_fetched

    if duplicate_violation_ids:
        demisto.debug(
            f"IR Violation: Skipped {len(duplicate_violation_ids)} duplicate IR violation(s): {duplicate_violation_ids}"
        )

    demisto.debug(f"Checkpoint for IR Violation: Next page token = {ir_next_run.get('next_page_token')}")
    return ir_next_run, incidents


def fetch_sensitive_data_objects(
    client: PolarisClient, last_run: dict, params: dict, max_fetch: Optional[int]
) -> tuple[dict, list]:
    """
    Fetch Sensitive Data Object incidents by polling CLASSIFICATION events, filtering by the
    "Results available in the Objects page" message, then fetching full object detail.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type last_run: ``dict``
    :param last_run: last run object obtained from demisto.getLastRun().

    :type params: ``dict``
    :param params: arguments obtained from demisto.params().

    :type max_fetch: ``Optional[int]``
    :param max_fetch: The maximum number of incidents to fetch.

    :return: tuple of next run object and list of incidents.
    :rtype: ``tuple[dict, list]``
    """
    object_types = argToList(params.get("sensitive_data_object_type"), transform=lambda s: s.strip())
    sensitivities = argToList(params.get("sensitive_data_object_sensitivity"), transform=lambda s: s.strip().upper())
    valid_sensitivities = validate_sensitive_data_object_fetch_params(sensitivities)

    sensitive_data_object_last_run = last_run.get("sensitive_data_object", {})
    last_run_time = sensitive_data_object_last_run.get("last_fetch", None)
    next_page_token = sensitive_data_object_last_run.get("next_page_token", "")
    already_fetched = sensitive_data_object_last_run.get("already_fetched", [])

    sensitive_data_object_next_run = sensitive_data_object_last_run.copy()

    if last_run_time is None:
        first_fetch = params.get("first_fetch", DEFAULT_FIRST_FETCH)
        first_fetch = arg_to_datetime(first_fetch, "First fetch time")
        last_run_time = first_fetch.strftime(DATE_TIME_FORMAT)  # type: ignore
        sensitive_data_object_next_run["last_fetch"] = last_run_time

    filters = {
        "lastActivityStatus": ["SUCCESS"],
        "lastActivityType": ["CLASSIFICATION"],
        "lastUpdatedTimeGt": last_run_time,
    }
    variables = {
        "first": max_fetch,
        "after": next_page_token,
        "sortOrder": "ASC",
        "filters": filters,
    }
    remove_nulls_from_dictionary(variables)

    events = client._query_raw(
        raw_query=SENSITIVE_DATA_OBJECT_EVENT_SERIES_LIST_QUERY,
        operation_name="SensitiveDataObjectEventSeriesList",
        variables=variables,
        timeout=60,
    )

    activity_series_connection = demisto.get(events, "data.activitySeriesConnection") or {}
    new_next_page_token = demisto.get(activity_series_connection, "pageInfo.endCursor")
    if new_next_page_token:
        sensitive_data_object_next_run["next_page_token"] = new_next_page_token

    edges = activity_series_connection.get("edges", [])
    incidents = []
    duplicate_object_ids = []
    base_url = str(client._baseurl).removesuffix("api")

    unmatched_activity_series_ids = []
    demisto.debug(f"Sensitive Data Object: Received {len(edges)} event(s) from activity series.")
    for event in edges:
        node = event.get("node", {})
        activity_series_id = node.get("activitySeriesId", "")
        object_id = node.get("objectId", "")

        activity_nodes = demisto.get(node, "activityConnection.nodes") or []
        snapshot_fid = ""
        matched = False
        for activity_node in activity_nodes:
            message = activity_node.get("message") or ""
            if message.startswith(SENSITIVE_DATA_OBJECT_CLASSIFICATION_MESSAGE):
                try:
                    activity_info = json.loads(activity_node.get("activityInfo") or "{}")
                except (TypeError, ValueError):
                    demisto.debug(
                        f"Sensitive Data Object: Failed to parse activityInfo for object {object_id}, "
                        f"activity {activity_node.get('id', '')}."
                    )
                    activity_info = {}
                matched = True
                snapshot_fid = activity_info.get("snapshotFid", "")
                break

        if not matched:
            unmatched_activity_series_ids.append(activity_series_id)
            continue

        if object_id in already_fetched:
            duplicate_object_ids.append(object_id)
            continue

        if not snapshot_fid:
            demisto.debug(f"Sensitive Data Object: No snapshot found in activityInfo for object {object_id}, skipping.")
            continue

        # Step 2: fetch full object detail using snappableFid + snapshotFid
        try:
            detail_response = client._query_raw(
                raw_query=SENSITIVE_OBJECT_DETAIL_QUERY,
                operation_name="SensitiveObjectDetailQuery",
                variables={"snappableFid": object_id, "snapshotFid": snapshot_fid},
                timeout=60,
            )
        except Exception as e:
            demisto.debug(
                f"Sensitive Data Object: Failed to fetch detail for object {object_id} "
                f"with snapshot {snapshot_fid}: {str(e)}, skipping."
            )
            continue
        policy_obj = demisto.get(detail_response, "data.policyObj") or {}
        if not policy_obj:
            demisto.debug(f"Sensitive Data Object: No detail returned for object {object_id}, skipping.")
            continue

        total_violations = demisto.get(policy_obj, "rootFileResult.hits.violations") or 0
        if total_violations <= 0:
            demisto.debug(
                f"Sensitive Data Object: No violations found for object {object_id} (violations={total_violations}), skipping."
            )
            continue

        snappable = demisto.get(policy_obj, "snappable") or {}
        risk_level = policy_obj.get("riskLevel", "")
        sensitivity = risk_level.replace("_RISK", "") if risk_level else ""

        if valid_sensitivities and risk_level not in valid_sensitivities:
            demisto.debug(
                f"Sensitive Data Object: Risk level {risk_level} not in filter {valid_sensitivities} "
                f"for object {object_id}, skipping."
            )
            continue

        object_type = snappable.get("objectType", "")
        if object_types and object_type not in object_types:
            demisto.debug(
                f"Sensitive Data Object: Object type {object_type} not in filter {object_types} for object {object_id}, skipping."
            )
            continue

        already_fetched.append(object_id)

        processed_incident: dict[str, Any] = {
            "incidentClassification": "RubrikSensitiveDataObject",
        }
        analyzer_group_results = demisto.get(policy_obj, "rootFileResult.analyzerGroupResults") or []
        data_categories = [
            {
                "name": demisto.get(result, "analyzerGroup.name", ""),
                "totalViolatedHits": demisto.get(result, "hits.violations") or 0,
            }
            for result in analyzer_group_results
        ]

        data_type_results = demisto.get(policy_obj, "rootFileResult.analyzerResults") or []
        data_types = [
            {
                "name": demisto.get(result, "analyzer.name") or "",
                "totalViolatedHits": demisto.get(result, "hits.violations") or 0,
            }
            for result in data_type_results
        ]

        processed_incident.update(policy_obj)
        processed_incident["dataCategories"] = data_categories
        processed_incident["dataTypes"] = data_types
        processed_incident["severity"] = convert_severity_to_incident_severity(sensitivity)
        processed_incident["incident_link"] = SENSITIVE_DATA_OBJECT_HYPERLINK.format(base_url, object_id, snapshot_fid)

        object_name = snappable.get("name", "")

        incidents.append(
            {
                "name": f"Rubrik Sensitive Data Object - {object_name}",
                "occurred": node.get("lastUpdated", ""),
                "rawJSON": json.dumps(remove_empty_elements_for_fetch(processed_incident)),
                "severity": processed_incident.get("severity"),
            }
        )

    sensitive_data_object_next_run["already_fetched"] = already_fetched

    if unmatched_activity_series_ids:
        demisto.debug(
            f"Sensitive Data Object: {len(unmatched_activity_series_ids)} unmatched event(s): {unmatched_activity_series_ids}"
        )

    if duplicate_object_ids:
        demisto.debug(
            f"Sensitive Data Object: Skipped {len(duplicate_object_ids)}"
            f" duplicate sensitive data object(s) ({len(set(duplicate_object_ids))} unique): {list(set(duplicate_object_ids))}"
        )

    demisto.debug(
        f"Checkpoint for Sensitive Data Object: Next page token = {sensitive_data_object_next_run.get('next_page_token')}"
    )
    return sensitive_data_object_next_run, incidents


def fetch_incidents(client: PolarisClient, last_run: dict, params: dict) -> tuple[dict, list]:
    """
    Fetch Rubrik incidents (Events, Threat Monitoring Objects, DSPM Violations, and IR Violations).

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type last_run: ``dict``
    :param last_run: last run object obtained from demisto.getLastRun()

    :type params: ``dict``
    :param params: arguments obtained from demisto.params()

    :return: tuple of next run object and list of incidents
    :rtype: ``tuple[dict, list]``
    """
    max_fetch = arg_to_number(params.get("max_fetch", DEFAULT_MAX_FETCH), "Fetch Limit")
    fetch_types = argToList(params.get("rsc_fetch_types", DEFAULT_FETCH_TYPE), transform=lambda s: s.strip().lower())

    validate_comman_fetch_params(max_fetch, fetch_types)

    total_incidents = []
    next_run = last_run.copy()

    FETCH_TYPE_HANDLERS = {
        EVENT_FETCH_TYPE: ("", fetch_events),
        THREAT_MONITORING_FETCH_TYPE: ("threat_monitoring", fetch_threat_monitoring_objects),
        DSPM_VIOLATION_FETCH_TYPE: ("dspm_violation", fetch_dspm_violations),
        IR_VIOLATION_FETCH_TYPE: ("ir_violation", fetch_ir_violations),
        SENSITIVE_DATA_OBJECT_FETCH_TYPE: ("sensitive_data_object", fetch_sensitive_data_objects),
    }

    selected_handlers = [FETCH_TYPE_HANDLERS[fetch_type] for fetch_type in fetch_types]
    remaining_limit: int = max_fetch  # type: ignore
    remaining_fetch_types = len(selected_handlers)

    for (state_key, fetch_function), fetch_type in zip(selected_handlers, fetch_types):
        allocation = remaining_limit // remaining_fetch_types if remaining_fetch_types > 0 else 0
        next_state, incidents = fetch_function(client, last_run, params, allocation)

        total_incidents.extend(incidents)
        demisto.info(f"Fetched {len(incidents)} incidents for {fetch_type}.")
        remaining_limit -= len(incidents)
        remaining_fetch_types -= 1

        if state_key:
            next_run[state_key] = next_state
        else:
            next_run.update(next_state)

    return next_run, total_incidents


def cdm_cluster_location_command(client: PolarisClient, args: Dict[str, Any]):
    """
    Find the CDM GeoLocation of a CDM Cluster.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    cluster_id = validate_required_arg("clusterId", args.get("clusterId"))

    raw_response = client.get_cdm_cluster_location(cluster_id)

    if raw_response == "No Location Configured":
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    hr_content = {"Location": raw_response}
    hr = tableToMarkdown("CDM Cluster Location", hr_content, headers="Location", removeNull=True)

    context = {"ClusterId": cluster_id.lower(), "Cluster": {"Location": raw_response}}

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["CDM_CLUSTER"],
        outputs_key_field="ClusterId",
        readable_output=hr,
        outputs=context,
        raw_response=raw_response,
    )


def cdm_cluster_connection_state_command(client: PolarisClient, args: Dict[str, Any]):
    """
    Find the CDM Connection State of a CDM Cluster.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    cluster_id = validate_required_arg("clusterId", args.get("clusterId"))

    raw_response = client.get_cdm_cluster_connection_status(cluster_id)

    hr_content = {"Connection State": raw_response}
    hr = tableToMarkdown("CDM Cluster Connection State", hr_content, headers="Connection State", removeNull=True)

    context = {"ClusterId": cluster_id.lower(), "Cluster": {"ConnectionState": raw_response}}

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["CDM_CLUSTER"],
        outputs_key_field="ClusterId",
        readable_output=hr,
        outputs=context,
        raw_response=raw_response,
    )


def radar_analysis_status_command(client: PolarisClient, args: Dict[str, Any]):
    """
    Check the Radar Event for updates.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    activity_series_id = validate_required_arg("activitySeriesId", args.get("activitySeriesId"))
    cluster_id = validate_required_arg("clusterId", args.get("clusterId"))

    raw_response = client.get_analysis_status(activity_series_id, cluster_id)

    activity_series = raw_response.get("data", {}).get("activitySeries", {})
    if not activity_series.get("activityConnection", {}).get("nodes", []):
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("radar analysis status"))

    context, hr = prepare_context_hr_radar_analysis_status(activity_series, activity_series_id, cluster_id)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["RADAR_ANALYSIS_STATUS"],
        outputs_key_field="ActivitySeriesId",
        readable_output=hr,
        outputs=context,
        raw_response=raw_response,
    )


def sonar_sensitive_hits_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Collect sensitive hits object information.

    :type client: PolarisClient
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    incident = demisto.incidents("CustomFields")

    # objectName is an optional value for the command. When not set,
    # look up the value in the incident custom fields
    object_name = args.get("objectName", None)
    if not object_name:
        try:
            object_name = incident.get("rubrikpolarisobjectname")
        except AttributeError:
            pass

    search_time_period = arg_to_number(args.get("searchTimePeriod", 7))
    response = client.get_sensitive_hits(search_time_period=search_time_period, object_name=object_name)
    data = response.get("data", {}).get("policyObj")
    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("sensitive hits"))

    context, hr = prepare_context_hr_sonar_sensitive_hits(data)
    headers = ["ID", "Total Hits"]
    readable_output = tableToMarkdown(name="Sensitive Hits", t=hr, headers=headers, removeNull=True)
    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SONAR_SENSITIVE_HITS"],
        outputs_key_field="id",
        outputs=context,
        raw_response=response,
        readable_output=readable_output,
    )


def rubrik_polaris_object_search_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Search for Rubrik discovered objects of any type, return zero or more matches.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    sort_by = args.get("sort_by", DEFAULT_SORT_BY)
    sort_order = args.get("sort_order", DEFAULT_SORT_ORDER)
    object_name = validate_required_arg("object_name", args.get("object_name"))

    if not limit or limit <= 0 or limit > 1000:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))
    filters = {"field": "REGEX", "texts": object_name}
    next_page_token = args.get("next_page_token")
    response = client.search_object(filters=filters, first=limit, sort_by=sort_by, sort_order=sort_order, after=next_page_token)

    edges = response.get("data", {}).get("globalSearchResults", {}).get("edges", {})
    if not edges:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("global search objects"))

    context, hr = prepare_context_hr_object_search(edges)
    table_name = "Global Objects"
    header = [OBJECT_ID, OBJECT_NAME, "Cluster", "Type", SLA_DOMAIN]

    page_cursor = response.get("data", {}).get("globalSearchResults", {}).get("pageInfo", {})
    next_page_context = {
        "next_page_token": page_cursor.get("endCursor", ""),
        "name": "rubrik-polaris-object-search",
        "has_next_page": page_cursor.get("hasNextPage", ""),
    }
    if next_page_context.get("has_next_page"):
        readable_output = (
            f"{tableToMarkdown(table_name, hr, header, removeNull=True)}\n "
            f"{MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}"
            ""
        )
    else:
        readable_output = tableToMarkdown(table_name, hr, header, removeNull=True)

    outputs = {
        f"{OUTPUT_PREFIX['GLOBAL_SEARCH']}(val.id == obj.id)": context,
        f"{OUTPUT_PREFIX['PAGE_TOKEN_GLOBAL_SEARCH']}(val.name == obj.name)": remove_empty_elements(next_page_context),
    }

    return CommandResults(outputs=outputs, raw_response=response, readable_output=readable_output)


def rubrik_sonar_policies_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    List available policies in Rubrik Polaris - Sonar.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    raw_response = client.list_policies()
    nodes = raw_response.get("data", {}).get("policies", {}).get("nodes", [])
    if not nodes:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("sonar policies"))
    context, hr = prepare_context_hr_sonar_policies(nodes)
    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SONAR_POLICIES_LIST"],
        outputs_key_field="id",
        readable_output=hr,
        outputs=context,
        raw_response=raw_response,
    )


def rubrik_sonar_policy_analyzer_groups_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    List available analyzer group policies in Rubrik Polaris - Sonar.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    raw_response = client.list_policy_analyzer_groups()
    nodes = raw_response.get("data", {}).get("analyzerGroups", {}).get("nodes", [])
    if not nodes:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("sonar policy analyzer groups"))
    context, hr = prepare_context_hr_sonar_policy_analyzer_groups(nodes)
    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SONAR_ANALYZER_GROUP"],
        outputs_key_field="id",
        readable_output=hr,
        outputs=context,
        raw_response=raw_response,
    )


def rubrik_sonar_ondemand_scan_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Request/Trigger an on demand scan of a system in Rubrik Polaris - Sonar.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    scan_name = args.get("scan_name", "")
    snappable_ids = argToList(args.get("objects_to_scan", ""))
    analyzer_groups = args.get("sonar_policy_analyzer_groups")

    if not scan_name:
        scan_name = date.today().strftime("%m/%d/%Y") + " Classification"

    snappable_ids = validate_required_arg("objects_to_scan", snappable_ids)
    analyzer_groups = validate_required_arg("sonar_policy_analyzer_groups", analyzer_groups)

    try:
        analyzer_groups_list = json.loads(analyzer_groups)
        analyzer_groups_list = validate_required_arg("sonar_policy_analyzer_groups", analyzer_groups_list)
    except json.JSONDecodeError:
        raise ValueError(ERROR_MESSAGES["JSON_DECODE"].format("sonar_policy_analyzer_groups"))

    raw_response = client.trigger_on_demand_scan(
        scan_name, [{"snappableFid": snappable_id} for snappable_id in snappable_ids], analyzer_groups_list
    )

    outputs = raw_response.get("data", {}).get("startCrawl", {})
    if not outputs:
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    hr_content = {"Crawl ID": outputs.get("crawlId", "")}
    hr = tableToMarkdown("Sonar On-Demand Scan", hr_content, headers="Crawl ID", removeNull=True)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SONAR_ON_DEMAND_SCAN"],
        outputs_key_field="crawlId",
        readable_output=hr,
        outputs=outputs,
        raw_response=raw_response,
    )


def rubrik_polaris_vm_object_metadata_get_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve details for a Vsphere object based on the provided object ID.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResults object
    """
    object_id = validate_required_arg("object_id", args.get("object_id"))

    response = client.get_object_metadata(object_id=object_id)

    data = response.get("data", {}).get("vSphereDetailData", {})

    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("vm object metadata"))

    context, hr = prepare_context_hr_vm_object_metadata(data)
    table_name = "VM Object Data"
    header = [
        OBJECT_ID,
        "Name",
        SNAPPABLE_ID,
        SLA_DOMAIN,
        CLUSTER_NAME,
        "Total Snapshots",
        "Oldest Snapshot Date",
        "Latest Snapshot Date",
    ]

    readable_output = tableToMarkdown(table_name, hr, header, removeNull=True)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["VM_OBJECT"],
        outputs_key_field="id",
        outputs=context,
        raw_response=response,
        readable_output=readable_output,
    )


def rubrik_polaris_vm_objects_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve a list of all the objects of the Vsphere Vm known to the Rubrik.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    if not limit or limit <= 0 or limit > 1000:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))
    sort_by = args.get("sort_by", DEFAULT_SORT_BY)
    sort_order = args.get("sort_order", DEFAULT_SORT_ORDER)
    is_relic = args.get("is_relic")
    is_replicated = args.get("is_replicated")
    filters = []
    if is_relic:
        is_relic = validate_boolean_argument(is_relic, "is_relic")
        filters.append({"field": "IS_RELIC", "texts": [str(is_relic)]})
    if is_replicated:
        is_replicated = validate_boolean_argument(is_replicated, "is_replicated")
        filters.append({"field": "IS_REPLICATED", "texts": [str(is_replicated)]})
    next_page_token = args.get("next_page_token")
    response = client.list_vm_objects(filters=filters, first=limit, sort_by=sort_by, sort_order=sort_order, after=next_page_token)

    edges = response.get("data", {}).get("vSphereVmNewConnection", {}).get("edges", {})
    if not edges:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("vm objects list"))

    context, hr = prepare_context_hr_vm_object_list(edges)
    table_name = "Objects List"
    header = [
        OBJECT_ID,
        "Name",
        SNAPPABLE_ID,
        "Cluster",
        OBJECT_TYPE,
        SLA_DOMAIN,
        "Assignment",
        "Snapshots",
        "RBS Status",
        "Source Storage",
        "Archival Storage",
    ]

    page_cursor = response.get("data", {}).get("vSphereVmNewConnection", {}).get("pageInfo", {})
    next_page_context = {
        "next_page_token": page_cursor.get("endCursor", ""),
        "name": "rubrik-polaris-vm-objects-list",
        "has_next_page": page_cursor.get("hasNextPage", ""),
    }
    if next_page_context.get("has_next_page"):
        readable_output = (
            f"{tableToMarkdown(table_name, hr, header, removeNull=True)}\n "
            f"{MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}"
            ""
        )
    else:
        readable_output = tableToMarkdown(table_name, hr, header, removeNull=True)

    outputs = {
        f"{OUTPUT_PREFIX['VM_OBJECT']}(val.id == obj.id)": context,
        f"{OUTPUT_PREFIX['PAGE_TOKEN_VM_OBJECT']}(val.name == obj.name)": remove_empty_elements(next_page_context),
    }

    return CommandResults(outputs=outputs, raw_response=response, readable_output=readable_output)


def rubrik_polaris_vm_object_snapshot_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Search for a Rubrik snapshot of an object based on the arguments.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    object_id = validate_required_arg("object_id", args.get("object_id"))

    start_date = end_date = ""
    start_date_ob = arg_to_datetime(validate_required_arg("start_date", args.get("start_date")))
    if start_date_ob:
        start_date = start_date_ob.strftime(DATE_TIME_FORMAT)

    end_date_ob = arg_to_datetime(validate_required_arg("end_date", args.get("end_date")))
    if end_date_ob:
        end_date = end_date_ob.strftime(DATE_TIME_FORMAT)

    timezone_offset = validate_required_arg("timezone_offset", args.get("timezone_offset"))
    cluster_connected = args.get("cluster_connected", DEFAULT_CLUSTER_CONNECTED)
    if cluster_connected:
        cluster_connected = validate_boolean_argument(cluster_connected, "cluster_connected")

    snapshot_group_by = args.get("snapshot_group_by", DEFAULT_SNAPSHOT_GROUP_BY)
    missed_snapshot_by = args.get("missed_snapshot_group_by", DEFAULT_MISSED_SNAPSHOT_GROUP_BY)
    time_range = {"start": start_date, "end": end_date}
    response = client.get_object_snapshot(
        snapshot_group_by=snapshot_group_by,
        missed_snapshot_group_by=missed_snapshot_by,
        object_id=object_id,
        time_range=time_range,
        timezone_offset=timezone_offset,
        cluster_connected=cluster_connected,
    )

    data = response.get("data", {}).get("snappable", {})
    if not data.get("snapshotGroupByConnection", {}).get("nodes"):
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("vm object snapshots"))

    context, hr = prepare_context_hr_vm_object_snapshot(data)
    table_name = "VM Object Snapshots"
    header = ["Snapshot Details", SNAPSHOT_IDS]

    readable_output = tableToMarkdown(table_name, hr, header, removeNull=True)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["VM_OBJECT"],
        outputs_key_field="id",
        outputs=context,
        raw_response=response,
        readable_output=readable_output,
    )


def rubrik_sonar_ondemand_scan_status_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the status of a scanned system in Polaris Sonar.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    crawl_id = args.get("crawl_id")

    if not crawl_id:
        raise ValueError(ERROR_MESSAGES["MISSING_REQUIRED_FIELD"].format("crawl_id"))
    raw_response = client.get_on_demand_scan_status(crawl_id)
    nodes = raw_response.get("data", {}).get("crawl", {}).get("crawlObjConnection", {}).get("nodes", [])
    response_crawl_id = raw_response.get("data", {}).get("crawl", {}).get("id", "")

    if not nodes:
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    context, hr = prepare_context_hr_sonar_ondemand_scan_status(nodes, response_crawl_id)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SONAR_ON_DEMAND_SCAN"],
        outputs_key_field="crawlId",
        readable_output=hr,
        outputs=context,
        raw_response=raw_response,
    )


def rubrik_sonar_ondemand_scan_result_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the download link for an on-demand scan of a system in Rubrik Polaris - Sonar.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    crawl_id = validate_required_arg("crawl_id", args.get("crawl_id", ""))
    file_type = validate_required_arg("file_type", args.get("file_type"))

    raw_response = client.get_on_demand_scan_result(crawl_id, {"fileType": file_type})
    outputs = raw_response.get("data", {}).get("downloadResultsCsv", {})

    if not outputs or not outputs.get("downloadLink"):
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    hr_content = {"Scan result CSV Download Link": f"Download the [CSV]({outputs.get('downloadLink')}) file to see the result."}
    hr = tableToMarkdown("Sonar On-Demand Scan Result", hr_content, headers="Scan result CSV Download Link", removeNull=True)
    context = {"crawlId": crawl_id.lower(), "Result": outputs}

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SONAR_ON_DEMAND_SCAN"],
        outputs_key_field="crawlId",
        readable_output=hr,
        outputs=context,
        raw_response=raw_response,
    )


def rubrik_radar_anomaly_csv_analysis_command(client: PolarisClient, args: Dict[str, Any]) -> list[Union[CommandResults, Any]]:
    """
    Request for the analysis and retrieve the download link for the Radar CSV analyzed file.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    cluster_id = validate_required_arg("cluster_id", args.get("cluster_id"))
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    object_id = validate_required_arg("object_id", args.get("object_id"))
    download_file = argToBoolean(args.get("download_file", False))

    response = client.get_csv_result(cluster_id=cluster_id, snappable_id=object_id, snapshot_id=snapshot_id)

    data = response.get("data", {})
    download_data = data.get("investigationCsvDownloadLink", {})
    if not download_data:
        return [CommandResults(readable_output=MESSAGES["NO_RESPONSE"])]
    context = {"clusterId": cluster_id, "snapshotId": snapshot_id, "objectId": object_id}
    context.update(data)
    table_name = "Radar Anomaly CSV Analysis"
    hr = [f"Download the analyzed [CSV]({download_data.get('downloadLink')}) file."]
    readable_output = tableToMarkdown(table_name, hr, ["CSV Download Link"], removeNull=True)

    result = [
        CommandResults(
            outputs_prefix=OUTPUT_PREFIX["RADAR_ANOMALY_CSV_ANALYSIS"],
            outputs_key_field=["clusterId", "snapshotId", "objectId"],
            outputs=context,
            raw_response=response,
            readable_output=readable_output,
        )
    ]

    if download_file:
        file_content = requests.request("GET", download_data.get("downloadLink")).text
        extract_file_name = re.search(r"[^\/]+\.csv", download_data.get("downloadLink"))
        file_name = ""
        if extract_file_name:
            file_name = extract_file_name.group()

        file_result = fileResult(filename=file_name, data=file_content)

        result.append(file_result)

    return result


def rubrik_sonar_csv_download_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Request for the analysis and retrieve the download link for the Radar CSV analyzed file.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    object_id = validate_required_arg("object_id", args.get("object_id"))
    file_type = args.get("file_type")
    filters = None
    if file_type:
        filters = {"fileType": file_type}
    response = client.get_csv_download(snappable_id=object_id, snapshot_id=snapshot_id, filters=filters)
    data = response.get("data", {})
    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])
    context = {"snapshotId": snapshot_id, "objectId": object_id}
    context.update(data)
    table_name = "Sonar CSV Download"
    if data.get("downloadSnapshotResultsCsv", {}).get("isSuccessful"):
        hr = ["Success"]
    else:
        hr = ["Failed"]
    readable_output = tableToMarkdown(table_name, hr, ["Download Status"], removeNull=True)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SONAR_CSV_DOWNLOAD"],
        outputs_key_field=["snapshotId", "objectId"],
        outputs=context,
        raw_response=response,
        readable_output=readable_output,
    )


def rubrik_gps_snapshot_files_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of the available files that can be downloaded.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id", ""))
    search_prefix = args.get("search_prefix", "")
    path = args.get("path", "")

    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    if not limit or limit <= 0 or limit > 1000:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    next_page_token = args.get("next_page_token")

    raw_response = client.get_snapshot_files(
        snapshot_id=snapshot_id, search_prefix=search_prefix, path=path, first=limit, after=next_page_token
    )

    outputs = raw_response.get("data", {}).get("browseSnapshotFileConnection", {}).get("edges", [])
    page_cursor = raw_response.get("data", {}).get("browseSnapshotFileConnection", {}).get("pageInfo", {})

    if not outputs:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("files"))

    context, hr = prepare_context_hr_gps_snapshot_files(outputs, snapshot_id)
    next_page_context = {
        "next_page_token": page_cursor.get("endCursor", ""),
        "name": "rubrik-gps-snapshot-files-list",
        "has_next_page": page_cursor.get("hasNextPage", ""),
    }
    outputs = {
        f"{OUTPUT_PREFIX['GPS_SNAPSHOT_FILES']}(val.snapshotId == obj.snapshotId)": context,
        f"{OUTPUT_PREFIX['PAGE_TOKEN_GPS_SNAPSHOT_FILES']}(val.name == obj.name)": remove_empty_elements(next_page_context),
    }
    if page_cursor.get("hasNextPage"):
        hr += f"{MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}"

    return CommandResults(readable_output=hr, outputs=outputs, raw_response=raw_response)


def rubrik_gps_vm_export_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Request to initiate an export of a snapshot of a virtual machine.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    config, object_id = validate_vm_export_args(args)

    raw_response = client.export_vm_snapshot(config, object_id)
    outputs = raw_response.get("data", {})

    if not outputs:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("vm export"))

    snapshot_export_request_id = outputs.get("vSphereVMExportSnapshotV2", {}).get("id", "")
    hr_content = {"Snapshot Export Request ID": snapshot_export_request_id}
    hr = tableToMarkdown("GPS VM Export", hr_content, headers="Snapshot Export Request ID", removeNull=True)

    context = {"id": snapshot_export_request_id}

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["GPS_VM_EXPORT"],
        outputs_key_field="id",
        readable_output=hr,
        outputs=context,
        raw_response=raw_response,
    )


def rubrik_user_downloads_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the user downloads. This would return the current and past download history.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    response = client.get_user_downloads()
    data = response.get("data", {})
    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("user downloads"))

    context, hr = prepare_context_hr_user_downloads(data.get("getUserDownloads", []))
    table_name = "User Downloads"
    headers = ["Download ID", "Name", "Status", "Identifier", "Creation Time", "Completion Time"]
    readable_output = tableToMarkdown(table_name, hr, headers, removeNull=True)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["USER_DOWNLOADS"],
        outputs_key_field="id",
        outputs=context,
        raw_response=response,
        readable_output=readable_output,
    )


def rubrik_sonar_csv_result_download_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the download link for the requested Sonar CSV Snapshot file.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    download_id = arg_to_number(validate_required_arg("download_id", args.get("download_id")))

    response = client.get_csv_result_download(download_id=download_id)

    data = response.get("data", {})
    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])
    context = {"downloadId": download_id}
    context.update(data)
    table_name = "Sonar CSV Result"
    url_ = data.get("getDownloadUrl", {}).get("url")
    hr = [f"Download the [CSV]({url_}) file to see the result."]
    readable_output = tableToMarkdown(table_name, hr, ["Download URL"], removeNull=True)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SONAR_CSV_DOWNLOAD"],
        outputs_key_field="downloadId",
        outputs=context,
        raw_response=response,
        readable_output=readable_output,
    )


def rubrik_gps_sla_domain_list(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    List available SLA Domains Rubrik Polaris - GPS.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    name = args.get("name", "")
    cluster_uuid = args.get("cluster_id", "")
    object_type = argToList(args.get("object_type"))
    show_cluster_slas_only = args.get("show_cluster_slas_only", DEFAULT_SHOW_CLUSTER_SLA_ONLY)
    sort_order = args.get("sort_order", DEFAULT_SORT_ORDER)
    sort_by = args.get("sort_by", DEFAULT_SORT_BY_SLA_DOMAIN)
    filters = []

    if name:
        filters.append({"field": "NAME", "text": name})
    if cluster_uuid:
        filters.append({"field": "CLUSTER_UUID", "text": cluster_uuid})

    if object_type:
        filters.append({"field": "OBJECT_TYPE", "objectTypeList": object_type})

    if show_cluster_slas_only:
        show_cluster_slas_only = validate_boolean_argument(show_cluster_slas_only, "show_cluster_slas_only")
        filters.append({"field": "SHOW_CLUSTER_SLAS_ONLY", "text": str(show_cluster_slas_only).lower()})

    nodes = list(
        client.list_sla_domains(filters=filters, sort_order=sort_order, sort_by=sort_by, show_protected_object_count=True)
    )

    if not nodes:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("sla domains"))

    context, hr = prepare_context_hr_sla_domains_list(nodes)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["GPS_SLA_DOMAIN"],
        outputs_key_field="id",
        outputs=context,
        raw_response=nodes,
        readable_output=hr,
    )


def rubrik_gps_vm_snapshot_create(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Trigger an on-demand vm snapshot.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    object_id = validate_required_arg("object_id", args.get("object_id", ""))
    sla_domain_id = args.get("sla_domain_id", "")

    raw_response = client.create_vm_snapshot(object_id, sla_domain_id)

    outputs = raw_response.get("data", {}).get("vsphereOnDemandSnapshot", {})
    outputs = remove_empty_elements(outputs)
    if not outputs or not outputs.get("id"):
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    hr_content = {"On-Demand Snapshot Request ID": outputs.get("id"), "Status": outputs.get("status")}
    hr = tableToMarkdown("GPS VM Snapshot", hr_content, headers=["On-Demand Snapshot Request ID", "Status"], removeNull=True)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["GPS_SNAPSHOT_CREATE"],
        outputs_key_field="id",
        outputs=outputs,
        raw_response=raw_response,
        readable_output=hr,
    )


def rubrik_gps_snapshot_files_download_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Request to download the snapshot file from the backup.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    file_path = argToList(validate_required_arg("file_path", args.get("file_path")))
    object_type: str = args.get("object_type", "VmwareVm")

    parsed_object_type: str = object_type.upper().replace("_", "")
    if parsed_object_type.find(FILESET_OBJECT_TYPE) != -1:
        download_file_filters = {"config": {"sourceDirs": file_path}, "id": snapshot_id}
        response = client._query_raw(
            raw_query=FILESET_DOWNLOAD_SNAPSHOT_FILES_MUTATION,
            operation_name="PhysicalHostDownloadSnapshotFilesMutation",
            variables=download_file_filters,
            timeout=60,
        )
        data = response.get("data", {}).get("filesetDownloadSnapshotFiles", {})
    elif parsed_object_type.find(VOLUME_GROUP_OBJECT_TYPE) != -1:
        download_file_filters = {"input": {"config": {"paths": file_path}, "id": snapshot_id}}
        response = client._query_raw(
            raw_query=VOLUME_GROUP_DOWNLOAD_SNAPSHOT_FILES_MUTATION,
            operation_name="RadarInvestigationVGDownloadFilesMutation",
            variables=download_file_filters,
            timeout=60,
        )
        data = response.get("data", {}).get("downloadVolumeGroupSnapshotFiles", {})
    else:
        response = client.request_download_snapshot_files(snapshot_id=snapshot_id, paths=file_path)
        data = response.get("data", {}).get("vsphereVmDownloadSnapshotFiles", {})

    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    context, hr = prepare_context_hr_gps_snapshot_download(data)
    table_name = "Snapshot File Request ID"

    readable_output = tableToMarkdown(table_name, hr, headers=["ID", "Status"], removeNull=True)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["GPS_SNAPSHOT_FILE_DOWNLOAD"],
        outputs_key_field="id",
        outputs=context,
        raw_response=response,
        readable_output=readable_output,
    )


def rubrik_gps_vm_livemount(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Trigger a live mount of a virtual machine snapshot in Rubrik Polaris - GPS.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    snappable_id = validate_required_arg("snappable_id", args.get("snappable_id"))
    should_recover_tags = args.get("should_recover_tags", True)
    power_on = args.get("power_on", True)
    keep_mac_addresses = args.get("keep_mac_addresses", False)
    remove_network_devices = args.get("remove_network_devices", False)
    host_id = args.get("host_id")
    cluster_id = args.get("cluster_id")
    resource_pool_id = args.get("resource_pool_id")
    snapshot_fid = args.get("snapshot_fid")
    vm_name = args.get("vm_name")
    vnic_bindings = args.get("vnic_bindings")
    recovery_point = args.get("recovery_point")

    if vnic_bindings:
        try:
            vnic_bindings = json.loads(args.get("vnic_bindings"))  # type: ignore[arg-type]
        except json.JSONDecodeError as exception:
            raise Exception(f"Could not able to parse the provided JSON data. Error: {exception!s}") from exception
    if power_on:
        power_on = validate_boolean_argument(power_on, "power_on")
    if keep_mac_addresses:
        keep_mac_addresses = validate_boolean_argument(keep_mac_addresses, "keep_mac_addresses")
    if remove_network_devices:
        remove_network_devices = validate_boolean_argument(remove_network_devices, "remove_network_devices")
    if should_recover_tags:
        should_recover_tags = validate_boolean_argument(should_recover_tags, "should_recover_tags")

    raw_response = client.create_vm_livemount_v2(
        snappable_id,
        should_recover_tags,
        power_on,
        keep_mac_addresses,
        remove_network_devices,
        host_id,
        cluster_id,
        resource_pool_id,
        snapshot_fid,
        vm_name,
        vnic_bindings,
        recovery_point,
    )

    outputs = raw_response.get("data", {}).get("vsphereVmInitiateLiveMountV2", {})
    outputs = remove_empty_elements(outputs)
    if not outputs or not outputs.get("id"):
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    hr_content = {"VM Live Mount Request ID": outputs.get("id")}
    hr = tableToMarkdown("GPS VM Livemount", hr_content, headers=["VM Live Mount Request ID"], removeNull=True)
    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["GPS_VM_LIVEMOUNT"],
        outputs_key_field="id",
        outputs=outputs,
        raw_response=raw_response,
        readable_output=hr,
    )


def rubrik_gps_vm_host_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of available Vsphere Hosts.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    host_name = args.get("name")
    cluster_id = args.get("cluster_id")
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    next_token = args.get("next_page_token")
    sort_by = args.get("sort_by", DEFAULT_SORT_BY)
    sort_order = args.get("sort_order", DEFAULT_SORT_ORDER)

    if not limit or limit <= 0 or limit > 1000:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    filters = []
    if host_name:
        filters.append({"field": "NAME", "texts": [host_name]})
    if cluster_id:
        filters.append({"field": "CLUSTER_ID", "texts": [cluster_id]})
    response = client.list_vsphere_hosts(first=limit, filters=filters, after=next_token, sort_by=sort_by, sort_order=sort_order)
    data = response.get("data", {}).get("vSphereHostConnection", {}).get("edges", [])
    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("vm hosts"))

    context, hr = prepare_context_hr_vm_host_list(data)
    table_name = "GPS VM Hosts"
    headers = ["VSphere Host ID", "Name", "Physical Host"]
    readable_output = tableToMarkdown(table_name, hr, headers, removeNull=True)

    page_cursor = response.get("data", {}).get("vSphereHostConnection", {}).get("pageInfo", {})
    next_page_context = {
        "next_page_token": page_cursor.get("endCursor", ""),
        "name": "rubrik-gps-vm-host-list",
        "has_next_page": page_cursor.get("hasNextPage", ""),
    }
    if next_page_context.get("has_next_page"):
        readable_output += f"\n {MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}\n"

    outputs = {
        f"{OUTPUT_PREFIX['GPS_VM_HOSTS']}(val.id == obj.id)": context,
        f"{OUTPUT_PREFIX['PAGE_TOKEN_VM_HOSTS']}(val.name == obj.name)": remove_empty_elements(next_page_context),
    }

    return CommandResults(outputs=outputs, raw_response=response, readable_output=readable_output)


def rubrik_gps_vm_datastore_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of the available datastores on a Vsphere Host.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    name = args.get("name", "")
    host_id = args.get("host_id", "")
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    next_page_token = args.get("next_page_token")
    sort_order = args.get("sort_order", DEFAULT_SORT_ORDER)
    sort_by = args.get("sort_by", DEFAULT_SORT_BY)
    filters = []

    if name:
        filters.append({"field": "REGEX", "texts": name})
    if not limit or limit <= 0 or limit > 1000:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    response = client.list_vsphere_datastores(
        host_id=host_id, first=limit, after=next_page_token, filters=filters, sort_by=sort_by, sort_order=sort_order
    )

    edges = response.get("data", {}).get("vSphereHost", {}).get("descendantConnection", {}).get("edges", [])
    if not edges:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("vm datastores"))

    context, hr = prepare_context_hr_vm_datastore_list(edges, host_id)

    page_cursor = response.get("data", {}).get("vSphereHost", {}).get("descendantConnection", {}).get("pageInfo", {})
    next_page_context = {
        "next_page_token": page_cursor.get("endCursor", ""),
        "name": "rubrik-gps-vm-datastore-list",
        "has_next_page": page_cursor.get("hasNextPage", ""),
    }
    if next_page_context.get("has_next_page"):
        hr += f"\n {MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}\n"

    outputs = {
        f"{OUTPUT_PREFIX['GPS_VM_HOSTS']}(val.id == obj.id)": context,
        f"{OUTPUT_PREFIX['PAGE_TOKEN_VM_HOSTS']}(val.name == obj.name)": {"Datastore": remove_empty_elements(next_page_context)},
    }

    return CommandResults(outputs=outputs, raw_response=response, readable_output=hr)


def rubrik_event_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of events.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    activity_status = args.get("activity_status", "")
    activity_type = args.get("activity_type", "")
    severity = args.get("severity", "")
    object_name = args.get("object_name", "")
    object_type = args.get("object_type", "")
    cluster_ids = args.get("cluster_id", "")
    start_date = end_date = ""
    start_date_ob = arg_to_datetime(args.get("start_date"))
    if start_date_ob:
        start_date = start_date_ob.strftime(DATE_TIME_FORMAT)

    end_date_ob = arg_to_datetime(args.get("end_date"))
    if end_date_ob:
        end_date = end_date_ob.strftime(DATE_TIME_FORMAT)

    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    sort_by = args.get("sort_by", DEFAULT_EVENT_SORT_BY)
    sort_order = args.get("sort_order", DEFAULT_EVENT_SORT_ORDER)
    next_page_token = args.get("next_page_token")

    if not limit or limit <= 0 or limit > 1000:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    response = client.list_event_series(
        object_type=object_type,
        activity_status=activity_status,
        activity_type=activity_type,
        severity=severity,
        cluster_id=cluster_ids,
        start_date=start_date,
        end_date=end_date,
        object_name=object_name,
        first=limit,
        sort_by=sort_by,
        sort_order=sort_order,
        after=next_page_token,
    )

    edges = response.get("data", {}).get("activitySeriesConnection", {}).get("edges", [])
    if not edges:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("events"))

    context, hr = prepare_context_hr_event_list(edges)

    page_cursor = response.get("data", {}).get("activitySeriesConnection", {}).get("pageInfo", {})
    next_page_context = {
        "next_page_token": page_cursor.get("endCursor", ""),
        "name": "rubrik-event-list",
        "has_next_page": page_cursor.get("hasNextPage", ""),
    }
    if next_page_context.get("has_next_page"):
        hr += f"\n {MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}\n"

    outputs = {
        f"{OUTPUT_PREFIX['EVENT']}(val.id == obj.id)": context,
        f"{OUTPUT_PREFIX['PAGE_TOKEN_EVENT']}(val.name == obj.name)": remove_empty_elements(next_page_context),
    }

    return CommandResults(outputs=outputs, raw_response=response, readable_output=hr)


def rubrik_polaris_object_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of Rubrik objects, based on the provided filters.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    type_filter = validate_required_arg("type_filter", args.get("type_filter", ""))
    cluster_id = args.get("cluster_id", "")
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    sort_by = args.get("sort_by", DEFAULT_SORT_BY)
    sort_order = args.get("sort_order", DEFAULT_SORT_ORDER)
    next_page_token = args.get("next_page_token")
    filters = {}
    if cluster_id:
        filters = {"field": "CLUSTER_ID", "texts": argToList(cluster_id)}

    if not limit or limit <= 0 or limit > 1000:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))

    response = client.list_objects(
        first=limit, type_filter=type_filter, sort_order=sort_order, sort_by=sort_by, after=next_page_token, filters=filters
    )
    data = response.get("data", {}).get("inventoryRoot", {}).get("descendantConnection", {})
    edges = data.get("edges", [])
    if not edges:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("objects"))

    context, hr = prepare_context_hr_object_list(edges)

    page_cursor = data.get("pageInfo", {})
    next_page_context = {
        "next_page_token": page_cursor.get("endCursor", ""),
        "name": "rubrik-polaris-object-list",
        "has_next_page": page_cursor.get("hasNextPage", ""),
    }
    if next_page_context.get("has_next_page"):
        hr += f"\n {MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}\n"

    outputs = {
        f"{OUTPUT_PREFIX['OBJECT']}(val.id == obj.id)": context,
        f"{OUTPUT_PREFIX['PAGE_TOKEN_OBJECT']}(val.name == obj.name)": remove_empty_elements(next_page_context),
    }

    return CommandResults(outputs=outputs, raw_response=response, readable_output=hr)


def rubrik_polaris_object_snapshot_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve Rubrik snapshot(s) of an object, based on the provided object ID.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    object_id = validate_required_arg("object_id", args.get("object_id", ""))
    snapshot_type = args.get("snapshot_type", "")

    start_date = end_date = ""
    start_date_ob = arg_to_datetime(args.get("start_date"))
    if start_date_ob:
        start_date = start_date_ob.strftime(DATE_TIME_FORMAT)

    end_date_ob = arg_to_datetime(args.get("end_date"))
    if end_date_ob:
        end_date = end_date_ob.strftime(DATE_TIME_FORMAT)

    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    sort_order = args.get("sort_order", DEFAULT_SORT_ORDER)
    next_page_token = args.get("next_page_token")

    if not limit or limit <= 0 or limit > 1000:
        raise ValueError(ERROR_MESSAGES["INVALID_LIMIT"].format(limit))
    snapshot_filter = {"field": "SNAPSHOT_TYPE", "typeFilters": argToList(snapshot_type)}
    response = client.list_object_snapshots(
        object_id=object_id,
        first=limit,
        sort_order=sort_order,
        after=next_page_token,
        start_date=start_date,
        end_date=end_date,
        snapshot_filter=snapshot_filter,
    )
    edges = response.get("data", {}).get("snapshotsListConnection", {}).get("edges", [])
    if not edges:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("object snapshots"))

    context, hr = prepare_context_hr_object_snapshot_list(edges, object_id)

    page_cursor = response.get("data", {}).get("snapshotsListConnection", {}).get("pageInfo", {})
    next_page_context = {
        "next_page_token": page_cursor.get("endCursor", ""),
        "name": "rubrik-polaris-object-snapshot-list",
        "has_next_page": page_cursor.get("hasNextPage", ""),
    }
    if next_page_context.get("has_next_page"):
        hr += f"\n {MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}\n"

    outputs = {
        f"{OUTPUT_PREFIX['OBJECT']}(val.id == obj.id)": remove_empty_elements(context),
        f"{OUTPUT_PREFIX['PAGE_TOKEN_OBJECT']}(val.name == obj.name)": {"Snapshot": remove_empty_elements(next_page_context)},
    }

    return CommandResults(outputs=outputs, raw_response=response, readable_output=hr)


def rubrik_radar_ioc_scan_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Trigger an IOC scan of a system.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    prepared_args = validate_ioc_scan_args(args)

    raw_response = client.trigger_ioc_scan(**prepared_args)

    outputs = raw_response.get("data", {}).get("startMalwareDetection", {})
    outputs = remove_empty_elements(outputs)
    if not outputs or not outputs.get("id"):
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    hr_content = {SCAN_ID: outputs.get("id"), "Status": outputs.get("status")}
    hr = tableToMarkdown("Radar IOC Scan", hr_content, headers=[SCAN_ID, "Status"], removeNull=True)
    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["RADAR_IOC_SCAN"],
        outputs_key_field="id",
        outputs=outputs,
        raw_response=raw_response,
        readable_output=hr,
    )


def rubrik_radar_ioc_scan_results_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve Rubrik Radar results of IOC scans.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    scan_id = validate_required_arg("scan_id", args.get("scan_id"))
    cluster_id = validate_required_arg("cluster_id", args.get("cluster_id"))

    response = client.get_ioc_scan_result(scan_id=scan_id, cluster_id=cluster_id)

    data = response.get("data", {}).get("malwareDetectionTaskResult", {})
    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    context, hr = prepare_context_hr_radar_ioc_scan_results(data)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["RADAR_IOC_SCAN"],
        outputs_key_field="id",
        outputs=context,
        raw_response=response,
        readable_output=hr,
    )


def rubrik_gps_async_result_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the result of an asynchronous request.

    This command will retrieve the result of requests made by commands "rubrik-gps-snapshot-files-download",
    "rubrik-gps-vm-livemount", "rubrik-gps-vm-export" and "rubrik-gps-vm-snapshot-create".

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    request_id = validate_required_arg("request_id", args.get("request_id"))
    cluster_id = validate_required_arg("cluster_id", args.get("cluster_id"))
    ip_address = args.get("cluster_ip_address", "")

    response = client.get_async_request_result(request_id=request_id, cluster_id=cluster_id)

    data = response.get("data", {}).get("vSphereVMAsyncRequestStatus", {})
    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    if "DOWNLOAD_SNAPPABLE_FILE" in request_id and not ip_address:
        raise ValueError(ERROR_MESSAGES["IP_ADDRESS_REQUIRED"])

    context, hr = prepare_context_hr_async_result(data, request_id, ip_address)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["GPS_ASYNC_RESULT"],
        outputs_key_field="id",
        outputs=context,
        raw_response=response,
        readable_output=hr,
    )


def rubrik_gps_cluster_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of the available rubrik clusters.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    name = args.get("name", "")
    cluster_type = args.get("type", "")
    sort_by = args.get("sort_by", DEFAULT_CLUSTER_SORT_BY)
    sort_order = args.get("sort_order", DEFAULT_SORT_ORDER)
    filters = {}
    if cluster_type:
        filters["type"] = argToList(cluster_type)
    if name:
        filters["name"] = argToList(name)

    nodes = list(client.list_clusters(sort_order=sort_order, sort_by=sort_by, filters=filters))
    if not nodes:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("clusters"))

    context, hr = prepare_context_hr_cluster_list(nodes)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["GPS_CLUSTER"],
        outputs_key_field="id",
        outputs=context,
        raw_response=nodes,
        readable_output=hr,
    )


def rubrik_radar_ioc_scan_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    List the IOC scan information on a Rubrik cluster.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    cluster_id = validate_required_arg("cluster_id", args.get("cluster_id"))

    raw_response = client.get_ioc_scan_list(cluster_id=cluster_id)

    data = raw_response.get("data", {}).get("malwareScans", {}).get("data", [])
    data = remove_empty_elements(data)
    if not data:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("ioc scans"))

    outputs, hr = prepare_context_hr_ioc_scan_list(data)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["RADAR_IOC_SCAN"],
        outputs_key_field="id",
        outputs=outputs,
        raw_response=raw_response,
        readable_output=hr,
    )


def rubrik_gps_vm_recover_files(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Recover files from a backup snapshot, back into a Vsphere VM.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``dict``
    :param args: arguments obtained from demisto.args()

    :return: CommandResult object
    """
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    cluster_id = validate_required_arg("cluster_id", args.get("cluster_id"))
    paths_to_recover = validate_required_arg("paths_to_recover", argToList(args.get("paths_to_recover")))
    restore_path = validate_required_arg("restore_path", args.get("restore_path"))
    destination_object_id = args.get("destination_object_id")

    restore_config = [{"path": path_to_recover, "restorePath": restore_path} for path_to_recover in paths_to_recover]

    raw_response = client.recover_vsphere_vm_files(
        snapshot_id=snapshot_id, cluster_id=cluster_id, restore_config=restore_config, destination_object_id=destination_object_id
    )

    outputs = raw_response.get("data", {}).get("vsphereVMRecoverFilesNew", {})
    outputs = remove_empty_elements(outputs)
    if not outputs:
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    hr_content = {"Recover Files Request ID": outputs.get("id")}
    hr = tableToMarkdown("GPS VM Recover Files", hr_content, headers=["Recover Files Request ID"], removeNull=True)
    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["GPS_VM_RECOVER_FILES"],
        outputs_key_field="id",
        outputs=outputs,
        raw_response=raw_response,
        readable_output=hr,
    )


def rubrik_sonar_user_access_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of user access, based on the provided filters.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``dict``
    :param args: Arguments for the command.

    :return: CommandResult object.
    """
    user_name = args.get("user_name", "")
    user_email = args.get("user_email", "")
    search_time_period: datetime = arg_to_datetime(
        args.get("search_time_period", "7 days"),  # type: ignore
        arg_name="search_time_period",
    )
    if search_time_period.tzinfo is None:
        search_time_period = search_time_period.replace(tzinfo=timezone.utc)
    search_time_period_iso = search_time_period.replace(microsecond=0).isoformat()
    risk_levels = argToList(args.get("risk_levels", []))
    group_id = args.get("group_id", "")
    include_whitelisted_results = argToBoolean(args.get("include_whitelisted_results", False))
    principal_summary_category = args.get("principal_summary_category", DEFAULT_PRINCIPAL_SUMMARY_CATEGORY)
    page_number = arg_to_number(args.get("page_number", 1), "page_number")
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT), "limit")
    sort_by = args.get("sort_by", DEFAULT_USER_ACCESS_SORT_BY)
    sort_order = str(args.get("sort_order", DEFAULT_USER_ACCESS_SORT_ORDER)).upper()
    next_page_token = args.get("next_page_token")

    validate_user_access_list_command_args(limit, sort_order, page_number)  # type: ignore

    # Prepare filter.
    filters = {
        "filter": {
            "principalType": "USER",
            "policyIds": [],
            "riskLevel": risk_levels,
            "principalName": user_name,
            "groupId": group_id,
            "principalSummaryCategory": principal_summary_category,
        },
        "timelineDate": search_time_period_iso,
        "sort": {"sortBy": sort_by, "sortOrder": sort_order},
        "includeWhitelistedResults": include_whitelisted_results,
        "first": limit if not user_email else MAXIMUM_PAGINATION_LIMIT,
    }
    if next_page_token:
        filters["after"] = next_page_token

    response = client._query_raw(
        raw_query=USER_ACCESS_QUERY, operation_name="UserAccessPrincipalListQuery", variables=filters, timeout=60
    )

    response["xsoar_risk_levels"] = []
    data = response.get("data", {}).get("principalSummaries", {})
    edges = data.get("edges", [])
    page_cursor = remove_empty_elements(data.get("pageInfo", {}))
    page_cursor.pop("__typename", None)
    page_cursor.update({"name": "rubrik-sonar-user-access-list"})
    record_hr = ""
    if page_cursor.get("hasNextPage"):
        record_hr = f"\n{MESSAGES['NEXT_PAGE_TOKEN'].format(page_cursor.get('endCursor'))}"
    outputs = {f"{OUTPUT_PREFIX['PAGE_TOKEN_USER_ACCESS']}(val.name == obj.name)": page_cursor}
    if not edges:
        page_cursor.update({"has_next_upn_page": False, "next_upn_page_number": 1})
        return CommandResults(
            outputs=outputs, raw_response=response, readable_output=MESSAGES["NO_RECORDS_FOUND"].format("user accesses")
        )

    base_url = str(client._baseurl).removesuffix("api")
    context, hr, pages, risk_levels = prepare_context_hr_user_access_list(
        edges,
        include_whitelisted_results,
        user_email,
        base_url,
        page_number,  # type: ignore
        limit,  # type: ignore
    )

    response["xsoar_risk_levels"] = list(risk_levels)

    if context:
        outputs[f"{OUTPUT_PREFIX['USER_ACCESS']}(val.principalId == obj.principalId)"] = context
        next_upn_page_number = 1
        has_next_upn_page = False
        if user_email:
            if page_number < pages:  # type: ignore
                next_upn_page_number = page_number + 1  # type: ignore
                has_next_upn_page = True
            else:
                next_upn_page_number = pages or 1
                hr = hr + record_hr
        elif record_hr:
            hr = hr + record_hr
        page_cursor.update({"has_next_upn_page": has_next_upn_page, "next_upn_page_number": next_upn_page_number})
    else:
        hr = MESSAGES["NO_RECORDS_FOUND"].format("user accesses")
        if record_hr:
            hr += f"\n{record_hr}"
        page_cursor.update({"has_next_upn_page": False, "next_upn_page_number": pages or 1})

    return CommandResults(outputs=outputs, raw_response=response, readable_output=hr)


def rubrik_sonar_user_access_get_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the of user access for the provided user_id.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``dict``
    :param args: Arguments for the command.

    :return: CommandResult object.
    """
    user_id = validate_required_arg("user_id", args.get("user_id"))
    search_time_period: datetime = arg_to_datetime(
        args.get("search_time_period", "7 days"),  # type: ignore
        arg_name="search_time_period",
    )
    if search_time_period.tzinfo is None:
        search_time_period = search_time_period.replace(tzinfo=timezone.utc)
    search_time_period_iso = search_time_period.replace(microsecond=0).isoformat()
    historical_delta_days = arg_to_number(args.get("historical_delta_days", "7"), arg_name="historical_delta_days", required=True)
    include_whitelisted_results = argToBoolean(args.get("include_whitelisted_results", False))

    # Prepare filter for user access query.
    access_filters = {
        "sid": user_id,
        "timelineDate": search_time_period_iso,
        "includeWhitelistedResults": include_whitelisted_results,
    }

    access_response = client._query_raw(
        raw_query=USER_ACCESS_DETAIL_QUERY, operation_name="UserAccessUserDetailsQuery", variables=access_filters, timeout=60
    )
    principal_details = access_response.get("data", {}).get("principalDetails", {})
    principal_summary = deepcopy(principal_details.get("principalSummary", {}))
    if not principal_summary.get("principalId"):
        return CommandResults(readable_output=MESSAGES["NO_RESPONSE"])

    principal_summary["directGroups"] = principal_details.get("directGroups", [])

    # Prepare filter for policy hits query.
    policy_hits_filters = {
        "sids": [user_id],
        "day": (search_time_period_iso.split("T")[0] + "T00:00:00+00:00"),
        "historicalDeltaDays": historical_delta_days,
        "includeWhitelistedResults": include_whitelisted_results,
    }
    policy_hits_response = client._query_raw(
        raw_query=POLICY_HITS_SUMMARY_CHART_QEURY,
        operation_name="PrincipalPolicyHitsSummaryChartQuery",
        variables=policy_hits_filters,
        timeout=60,
    )
    policy_hits_summaries = policy_hits_response.get("data", {}).get("sidsPolicyHitsSummary", {}).get("sidSummaries", [])

    if not isinstance(policy_hits_summaries, list) or not policy_hits_summaries:
        policy_hits_context: list = []
    else:
        policy_hits_context: list = deepcopy(policy_hits_summaries[0].get("summary") or [])  # type: ignore

    base_url = str(client._baseurl).removesuffix("api")
    access_context, access_hr, policy_hr = prepare_context_hr_user_access_get(
        principal_summary, policy_hits_context, base_url, include_whitelisted_results
    )
    outputs = {f"{OUTPUT_PREFIX['USER_ACCESS']}(val.principalId == obj.principalId)": access_context}

    return CommandResults(outputs=outputs, raw_response=access_response, readable_output=f"{access_hr}\n\n{policy_hr}")


def rubrik_sonar_file_context_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of file context, based on the provided filters.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``dict``
    :param args: Arguments for the command.

    :return: CommandResult object.
    """
    object_id = validate_required_arg("object_id", args.get("object_id"))
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    file_name = args.get("file_name", "")
    file_path = args.get("file_path", "")
    user_id = args.get("user_id")
    user_ids = []
    if user_id:
        user_ids.append(user_id)
    include_whitelisted_results = argToBoolean(args.get("include_whitelisted_results", False))
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT), "limit")
    sort_by = args.get("sort_by", DEFAULT_FILE_CONTEXT_SORT_BY)
    sort_order = str(args.get("sort_order", DEFAULT_FILE_CONTEXT_SORT_ORDER)).upper()
    next_page_token = args.get("next_page_token")

    validate_user_access_list_command_args(limit, sort_order)  # type: ignore

    # Prepare filter.
    filters = {
        "snappableFid": object_id,
        "snapshotFid": snapshot_id,
        "filters": {
            "sids": user_ids,
            "fileType": "HITS",
            "searchText": file_name,
            "snappablePaths": [{"snappableFid": object_id, "stdPath": file_path}],
            "whitelistEnabled": not include_whitelisted_results,
        },
        "sort": {"sortBy": sort_by, "sortOrder": sort_order},
        "timezone": "UTC",
        "first": limit,
    }
    if next_page_token:
        filters["after"] = next_page_token

    response = client._query_raw(
        raw_query=FILE_CONTEXT_QUERY, operation_name="CrawlsFileListQuery", variables=filters, timeout=60
    )
    data = response.get("data", {}).get("policyObj", {}).get("fileResultConnection", {})
    edges = data.get("edges", [])
    if not edges:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("file contexts"))

    context, hr = prepare_context_hr_file_context_list(edges, include_whitelisted_results)

    page_cursor = remove_empty_elements(data.get("pageInfo", {}))
    page_cursor.pop("__typename", None)
    page_cursor.update({"name": "rubrik-sonar-file-context-list"})
    if page_cursor.get("hasNextPage"):
        hr += f"\n{MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}"

    outputs = {
        f"{OUTPUT_PREFIX['FILE_CONTEXT']}(val.stdPath == obj.stdPath)": context,
        f"{OUTPUT_PREFIX['PAGE_TOKEN_FILE_CONTEXT']}(val.name == obj.name)": page_cursor,
    }

    return CommandResults(outputs=outputs, raw_response=response, readable_output=hr)


def rubrik_radar_suspicious_file_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of suspicious files, based on the provided filters.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``dict``
    :param args: Arguments for the command.

    :return: CommandResult object.
    """
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))

    # Prepare filter for the SNAPPABLE_INVESTIGATIONS_QUERY.
    snappable_investigations_filters = {"id": snapshot_id}

    snappable_investigations_response = client._query_raw(
        raw_query=SNAPPABLE_INVESTIGATIONS_QUERY,
        operation_name="SnappableInvestigationsQuery",
        variables=snappable_investigations_filters,
        timeout=60,
    )

    snappable_investigations_data = snappable_investigations_response.get("data", {}).get("snapshot", {})
    raw_response = deepcopy(snappable_investigations_response)
    if not snappable_investigations_data:
        return CommandResults(
            readable_output=MESSAGES["NO_RECORD_FOUND"].format("snapshot"), raw_response=snappable_investigations_response
        )

    snapshot_cdm_id = snappable_investigations_data.get("cdmId", "")
    cluster_id = snappable_investigations_data.get("cluster", {}).get("id", "")
    if not snapshot_cdm_id or not cluster_id:
        return CommandResults(
            readable_output=MESSAGES["NO_RECORD_FOUND"].format("snapshot"), raw_response=snappable_investigations_response
        )

    # Prepare filter for the ANOMALY_RESULT_QUERY.
    suspicious_file_filters = {"snapshotId": snapshot_cdm_id, "clusterUuid": cluster_id}

    suspicious_file_response = client._query_raw(
        raw_query=ANOMALY_RESULT_QUERY, operation_name="AnomalyResultQuery", variables=suspicious_file_filters, timeout=60
    )
    suspicious_file_data = suspicious_file_response.get("data", {}).get("anomalyResultOpt", {})
    raw_response["data"]["anomalyResultOpt"] = deepcopy(suspicious_file_data)
    if not suspicious_file_data:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("suspicious files"), raw_response=raw_response)

    context, hr = prepare_context_hr_suspicious_file_list(snappable_investigations_data, suspicious_file_data)

    outputs = {f"{OUTPUT_PREFIX['SUSPICIOUS_FILE']}(val.id == obj.id)": remove_empty_elements(context)}

    return CommandResults(outputs=outputs, raw_response=raw_response, readable_output=hr)


def ip_command(client: PolarisClient, args: Dict[str, Any]) -> List[CommandResults]:
    """
    Retrieve the detail information of given ip(s).

    :type client: ``Client``
    :param client: Object of Client class.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :rtype: ``List[CommandResults]``
    :return: List of standard command result.
    """
    ips_list = argToList(args.get("ip"))
    ips = []

    for raw_ip in ips_list:
        ip = raw_ip.strip('"').strip()
        if ip:
            ips.append(ip)

    if not ips:
        raise ValueError(ERROR_MESSAGES["MISSING_REQUIRED_FIELD"].format("ip"))

    invalid_ips, valid_ips = validate_ip_addresses(ips)
    if invalid_ips:
        return_warning(
            "The following IP Addresses were found invalid: {}".format(", ".join(invalid_ips)), exit=len(invalid_ips) == len(ips)
        )

    command_results = []

    for ip in valid_ips:
        raw_resp = requests.get(
            f"{client._baseurl}/thirdparty/workload_summary",
            params={"search_string": ip, "search_type": "ipv6" if is_ipv6_valid(ip) else "ipv4"},
            headers=client.prepare_headers(),
            verify=client._verify,
            proxies=client._proxies,
            timeout=60,
        )
        raw_resp.raise_for_status()
        response = raw_resp.json()

        if MESSAGES["NO_OBJECT_FOUND"] in response.get(GENERAL_INFO_KEY, {}).get("fid", MESSAGES["NO_OBJECT_FOUND"]):
            return_warning(MESSAGES["IP_NOT_FOUND"].format(ip))
            continue

        ip_response = deepcopy(response)
        ip_response = remove_empty_elements(ip_response)
        severity_score, ip_hr_output = prepare_score_and_hr_for_reputation_command(ip_response, ip, "IP")
        ip_response["ip"] = ip

        dbot_score = Common.DBotScore(
            indicator=ip,
            indicator_type=DBotScoreType.IP,
            integration_name=VENDOR_NAME,
            score=severity_score,
            reliability=demisto.params().get("integration_reliability", DEFAULT_RELIABILITY),
        )
        dbot_score.integration_name = VENDOR_NAME

        ip_indicator = Common.IP(
            ip=ip,
            updated_date=response.get("threatMonitoringInfo", {}).get("latestThreatMonitoring", {}).get("monitoringScanTime"),
            dbot_score=dbot_score,
        )

        command_result = CommandResults(
            outputs_prefix=OUTPUT_PREFIX["IP"],
            outputs_key_field="ip",
            outputs=ip_response,
            raw_response=response,
            readable_output=ip_hr_output,
            indicator=ip_indicator,
        )

        command_results.append(command_result)

    return command_results


def domain_command(client: PolarisClient, args: Dict[str, Any]) -> List[CommandResults]:
    """
    Retrieve the detail information of given domain(s).

    :type client: ``Client``
    :param client: Object of Client class.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :rtype: ``List[CommandResults]``
    :return: List of standard command result.
    """
    domain_list = argToList(args.get("domain"))
    domains = []

    for raw_domain in domain_list:
        domain = raw_domain.strip('"').strip()
        if domain:
            domains.append(domain)

    if not domains:
        raise ValueError(ERROR_MESSAGES["MISSING_REQUIRED_FIELD"].format("domain"))
    command_results = []

    for domain in domains:
        raw_resp = requests.get(
            f"{client._baseurl}/thirdparty/workload_summary",
            params={"search_string": domain, "search_type": "name"},
            headers=client.prepare_headers(),
            verify=client._verify,
            proxies=client._proxies,
            timeout=60,
        )
        raw_resp.raise_for_status()
        response = raw_resp.json()

        if MESSAGES["NO_OBJECT_FOUND"] in response.get(GENERAL_INFO_KEY, {}).get("fid", MESSAGES["NO_OBJECT_FOUND"]):
            return_warning(MESSAGES["DOMAIN_NOT_FOUND"].format(domain))
            continue

        domain_response = deepcopy(response)
        domain_response = remove_empty_elements(domain_response)
        severity_score, domain_hr_output = prepare_score_and_hr_for_reputation_command(domain_response, domain, "domain")
        domain_response["domain"] = domain

        dbot_score = Common.DBotScore(
            indicator=domain,
            indicator_type=DBotScoreType.DOMAIN,
            integration_name=VENDOR_NAME,
            score=severity_score,
            reliability=demisto.params().get("integration_reliability", DEFAULT_RELIABILITY),
        )
        dbot_score.integration_name = VENDOR_NAME

        domain_indicator = Common.Domain(
            domain=domain,
            updated_date=response.get("threatMonitoringInfo", {}).get("latestThreatMonitoring", {}).get("monitoringScanTime"),
            dbot_score=dbot_score,
        )

        command_result = CommandResults(
            outputs_prefix=OUTPUT_PREFIX["DOMAIN"],
            outputs_key_field="domain",
            outputs=domain_response,
            raw_response=response,
            readable_output=domain_hr_output,
            indicator=domain_indicator,
        )

        command_results.append(command_result)

    return command_results


def rubrik_radar_anomaly_status_update_command(client: PolarisClient, args: Dict[str, Any]):
    """
    Update the status of a radar anomaly.

    :type client: ``Client``
    :param client: Object of Client class.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :rtype: ``CommandResults``
    :return: Standard command result.
    """
    anomaly_type = validate_required_arg("anomaly_type", args.get("anomaly_type"))
    workload_id = validate_required_arg("workload_id", args.get("workload_id"))
    anomaly_id = validate_required_arg("anomaly_id", args.get("anomaly_id"))
    false_positive_type = args.get("false_positive_type")
    false_positive_reason = args.get("false_positive_reason")

    validate_anomaly_status_update_command_args(anomaly_type, false_positive_type, false_positive_reason)

    params = {"anomalyType": anomaly_type.upper(), "workloadId": workload_id, "anomalyId": anomaly_id}

    if false_positive_type:
        false_positive_params = {"falsePositiveType": false_positive_type.upper()}
        if false_positive_type.upper() == "OTHER":
            false_positive_params["otherReason"] = false_positive_reason
        params.update({"falsePositiveReport": false_positive_params})

    input_params = {"input": params}

    anomaly_status_update_response = client._query_raw(
        raw_query=ANOMALY_UPDATE_STATUS_MUTATION, operation_name="AnomalyUpdateStatusMutation", variables=input_params, timeout=60
    )
    ec = {
        "command_name": "rubrik-radar-anomaly-update-status",
        "anomaly_id": anomaly_id,
        "anomaly_type": anomaly_type,
        "workload_id": workload_id,
    }
    if false_positive_type:
        ec["false_positive_type"] = false_positive_type
        if false_positive_type.upper() == "OTHER":
            ec["false_positive_reason"] = false_positive_reason
        hr_output = f"### Anomaly detection with the ID {anomaly_id} marked as false positive successfully."
    else:
        ec["is_resloved"] = True
        hr_output = f"### Anomaly detection with the ID {anomaly_id} resolved successfully."

    return CommandResults(
        readable_output=hr_output,
        raw_response=anomaly_status_update_response,
        outputs=remove_empty_elements(ec),
        outputs_prefix=OUTPUT_PREFIX["ANOMALY_UPDATE_STATUS"],
        outputs_key_field=["command_name", "anomaly_id", "workload_id"],
    )


def rubrik_threat_monitoring_matched_object_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Get the list of matched objects in the threat monitoring.

    :type client: ``Client``
    :param client: Object of Client class.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    :rtype: ``CommandResults``
    """
    limit = arg_to_number(args.get("limit", "50"))
    next_page_token = args.get("next_page_token")
    start_time_obj = arg_to_datetime(args.get("start_time", "7 days"))
    cluster_uuids = argToList(args.get("cluster_id"))
    object_types = argToList(args.get("object_type"))
    object_name = args.get("object_name")
    match_types = argToList(args.get("match_type"))

    validate_threat_monitoring_matched_object_list_command_args(start_time_obj, limit, match_types)

    ioc_match_type = []
    for match_type in match_types:
        ioc_match_type.append(IOC_TYPE_MAPPING.get(match_type))

    threat_monitoring_filters = {
        "clusterUuidFilter": cluster_uuids,
        "matchTypeFilter": ioc_match_type,
        "objectTypeFilter": object_types,
        "workloadNameSearch": object_name,
        "first": limit,
        "after": next_page_token,
    }

    if start_time_obj:
        start_time = start_time_obj.strftime(DATE_TIME_FORMAT)  # type: ignore
        threat_monitoring_filters["beginTime"] = start_time

    remove_nulls_from_dictionary(threat_monitoring_filters)

    threat_monitoring_response = client._query_raw(
        raw_query=THREAT_MONITORING_MATCHED_OBJECT_LIST_QUERY,
        operation_name="ThreatMonitoringMatchedObjectsQuery",
        variables=threat_monitoring_filters,
        timeout=60,
    )

    edges = []
    page_info, stats_info = {}, {}
    threat_monitoring_data = threat_monitoring_response.get("data", {})
    if threat_monitoring_data is not None:
        edges = threat_monitoring_data.get("threatMonitoringMatchedObjects", {}).get("edges", [])
        page_info = threat_monitoring_data.get("threatMonitoringMatchedObjects", {}).get("pageInfo", {})
        stats_info = threat_monitoring_data.get("threatMonitoringMatchedObjects", {}).get("stats", {})

    page_cursor = remove_empty_elements(page_info)
    page_cursor.pop("__typename", None)
    page_cursor.update(
        {
            "name": "rubrik-threat-monitoring-matched-object-list",
            "total_matched_count": stats_info.get("objectsWithMatches"),
        }
    )

    outputs = {f"{OUTPUT_PREFIX['PAGE_TOKEN_THREAT_MONITORING']}(val.name == obj.name)": page_cursor}

    if not edges:
        return CommandResults(
            outputs=outputs,
            raw_response=threat_monitoring_response,
            readable_output=MESSAGES["NO_RECORDS_FOUND"].format("threat monitoring objects"),
        )

    context, hr = prepare_context_hr_threat_monitoring_matched_object_list(edges)

    if page_cursor.get("hasNextPage"):
        hr += f"\n{MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}"

    outputs[f"{OUTPUT_PREFIX['THREAT_MONITORING']}(val.objectFid == obj.objectFid)"] = context

    return CommandResults(outputs=remove_empty_elements(outputs), raw_response=threat_monitoring_response, readable_output=hr)


def rubrik_threat_monitoring_matched_object_get_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Get the matched object in the threat monitoring.

    :type client: ``Client``
    :param client: Object of Client class.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    :rtype: ``CommandResults``
    """
    object_id = args.get("object_id", "").strip()
    object_id = validate_required_arg("object_id", object_id)

    threat_monitoring_get_filters = {
        "fid": object_id,
    }

    threat_monitoring_response = client._query_raw(
        raw_query=THREAT_MONITORING_MATCHED_OBJECT_GET_QUERY,
        operation_name="ThreatMonitoringObjectTypeQuery",
        variables=threat_monitoring_get_filters,
        timeout=60,
    )

    threat_monitoring_data = threat_monitoring_response.get("data", {})
    if threat_monitoring_data:
        threat_monitoring_data = threat_monitoring_data.get("hierarchyObject", {})

    if not threat_monitoring_data:
        return CommandResults(readable_output=MESSAGES["NO_RECORD_FOUND"].format("threat monitoring object"))

    hr = prepare_hr_threat_monitoring_matched_objects_get(threat_monitoring_data)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["THREAT_MONITORING"],
        outputs_key_field="id",
        outputs=remove_empty_elements(threat_monitoring_data),
        raw_response=threat_monitoring_response,
        readable_output=hr,
    )


def rubrik_threat_monitoring_matched_file_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Get the list of matched files for a threat monitoring object.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :rtype: ``CommandResults``
    :return: Standard command result.
    """
    object_id = args.get("object_id", "").strip()
    limit = arg_to_number(args.get("limit", "50"))
    next_page_token = args.get("next_page_token")
    file_name = args.get("file_name")

    validate_threat_monitoring_matched_file_list_command_args(object_id, limit)

    variables = {
        "objectFid": object_id,
        "first": limit,
        "after": next_page_token,
        "filenameSearchFilter": file_name,
    }
    remove_nulls_from_dictionary(variables)

    response = client._query_raw(
        raw_query=THREAT_MONITORING_MATCHED_FILE_LIST_QUERY,
        operation_name="ThreatMonitoringMatchedFiles",
        variables=variables,
        timeout=60,
    )

    edges = []
    data, page_info = {}, {}

    file_list_response = response.get("data", {})
    if file_list_response:
        data = file_list_response.get("threatMonitoringMatchedFiles", {})
        edges = data.get("edges", [])
        page_info = data.get("pageInfo", {})

    page_cursor = remove_empty_elements(page_info)
    page_cursor.pop("__typename", None)
    page_cursor.update(
        {
            "name": "rubrik-threat-monitoring-matched-file-list",
            "total_matched_count": data.get("count"),
        }
    )

    outputs = {f"{OUTPUT_PREFIX['PAGE_TOKEN_THREAT_MONITORING_FILE']}(val.name == obj.name)": page_cursor}

    if not edges:
        return CommandResults(
            outputs=outputs, raw_response=response, readable_output=MESSAGES["NO_RECORDS_FOUND"].format("threat monitoring files")
        )

    context, hr = prepare_context_hr_threat_monitoring_matched_file_list(edges)

    if page_cursor.get("hasNextPage"):
        hr += f"\n{MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}"

    outputs[f"{OUTPUT_PREFIX['THREAT_MONITORING_FILE']}(val.matchId == obj.matchId)"] = context

    return CommandResults(outputs=remove_empty_elements(outputs), raw_response=response, readable_output=hr)


def rubrik_threat_monitoring_matched_file_get_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Get the details of a matched file in the threat monitoring.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: CommandResults object containing the results
    :rtype: ``CommandResults``
    """
    # Get and validate arguments
    matched_snapshot_id = args.get("matched_snapshot_id", "").strip()
    file_path = args.get("file_path", "").strip()

    # Validate required arguments
    validate_threat_monitoring_matched_file_get_command_args(matched_snapshot_id, file_path)

    # Prepare variables for the GraphQL query
    variables = {"matchedSnapshotFid": matched_snapshot_id, "filepath": file_path}

    # Make the API call
    response = client._query_raw(
        raw_query=THREAT_MONITORING_MATCHED_FILE_DETAILS_QUERY,
        operation_name="ThreatMonitoringMatchedFileDetailsV2Query",
        variables=variables,
        timeout=60,
    )

    # Extract the file details from the response
    file_details = {}
    data = response.get("data", {})
    if data:
        file_details = data.get("threatMonitoringMatchedFileDetailsV2", {})

    if not file_details:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("matched file details"), raw_response=response)

    # Prepare human readable output
    hr_content = prepare_context_hr_threat_monitoring_matched_file_get(file_details)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["THREAT_MONITORING_FILE"],
        outputs_key_field=["fileName", "filePath"],
        outputs=remove_empty_elements(file_details),
        raw_response=response,
        readable_output=hr_content,
    )


def rubrik_ioc_scan_list_v2_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of IOC scans.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    """
    cluster_id = argToList(args.get("cluster_id"))
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    next_page_token = args.get("next_page_token")
    start_time_obj = arg_to_datetime(args.get("start_time", DEFAULT_TIME_PERIOD))
    end_time_obj = arg_to_datetime(args.get("end_time"))
    ioc_match = argToList(args.get("ioc_match"))
    quarantine_status = argToList(args.get("quarantine_status"))
    hunt_status = argToList(args.get("hunt_status"))

    validate_ioc_scan_list_v2_command_args(limit, ioc_match, quarantine_status, hunt_status)

    ioc_scan_filters = {
        "first": limit,
        "after": next_page_token,
        "matchesFoundFilter": ioc_match,
        "quarantinedMatchesFilter": quarantine_status,
        "statusFilter": hunt_status,
        "clusterUuidFilter": cluster_id,
    }

    if start_time_obj:
        start_time = start_time_obj.strftime(DATE_TIME_FORMAT)
        ioc_scan_filters["beginTime"] = start_time
    if end_time_obj:
        end_time = end_time_obj.strftime(DATE_TIME_FORMAT)
        ioc_scan_filters["endTime"] = end_time

    remove_nulls_from_dictionary(ioc_scan_filters)

    response = client._query_raw(
        raw_query=List_Threat_Hunts_Query, operation_name="ListThreatHuntsQuery", variables=ioc_scan_filters, timeout=60
    )

    edges = []
    data, page_info = {}, {}
    ioc_scan_data = response.get("data", {})
    if ioc_scan_data:
        data = ioc_scan_data.get("threatHunts", {})
        edges = data.get("edges", [])
        page_info = data.get("pageInfo", {})

    page_cursor = remove_empty_elements(page_info)
    page_cursor.pop("__typename", None)
    page_cursor.update(
        {
            "name": "rubrik-ioc-scan-list-v2",
            "total_matched_count": data.get("count"),
        }
    )

    outputs = {f"{OUTPUT_PREFIX['PAGE_TOKEN_IOC_SCAN']}(val.name == obj.name)": page_cursor}

    if not edges:
        return CommandResults(
            outputs=outputs, raw_response=response, readable_output=MESSAGES["NO_RECORDS_FOUND"].format("ioc scans")
        )

    context, hr = prepare_context_hr_ioc_scan_v2_list(edges)

    if page_cursor.get("hasNextPage"):
        hr += f"\n{MESSAGES['NEXT_RECORD']} {page_cursor.get('endCursor')}"

    outputs[f"{OUTPUT_PREFIX['IOC_SCAN']}(val.huntId == obj.huntId)"] = context

    return CommandResults(outputs=remove_empty_elements(outputs), raw_response=response, readable_output=hr)


def rubrik_ioc_scan_results_v2_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve details of the Turbo and Advance Threat Hunt.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    :rtype: ``CommandResults``
    """
    hunt_id = validate_required_arg("hunt_id", args.get("hunt_id"))

    ioc_scan_filters = {"huntId": hunt_id}

    response = client._query_raw(
        raw_query=THREAT_HUNT_DETAILS_V2_QUERY, operation_name="ThreatHuntDetailsV2Query", variables=ioc_scan_filters, timeout=60
    )

    ioc_scan_data = {}
    response_data = deepcopy(response.get("data", {}))
    if response_data:
        ioc_scan_data = response_data.get("threatHuntDetailV2", {})
        ioc_scan_data["threatHuntObjectMetrics"] = response_data.get("threatHuntObjectMetrics", {})
        ioc_scan_data["hunt_id"] = hunt_id

    if not ioc_scan_data:
        return CommandResults(raw_response=response, readable_output=MESSAGES["NO_RECORD_FOUND"].format("ioc scan result"))

    hr = prepare_hr_ioc_scan_results_v2(ioc_scan_data)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["IOC_SCAN"],
        outputs_key_field="hunt_id",
        outputs=remove_empty_elements(ioc_scan_data),
        raw_response=response,
        readable_output=hr,
    )


def rubrik_turbo_ioc_scan_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Start a new turbo threat hunt.

    :type client: ``PolarisClient``
    :param client: Object of Client class.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    :rtype: ``CommandResults``
    """
    ioc = argToList(args.get("ioc"), transform=lambda s: s.strip())
    scan_name = args.get("scan_name", DEFAULT_REQUEST_NAME)
    cluster_ids = argToList(args.get("cluster_id"), transform=lambda s: s.strip())
    start_time_obj = arg_to_datetime(args.get("start_time"))
    end_time_obj = arg_to_datetime(args.get("end_time"))
    max_snapshots_per_object = arg_to_number(args.get("max_snapshots_per_object"))

    validate_turbo_ioc_scan_command_args(ioc, max_snapshots_per_object)

    indicators_of_compromise = [{"iocKind": "IOC_HASH", "iocValue": ioc} for ioc in ioc]

    scan_config = {}
    if start_time_obj:
        scan_config["startTime"] = start_time_obj.strftime(DATE_TIME_FORMAT)
    if end_time_obj:
        scan_config["endTime"] = end_time_obj.strftime(DATE_TIME_FORMAT)
    if max_snapshots_per_object:
        scan_config["maxSnapshotsPerObject"] = max_snapshots_per_object  # type: ignore

    if not cluster_ids:
        cluster_ids = []

    input_data = {
        "config": {
            "baseConfig": {
                "name": scan_name,
                "threatHuntType": "TURBO_THREAT_HUNT",
                "ioc": {"iocList": {"indicatorsOfCompromise": indicators_of_compromise}},
                "snapshotScanLimit": {"scanConfig": scan_config},
            },
            "objectsToScan": [{"objectType": "CDM_CLUSTER", "objectIds": cluster_ids}],
        }
    }

    response = client._query_raw(
        raw_query=START_TURBO_THREAT_HUNT_MUTATION,
        operation_name="StartTurboThreatHunt",
        variables={"input": input_data},
        timeout=60,
    )

    data = response.get("data", {})
    hunt_data = data.get("startTurboThreatHunt", {})

    readable_output = f"#### The new Turbo Threat Hunt started with ID: {hunt_data.get('huntId')}"

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["TURBO_IOC_SCAN"],
        outputs_key_field="huntId",
        outputs=hunt_data,
        raw_response=response,
        readable_output=readable_output,
    )


def rubrik_advance_ioc_scan_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Trigger an advance threat hunt.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    :rtype: ``CommandResults``
    """
    object_ids = validate_required_arg("object_id", argToList(args.get("object_id")))
    ioc_type = args.get("ioc_type")
    ioc_value = args.get("ioc_value")
    scan_name = args.get("scan_name", DEFAULT_REQUEST_NAME)
    advance_ioc = args.get("advance_ioc")
    start_time_obj = arg_to_datetime(args.get("start_date"))
    end_time_obj = arg_to_datetime(args.get("end_date"))
    max_matches_per_snapshot = arg_to_number(args.get("max_matches_per_snapshot"), "max_matches_per_snapshot")
    max_snapshots_per_object = arg_to_number(args.get("max_snapshots_per_object"), "max_snapshots_per_object")
    min_file_size = arg_to_number(args.get("min_file_size"), "min_file_size")
    max_file_size = arg_to_number(args.get("max_file_size"), "max_file_size")
    paths_to_include = argToList(args.get("paths_to_include"))
    paths_to_exclude = argToList(args.get("paths_to_exclude"))
    paths_to_exempt = argToList(args.get("paths_to_exempt"))

    iocs = prepare_ioc_and_validate_advance_ioc_scan_args(
        ioc_type, ioc_value, advance_ioc, max_matches_per_snapshot, max_snapshots_per_object, min_file_size, max_file_size
    )

    input_data = {
        "baseConfig": {
            "name": scan_name,
            "threatHuntType": "THREAT_HUNT_V2",
            "ioc": {"iocList": {"indicatorsOfCompromise": iocs}},
            "fileScanCriteria": {
                "fileSizeLimits": {"maximumSizeInBytes": max_file_size, "minimumSizeInBytes": min_file_size},
                "pathFilter": {"inclusions": paths_to_include, "exclusions": paths_to_exclude, "exemptions": paths_to_exempt},
            },
            "maxMatchesPerSnapshot": max_matches_per_snapshot,
            "snapshotScanLimit": {"scanConfig": {"maxSnapshotsPerObject": max_snapshots_per_object}},
        },
        "objectFids": object_ids,
    }

    if start_time_obj:
        start_time = start_time_obj.strftime(DATE_TIME_FORMAT)
        input_data["baseConfig"]["snapshotScanLimit"]["scanConfig"]["startTime"] = start_time
    if end_time_obj:
        end_time = end_time_obj.strftime(DATE_TIME_FORMAT)
        input_data["baseConfig"]["snapshotScanLimit"]["scanConfig"]["endTime"] = end_time

    remove_nulls_from_dictionary(input_data)

    raw_response = client._query_raw(
        raw_query=START_ADVANCE_THREAT_HUNT_MUTATION,
        operation_name="StartAdvanceThreatHuntMutation",
        variables={"input": input_data},
        timeout=60,
    )

    data = raw_response.get("data", {})
    hunts_data = data.get("startBulkThreatHunt", {}).get("hunts", [])

    hr = f"#### The new advance Threat Hunt started with ID: {hunts_data[0].get('huntId')}."

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["ADVANCE_IOC_SCAN"],
        outputs_key_field="huntId",
        outputs=hunts_data,
        raw_response=raw_response,
        readable_output=hr,
    )


def rubrik_anomaly_csv_analysis_v2_command(client: PolarisClient, args: Dict[str, Any]) -> List[CommandResults]:
    """
    Scheduled polling command to download anomaly details CSV file.

    This command implements a three-step polling workflow:
    1. First execution: Triggers CSV download using downloadAnomalyDetailsCsv mutation.
    2. Polling iterations: Polls allUserFiles query until file status becomes READY.
    3. Final step: Downloads the file data using external_id through REST API and returns the CSV file.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``Dict[str, Any]``
    :param args: Command arguments obtained from demisto.args().

    :rtype: ``List[CommandResults]``
    :return: List of CommandResults.
    """
    cluster_id = validate_required_arg("cluster_id", args.get("cluster_id"))
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    object_id = validate_required_arg("object_id", args.get("object_id"))

    polling = argToBoolean(args.get("polling", False))

    is_successful = True
    if not polling:
        input_data = {
            "clusterUuid": cluster_id,
            "snapshotId": snapshot_id,
            "workloadId": object_id,
        }

        response = client._query_raw(
            raw_query=DOWNLOAD_ANOMALY_DETAILS_CSV_MUTATION,
            operation_name="DownloadAnomalyDetailsCsvMutation",
            variables={"input": input_data},
            timeout=60,
        )

        data = response.get("data", {})
        download_data = data.get("downloadAnomalyDetailsCsv", {})
        if not download_data:
            return [CommandResults(readable_output=f"#### {MESSAGES['NO_RESPONSE']}", outputs={})]
        is_successful = download_data.get("isSuccessful", False)

        outputs = {
            "clusterId": cluster_id,
            "snapshotId": snapshot_id,
            "objectId": object_id,
            "isSuccessful": is_successful,
        }

        hr = "#### Successfully analyzed the CSV file." if is_successful else "#### Failed to analyze the CSV file."

        result = [
            CommandResults(
                outputs_prefix=OUTPUT_PREFIX["ANOMALY_CSV_ANALYSIS_V2"],
                outputs_key_field=["clusterId", "snapshotId", "objectId"],
                outputs=outputs,
                readable_output=hr,
                raw_response=response,
            )
        ]

    target_file_name = f"snapshot_{snapshot_id}"
    external_id = ""

    if polling:
        user_files_response = client._query_raw(
            raw_query=ALL_USER_DOWNLOADS_FILES_QUERY,
            operation_name="DownloadBarQuery",
            variables={},
            timeout=60,
        )

        data = user_files_response.get("data", {})
        user_files = data.get("allUserFiles", [])

        for user_file in user_files:
            downloaded_files = user_file.get("downloads", [])
            downloaded_files = downloaded_files[::-1]
            for file_info in downloaded_files:
                if file_info.get("filename") == target_file_name:
                    file_state = file_info.get("state", "").lower()
                    if file_state == "ready":
                        external_id = file_info.get("externalId", "")
                        break
                    if file_state == "failed":
                        is_successful = False
                        break

        # Attempt to download the file if external_id is available
        file_result = None
        if external_id:
            base_url = str(client._baseurl).removesuffix("api")
            download_url = urljoin(base_url, f"file-downloads/{external_id}")
            response = requests.get(
                download_url,
                headers=client.prepare_headers(),
                verify=client._verify,
                proxies=client._proxies,
                timeout=60,
            )
            response.raise_for_status()

            file_result = fileResult(
                filename=f"{target_file_name}.csv", data=response.content, file_type=EntryType.ENTRY_INFO_FILE
            )

        # Determine human-readable message based on status
        if not is_successful:
            hr = "#### Failed to download the analyzed CSV file."
        elif file_result:
            hr = "#### Successfully downloaded the analyzed CSV file."
        else:
            hr = "#### Polling for CSV file availability. The command will automatically retry..."

        # Prepare outputs and results
        outputs = {
            "clusterId": cluster_id,
            "snapshotId": snapshot_id,
            "objectId": object_id,
            "isSuccessful": is_successful,
            "externalId": external_id,
        }

        result = [
            CommandResults(
                outputs_prefix=OUTPUT_PREFIX["ANOMALY_CSV_ANALYSIS_V2"],
                outputs_key_field=["clusterId", "snapshotId", "objectId"],
                outputs=outputs,
                readable_output=hr,
                raw_response=user_files_response,
            )
        ]

        if file_result:
            result.append(file_result)

    return result


def rubrik_data_security_violation_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of DSPM violations.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    :rtype: ``CommandResults``
    """
    limit = arg_to_number(args.get("limit", "50"))
    next_page_token = args.get("next_page_token")
    object_types = argToList(args.get("object_type"), transform=lambda s: s.strip().upper())
    sort_by = args.get("sort_by", "DETECTION_TIME")
    sort_order = args.get("sort_order", DESCENDING_SORT_ORDER)

    statuses = argToList(args.get("status"), transform=lambda s: s.strip())
    severities = argToList(args.get("severity"), transform=lambda s: s.strip())
    sensitivities = argToList(args.get("sensitivity"), transform=lambda s: s.strip())
    categories = argToList(args.get("category"), transform=lambda s: s.strip().upper())

    detection_start_date = arg_to_datetime(args.get("detection_start_date"), arg_name="detection_start_date")
    detection_end_date = arg_to_datetime(args.get("detection_end_date"), arg_name="detection_end_date")
    resolved_start_date = arg_to_datetime(args.get("resolved_start_date"), arg_name="resolved_start_date")
    resolved_end_date = arg_to_datetime(args.get("resolved_end_date"), arg_name="resolved_end_date")

    validate_data_security_violation_list_command_args(
        limit, sort_by, sort_order, detection_start_date, detection_end_date, resolved_start_date, resolved_end_date
    )

    mapped_statuses, mapped_severities, mapped_sensitivities = validate_dspm_violation_fetch_params(
        statuses, severities, sensitivities, is_fetch=False
    )

    mapped_sort_by = f"SORT_{sort_by.upper()}" if sort_by else None

    dspm_filters: Dict[str, Any] = {
        "statuses": mapped_statuses,
        "severities": mapped_severities,
        "sensitivityLevels": mapped_sensitivities,
        "categories": categories,
        "first": limit,
        "after": next_page_token,
        "sortBy": mapped_sort_by,
        "sortOrder": sort_order.upper(),
    }

    if object_types:
        dspm_filters["resourceMetadataFilter"] = {"managedObjectTypes": object_types}

    if detection_start_date and detection_end_date:
        dspm_filters["detectionDate"] = {
            "start": detection_start_date.strftime(DATE_TIME_FORMAT),
            "end": detection_end_date.strftime(DATE_TIME_FORMAT),
        }

    if resolved_start_date and resolved_end_date:
        dspm_filters["updateDate"] = {
            "start": resolved_start_date.strftime(DATE_TIME_FORMAT),
            "end": resolved_end_date.strftime(DATE_TIME_FORMAT),
        }

    remove_nulls_from_dictionary(dspm_filters)

    response = client._query_raw(
        raw_query=DSPM_VIOLATIONS_LIST_QUERY,
        operation_name="DataSecurityViolationsListQuery",
        variables=dspm_filters,
        timeout=60,
    )

    edges = []
    page_info = {}
    dspm_data = response.get("data", {})
    if dspm_data is not None:
        policy_violations = dspm_data.get("policyViolations", {})
        if policy_violations:
            edges = policy_violations.get("edges", [])
            page_info = policy_violations.get("pageInfo", {})

    page_cursor = remove_empty_elements(page_info)
    page_cursor.pop("__typename", None)
    end_cursor = page_cursor.pop("endCursor", None)
    has_next_page = page_cursor.pop("hasNextPage", False)
    page_cursor.pop("startCursor", None)
    page_cursor.pop("hasPreviousPage", None)
    page_cursor.update(
        {
            "name": "rubrik-data-security-violation-list",
            "next_page_token": end_cursor,
            "has_next_page": has_next_page,
        }
    )

    outputs: Dict[str, Any] = {
        f"{OUTPUT_PREFIX['PAGE_TOKEN_DSPM_VIOLATION']}(val.name == obj.name)": remove_empty_elements(page_cursor),
    }

    if not edges:
        return CommandResults(
            outputs=outputs,
            raw_response=response,
            readable_output=f"#### {MESSAGES['NO_RECORDS_FOUND'].format('DSPM violations')}",
        )

    context, hr = prepare_context_hr_data_security_violation_list(edges)

    if has_next_page:
        hr += f"\n{MESSAGES['NEXT_RECORD']} {end_cursor}"

    outputs[f"{OUTPUT_PREFIX['DSPM_VIOLATION']}(val.policyViolationId == obj.policyViolationId)"] = context

    return CommandResults(
        outputs=remove_empty_elements(outputs),
        raw_response=response,
        readable_output=hr,
    )


def rubrik_data_security_violation_get_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the details of DSPM violation based on the provided violation ID.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``dict``
    :param args: Arguments for the command.

    :return: CommandResult object.
    """
    violation_id = validate_required_arg("violation_id", args.get("violation_id"))

    filters = {"violationId": violation_id}

    response = client._query_raw(
        raw_query=DSPM_VIOLATION_GET_QUERY,
        operation_name="DataSecurityViolationGetQuery",
        variables=filters,
        timeout=60,
    )

    violation_data = response.get("data", {}).get("policyViolation", {})
    if not violation_data:
        return CommandResults(readable_output=f"#### {MESSAGES['NO_RESPONSE']}", raw_response=response)

    context, hr = prepare_context_hr_dspm_violation_get(violation_data)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["DSPM_VIOLATION"],
        outputs_key_field="policyViolationId",
        outputs=context,
        raw_response=response,
        readable_output=hr,
    )


def rubrik_data_security_violation_status_update_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Update the status of a DSPM violation.

    :type client: ``Client``
    :param client: Object of Client class.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :rtype: ``CommandResults``
    :return: Standard command result.
    """
    violation_id = args.get("violation_id", "").strip()
    status = args.get("status", "").strip()

    validate_required_arg("violation_id", violation_id)
    validate_required_arg("status", status)

    if status.upper() not in DSPM_VIOLATION_STATUS:
        raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(status, "status", DSPM_VIOLATION_STATUS))

    update_status = f"POLICY_VIOLATION_STATUS_{status.upper()}"
    params = {
        "newPolicyViolationStatus": update_status,
        "policyViolationIds": [violation_id],
    }

    input_params = {"input": params}

    violation_status_update_response = client._query_raw(
        raw_query=DSPM_VIOLATION_STATUS_UPDATE_MUTATION,
        operation_name="UpdatePolicyViolationsMutation",
        variables=input_params,
        timeout=60,
    )

    ec = {
        "policyViolationId": violation_id,
        "status": update_status,
    }

    status_display = status.replace("_", " ").title()
    hr_output = f"#### Successfully updated the DSPM violation status to {status_display}"

    return CommandResults(
        readable_output=hr_output,
        raw_response=violation_status_update_response,
        outputs=remove_empty_elements(ec),
        outputs_prefix=OUTPUT_PREFIX["DSPM_VIOLATION"],
        outputs_key_field=["policyViolationId"],
    )


def rubrik_data_security_violation_file_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of Files information of DSPM violation.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    :rtype: ``CommandResults``
    """
    violation_id = validate_required_arg("violation_id", args.get("violation_id"))
    object_id = validate_required_arg("object_id", args.get("object_id"))
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))

    limit = arg_to_number(args.get("limit", "25"))
    next_page_token = args.get("next_page_token")
    file_search_text = args.get("file_name")
    sort_by = args.get("sort_by", "HITS")
    sort_order = args.get("sort_order", DESCENDING_SORT_ORDER)
    sensitivities = argToList(args.get("sensitivity"), transform=lambda s: s.strip().upper())
    exposures = argToList(args.get("exposure"), transform=lambda s: s.strip().upper())
    access_via = args.get("access_via", "ACCESS_TYPE_UNSPECIFIED")

    last_access_start_date = arg_to_datetime(args.get("last_access_start_date"), arg_name="last_access_start_date")
    last_access_end_date = arg_to_datetime(args.get("last_access_end_date"), arg_name="last_access_end_date")
    last_modified_start_date = arg_to_datetime(args.get("last_modified_start_date"), arg_name="last_modified_start_date")
    last_modified_end_date = arg_to_datetime(args.get("last_modified_end_date"), arg_name="last_modified_end_date")
    creation_start_date = arg_to_datetime(args.get("creation_start_date"), arg_name="creation_start_date")
    creation_end_date = arg_to_datetime(args.get("creation_end_date"), arg_name="creation_end_date")
    last_scan_start_date = arg_to_datetime(args.get("last_scan_start_date"), arg_name="last_scan_start_date")
    last_scan_end_date = arg_to_datetime(args.get("last_scan_end_date"), arg_name="last_scan_end_date")

    validate_data_security_violation_file_list_command_args(
        limit,
        sort_by,
        sort_order,
        sensitivities,
        exposures,
        access_via,
        last_access_start_date,
        last_access_end_date,
        last_modified_start_date,
        last_modified_end_date,
        creation_start_date,
        creation_end_date,
        last_scan_start_date,
        last_scan_end_date,
    )

    mapped_sensitivities = [f"{sensitivity.upper()}_RISK" for sensitivity in sensitivities]
    timezone = "UTC"
    file_filters: dict[str, Any] = {
        "violationId": violation_id,
        "accessVia": access_via.upper(),
        "fileType": "HITS",
        "whitelistEnabled": True,
        "searchText": file_search_text,
        "snappablePaths": [{"snappableFid": object_id}],
        "riskLevelTypesFilter": mapped_sensitivities,
        "exposureFilter": exposures,
    }

    if creation_start_date and creation_end_date:
        file_filters["creationTimeFilter"] = {
            "startTime": creation_start_date.strftime(DATE_TIME_FORMAT),
            "endTime": creation_end_date.strftime(DATE_TIME_FORMAT),
            "timezone": timezone,
        }

    if last_modified_start_date and last_modified_end_date:
        file_filters["lastModifiedFilter"] = {
            "startTime": last_modified_start_date.strftime(DATE_TIME_FORMAT),
            "endTime": last_modified_end_date.strftime(DATE_TIME_FORMAT),
            "timezone": timezone,
        }

    if last_access_start_date and last_access_end_date:
        file_filters["lastAccessFilter"] = {
            "startTime": last_access_start_date.strftime(DATE_TIME_FORMAT),
            "endTime": last_access_end_date.strftime(DATE_TIME_FORMAT),
            "timezone": timezone,
        }

    if last_scan_start_date and last_scan_end_date:
        file_filters["lastScanFilter"] = {
            "startTime": last_scan_start_date.strftime(DATE_TIME_FORMAT),
            "endTime": last_scan_end_date.strftime(DATE_TIME_FORMAT),
            "timezone": timezone,
        }

    remove_nulls_from_dictionary(file_filters)
    dspm_file_list_filters: dict[str, Any] = {
        "snapshotFid": snapshot_id,
        "snappableFid": object_id,
        "first": limit,
        "after": next_page_token,
        "sort": {"sortBy": sort_by, "sortOrder": sort_order},
        "filters": file_filters,
        "timezone": timezone,
    }

    remove_nulls_from_dictionary(dspm_file_list_filters)

    response = client._query_raw(
        raw_query=DSPM_VIOLATION_FILE_LIST_QUERY,
        operation_name="DSPMViolationFileListQuery",
        variables=dspm_file_list_filters,
        timeout=60,
    )

    edges = []
    page_info = {}
    object_data = response.get("data", {})
    if object_data is not None:
        file_info = demisto.get(object_data, "policyObj.fileResultConnection")
        if file_info:
            edges = file_info.get("edges", [])
            page_info = file_info.get("pageInfo", {})

    page_cursor = remove_empty_elements(page_info)
    page_cursor.pop("__typename", None)
    end_cursor = page_cursor.pop("endCursor", None)
    has_next_page = page_cursor.pop("hasNextPage", False)
    page_cursor.pop("startCursor", None)
    page_cursor.pop("hasPreviousPage", None)
    page_cursor.update(
        {
            "name": "rubrik-data-security-violation-file-list",
            "next_page_token": end_cursor,
            "has_next_page": has_next_page,
        }
    )

    outputs: Dict[str, Any] = {
        f"{OUTPUT_PREFIX['PAGE_TOKEN_DSPM_VIOLATION_FILE']}(val.name == obj.name)": remove_empty_elements(page_cursor),
    }

    if not edges:
        return CommandResults(
            outputs=outputs,
            raw_response=response,
            readable_output=f"#### {MESSAGES['NO_RECORDS_FOUND'].format('DSPM violation Files')}",
        )

    context, hr = prepare_context_hr_data_security_violation_file_list(edges)

    if has_next_page:
        hr += f"\n{MESSAGES['NEXT_RECORD']} {end_cursor}"

    outputs[f"{OUTPUT_PREFIX['DSPM_VIOLATION_FILE']}(val.stdPath == obj.stdPath)"] = context

    return CommandResults(
        outputs=remove_empty_elements(outputs),
        raw_response=response,
        readable_output=hr,
    )


def rubrik_data_security_violation_csv_download_command(client: PolarisClient, args: Dict[str, Any]) -> List[CommandResults]:
    """
    Scheduled polling command to download DSPM Violation Files at Risk CSV file.

    This command implements a three-step polling workflow:
    1. First execution: Triggers CSV download using downloadSnapshotResultsCsv mutation.
    2. Polling iterations: Polls allUserFiles query until file status becomes READY.
    3. Final step: Downloads the file data using external_id through REST API and returns the CSV file.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``Dict[str, Any]``
    :param args: Command arguments obtained from demisto.args().

    :rtype: ``List[CommandResults]``
    :return: List of CommandResults.
    """
    violation_id = validate_required_arg("violation_id", args.get("violation_id"))
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    object_id = validate_required_arg("object_id", args.get("object_id"))
    object_name = args.get("object_name")

    if not object_name:
        filters = {"violationId": violation_id}
        demisto.debug(f"Retrieving the object name by using the get violation request for ID {violation_id}.")
        violation_response = client._query_raw(
            raw_query=DSPM_VIOLATION_GET_QUERY,
            operation_name="DataSecurityViolationGetQuery",
            variables=filters,
            timeout=60,
        )

        violation_data = violation_response.get("data", {}).get("policyViolation", {})
        metadata = demisto.get(violation_data, "resourceMetadata.metadata", {})
        object_name = metadata.get("name", "")

    polling = argToBoolean(args.get("polling", False))
    outputs = {
        "violationId": violation_id,
        "snapshotId": snapshot_id,
        "objectId": object_id,
        "objectName": object_name,
    }

    is_successful = True
    if not polling:
        input_data = {
            "snappableFid": object_id,
            "snapshotFid": snapshot_id,
            "filters": {"policyViolationId": violation_id, "fileType": "HITS"},
        }

        response = client._query_raw(
            raw_query=DOWNLOAD_DSPM_VIOLATION_CSV_MUTATION,
            operation_name="DownloadDSPMViolationCsvMutation",
            variables=input_data,
            timeout=60,
        )

        data = response.get("data", {})
        download_data = data.get("downloadSnapshotResultsCsv", {})
        if not download_data:
            return [CommandResults(readable_output=f"#### {MESSAGES['NO_RESPONSE']}")]
        is_successful = download_data.get("isSuccessful", False)

        outputs.update({"isSuccessful": is_successful})

        hr = (
            "#### Successfully initiated the downloading of the CSV file."
            if is_successful
            else "#### Failed to initiated the downloading of the CSV file."
        )

        return [
            CommandResults(
                outputs_prefix=OUTPUT_PREFIX["DSPM_VIOLATION_CSV_DOWNLOAD"],
                outputs_key_field=["violationId", "snapshotId", "objectId"],
                outputs=outputs,
                readable_output=hr,
                raw_response=response,
            )
        ]

    # Check the state of file
    target_file_name = f"{object_name.replace(' ', '-')}-violating-files_file_results"
    download_file_name = ""
    external_id = ""

    user_files_response = client._query_raw(
        raw_query=ALL_USER_DOWNLOADS_FILES_QUERY,
        operation_name="DownloadBarQuery",
        variables={},
        timeout=60,
    )

    data = user_files_response.get("data", {})
    user_files = data.get("allUserFiles", [])

    for user_file in user_files:
        downloaded_files = user_file.get("downloads", [])
        downloaded_files = downloaded_files[::-1]
        for file_info in downloaded_files:
            if target_file_name in file_info.get("filename"):
                download_file_name = file_info.get("filename")
                file_state = file_info.get("state", "").lower()
                if file_state == "ready":
                    external_id = file_info.get("externalId", "")
                    break
                if file_state == "failed":
                    is_successful = False
                    break

    # Attempt to download the file if external_id is available
    file_result = None
    if external_id:
        base_url = str(client._baseurl).removesuffix("api")
        download_url = urljoin(base_url, f"file-downloads/{external_id}")
        response = requests.get(
            download_url,
            headers=client.prepare_headers(),
            verify=client._verify,
            proxies=client._proxies,
            timeout=60,
        )
        response.raise_for_status()

        file_result = fileResult(filename=download_file_name, data=response.content, file_type=EntryType.ENTRY_INFO_FILE)

    # Determine human-readable message based on status
    if not is_successful:
        hr = "#### Failed to download the Files at Risk CSV file."
    elif file_result:
        hr = "#### Successfully downloaded the Files at Risk CSV file."
    else:
        hr = "#### Polling for CSV file availability. The command will automatically retry..."

    # Prepare outputs and results
    outputs.update({"isSuccessful": is_successful, "externalId": external_id})

    result = [
        CommandResults(
            outputs_prefix=OUTPUT_PREFIX["DSPM_VIOLATION_CSV_DOWNLOAD"],
            outputs_key_field=["violationId", "snapshotId", "objectId"],
            outputs=remove_empty_elements(outputs),
            readable_output=hr,
            raw_response=user_files_response,
        )
    ]

    if file_result:
        result.append(file_result)

    return result


def rubrik_data_security_violation_log_download_command(client: PolarisClient, args: Dict[str, Any]) -> List[CommandResults]:
    """
    Scheduled polling command to download DSPM Violation Remediation Log file.

    This command implements a three-step polling workflow:
    1. First execution: Triggers Log download using createViolationRemediation mutation.
    2. Polling iterations: Polls allUserFiles query until file status becomes READY.
    3. Final step: Downloads the file data using external_id through REST API and returns the file.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use

    :type args: ``Dict[str, Any]``
    :param args: Command arguments obtained from demisto.args().

    :rtype: ``List[CommandResults]``
    :return: List of CommandResults.
    """
    violation_id = validate_required_arg("violation_id", args.get("violation_id"))
    object_id = validate_required_arg("object_id", args.get("object_id"))
    object_name = args.get("object_name")

    if not object_name:
        filters = {"violationId": violation_id}
        demisto.debug("Retrieving the object name using the get violation request.")
        violation_response = client._query_raw(
            raw_query=DSPM_VIOLATION_GET_QUERY,
            operation_name="DataSecurityViolationGetQuery",
            variables=filters,
            timeout=60,
        )

        violation_data = violation_response.get("data", {}).get("policyViolation", {})
        metadata = demisto.get(violation_data, "resourceMetadata.metadata", {})
        object_name = metadata.get("name", "")

    polling = argToBoolean(args.get("polling", False))
    outputs = {
        "violationId": violation_id,
        "objectId": object_id,
        "objectName": object_name,
    }

    is_successful = True
    if not polling:
        input_data = {
            "targets": {
                "targetIds": [violation_id],
                "targetType": "REMEDIATION_TARGET_TYPE_VIOLATION",
            },
            "remediationType": "REMEDIATION_TYPE_EXPORT_ACTIONS_LOG_TO_CSV",
            "resourceId": object_id,
        }

        response = client._query_raw(
            raw_query=DOWNLOAD_DSPM_VIOLATION_REMEDIATION_LOG_MUTATION,
            operation_name="DownloadDSPMViolationRemediationLogMutation",
            variables={"input": input_data},
            timeout=60,
        )

        data = response.get("data", {})
        download_data = data.get("createViolationRemediation", {})
        if not download_data:
            return [CommandResults(readable_output=f"#### {MESSAGES['NO_RESPONSE']}")]
        remediation_id = download_data.get("remediationId")

        is_successful = bool(remediation_id)
        outputs.update({"remediationId": remediation_id, "isSuccessful": is_successful})

        hr = (
            "#### Successfully initiated the downloading of the Remediation Log file."
            if is_successful
            else "#### Failed to initiated the downloading of the Remediation Log file."
        )

        return [
            CommandResults(
                outputs_prefix=OUTPUT_PREFIX["DSPM_VIOLATION_LOG_DOWNLOAD"],
                outputs_key_field=["violationId", "objectId"],
                outputs=outputs,
                readable_output=hr,
                raw_response=response,
            )
        ]

    # Check the state of file
    target_file_name = f"{object_name} actions log"
    external_id = ""

    user_files_response = client._query_raw(
        raw_query=ALL_USER_DOWNLOADS_FILES_QUERY,
        operation_name="DownloadBarQuery",
        variables={},
        timeout=60,
    )

    data = user_files_response.get("data", {})
    user_files = data.get("allUserFiles", [])

    for user_file in user_files:
        downloaded_files = user_file.get("downloads", [])
        downloaded_files = downloaded_files[::-1]
        for file_info in downloaded_files:
            if target_file_name in file_info.get("filename"):
                file_state = file_info.get("state", "").lower()
                if file_state == "ready":
                    external_id = file_info.get("externalId", "")
                    break
                if file_state == "failed":
                    is_successful = False
                    break

    # Attempt to download the file if external_id is available
    file_result = None
    if external_id:
        base_url = str(client._baseurl).removesuffix("api")
        download_url = urljoin(base_url, f"file-downloads/{external_id}")
        response = requests.get(
            download_url,
            headers=client.prepare_headers(),
            verify=client._verify,
            proxies=client._proxies,
            timeout=60,
        )
        response.raise_for_status()

        file_result = fileResult(filename=f"{target_file_name}.csv", data=response.content, file_type=EntryType.ENTRY_INFO_FILE)

    # Determine human-readable message based on status
    if not is_successful:
        hr = "#### Failed to download the Remediation Log file."
    elif file_result:
        hr = "#### Successfully downloaded the Remediation Log file."
    else:
        hr = "#### Polling for Remediation Log file availability. The command will automatically retry..."

    # Prepare outputs and results
    outputs.update({"isSuccessful": is_successful, "externalId": external_id})

    result = [
        CommandResults(
            outputs_prefix=OUTPUT_PREFIX["DSPM_VIOLATION_LOG_DOWNLOAD"],
            outputs_key_field=["violationId", "objectId"],
            outputs=remove_empty_elements(outputs),
            readable_output=hr,
            raw_response=user_files_response,
        )
    ]

    if file_result:
        result.append(file_result)

    return result


def rubrik_identity_resilience_violation_list_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the list of IR violations.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :return: Standard command result.
    :rtype: ``CommandResults``
    """
    limit = arg_to_number(args.get("limit", "50"))
    next_page_token = args.get("next_page_token")
    sort_by = args.get("sort_by", "DETECTION_TIME")
    sort_order = args.get("sort_order", DESCENDING_SORT_ORDER)

    statuses = argToList(args.get("status"), transform=lambda s: s.strip())
    severities = argToList(args.get("severity"), transform=lambda s: s.strip())
    categories = argToList(args.get("category"), transform=lambda s: s.strip().upper())
    policy_types = argToList(args.get("policy_type"), transform=lambda s: s.strip().upper())
    identity_providers = argToList(args.get("identity_provider"), transform=lambda s: s.strip().upper())
    identity_tags = argToList(args.get("identity_tag"), transform=lambda s: s.strip().upper())

    detection_start_date = arg_to_datetime(args.get("detection_start_date"), arg_name="detection_start_date")
    detection_end_date = arg_to_datetime(args.get("detection_end_date"), arg_name="detection_end_date")
    resolved_start_date = arg_to_datetime(args.get("resolved_start_date"), arg_name="resolved_start_date")
    resolved_end_date = arg_to_datetime(args.get("resolved_end_date"), arg_name="resolved_end_date")
    policy_types = policy_types or IR_VIOLATION_POLICY_TYPE

    validate_ir_violation_list_command_args(
        limit, sort_by, sort_order, detection_start_date, detection_end_date, resolved_start_date, resolved_end_date
    )

    mapped_statuses, mapped_severities, mapped_policy_types, mapped_identity_providers, mapped_identity_tags = (
        validate_ir_violation_fetch_params(statuses, severities, policy_types, identity_providers, identity_tags, is_fetch=False)
    )

    mapped_sort_by = f"SORT_{sort_by.upper()}" if sort_by else None

    resource_metadata_filter: Dict[str, Any] = {}
    if mapped_identity_providers:
        resource_metadata_filter["idpTypes"] = mapped_identity_providers
    if mapped_identity_tags:
        resource_metadata_filter["identityTags"] = mapped_identity_tags

    ir_filters: Dict[str, Any] = {
        "statuses": mapped_statuses,
        "severities": mapped_severities,
        "categories": categories,
        "policyTypes": mapped_policy_types,
        "resourceMetadataFilter": resource_metadata_filter,
        "first": limit,
        "after": next_page_token,
        "sortBy": mapped_sort_by,
        "sortOrder": sort_order.upper(),
    }

    if detection_start_date and detection_end_date:
        ir_filters["detectionDate"] = {
            "start": detection_start_date.strftime(DATE_TIME_FORMAT),
            "end": detection_end_date.strftime(DATE_TIME_FORMAT),
        }

    if resolved_start_date and resolved_end_date:
        ir_filters["updateDate"] = {
            "start": resolved_start_date.strftime(DATE_TIME_FORMAT),
            "end": resolved_end_date.strftime(DATE_TIME_FORMAT),
        }

    remove_nulls_from_dictionary(ir_filters)

    response = client._query_raw(
        raw_query=IR_VIOLATIONS_LIST_QUERY,
        operation_name="IdentityResilienceViolationsListQuery",
        variables=ir_filters,
        timeout=60,
    )

    edges = []
    page_info = {}
    ir_violation_data = response.get("data", {})
    if ir_violation_data is not None:
        policy_violations = ir_violation_data.get("policyViolations", {})
        if policy_violations:
            edges = policy_violations.get("edges", [])
            page_info = policy_violations.get("pageInfo", {})

    page_cursor = remove_empty_elements(page_info)
    page_cursor.pop("__typename", None)
    end_cursor = page_cursor.pop("endCursor", None)
    has_next_page = page_cursor.pop("hasNextPage", False)
    page_cursor.pop("startCursor", None)
    page_cursor.pop("hasPreviousPage", None)
    page_cursor.update(
        {
            "name": "rubrik-identity-resilience-violation-list",
            "next_page_token": end_cursor,
            "has_next_page": has_next_page,
        }
    )

    outputs: Dict[str, Any] = {
        f"{OUTPUT_PREFIX['PAGE_TOKEN_IR_VIOLATION']}(val.name == obj.name)": remove_empty_elements(page_cursor),
    }

    if not edges:
        return CommandResults(
            outputs=outputs,
            raw_response=response,
            readable_output=f"#### {MESSAGES['NO_RECORDS_FOUND'].format('IR violations')}",
        )

    context, hr = prepare_context_hr_identity_resilience_violation_list(edges)

    if has_next_page:
        hr += f"\n{MESSAGES['NEXT_RECORD']} {end_cursor}"

    outputs[f"{OUTPUT_PREFIX['IR_VIOLATION']}(val.policyViolationId == obj.policyViolationId)"] = context

    return CommandResults(
        outputs=remove_empty_elements(outputs),
        raw_response=response,
        readable_output=hr,
    )


def rubrik_identity_resilience_violation_get_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the details of an IR violation based on the provided violation ID.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``dict``
    :param args: Arguments for the command.

    :return: CommandResult object.
    """
    violation_id = validate_required_arg("violation_id", args.get("violation_id"))
    policy_type = args.get("policy_type")

    if not policy_type:
        policy_types = [f"POLICY_TYPE_{pt}" for pt in IR_VIOLATION_POLICY_TYPE]
    else:
        if policy_type.upper() not in IR_VIOLATION_POLICY_TYPE:
            raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(policy_type, "policy_type", IR_VIOLATION_POLICY_TYPE))
        policy_types = [f"POLICY_TYPE_{policy_type.upper()}"]

    filters = {
        "violationId": violation_id,
        "policyTypes": policy_types,
    }

    response = client._query_raw(
        raw_query=IR_VIOLATION_GET_QUERY,
        operation_name="IdentityResilienceViolationsGetQuery",
        variables=filters,
        timeout=60,
    )

    violation_data = demisto.get(response, "data.policyViolation") or {}
    if not violation_data:
        return CommandResults(readable_output=f"#### {MESSAGES['NO_RESPONSE']}", raw_response=response)

    current_time = arg_to_datetime("now").strftime(DATE_TIME_FORMAT)  # type: ignore
    inputs = {
        "principalId": violation_data.get("resourceId"),
        "timelineDate": current_time,
        "featureFilter": "IR",
    }
    violation_sensitive_data = client._query_raw(
        raw_query=IR_VIOLATION_PRINCIPAL_SUMMARY_QUERY,
        operation_name="GetPrincipalSummaryQuery",
        variables={"input": inputs},
        timeout=60,
    )

    response["principal_summary_data"] = violation_sensitive_data
    sensitive_info = demisto.get(violation_sensitive_data, "data.principalSummary.summary") or {}
    if sensitive_info:
        violation_data.update(sensitive_info)

    context, hr = prepare_context_hr_ir_violation_get(violation_data)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["IR_VIOLATION"],
        outputs_key_field="policyViolationId",
        outputs=context,
        raw_response=response,
        readable_output=hr,
    )


def rubrik_identity_resilience_violation_status_update_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Update the status of an Identity Resilience (IR) violation.

    :type client: ``Client``
    :param client: Object of Client class.

    :type args: ``Dict[str, Any]``
    :param args: Arguments provided by user.

    :rtype: ``CommandResults``
    :return: Standard command result.
    """
    violation_id = args.get("violation_id", "").strip()
    status = args.get("status", "").strip()

    validate_required_arg("violation_id", violation_id)
    validate_required_arg("status", status)

    if status.upper() not in IR_VIOLATION_STATUS:
        raise ValueError(ERROR_MESSAGES["INVALID_SELECT"].format(status, "status", IR_VIOLATION_STATUS))

    update_status = f"POLICY_VIOLATION_STATUS_{status.upper()}"
    params = {
        "newPolicyViolationStatus": update_status,
        "policyViolationIds": [violation_id],
    }

    input_params = {"input": params}

    violation_status_update_response = client._query_raw(
        raw_query=IR_VIOLATION_STATUS_UPDATE_MUTATION,
        operation_name="IdentityResilienceViolationsStatusUpdateMutation",
        variables=input_params,
        timeout=60,
    )

    ec = {
        "policyViolationId": violation_id,
        "status": update_status,
    }

    status_display = status.replace("_", " ").title()
    hr_output = f"#### Successfully updated the IR violation status to {status_display}"

    return CommandResults(
        readable_output=hr_output,
        raw_response=violation_status_update_response,
        outputs=remove_empty_elements(ec),
        outputs_prefix=OUTPUT_PREFIX["IR_VIOLATION"],
        outputs_key_field=["policyViolationId"],
    )


def rubrik_sensitive_data_object_get_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the details of a sensitive data object.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments obtained from demisto.args().

    :rtype: ``CommandResults``
    :return: Standard command result.
    """
    object_id = validate_required_arg("object_id", args.get("object_id"))
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    include_whitelisted_results = argToBoolean(args.get("include_whitelisted_results", "False"))

    variables = {
        "snappableFid": object_id,
        "snapshotFid": snapshot_id,
        "includeWhitelistedResults": include_whitelisted_results,
    }

    response = client._query_raw(
        raw_query=SENSITIVE_OBJECT_DETAIL_QUERY,
        operation_name="SensitiveObjectDetailQuery",
        variables=variables,
        timeout=60,
    )

    object_data = demisto.get(response, "data.policyObj") or {}
    if not object_data:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("sensitive data object"))

    context, hr = prepare_context_hr_sensitive_data_object_get(object_data)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SENSITIVE_DATA_OBJECT"],
        outputs_key_field="id",
        outputs=context,
        raw_response=response,
        readable_output=hr,
    )


def rubrik_sensitive_data_object_file_get_command(client: PolarisClient, args: Dict[str, Any]) -> CommandResults:
    """
    Retrieve the file information of a sensitive data object.

    :type client: ``PolarisClient``
    :param client: Rubrik Polaris client to use.

    :type args: ``Dict[str, Any]``
    :param args: Arguments obtained from demisto.args().

    :rtype: ``CommandResults``
    :return: Standard command result.
    """
    object_id = validate_required_arg("object_id", args.get("object_id"))
    snapshot_id = validate_required_arg("snapshot_id", args.get("snapshot_id"))
    file_path = validate_required_arg("file_path", args.get("file_path"))
    resolve_sids = argToBoolean(args.get("resolve_sids", "True"))

    access_variables = {
        "snappableFid": object_id,
        "snapshotFid": snapshot_id,
        "stdPath": file_path,
        "skipResolveSids": not resolve_sids,
    }
    details_variables = {
        "sensitiveFileInput": {
            "filePath": file_path,
            "objectFid": object_id,
            "snapshotFid": snapshot_id,
        },
    }

    file_access_data: dict = {}
    access_response: dict = {}
    try:
        access_response = client._query_raw(
            raw_query=FILE_ACCESS_QUERY,
            operation_name="FileAccessQuery",
            variables=access_variables,
            timeout=60,
        )
        file_access_data = demisto.get(access_response, "data.datagovSecDesc") or {}
    except Exception as e:
        demisto.debug(f"[RubrikPolaris] datagovSecDesc not available for this object type: {e}")

    details_response = client._query_raw(
        raw_query=FILE_DETAILS_QUERY,
        operation_name="FileDetailsQuery",
        variables=details_variables,
        timeout=60,
    )

    file_details = demisto.get(details_response, "data.sensitiveFileDetails") or {}
    if not file_access_data and not file_details:
        return CommandResults(readable_output=MESSAGES["NO_RECORDS_FOUND"].format("sensitive data object file information"))

    context, hr = prepare_context_hr_sensitive_data_object_file_get(file_access_data, file_details, object_id, file_path)

    return CommandResults(
        outputs_prefix=OUTPUT_PREFIX["SENSITIVE_DATA_OBJECT_FILE"],
        outputs_key_field=["objectId", "stdPath"],
        outputs=context,
        raw_response={"fileAccessData": access_response, "fileDetails": details_response},
        readable_output=hr,
    )


def run_polling_command(client, args: dict, command_name: str, search_function: Callable) -> List[CommandResults]:
    """
    For Scheduling command.

    :param client: Rubrik Polaris client to use.
    :param args: Command arguments.
    :param command_name: Name of the command.
    :param search_function: Callable object of command.
    :return: List of CommandResults.
    """
    result = search_function(client, args)
    outputs = result[0].outputs or {}

    if not outputs.get("isSuccessful"):
        return result

    if not outputs.get("externalId"):
        polling_args = {"polling": True, **args, "object_name": outputs.get("objectName")}
        scheduled_command = ScheduledCommand(
            command=command_name,
            next_run_in_seconds=DEFAULT_POLLING_NEXT_RUN_IN_SECONDS,
            args=polling_args,
            timeout_in_seconds=DEFAULT_POLLING_TIMEOUT,
        )
        command_results = CommandResults(scheduled_command=scheduled_command)

        return [result, command_results]

    return result


def trim_spaces_from_args(args):
    """
    Trim spaces from values of the args dict.

    :param args: Dict to trim spaces from
    :type args: dict
    :return:
    """
    for key, val in args.items():
        if isinstance(val, str):
            args[key] = val.strip()
        val_list = argToList(val)
        if len(val_list) > 1:
            val_list = [item.strip() for item in val_list if item.strip()]
            args[key] = ",".join(val_list)

    return args


def create_client_object(service_account_json, username, domain, password, proxies, insecure):
    """
    Create a client object using the authentication information.

    :param service_account_json: Service Account JSON to authenticate
    :param username: Username to authenticate
    :param domain: Domain of the host
    :param password: Password to authenticate
    :param proxies: Proxy values to authenticate
    :param insecure: authentication security

    :return: client object
    :raises: Exception as relevant
    """
    if service_account_json:
        try:
            client = MyClient(json_data=service_account_json, proxies=proxies, insecure=insecure, user_agent=DEFAULT_REQUEST_NAME)
        except json.JSONDecodeError:
            raise ValueError(ERROR_MESSAGES["SA_JSON_DECODE_ERR"])
        except KeyError as e:
            raise ValueError(ERROR_MESSAGES["KEY_NOT_FOUND_IN_SA_JSON"].format(str(e)))
        except ProxyException:
            raise ProxyException(ERROR_MESSAGES["PROXY_ERROR"])
    elif domain and username and password:
        try:
            client = MyClient(
                domain=domain,
                username=username,
                password=password,
                proxies=proxies,
                insecure=insecure,
                user_agent=DEFAULT_REQUEST_NAME,
            )
        except ProxyException:
            raise ProxyException(ERROR_MESSAGES["PROXY_ERROR"])
    else:
        raise ValueError(ERROR_MESSAGES["NO_CREDENTIALS_PROVIDED"])

    return client


def main() -> None:
    """Drive all the tasks to be performed."""
    params = demisto.params()

    domain = params.get("url")
    service_account_json = params.get("service_account_json")
    username = password = ""
    if params.get("email"):
        username = params.get("email").get("identifier", "").strip()
        password = params.get("email").get("password")
    insecure = params.get("insecure", False)
    proxy = params.get("proxy", False)
    demisto.info(f"Command being called is {demisto.command()}")
    try:
        proxies = {"http": "", "https": ""}
        if proxy:
            # method from common server python to add default http prefix to proxies if no protocol is specified
            ensure_proxy_has_http_prefix()
            proxies = {
                "http": os.environ.get("HTTP_PROXY") or os.environ.get("http_proxy", "") or "",
                "https": os.environ.get("HTTPS_PROXY") or os.environ.get("https_proxy", "") or "",
            }
        client = create_client_object(service_account_json, username, domain, password, proxies, insecure)

        client.auth()
        remove_nulls_from_dictionary(trim_spaces_from_args(params))
        if demisto.command() == "test-module":
            # This is the call made when pressing the integration Test button.
            return_results(test_module(client, params))
        elif demisto.command() == "fetch-incidents":
            last_run = demisto.getLastRun()
            next_run, incidents = fetch_incidents(client, last_run, params)
            demisto.info(f"Fetched {len(incidents)} new incidents")
            demisto.incidents(incidents)
            demisto.setLastRun(next_run)
        else:
            COMMAND_TO_FUNCTION = {
                "rubrik-cdm-cluster-location": cdm_cluster_location_command,
                "rubrik-cdm-cluster-connection-state": cdm_cluster_connection_state_command,
                "rubrik-radar-analysis-status": radar_analysis_status_command,
                "rubrik-sonar-sensitive-hits": sonar_sensitive_hits_command,
                "rubrik-polaris-object-search": rubrik_polaris_object_search_command,
                "rubrik-sonar-policies-list": rubrik_sonar_policies_list_command,
                "rubrik-sonar-policy-analyzer-groups-list": rubrik_sonar_policy_analyzer_groups_list_command,
                "rubrik-polaris-vm-object-metadata-get": rubrik_polaris_vm_object_metadata_get_command,
                "rubrik-polaris-vm-objects-list": rubrik_polaris_vm_objects_list_command,
                "rubrik-sonar-ondemand-scan": rubrik_sonar_ondemand_scan_command,
                "rubrik-sonar-ondemand-scan-status": rubrik_sonar_ondemand_scan_status_command,
                "rubrik-sonar-ondemand-scan-result": rubrik_sonar_ondemand_scan_result_command,
                "rubrik-polaris-vm-object-snapshot-list": rubrik_polaris_vm_object_snapshot_list_command,
                "rubrik-radar-anomaly-csv-analysis": rubrik_radar_anomaly_csv_analysis_command,
                "rubrik-sonar-csv-download": rubrik_sonar_csv_download_command,
                "rubrik-gps-snapshot-files-list": rubrik_gps_snapshot_files_list_command,
                "rubrik-gps-vm-export": rubrik_gps_vm_export_command,
                "rubrik-user-downloads-list": rubrik_user_downloads_list_command,
                "rubrik-gps-sla-domain-list": rubrik_gps_sla_domain_list,
                "rubrik-sonar-csv-result-download": rubrik_sonar_csv_result_download_command,
                "rubrik-gps-vm-snapshot-create": rubrik_gps_vm_snapshot_create,
                "rubrik-gps-snapshot-files-download": rubrik_gps_snapshot_files_download_command,
                "rubrik-gps-vm-livemount": rubrik_gps_vm_livemount,
                "rubrik-gps-vm-host-list": rubrik_gps_vm_host_list_command,
                "rubrik-gps-vm-datastore-list": rubrik_gps_vm_datastore_list_command,
                "rubrik-event-list": rubrik_event_list_command,
                "rubrik-polaris-object-list": rubrik_polaris_object_list_command,
                "rubrik-polaris-object-snapshot-list": rubrik_polaris_object_snapshot_list_command,
                "rubrik-radar-ioc-scan": rubrik_radar_ioc_scan_command,
                "rubrik-radar-ioc-scan-results": rubrik_radar_ioc_scan_results_command,
                "rubrik-radar-ioc-scan-list": rubrik_radar_ioc_scan_list_command,
                "rubrik-gps-async-result": rubrik_gps_async_result_command,
                "rubrik-gps-cluster-list": rubrik_gps_cluster_list_command,
                "rubrik-gps-vm-recover-files": rubrik_gps_vm_recover_files,
                "rubrik-sonar-user-access-list": rubrik_sonar_user_access_list_command,
                "rubrik-sonar-user-access-get": rubrik_sonar_user_access_get_command,
                "rubrik-sonar-file-context-list": rubrik_sonar_file_context_list_command,
                "rubrik-radar-suspicious-file-list": rubrik_radar_suspicious_file_list_command,
                "rubrik-radar-anomaly-status-update": rubrik_radar_anomaly_status_update_command,
                "ip": ip_command,
                "domain": domain_command,
                "rubrik-threat-monitoring-matched-object-list": rubrik_threat_monitoring_matched_object_list_command,
                "rubrik-threat-monitoring-matched-object-get": rubrik_threat_monitoring_matched_object_get_command,
                "rubrik-threat-monitoring-matched-file-list": rubrik_threat_monitoring_matched_file_list_command,
                "rubrik-threat-monitoring-matched-file-get": rubrik_threat_monitoring_matched_file_get_command,
                "rubrik-ioc-scan-list-v2": rubrik_ioc_scan_list_v2_command,
                "rubrik-ioc-scan-results-v2": rubrik_ioc_scan_results_v2_command,
                "rubrik-turbo-ioc-scan": rubrik_turbo_ioc_scan_command,
                "rubrik-advance-ioc-scan": rubrik_advance_ioc_scan_command,
                "rubrik-data-security-violation-list": rubrik_data_security_violation_list_command,
                "rubrik-data-security-violation-get": rubrik_data_security_violation_get_command,
                "rubrik-data-security-violation-status-update": rubrik_data_security_violation_status_update_command,
                "rubrik-data-security-violation-file-list": rubrik_data_security_violation_file_list_command,
                "rubrik-identity-resilience-violation-list": rubrik_identity_resilience_violation_list_command,
                "rubrik-identity-resilience-violation-get": rubrik_identity_resilience_violation_get_command,
                "rubrik-identity-resilience-violation-status-update": rubrik_identity_resilience_violation_status_update_command,
                "rubrik-sensitive-data-object-get": rubrik_sensitive_data_object_get_command,
                "rubrik-sensitive-data-object-file-get": rubrik_sensitive_data_object_file_get_command,
            }

            SCHEDULED_COMMAND_TO_FUNCTION: dict = {
                "rubrik-anomaly-csv-analysis-v2": rubrik_anomaly_csv_analysis_v2_command,
                "rubrik-data-security-violation-csv-download": rubrik_data_security_violation_csv_download_command,
                "rubrik-data-security-violation-log-download": rubrik_data_security_violation_log_download_command,
            }
            command = demisto.command()

            if COMMAND_TO_FUNCTION.get(demisto.command()):
                args = demisto.args()
                remove_nulls_from_dictionary(trim_spaces_from_args(args))

                return_results(COMMAND_TO_FUNCTION[demisto.command()](client, args))
            elif SCHEDULED_COMMAND_TO_FUNCTION.get(command):
                args = demisto.args()
                remove_nulls_from_dictionary(trim_spaces_from_args(args))

                return_results(
                    run_polling_command(
                        client=client,
                        args=args,
                        search_function=SCHEDULED_COMMAND_TO_FUNCTION[command],
                        command_name=command,
                    )
                )
            else:
                raise NotImplementedError(f"Command {demisto.command()} is not implemented")
    # Log exceptions and return errors
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}")  # noqa: E231


""" ENTRY POINT """

if __name__ in ("__main__", "__builtin__", "builtins"):
    main()