Wiz
This CLI is provided to perform batch processing and orchestration of the Wiz Cloud-Native Application Protection Platform (CNAPP). It is designed to perform bulk processing of Wiz data to create, update, and otherwise sync with RegScale to allow for compliance automation reporting. The CLI currently supports the following functionalities:
authenticate- Authenticate with Wiz and get a JSON Web Token (JWT) for future requests to Wizadd_report_evidence- downloads a Wiz report by ID and attach to Evidenceinventory- syncs the Wiz entity types inwizInventoryFilterBy'stypelist into RegScale as assets (see the default list below)issues- syncs any identified problems as issues/POAMs to RegScalevulnerabilities- process vulnerabilities from Wizattach_sbom- downloads SBOM report from Wiz into your security plancompliance_report- process Wiz compliance reports and create assessments in RegScalesync_compliance- (deprecated) syncs compliance posture from Wiz to RegScale, usecompliance_reportinsteadsync_benchmarks- imports STIG and CIS benchmark definitions from Wiz into RegScalestig_checks- syncs STIG and CIS benchmark check results from Wiz into RegScale
Wiz Service Account Setup
Before using the RegScale CLI with Wiz, you must create a service account in Wiz with the correct permissions. Follow these steps carefully.
Step 1: Create a Service Account in Wiz
- Log in to your Wiz tenant
- Click the user profile icon in the top right and navigate to Settings > Service Accounts (or use the search bar and enter "Service Accounts")
- Click Add Service Account and configure the following fields:
| Field | Value |
|---|---|
| Name | regscale_cli_sa (or your preferred name) |
| Type | Custom Integration (GraphQL API) |
| Description | RegScale CLI integration |
| Projects | Leave empty to grant access to all projects, or select up to 50 specific projects to limit access |
| Expiration Date | Optional - set an expiration date if required by your security policy |
Step 2: Configure API Scopes
Under API Scopes, enable the following permissions:
Required Global Scopes:
| Scope | Permission Key | Description |
|---|---|---|
| Administer all admin entities | admin:all | Required for managing reports and configurations |
| Read all entities | read:all | Required for reading issues, inventory, vulnerabilities, and compliance data |
Required Report Scopes (under Reports section):
All report scopes must be enabled for compliance reporting, SBOM downloads, and evidence collection:
| Scope | Permission Key |
|---|---|
| Manage report settings | admin:reports |
| Read report | read:reports |
| Update reports | update:reports |
| Create report | create:reports |
| Delete report | delete:reports |
| Create and delete reports | write:reports |
Step 3: Save Credentials
After creating the service account, Wiz will display the Client ID and Client Secret. Copy these values immediately - the Client Secret will not be shown again.
Store the credentials using one of these methods:
Option A: Environment Variables (Recommended)
export WizClientID='YOUR_WIZ_CLIENT_ID'
export WizClientSecret='YOUR_WIZ_CLIENT_SECRET'
Option B: init.yaml Configuration
Add the credentials to your init.yaml file:
wizClientId: YOUR_WIZ_CLIENT_ID
wizClientSecret: YOUR_WIZ_CLIENT_SECRET
Option C: Command-Line Arguments
Pass credentials directly to each command:
regscale wiz authenticate --client_id YOUR_CLIENT_ID --client_secret YOUR_CLIENT_SECRET
Step 4: Get the Wiz API URL
- In Wiz, click the user profile icon in the top right and navigate to Tenant Info
- Copy the API Endpoint URL and set it in your
init.yaml:
wizUrl: https://api.us27.app.wiz.io/graphql
Note for GovCloud customers: The default
wizAuthUrlishttps://auth.wiz.io/oauth/token. Government customers may need to use an alternate authentication URL. SetwizAuthUrlin yourinit.yamlif needed.
init.yaml Configuration
The following configuration variables are available for the Wiz integration in your init.yaml file:
| Variable | Type | Default | Description |
|---|---|---|---|
wizUrl | string | https://api.us27.app.wiz.io/graphql | GraphQL endpoint for your Wiz instance |
wizClientId | string | Wiz service account Client ID | |
wizClientSecret | string | Wiz service account Client Secret | |
wizAccessToken | string | Auto-populated after authentication | |
wizFullPullLimitHours | int | 8 | Maximum age of cached Wiz data, in hours, before a sync fetches it again |
wizIncrementalPulls | bool | false | Delta pulls — each sync fetches only what changed since its last successful run. Planned to become the default in a later major release (still opt-in in 7.0.0) |
wizIncrementalRebaselineHours | int | 168 | With delta pulls on, force a full pull once the last full pull is this many hours old |
wizPullWatermarks | map | Written by the CLI: each sync scope's delta watermark and last full pull. Do not edit by hand | |
wizLastInventoryPull, wizLastVulnerabilityPull, wizLastIssuePull and their *FullPull forms | string | Deprecated, no longer read. Replaced by wizPullWatermarks; delete them | |
wizRetentionReconciliation | bool | false | Close RegScale issues whose Wiz findings have aged out of Wiz's retention window |
wizDataRetentionDays | int | 7 | Wiz's detection-data retention window; only used when wizRetentionReconciliation is enabled |
wizCollapseRepresentativeAssets | bool | false | Keep only the Wiz Representative Resource where an ephemeral/representative pair is proven (shared grouping and same container image); findings on a collapsed container are re-pointed at its representative, so no CVE is lost |
wizCollapseRepresentativeAssetsDryRun | bool | false | Report what would collapse and change nothing; works on its own, and is the recommended first run on an established tenant because the collapse removes assets from the register |
wizDropUndeployedRegistryImages | bool | false | Skip vulnerability and end-of-life findings on container images Wiz found only in a registry (scan source exactly REGISTRY) with no execution controller. Turning it on closes any such findings already imported at the next full sync |
wizInventoryFilterBy | string | (default type list) | Default JSON filter for inventory pulls |
wizIssueFilterBy | string | {} | Default JSON filter for issue pulls |
wizVulnerabilitiesFilterBy | string | {} | Default JSON filter for vulnerability pulls |
useWizHardwareAssetTypes | bool | false | Whether to use wizHardwareAssetTypes to classify hardware vs software assets |
wizHardwareAssetTypes | list | VIRTUAL_MACHINE, CONTAINER, ... | Asset types from Wiz to create as hardware assets in RegScale |
wizExcludes | string | Comma-separated list of asset names to exclude from syncing | |
wizReportAge | int | 15 (14 if the key is absent) | Maximum age in days for reusing existing Wiz reports |
wizStigMapperFile | string | Written to the default init.yaml template but not read by the STIG mapper; set stigMapperFile instead (see STIG Mapper) | |
issues.wiz.critical | int | 30 | Shipped default; not read by wiz issues/wiz vulnerabilities — due dates come from first detection + the plan's compliance-settings SLA (see the issue workflow) |
issues.wiz.high | int | 90 | Shipped default; not read by the Wiz commands |
issues.wiz.medium | int | 90 | Shipped default; not read by the Wiz commands |
issues.wiz.low | int | 365 | Shipped default; not read by the Wiz commands |
issues.wiz.status | string | Open | Default status for new RegScale issues |
Quick Start
- Log into RegScale (skip if using a RegScale Service Account):
regscale login
- Authenticate to Wiz (credentials auto-detected from environment or init.yaml):
regscale wiz authenticate
- Run the desired sync command:
# Sync issues
regscale wiz issues --regscale_ssp_id=5
# Sync inventory
regscale wiz inventory --regscale_ssp_id=5
# Sync vulnerabilities
regscale wiz vulnerabilities -p "project-123" --regscale_ssp_id=5
# Sync compliance
regscale wiz compliance_report -p "project-123" --regscale_id=5
Issue Processing Workflow
The issue sync pulls Wiz issues in all four statuses — OPEN, IN_PROGRESS, RESOLVED,
REJECTED (PS-590: resolved and rejected issues land too, so a rejection closes its RegScale
record instead of orphaning it) — and writes them to RegScale:
- Authenticates to Wiz (auto-authenticates if credentials are configured)
- Retrieves all existing RegScale issues for the given security plan
- Fetches the project's issues with a GraphQL query (
issuesV2), grouped by their
source rule — no report is created in Wiz for this command - Writes one RegScale issue per source-rule group (the control for a control issue),
not one per Wiz issue: the group's vulnerability and issue stay the same records for as
long as the rule keeps failing (REG-30187) - Closes any RegScale issues where the corresponding Wiz issues no longer exist (remediated)
Due dates: a Wiz issue's RegScale due date is its finding's first detection date plus
the security plan's compliance-settings SLA for its severity (KEV findings aside, which
follow the KEV clock). The issues.wiz day counts in init.yaml are not read by
wiz issues or wiz vulnerabilities.
# Basic usage
regscale wiz issues --regscale_ssp_id=5
# With project filter and severity filter
regscale wiz issues \
-p "project-123" \
--regscale_ssp_id=5 \
--filter_by_override='{"severity": ["HIGH", "CRITICAL"]}'
Inventory Processing Workflow
The inventory sync retrieves cloud entities from Wiz and creates or updates assets in RegScale:
- Authenticates to Wiz
- Retrieves all existing assets in RegScale for the given security plan
- Pulls only the entity types in the filter's
typelist (wizInventoryFilterBy, or
--filter_by_overridefor one run). A filter with notypekey pulls every type. A project can hold thousands of entities of other
types (DNS records, subnets, IAM artifacts, …); those never become assets. The shipped
default list is:
VIRTUAL_MACHINE,VIRTUAL_DESKTOP,KUBERNETES_CLUSTER,VIRTUAL_MACHINE_IMAGE,
CONTAINER_IMAGE,CONTAINER,POD,SERVERLESS,SERVERLESS_PACKAGE,APPLICATION,
WEB_SERVICE,KUBERNETES_SERVICE,CONTAINER_REGISTRY,CONTAINER_SERVICE,DATABASE,
DB_SERVER,BUCKET,STORAGE_ACCOUNT,VOLUME,FILE_SYSTEM_SERVICE,BACKUP_SERVICE,
FIREWALL,LOAD_BALANCER,MESSAGING_SERVICE,SECRET_CONTAINER - For each Wiz entity: updates the existing RegScale asset if found, otherwise creates a new one
# Basic usage
regscale wiz inventory --regscale_ssp_id=5
# With project and type filters
regscale wiz inventory \
--wiz_project_id="project-123" \
--regscale_ssp_id=5 \
--filter_by_override='{"type": ["VIRTUAL_MACHINE", "DATABASE"]}'
Data-Retention Reconciliation
Wiz keeps vulnerability and issue detection data for a limited window — seven days by
default. Once a finding ages out of that window it stops appearing in every subsequent
pull, and because Wiz never reports it as resolved, nothing in a normal sync tells
RegScale the finding is gone. The matching RegScale issue stays open indefinitely.
Reconciliation closes those issues. It is off by default because closing issues is
destructive:
wizRetentionReconciliation: true
wizDataRetentionDays: 7 # must match your Wiz tenant's retention setting
After each sync writes its findings, reconciliation compares the open Wiz-sourced issues
on the plan against the findings the run reported. An issue is closed only when all of
the following hold:
- its finding was not reported by this run
- it was last seen more than
wizDataRetentionDaysdays ago - it is not protected from auto-closure (
preventAutoClose, aPREVENT_AUTO_CLOSE
property, or a manual-reopen note)
Anything that cannot be proven gone is left open. Reconciliation is skipped entirely —
with a log line explaining which condition tripped — when the run processed a paginated
subset, when the run was incremental or otherwise incomplete, or when it reported zero
findings (far more often a scoping or credential problem than an empty tenant).
On RegScale platform 6.35.1.0 and newer, when the run's findings are posted in a single
final vulnerability batch flush of one request, the comparison and the closures happen on the server: the sync sends
wizDataRetentionDays with that request (the Client API's mopUpMaxAgeDays option) and
RegScale closes the aged-out issues, writes the audit note and refreshes the status of the
controls they were linked to; the sync logs "Closed N outdated issues." from the server's
count once the server has confirmed it ran the pass. On an older platform, or when the run's
findings are posted in more than one flush or request (the server's pass only knows the
findings of the request that carries the option), the CLI performs the same pass itself, as
6.x did, and logs once why. A run whose findings exactly fill a finding chunk
(findingChunkSize, 5000 by default) is also closed client-side, because the flush that
carries its findings is not marked as the run's final one. preventAutoClose turns the retention close
off on either path; it does not affect the server's close-findings-not-in-scan mop-up.
Setting wizDataRetentionDays shorter than the tenant's real Wiz retention window will
close findings that Wiz is still reporting. If you are unsure of the window, leave the
default and confirm with your Wiz administrator before shortening it.
Filter Parameters
All commands that support --filter_by_override accept a JSON string with one or more of the following parameters:
| Parameter | Type | Description |
|---|---|---|
project | array | Wiz project IDs, as a list (auto-injected from --wiz_project_id for issues/inventory) |
projectId | array | Multiple project IDs (auto-injected from --wiz_project_id for vulnerabilities) |
type | array | Resource type filter (e.g., ["VIRTUAL_MACHINE", "DATABASE"]) |
status | array | Issue status filter (["OPEN", "IN_PROGRESS", "RESOLVED", "REJECTED"]) |
severity | array | Severity filter (["CRITICAL", "HIGH", "MEDIUM", "LOW"]) |
search | string | Free text search on resource name |
subscriptionExternalId | array | External subscription IDs (AWS Account, Azure Subscription, etc.) |
providerUniqueId | array | Cloud provider unique identifiers |
updatedAt | object | Date filter with before/after in ISO 8601 format |
deletedAt | object | Date filter for deleted resources |
Note: The
--wiz_project_idparameter is automatically injected into your filter. You do not need to include the project ID in your--filter_by_overrideJSON.
init.yaml Example
domain: https://mycompany.regscale.com
maxThreads: 1000
wizClientId: your-wiz-client-id
wizClientSecret: your-wiz-client-secret
wizUrl: https://api.us27.app.wiz.io/graphql
wizAuthUrl: https://auth.wiz.io/oauth/token
wizFullPullLimitHours: 8
wizReportAge: 14
wizInventoryFilterBy: '{}'
wizIssueFilterBy: '{}'
wizVulnerabilitiesFilterBy: '{}'
useWizHardwareAssetTypes: true
wizHardwareAssetTypes:
- VIRTUAL_MACHINE
- VIRTUAL_MACHINE_IMAGE
- CONTAINER
- CONTAINER_IMAGE
- DB_SERVER
- SERVER_APPLICATION
- CLIENT_APPLICATION
- VIRTUAL_APPLIANCE
wizExcludes: Azure AD Builtin Application Service Principal, Azure Active Directory (AAD) User
wizStigMapperFile: /path/to/stig_mapper_rules.json
issues:
wiz:
critical: 30
high: 90
low: 365
medium: 90
status: Open
Note: The
wizAccessTokenandwizScopefields are auto-populated after authenticating to Wiz via the CLI.
Building a Bash Script to Execute the CLI
You can chain together RegScale CLI commands using scripts. These scripts could be in Bash, Python, PowerShell, etc. Below is an example Bash file for executing the Wiz CLI:
#!/bin/sh
# Wiz auto-authenticates on every execution of issues or inventory functions
regscale wiz issues --regscale_ssp_id=5
regscale wiz inventory --regscale_ssp_id=5
regscale wiz vulnerabilities -p "project-123" --regscale_ssp_id=5
regscale wiz compliance_report -p "project-123" --regscale_id=5
Compliance Report
Process Wiz compliance reports and create assessments in RegScale. This is the recommended command for compliance sync (replaces the deprecated sync_compliance).
regscale wiz compliance_report [OPTIONS]
Options:
-p, --wiz_project_id TEXT Wiz project ID [required]
--regscale_id INTEGER RegScale record ID [required]
--regscale_module TEXT RegScale module (default: securityplans)
-i, --client_id TEXT Wiz Client ID
-s, --client_secret TEXT Wiz Client Secret
-f, --report_file_path TEXT Path to existing CSV compliance report
--create-issues/--no-create-issues Create issues for failed assessments (default: enabled)
--update-control-status/--no-update-control-status Update control status (default: enabled)
--create-poams/--no-create-poams Mark issues as POAMs (default: disabled)
--reuse-existing-reports/--no-reuse-existing-reports Reuse existing Wiz reports (default: enabled)
--force-fresh-report/--no-force-fresh-report Force new report creation (default: disabled)
--create-evidence/--no-create-evidence Attach the report as evidence mapped to controls (default: enabled)
The command can either create a new compliance report from Wiz or process an existing CSV file. By default, it reuses existing compliance reports in Wiz to prevent accumulation of duplicate reports.
Prerequisite: the security plan must have the framework's catalogue controls attached —
assessments are written per control implementation, so a plan without the report's controls
assesses nothing.
What it writes:
- One control assessment per control in the report (37 controls in a NIST report assess 37
implementations). - Assets for the report's resources whose entity type is inventory-eligible — the same
wizInventoryFilterBytypelist the inventory pull uses, so compliance never creates an
entity kindwiz inventorywould not. - Issues for failed assessments (
--create-issues, default on;--create-poamsmarks them
POAMs). - With
--create-evidence(default on), the report file is attached as evidence mapped to the
assessed controls. - A report the command creates in Wiz is left in place with a weekly schedule, and later
runs reuse it (--reuse-existing-reports, default on;--force-fresh-reportcreates a new one).
# Basic compliance sync
regscale wiz compliance_report -p "project-123" --regscale_id=5
# With POAM creation and fresh report
regscale wiz compliance_report \
-p "project-123" \
--regscale_id=5 \
--create-poams \
--force-fresh-report
# Process existing CSV report file
regscale wiz compliance_report \
-p "project-123" \
--regscale_id=5 \
--report_file_path=/path/to/compliance_report.csv
Vulnerabilities Processing Workflow
wiz vulnerabilities pulls eight finding streams from Wiz, each with its own GraphQL query,
and writes one RegScale vulnerability per finding (the platform opens issues per the
vulnerabilityCreation setting):
| Stream | Family name (for the filter options) | Wiz source |
|---|---|---|
VULNERABILITY | vulnerability | Vulnerability findings (CVEs on workloads) |
CONFIGURATION | configuration_finding | Cloud configuration findings |
HOST_FINDING | host_finding | Host configuration findings |
DATA_FINDING | data_finding | Data findings |
SECRET_FINDING | secret_finding | Secret findings |
NETWORK_EXPOSURE_FINDING | network_exposure_finding | Network exposure findings |
END_OF_LIFE_FINDING | end_of_life_finding | End-of-life technology findings |
EXCESSIVE_ACCESS_FINDING | excessive_access_finding | Excessive access findings |
External attack surface exposures arrive through the NETWORK_EXPOSURE_FINDING stream; the
separate EXTERNAL_ATTACH_SURFACE stream is no longer pulled, because it returned the same
exposures a second time. Each stream lands once per finding; due dates follow the plan's compliance-settings SLA as
described under the issue workflow.
Filtering by family (REG-32996): --finding-families imports only the named families
(use the family names from the table above, not the stream names);
--exclude-finding-families imports everything else (e.g. --exclude-finding-families network_exposure for tenants that do not consider network exposures vulnerabilities). The
_finding suffix may be omitted and names are case-insensitive. A skipped family reports
nothing, so its findings already in RegScale may be closed as no longer reported when
mop-up runs.
SBOM Management
Download and attach SBOMs from Wiz reports:
regscale wiz attach_sbom \
--regscale_ssp_id=5 \
--report_id YOUR_WIZ_REPORT_ID \
--standard CycloneDX
Options:
--client_id,-ci- Wiz Client ID (falls back to environment variable)--client_secret,-cs- Wiz Client Secret (falls back to environment variable)--regscale_ssp_id- RegScale SSP ID [required]--report_id,-r- Wiz Report ID [required]--standard,-s- SBOM standard:CycloneDXorSPDX(default:CycloneDX)
Evidence Management
Download a Wiz report and attach it to the RegScale Evidence locker:
regscale wiz add_report_evidence \
--evidence_id 123 \
--report_id YOUR_WIZ_REPORT_ID \
--report_file_name evidence_report \
--report_file_extension csv
Filtering Guide
Filtering Methods
1. Command-Line Filter Override
The most direct way to apply filters is using the --filter_by_override parameter:
regscale wiz issues --filter_by_override='{"status": ["OPEN"], "severity": ["HIGH", "CRITICAL"]}'
2. Configuration Variables
Set default filters using Wiz-specific configuration variables in your init.yaml file.
3. Environment Variables
Use environment variables to set filter configurations.
4. Programmatic Filtering
Apply filters directly in code when using the integration classes.
Project ID Auto-Injection
Important: When you use the -p or --wiz_project_id option, the project ID is automatically injected into your filter. You do NOT need to include it in your --filter_by_override or init.yaml configuration.
| Command | Auto-Injected Key | Format |
|---|---|---|
inventory | "project" | String |
issues | "project" | String |
vulnerabilities | "projectId" | Array |
# You provide a simple filter (no project ID needed):
regscale wiz vulnerabilities -p "abc123" -f '{"severity": ["CRITICAL", "HIGH"]}'
# CLI automatically creates this filter for the Wiz API:
# {"severity": ["CRITICAL", "HIGH"], "projectId": ["abc123"]}
Multi-Tenant Configuration
This enables easy multi-tenant deployments. Configure a single filter in init.yaml:
# init.yaml - DO NOT include projectId, it's added automatically per run
wizVulnerabilitiesFilterBy: '{"severity": ["CRITICAL", "HIGH"]}'
Then run for different tenants/projects:
regscale wiz vulnerabilities -p "tenant-a-project" --regscale_ssp_id 123
regscale wiz vulnerabilities -p "tenant-b-project" --regscale_ssp_id 456
Issue Filtering
By default, the Wiz issue integration applies this filter:
{
"project": ["project-id"],
"status": ["OPEN", "IN_PROGRESS", "RESOLVED", "REJECTED"]
}
Issues in all four statuses are synchronized. If your filter (wizIssueFilterBy or
--filter_by_override) has no status list, the integration adds all four statuses. If your
filter has a status list, the integration uses your list.
If your list does not include RESOLVED and REJECTED, Wiz does not return an issue after it
is resolved or rejected. Mop-up then closes the RegScale issue as remediated, and the rejection
reason does not reach RegScale.
Configuration Variable: wizIssueFilterBy
wizIssueFilterBy# init.yaml - project ID is auto-injected from --wiz_project_id, no need to include it
wizIssueFilterBy: '{"status": ["OPEN"], "severity": ["HIGH", "CRITICAL"]}'
Issue Filter Examples
# Filter by severity
regscale wiz issues \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"severity": ["HIGH", "CRITICAL"]}'
# Filter by status and time
regscale wiz issues \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"status": ["OPEN"], "updatedAt": {"after": "2023-06-14T14:07:06Z"}}'
# Complex filtering (project auto-injected from --wiz_project_id)
regscale wiz issues \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"status": ["OPEN", "IN_PROGRESS"], "severity": ["HIGH", "CRITICAL"], "search": "database"}'
Asset Filtering
The asset integration pulls only the entity types in the filter's type list. The default
wizInventoryFilterBy filter is the shipped list from the
Inventory Processing Workflow:
{
"type": [
"VIRTUAL_MACHINE", "VIRTUAL_DESKTOP", "KUBERNETES_CLUSTER", "VIRTUAL_MACHINE_IMAGE",
"CONTAINER_IMAGE", "CONTAINER", "POD", "SERVERLESS", "SERVERLESS_PACKAGE", "APPLICATION",
"WEB_SERVICE", "KUBERNETES_SERVICE", "CONTAINER_REGISTRY", "CONTAINER_SERVICE", "DATABASE",
"DB_SERVER", "BUCKET", "STORAGE_ACCOUNT", "VOLUME", "FILE_SYSTEM_SERVICE", "BACKUP_SERVICE",
"FIREWALL", "LOAD_BALANCER", "MESSAGING_SERVICE", "SECRET_CONTAINER"
]
}
A filter that you set replaces this list. If your filter has a type list, entities of other
types do not become assets. If your filter has no type key, no type filter is sent and Wiz
returns entities of every type.
Configuration Variable: wizInventoryFilterBy
wizInventoryFilterBy# init.yaml - project ID is auto-injected from --wiz_project_id, no need to include it
wizInventoryFilterBy: '{"type": ["VIRTUAL_MACHINE", "DATABASE"]}'
Asset Filter Examples
# Filter by resource type
regscale wiz inventory \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"type": ["VIRTUAL_MACHINE", "DATABASE"]}'
# Filter by subscription (project auto-injected from --wiz_project_id)
regscale wiz inventory \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"subscriptionExternalId": ["sub-456"]}'
# Time-based filtering for incremental updates
regscale wiz inventory \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"updatedAt": {"after": "2023-06-14T14:07:06Z"}}'
Vulnerability Filtering
The vulnerabilities integration requires a project ID to be specified. The filter uses projectId as an array.
Configuration Variable: wizVulnerabilitiesFilterBy
wizVulnerabilitiesFilterBy# init.yaml - projectId is auto-injected from --wiz_project_id, no need to include it
wizVulnerabilitiesFilterBy: '{"severity": ["CRITICAL", "HIGH"]}'
Vulnerability Filter Examples
# Filter by severity
regscale wiz vulnerabilities \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"severity": ["CRITICAL", "HIGH"]}'
# Filter by CVE detection date
regscale wiz vulnerabilities \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"detectedAt": {"after": "2023-06-14T14:07:06Z"}}'
# Filter by exploit availability
regscale wiz vulnerabilities \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"hasExploit": true}'
Detailed Filter Parameters
Project and Subscription Filters
| Parameter | Type | Description | Example |
|---|---|---|---|
project | array | Project IDs, as a list | ["project-123"] |
projectId | array | Multiple project IDs | ["project-123", "project-456"] |
subscriptionExternalId | array | Subscription external IDs | ["sub-123", "sub-456"] |
providerUniqueId | array | Provider unique identifiers | ["provider-123"] |
Status Filters
| Parameter | Type | Description | Valid Values |
|---|---|---|---|
status | array | Issue status filter | ["OPEN", "IN_PROGRESS", "RESOLVED", "REJECTED"] |
Severity Filters
| Parameter | Type | Description | Valid Values |
|---|---|---|---|
severity | array | Severity level filter | ["CRITICAL", "HIGH", "MEDIUM", "LOW"] |
Resource Type Filters
| Parameter | Type | Description | Example |
|---|---|---|---|
type | array | Resource type filter | ["VIRTUAL_MACHINE", "DATABASE", "CONTAINER"] |
Time-based Filters
| Parameter | Type | Description | Example |
|---|---|---|---|
updatedAt | object | Filter by update time | {"after": "2023-06-14T14:07:06Z"} |
createdAt | object | Filter by creation time | {"before": "2023-12-31T23:59:59Z"} |
Search Filters
| Parameter | Type | Description | Example |
|---|---|---|---|
search | string | Text search filter | "database" |
Filter Usage Examples
High-Priority Security Issues Only
regscale wiz issues \
--wiz_project_id "prod-project" \
--regscale_ssp_id 123 \
--filter_by_override='{"status": ["OPEN"], "severity": ["HIGH", "CRITICAL"]}'
Recent Changes in Specific Resource Types
regscale wiz inventory \
--wiz_project_id "prod-project" \
--regscale_ssp_id 123 \
--filter_by_override='{"type": ["DATABASE", "STORAGE_ACCOUNT"], "updatedAt": {"after": "2023-11-01T00:00:00Z"}}'
Multi-Project Vulnerability Scan
To scan multiple projects, explicitly specify projectId in the filter override (overrides the auto-injected single project):
regscale wiz vulnerabilities \
--wiz_project_id "prod-project" \
--regscale_ssp_id 123 \
--filter_by_override='{"projectId": ["proj-1", "proj-2"], "severity": ["CRITICAL"]}'
Comprehensive Security Review
The project key is auto-injected from --wiz_project_id, so you only need to specify other filters:
{
"status": ["OPEN", "IN_PROGRESS"],
"severity": ["HIGH", "CRITICAL"],
"type": ["DATABASE", "API_GATEWAY", "STORAGE_ACCOUNT"],
"updatedAt": {"after": "2023-10-01T00:00:00Z"},
"search": "encryption"
}
Setting Default Filters
In init.yaml
# Issue filtering defaults
wizIssueFilterBy: |
{
"status": ["OPEN", "IN_PROGRESS"],
"severity": ["HIGH", "CRITICAL"]
}
# Asset filtering defaults
wizInventoryFilterBy: |
{
"type": ["VIRTUAL_MACHINE", "DATABASE", "STORAGE_ACCOUNT"],
"updatedAt": {"after": "2023-01-01T00:00:00Z"}
}
Environment Variables
export WIZ_ISSUE_FILTER_BY='{"status": ["OPEN"], "severity": ["CRITICAL"]}'
export WIZ_INVENTORY_FILTER_BY='{"type": ["DATABASE", "VIRTUAL_MACHINE"]}'
Time-based Incremental Updates
Incremental (delta) pulls are off by default and planned to become the default in a later major release; they stayed opt-in on the 7.0.0 line. Turn
them on with wizIncrementalPulls:
wizIncrementalPulls: true
wizIncrementalRebaselineHours: 168 # Force a full pull once the last *full* pull is a week old
Each sync then asks Wiz only for what changed since its last successful run — inventory
filters on updatedAt, vulnerabilities on updatedAt, and issues on statusChangedAt.
The CLI keeps a separate watermark for every sync scope: the topic (inventory,
vulnerabilities or issues), the RegScale SSP, the Wiz project and the filter. Syncing project A
into one SSP and project B into another therefore never shares a watermark, and each scope's
first incremental run is a full pull. The watermarks are written to wizPullWatermarks in
init.yaml; leave that map to the CLI. Deleting it forces the next run of every sync to be a
full pull. A --dry-run never moves a watermark, because it writes nothing to RegScale.
The global keys used before (wizLastInventoryPull, wizLastVulnerabilityPull,
wizLastIssuePull and their *FullPull forms) are deprecated and no longer read. The CLI
warns while one still holds a timestamp; delete them.
Three behaviors follow from a delta result set being a deliberate subset of the project:
- Nothing is closed for being absent. Close-findings-not-in-scan (mop-up) is disabled
automatically for any run that pulls incrementally, because a delta says nothing about the
findings it did not return.wizRetentionReconciliationis suppressed along with it: it closes
issues by their absence from the sync, which a delta cannot distinguish from "unchanged".
Findings that Wiz reports as resolved still close on a delta run, because the status change
is itself a change the delta returns. Closing by absence is not switched off, only deferred
to the next full pull — whichwizIncrementalRebaselineHoursguarantees happens periodically. - Assets missing from a delta are not marked Inactive. A full inventory sync marks assets
that are no longer in WizInactive. A delta inventory sync turns that off, because it only
returns the assets that changed; the next full pull marks the assets that really left Wiz. - Cached pages are never reused. A delta run always calls Wiz, so it cannot skip records
that arrived between the cached run and now.
A watermark only moves forward after a run that read its whole window and wrote every
record to RegScale: if a query fails, a result type is skipped, or any record fails to save,
the watermark stays put and the next run re-reads the same window. With incremental pulls on,
every run reads Wiz rather than a cached copy, full pulls included, because the watermark it
records says RegScale is current as of that run.
wizIncrementalRebaselineHours is the interval at which the CLI re-baselines with a full
pull, so a record a delta missed cannot stay missing indefinitely, and findings and assets
that left Wiz without a status change get closed. The default of 168 hours (a week) keeps a
daily sync incremental between re-baselines. Wiz recommends incremental pulls for daily
updates and full pulls for the initial baseline and periodic full assessments (WIN API docs,
"Reports"); lower it if absent findings must close sooner. It is
separate from wizFullPullLimitHours, which only limits how old cached Wiz data may be. It is
measured against each scope's last full pull, written only when a full pull of that scope
completes — not against the delta watermark above. The delta watermark cannot serve that purpose: it carries the newest updatedAt /
statusChangedAt the run actually saw, so on a quiet project it reads hours or days old while
the sync itself ran minutes ago. If no full-pull timestamp is recorded yet, the next run is a
full pull to establish one.
Filtering Best Practices
- Start with broad filters and gradually narrow them down
- Use time-based filtering for large environments to reduce data volume
- Combine multiple filter types for precise data selection
- Test filters before production with a small dataset first
- Use specific project IDs when possible for better performance
- Document your filters for different environments (production, development, security audit)
Scanner Integration Base Filtering
The Wiz integration extends the base ScannerIntegration class, which provides additional filtering capabilities:
| Variable | Description | Default | Options |
|---|---|---|---|
issueCreation | How issues are created | "Consolidated" | "PerAsset", "Consolidated" |
vulnerabilityCreation | Vulnerability handling | "IssueCreation" | "IssueCreation", "PoamCreation" ("NoIssue" is deprecated and treated as "IssueCreation") |
These are set in init.yaml (there is no command-line override for them).
ingestClosedIssues is deprecated and no integration reads it. The Wiz issue pull already
fetches resolved and rejected issues. Delete the key from init.yaml. To pull only some
statuses, set a status list in the filter:
regscale wiz issues \
--wiz_project_id "project-123" \
--regscale_ssp_id 456 \
--filter_by_override='{"status": ["OPEN", "RESOLVED"]}'
Filter Troubleshooting
- No results returned: Check if your filter criteria are too restrictive
- Too many results: Add more specific filters like severity or time ranges
- Authentication errors: Ensure your Wiz credentials are correctly configured
- Invalid filter format: Verify JSON syntax in filter strings
Enable debug logging to see applied filters:
# --debug is a global option and goes before the command group
regscale --debug wiz issues \
--regscale_ssp_id 456 \
--filter_by_override='{"status": ["OPEN"]}'
STIG Mapper
The STIG Mapper module automatically maps STIGs to assets based on configurable rules. The scanner
framework loads the rules file named by the root-level stigMapperFile variable in your init.yaml
(default: stig_mapper_rules.json in the current working directory); if that file does not exist,
STIG mapping is skipped:
stigMapperFile: /path/to/stig_mapper_rules.json
Note:
wizStigMapperFileappears in the defaultinit.yamltemplate but is not read by the
mapper. The rules can also be applied on demand with
regscale stig_mapper run --json-file <rules.json> --regscale_id <id> --regscale_module securityplans.
STIG Mapper Rules Format
The rules file uses JSON with comparator-based matching against asset properties:
{
"rules": [
{
"stig": "Windows 2012 Configuration STIG",
"comparators": [
{"comparator": "contains", "value": "Windows 2012", "property": "name"},
{"comparator": "notin", "value": "Windows 2012 Account Access Group", "property": "name"}
]
},
{
"stig": "Network Security STIG",
"comparators": [
{"comparator": "startswith", "value": "Kubernetes", "property": "name"},
{"comparator": "endswith", "value": "Security", "property": "name"}
]
}
]
}
Available Comparators
| Comparator | Description |
|---|---|
equals | Exact string match |
contains | String contains value |
startswith | String starts with value |
endswith | String ends with value |
notin | String does not contain value |
in | String is present in value |
nin | String is not present in value |
gt, lt, gte, lte, ne | Comparison operators |
Rules can match against any asset property including name, operatingSystem, manufacturer, description, and others.
Updated 4 days ago
