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
| ID | RubrikPolaris |
|---|---|
| Provider | Rubrik |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.0.0 |
| Docker Image | demisto/rubrik-polaris-sdk-py3:1.0.0.10133006 |
| Supported Modules | Agentix 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 | |
| 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 "<today's date> 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: "<Cluster-ID>:::VirtualMachine:::<Snappable-ID>:::<CDM-ID>". | 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:::<Snappable-ID>". | 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 : "/<directory name>/<sub directory name or file name>"<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 "<Snapshot VM Name> <MM/DD of snapshot creation> <hh/mm of snapshot creation> <Num>". | 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: "/<directory name>/<sub directory name or file name>"<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 "<Snapshot VM Name> <MM/DD of snapshot creation> <hh/mm of snapshot creation> <Num>". | 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/>"<ioc_type1>": ["<ioc_value1>", "<ioc_value2>"],<br/>"<ioc_type2>": "<ioc_value2>"<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: 2000uk_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: 1712Note: 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 FoundhuntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Foundhttps://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 FoundsnapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-18T05:51:31Z
isMalicious: No Matcheshttps://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 FoundhuntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Foundhttps://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 FoundsnapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-18T05:51:31Z
isMalicious: No Matcheshttps://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: v0false id: dummy-configured-sla-id
name: Dummy_Configured_SLA
version: v0fid: 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_Type20
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: ACTIVE00000000-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: dummyhashvalue0000000000000000000002totalObjectsScanned: 100
totalAffectedObjects: 5
totalUnaffectedObjects: 95
totalObjectsUnscannable: 0
unaffectedObjectsFromDb: 95
cleanRecoverableObjectLimit: 999totalMatchedSnapshots: 10
totalScannedSnapshots: 200
totalUniqueFileMatches: 32025-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: 393Note: 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,
CISReview 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 JSONurl— Rubrik Account (e.g. ${rubrikAccount}.my.rubrik.com)email— EmailisFetch— Fetch incidentsincidentType— Incident typersc_fetch_types— RSC Fetch Typesevent_types— Event types to fetch as incidentsevent_severities— Event severities to fetch as incidentsthreat_monitoring_match_types— Threat Monitoring Match Typesthreat_monitoring_object_types— Threat Monitoring Object Typesfirst_fetch— First fetch timeincidentFetchInterval— Incidents Fetch Intervalmax_fetch— Fetch Limit (Maximum of 1000)radar_critical_severity_mapping— Event Critical Severity Level Mappingradar_warning_severity_mapping— Event Warning Severity Level Mappingthreat_monitoring_severity_mapping— Threat Monitoring Object Severity Level Mappingdspm_violation_status— DSPM Violation Statusesdspm_violation_sensitivity— DSPM Violation Sensitivity Levelsdspm_violation_severity— DSPM Violation Severity Levelsdspm_violation_category— DSPM Violation Categoriesdspm_violation_object_type— DSPM Violation Object Typesir_violation_policy_type— IR Violation Policy Typesir_violation_status— IR Violation Statusesir_violation_severity— IR Violation Severity Levelsir_violation_category— IR Violation Categoriesir_violation_identity_provider— IR Violation Identity Providersir_violation_identity_tag— IR Violation Identity Tagssensitive_data_object_sensitivity— Sensitive Data Object Sensitivity Levelssensitive_data_object_type— Sensitive Data Object Typesintegration_reliability— Source Reliabilityproxy— Use system proxy settingsinsecure— Trust any certificate (not secure)
Commands (61)
-
domainRetrieve the sensitive information available for the given domain(s).
-
ipRetrieve the sensitive information available for the given IP address(es).
-
rubrik-advance-ioc-scanStart a new advance threat hunt.
-
rubrik-anomaly-csv-analysis-v2Request for the analysis and directly download the anomaly CSV analyzed file.
-
rubrik-cdm-cluster-connection-stateFind the CDM Connection State of a CDM Cluster.
-
rubrik-cdm-cluster-locationFind the CDM GeoLocation of a CDM Cluster.
-
rubrik-data-security-violation-csv-downloadDownload all files at risk as CSV file for the specified data security violation.
-
rubrik-data-security-violation-file-listRetrieve the file information of data security violation based on the provided violation ID.
-
rubrik-data-security-violation-getRetrieve the details of DSPM violation based on the provided violation ID.
-
rubrik-data-security-violation-listRetrieve the list of DSPM violations.
-
rubrik-data-security-violation-log-downloadDownload remediation logs as CSV file for the specified data security violation.
-
rubrik-data-security-violation-status-updateUpdates the status of the DSPM violation.
-
rubrik-event-listRetrieve the list of events.
-
rubrik-gps-async-resultRetrieve 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-listRetrieve the list of the available rubrik clusters.
-
rubrik-gps-sla-domain-listEnumerates the available SLA Domains to apply to the on-demand snapshot as a retention policy.
-
rubrik-gps-snapshot-files-downloadRequest 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-listRetrieve 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-listRetrieve the list of the available datastores on a Vsphere Host.
-
rubrik-gps-vm-exportRequest 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-listRetrieve the list of available Vsphere Hosts.
-
rubrik-gps-vm-livemountPerforms 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-filesRecovers 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-createTriggers 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-getRetrieves the details of the Identity Resilience (IR) violation based on the provided violation ID.
-
rubrik-identity-resilience-violation-listRetrieves the list of Identity Resilience (IR) violations.
-
rubrik-identity-resilience-violation-status-updateUpdates the status of the Identity Resilience (IR) violation.
-
rubrik-ioc-scan-list-v2List details of the Turbo and Advance Threat Hunt.
-
rubrik-ioc-scan-results-v2Retrieve details of the Turbo and Advance Threat Hunt.
-
rubrik-polaris-object-listRetrieve the list of Rubrik objects, based on the provided filters.
-
rubrik-polaris-object-searchSearch for Rubrik discovered objects of any type, return zero or more matches.
-
rubrik-polaris-object-snapshot-listRetrieve Rubrik snapshot(s) of an object, based on the provided object ID.
-
rubrik-polaris-vm-object-metadata-getRetrieve details for a Vsphere object based on the provided object ID.
-
rubrik-polaris-vm-object-snapshot-listSearch 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-listRetrieve a list of all the objects of the Vsphere Vm known to the Rubrik.
-
rubrik-radar-analysis-statusDeprecatedCheck the Radar Event for updates.
-
rubrik-radar-anomaly-csv-analysisRequest for the analysis and retrieve the download link or directly download file for the Radar CSV analyzed file.
-
rubrik-radar-anomaly-status-updateUpdates 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-scanTriggers 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-listLists 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-resultsRetrieves 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-listRetrieve the suspicious list of files for a snapshot ID with detected file anomalies.
-
rubrik-sensitive-data-object-file-getRetrieve the file information for the provided file path in the object.
-
rubrik-sensitive-data-object-getRetrieve the details of the object based on the provided object ID and snapshot ID.
-
rubrik-sonar-csv-downloadRequest 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-downloadRetrieve the download link for the requested Sonar CSV Snapshot file.
-
rubrik-sonar-file-context-listRetrieve the context of the file, folder, or file share for the provided object and the file details.
-
rubrik-sonar-ondemand-scanTrigger 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-resultRetrieve the download link for the requested scanned file.
-
rubrik-sonar-ondemand-scan-statusRetrieve the status of a scanned system. Note: To download the completed request use the "rubrik-sonar-ondemand-scan-result" command.
-
rubrik-sonar-policies-listRetrieve the list of all the available Sonar policies.
-
rubrik-sonar-policy-analyzer-groups-listList the analyzer group policies.
-
rubrik-sonar-sensitive-hitsFind data classification hits on an object.
-
rubrik-sonar-user-access-getRetrieve the user access information based on the provided user ID.
-
rubrik-sonar-user-access-listRetrieve the user access information.
-
rubrik-threat-monitoring-matched-file-getGet the matched file for the Threat Monitoring object.
-
rubrik-threat-monitoring-matched-file-listList the matched files for the Threat Monitoring object.
-
rubrik-threat-monitoring-matched-object-getGet the matched object for Threat Monitoring.
-
rubrik-threat-monitoring-matched-object-listList the matched objects for Threat Monitoring.
-
rubrik-turbo-ioc-scanStart a new turbo threat hunt.
-
rubrik-user-downloads-listRetrieve 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()