Wiz Policy Integration
Related Guides and Examples:
Overview: Firefly Workflows and Guardrails: High-level concepts and options.
Creating Guardrail Rules in Firefly: How to define and enforce Firefly's own policies and best practices.
Creating Variable Sets: Managing reusable variable collections, including the
Wiz Policy Integration Authenticationtemplate.Creating New Firefly Workflows: How to set up managed workflows.
Integrating Existing CI/CD Pipelines with Firefly Workflows: Setting up
fireflyciin your own pipeline.
Firefly can delegate Infrastructure-as-Code policy evaluation to Wiz. When a workspace resolves Wiz credentials, its runs are scanned by Wiz instead of by Firefly's built-in policy engine, and the run is blocked if Wiz returns a failing verdict.
This is intended for organizations that already treat Wiz as the authority for cloud security policy and want the same policies enforced at the IaC level, before infrastructure is applied — without maintaining a parallel policy set in Firefly.
Wiz remains the policy authority throughout. Firefly does not interpret Wiz rules, choose which Wiz policies run, or remap Wiz verdicts into its own vocabulary. It runs the scan, presents the result verbatim, and enforces the outcome.
How It Works
For a Wiz-integrated workspace, a run proceeds through the following stages:
Checking Integrations: Before
init, Firefly validates the Wiz connection using the resolved credentials. The run displays a dedicated Checking Integrations status while this happens. If validation fails, the run stops with Init Failed.Init and Plan:
terraform initandterraform plan(or the OpenTofu/Terragrunt equivalents) run as usual.Wiz Scan: After
plan, the plan is exported to JSON and scanned by Wiz. The scan is plan-aware — Wiz evaluates the changes the plan will make, not just the static configuration.Guardrails Step: Wiz results are displayed alongside any Firefly custom policy results.
Gate: If Wiz returns a failing verdict, the run is blocked before
apply. Otherwise it proceeds toapply(or awaits approval, per your existing workflow configuration).
What Changes for an Integrated Workspace
Wiz scan
Runs. Blocking on the Wiz verdict.
Firefly built-in policy scans
Skipped. Wiz is the policy authority.
Kicks scans
Skipped.
Firefly custom policy scans
Runs. Reported but non-blocking, unless the policy's Violation Behavior is set to Strict Block.
Workspaces that do not resolve Wiz credentials are entirely unaffected — kicks and built-in policy scans run exactly as before.
Execution Models
The integration supports two execution models. Both use the same Wiz scan output, the same blocking rules, and the same UI. They differ in who runs the Wiz CLI:
Firefly-managed workspaces. Firefly provisions the Wiz CLI, authenticates, runs the scan, and enforces the gate. See Setting Up for Firefly-Managed Workspaces.
Your existing CI/CD pipeline. Your pipeline owns and runs the Wiz CLI, then hands the scan result to Firefly through
fireflyci. See Setting Up in an Existing CI/CD Pipeline.
Prerequisites
A Wiz tenant with IaC scanning enabled.
A Wiz OAuth2 service account. Create a service account in the Wiz portal and record its Client ID and Client Secret. The service account only needs read-only permissions — it scans, it does not modify your Wiz tenant.
Network egress to Wiz. Whatever environment runs the scan needs outbound HTTPS access to the Wiz authentication and API hosts (
auth.app.wiz.ioandapi.*.wiz.io, or their GovCloud/FedRAMP equivalents). For Firefly-managed runs this applies to Firefly's runners; if you use a self-hosted runner pool, ensure your network policy allows it.Linux amd64 or arm64 runners. The Wiz CLI is distributed only as a Linux amd64/arm64 binary. This constrains self-hosted runner pools used for Wiz-integrated workspaces, and your CI/CD job images in the pipeline model.
Setting Up for Firefly-Managed Workspaces
Wiz is enabled through a variable set. There is no separate enable toggle — a workspace becomes Wiz-integrated as soon as WIZ_CLIENT_ID and WIZ_CLIENT_SECRET resolve for it, whether directly or through inheritance.
Step 1: Create the Variable Set
In the Firefly UI, navigate to Workflows > Projects & Variables.
Click + Create new variable set.
Select the
Wiz Policy Integration Authenticationtemplate. This pre-populates the set with the three Wiz variables.Give the set a name and, optionally, assign it to specific projects to control which workspaces can consume it.
Fill in the variable values:
WIZ_CLIENT_ID
The OAuth2 service account client ID from the Wiz portal.
Yes
WIZ_CLIENT_SECRET
The OAuth2 service account client secret. Must be marked Sensitive.
Yes
WIZ_ENV
Set to gov for Wiz GovCloud (gov.wiz.io) or fedramp for Wiz FedRAMP (app.wiz.us). Omit for standard Wiz.
No
Click Create.
WIZ_CLIENT_SECRET is held in Firefly's secret store and encrypted at rest. It is never written to logs, API responses, or run output.
For full details on creating and managing variable sets, see Creating Variable Sets.
Step 2: Consume the Variable Set at the Right Scope
The Wiz variable set can be consumed at Organization, Project, or Workspace scope, and standard variable inheritance applies — a more specific scope overrides a broader one. This determines how widely the integration takes effect:
Organization Variables: every workspace in the organization becomes Wiz-integrated.
Project: all workspaces in that project and its sub-projects become Wiz-integrated.
Workspace: only that workspace becomes Wiz-integrated.
Consuming at organization scope is the most direct way to make Wiz the policy authority everywhere. Consuming at project or workspace scope lets you roll the integration out incrementally, or keep it scoped to the environments that need it.
Step 3: Verify
Open the workspace and check the Workspace Summary. A Wiz-integrated workspace displays a Wiz Integrations indication confirming the connection.
The indication reports only that the workspace is integrated. It does not list policies — those live in your Wiz tenant and are not known to Firefly.
Then trigger a run. A correctly configured workspace passes through the Checking Integrations status and reaches the Guardrails step with Wiz results present.
Setting Up in an Existing CI/CD Pipeline
In this model your pipeline runs the Wiz CLI and passes the result to Firefly. Firefly ingests, persists, gates on, and displays the result, but does not run the scan itself. There is no pre-init connection check in this model and no Checking Integrations status — validating that Wiz is reachable is your pipeline's responsibility.
This section assumes you already have fireflyci integrated into your pipeline. If you don't, set that up first — see Integrating Existing CI/CD Pipelines with Firefly Workflows.
Verified versions: The steps below were verified end-to-end on a live GitLab CI pipeline using
fireflyciv0.6.26 and Wiz CLI 0.109.16. The--wiz-scan-fileflag requiresfireflyciv0.6.26 or later.
Add the following three steps to the job that runs your plan, before your fireflyci post-plan step.
Step 1: Install the Wiz CLI
Pin the version and verify the checksum rather than tracking latest, so a Wiz-side release cannot change your gate's behavior mid-pipeline:
Version 0.109.16 is the version Firefly pins in its own runner image.
Note: The SHA256 above is specific to version
0.109.16of thelinux-amd64binary. If you bumpWIZCLI_VERSION, you must updateWIZCLI_SHA256to match, orsha256sum -cwill fail the job. Obtain the checksum for a different version or architecture from Wiz.
Step 2: Authenticate
Two details matter here:
Pass credentials through the environment, not as flags.
wizcli authreadsWIZ_CLIENT_IDandWIZ_CLIENT_SECRET(and optionallyWIZ_ENV) directly from the environment. The--idand--secretflags exist but should not be used: command-line arguments are visible to any process on the host through/proc/<pid>/cmdlineandps, which exposes your Wiz secret to anything else sharing the runner. Store the credentials as masked/protected CI/CD variables instead.Set a per-job
WIZ_DIR. The Wiz CLI writes its authentication token intoWIZ_DIR. If several jobs share a runner and share the default location — which is exactly what happens in a pipeline that fans out one job per module — they will overwrite each other's token, and jobs will fail to authenticate intermittently. DerivingWIZ_DIRfrom the job ID, as above, isolates them.
Step 3: Scan and Pass the Result to Firefly
Run the scan after terraform plan, then point fireflyci post-plan at the resulting file:
rm -fclears any stale result from a previous run in a reused workspace directory, so a failed scan cannot be silently gated on an old passing result.--namegives the scan a label in the Wiz dashboard. Use something unique per run so scans are traceable.--wiz-scan-fileis the flag that hands the result to Firefly. Ifpost-plandetermines the run should be blocked, it exits non-zero, which stops your pipeline beforeapply.
Important:
-o "$PWD/wiz_scan.json,json"must be written exactly as shown. Both halves of that value are load-bearing, and both fail silently if you get them wrong.The
,jsonsuffix is what makes the file JSON. The output file's format is set by-oitself, not by-f. The-f jsonflag only controls how results are styled on stdout. A bare-o wiz_scan.jsonwrites a human-readable report instead: Firefly parses it as zero coverage, discards it, and then fail-closed blocks the run. The result is that every run is blocked, and nothing in the error message points at the flag that caused it.The path must be absolute. A relative path is resolved against the working directory of whichever command is using it, and
post-planmay not share the scan's working directory. Any pipeline thatcds into a module directory — which every per-module pipeline does — will have the two diverge, and the run will be blocked withexpected a valid Wiz scan result and did not receive one. Using$PWDkeeps the path absolute and unambiguous.
Step 4: Report the Apply
Your existing fireflyci post-apply step needs no Wiz-specific changes. It continues to report apply results to Firefly for visibility.
Limits of Enforcement in This Model
Firefly can only gate a run it is told about. If a pipeline never invokes fireflyci post-plan, or invokes it but ignores its exit code, the apply will proceed regardless of the Wiz verdict.
This is a weaker guarantee than the Firefly-managed model, where Firefly controls the run end to end. If your requirement is that a failing Wiz verdict can never be bypassed, use Firefly-managed workspaces, or protect the pipeline definition itself so the fireflyci step cannot be removed.
Understanding Wiz Results in the Guardrails Step
Open a run and select the Guardrails step. For a Wiz-integrated workspace it shows a Wiz policies panel, with a green Connected chip confirming the integration is active.
Overall Verdict
Wiz returns a single verdict for the scan, which Firefly displays verbatim without remapping:
PASSED_BY_POLICY
No policy failures.
No
WARN_BY_POLICY
Findings exist, but not at a level Wiz treats as a failure.
No
FAILED_BY_POLICY
At least one Wiz policy failed.
Yes
Per-Policy Breakdown
Beneath the overall verdict is one row per policy Wiz evaluated, each with a result indicator, a severity, and the verdict Wiz returned:
Red ✕ —
Failed by Policy: a hard failure. This blocks the run.Amber ⚠ —
Passed: a soft failure. The policy flagged something, but the Wiz verdict still passed, so this is informational and does not block. This is theWARN_BY_POLICYcase.Green ✓ —
Passed: no findings.
When any policy shows Failed by Policy, the Apply action is disabled and marked with a lock badge.
Findings
Individual findings are listed below the policy breakdown:
Rule matches: the rule name plus the location in your configuration, as
fileName:lineNumber.Secrets: any secrets Wiz detected in the scanned configuration, with their type and location.
Report link: a deep link to the full report in the Wiz dashboard, for the complete detail Wiz holds on the scan.
A scan with no findings at all is a valid, successful result — not an error.
Firefly Custom Policy Results
Firefly custom policy results appear in the same Guardrails step, alongside the Wiz results. Both are shown because a run can be blocked by either a Wiz FAILED_BY_POLICY verdict or a Firefly custom policy set to Strict Block, and you need to see which one caused it. A blocked run is always attributable to the specific policy that blocked it.
What Blocks a Run
A run is blocked before apply if any of the following is true:
Wiz returns
FAILED_BY_POLICY.A Firefly custom policy with Violation Behavior = Strict Block is violated. See Creating Guardrail Rules.
The Wiz scan cannot be completed. If the connection check passed but the scan then crashes, exits non-zero, cannot reach Wiz, or returns malformed output, the run is blocked.
No valid Wiz result is available. In the CI/CD model, if the pipeline sends no scan result, or sends one that is empty, malformed, or in the wrong format, the run is blocked with an error stating that a valid Wiz result was expected and not received.
These last two are deliberate: this is a security gate, so it fails closed. A scan that errors is never treated as a scan that passed.
WARN_BY_POLICY and PASSED_BY_POLICY do not block, and neither does a violated custom policy that is not set to Strict Block.
Limitations and Considerations
Firefly does not control which Wiz policies run. Policy selection is entirely a function of your Wiz tenant configuration. This is intentional: it means policy changes you make in Wiz take effect on Firefly runs immediately, with no corresponding change in Firefly. It also means Firefly cannot scope, exclude, or threshold Wiz policies for a particular workspace — do that in Wiz.
Severity thresholds are not configurable in Firefly. Firefly blocks on the verdict Wiz returns. If you want severity-based gating, configure it in your Wiz policies.
Built-in Firefly policy scans and kicks scans are skipped for integrated workspaces. If you rely on specific Firefly built-in policies today, reproduce them as Wiz policies or as Firefly custom policies before enabling the integration.
The Wiz CLI is Linux amd64/arm64 only, which constrains self-hosted runner pools and CI/CD job images.
Enabling is implicit. Because resolved credentials are the trigger, consuming the Wiz variable set at organization scope silently changes scan behavior for every workspace in the organization. Roll out at project or workspace scope first if you want to stage the change.
Troubleshooting
Run fails at Checking Integrations with Init Failed
Invalid or missing credentials, or Wiz is unreachable.
Verify WIZ_CLIENT_ID and WIZ_CLIENT_SECRET resolve for the workspace and are correct. If you use Wiz GovCloud or FedRAMP, confirm WIZ_ENV is set to gov or fedramp. Confirm the runner has egress to the Wiz auth and API hosts.
Init Failed with no Wiz output at all
The Wiz CLI binary could not be provisioned on the runner.
Confirm the runner can reach downloads.wiz.io, and that a self-hosted runner is Linux amd64 or arm64.
Every CI/CD run is blocked with expected a valid Wiz scan result and did not receive one, and the scan itself looks successful
The ,json suffix is missing from -o, so the file is a human-readable report rather than JSON.
Use -o "$PWD/wiz_scan.json,json" exactly. See Step 3.
Same error, in a pipeline that runs one job per module
A relative path to wiz_scan.json is resolving against a different working directory than post-plan uses.
Use an absolute path — "$PWD/wiz_scan.json" — in both the -o value and --wiz-scan-file.
fireflyci: unknown flag: --wiz-scan-file
fireflyci predates the flag.
Upgrade to fireflyci v0.6.26 or later.
Jobs fail to authenticate to Wiz intermittently when several run at once
Concurrent jobs on a shared runner are overwriting each other's auth token in a shared WIZ_DIR.
Set a per-job WIZ_DIR, as in Step 2.
sha256sum -c fails during install
WIZCLI_VERSION was changed without updating WIZCLI_SHA256, or the architecture differs.
Update the checksum to match the version and architecture you are downloading.
Run is blocked but the Guardrails step shows no failing policy
The scan could not be completed or returned unparseable output, so the fail-closed gate applied.
Check the Wiz CLI exit code and output in the job log for the underlying failure.
A policy shows amber ⚠ but the run proceeds
Expected behavior — this is the WARN_BY_POLICY soft-fail case, which is informational.
To make these block, raise their severity or strictness in your Wiz policy configuration.
Firefly built-in policy violations no longer appear
Expected behavior — built-in policy scans are skipped for Wiz-integrated workspaces.
Reproduce the checks you need as Wiz policies or Firefly custom policies.
Security Considerations
Secret handling. In the Firefly-managed model,
WIZ_CLIENT_SECRETis stored in Firefly's secret store, encrypted at rest, and never written to logs, API responses, or run output. In the CI/CD model, Firefly never receives your Wiz credentials at all — they stay in your CI/CD environment, and Firefly receives only the scan output.Least privilege. The Wiz service account requires read-only permissions.
Do not pass credentials as CLI flags. See Step 2.
Scan result contents. Wiz results may include resource names, configuration detail, and the location of detected secrets. Firefly applies the same access controls to them as to other run data, and they are visible to anyone who can view the run.
Binary integrity. Pin the Wiz CLI version and verify its checksum, as shown in Step 1.
Last updated
Was this helpful?