# Wiz

> Investigate the project's cloud security posture through the Wiz MCP (read-only), routing each query to the right domain and scoping to the project's own resources.

- Skill: `alexisbalayre/wiz` (Agent Skill)
- Install (CLI): `npx skillmds@latest add alexisbalayre/wiz`
- Raw SKILL.md: https://api.skillmd.com/api/skills/alexisbalayre/wiz/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: AlexisBalayre (https://skillmd.com/u/alexisbalayre)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/alexisbalayre/wiz

---


# Wiz (cloud security)

The Wiz MCP exposes ~250 tools across 24 security domains behind two gateway tools. You never call a Wiz tool directly: `discover` finds it, `execute` runs it. This skill is read-only: investigate, never mutate.

> **Setup:** this skill needs the Wiz MCP server enabled in `.claude/settings.local.json` and
> your own Wiz resource IDs in `.env` (see `.env.example`): `WIZ_REPO_BRANCH_ID` (the
> default-branch REPOSITORY_BRANCH resource for SAST) and `WIZ_CONTAINER_REPO_IDS` (the
> container-repository UUIDs for your images). Resolve them once per the "Resolve to IDs"
> section below, then fill them in — never hardcode real UUIDs in the repo.

## The loop

Every query takes the same four steps:

1. **Route.** Call `discover()` with no argument to list the domains. Pick the one domain that owns the answer by the *type of finding* you want, not by nouns in the question (see Routing traps).
2. **Spec.** Call `discover(domain)` for the exact tool `name` and its parameter schema. Read it: params that sound singular are usually **arrays** (`group_by`, `severity`, `status`, `asset_name`, `container_repository`), some are **required** (e.g. `list_issues_grouped` needs `group_by` + `type`), and the `first` / `limit` cap differs per tool (often 20). Never guess.
3. **Query.** Call `execute(tool_name, parameters)` with the exact `name` from step 2, scoped per the project section below. If `execute` rejects the name, re-run `discover(domain)` to confirm spelling (some names repeat across domains).
4. **Summarize.** A result too large for one response is auto-saved to a `tool-results/*.txt` file instead of returned. Parse it with jq or python (or hand the file to a subagent), never re-read it whole. Report a ranked summary (severity, then affected resource) with the Wiz finding IDs so the user can open each in the portal. Never paste raw JSON back.

Prefer a `*_grouped` tool with a small `first` over a raw list: fewer tokens, and it answers "where is the load" directly.

## Routing traps

Route by finding type. `discover()`'s own text carries "Do NOT use for X → Y" notes; these are the most-often mis-routed:

- **"AI" in the question does not mean the `ai_security` domain.** Route by what you want *about* AI: issues to `issues`, threats to `soc`, SAST to `codesec`, CVEs to `vulnerabilities`, sensitive data to `dspm`, compliance to `compliance`. Use `ai_security` only for the AI resource inventory itself.
- **Third-party CVE on a cloud resource or image goes to `vulnerabilities`; a first-party source-code weakness (SAST) goes to `codesec`.** "Issues in our images / repo" spans both: image CVEs are `vulnerabilities`, code flaws are `codesec`. Check both when the ask is broad.
- **A compliance framework score or cross-framework gap goes to `compliance`; a single misconfiguration or security rule goes to `cspm`.**
- **Cloud IAM (principals, entitlements, access keys, MFA) goes to `identity`; Wiz portal users and RBAC go to `settings`.**
- **EOL, outdated, or unsupported technology goes to `inventory`, not `container_security`.**

## Resolve to IDs (names lie)

A free-text name filter that returns zero does **not** mean the resource is absent: `asset_name: ["<project name>"]` can return nothing even though the project's images exist. Filter by the resource's Wiz UUID instead.

The fastest UUID source is a **Wiz portal URL**: its hash fragment encodes the exact filter IDs the view uses (`resource`, `containerRepository`, ...). Ask the user to paste the portal link for the view they mean, or read the IDs out of one they already sent. Otherwise resolve the UUID with a listing / inventory tool, then filter by it.

## The project in Wiz

Typically the project's code and images live under the source host and container registry (e.g. **GitHub / ghcr.io**), not the cloud account; only the running workloads are on the cloud provider (`cloud_platform: ["AWS"]` or equivalent, plus your prod account, cluster, and namespace). So a cloud-platform filter **hides** the image and SAST findings: scope those by the IDs below, not by cloud platform.

- **Source repo (SAST → `codesec` / `list_sast_findings`)**: `resource_id: ["${WIZ_REPO_BRANCH_ID}"]` (the default-branch REPOSITORY_BRANCH resource). Add `is_default_branch: true`.
- **Container images (CVEs → `vulnerabilities`)**: filter `container_repository` by the UUIDs in `${WIZ_CONTAINER_REPO_IDS}` — one per image the project ships.

Default `severity` to `["CRITICAL", "HIGH"]`, `status` to `["OPEN"]`, and add `has_fix: true` when the goal is to fix (only fixable findings are actionable). Per finding, `layerMetadata.isBaseLayer` and `artifactType.group` (`OS_PACKAGE` vs `CODE_LIBRARY`) say whether the fix is a base-image bump or a dependency bump.

```
execute("list_vulnerability_findings_grouped", {
  group_by: ["VULNERABLE_ASSET"], asset_type: ["CONTAINER_IMAGE"],
  container_repository: ["<UUID from $WIZ_CONTAINER_REPO_IDS>"],
  severity: ["CRITICAL", "HIGH"], status: ["OPEN"], has_fix: true, first: 20 })
```

## Before treating a finding as real

Wiz findings, SAST especially, carry false positives; verify against the code before proposing a fix. Read the flagged line. Example false-positive shapes: a weak hash (SHA-1, MD5) mandated by a protocol or used as a non-security checksum, a timer or callback API flagged as "eval", internal config dirs flagged as path traversal, and template rendering with escaping off that produces plain text rather than HTML.

## Read-only guardrail

This skill only investigates. Execute only read tools: names beginning `list_`, `get_`, or `search_`, plus `discover`.

Refuse any mutating tool: anything that creates, changes, resolves, assigns, deletes, reports, or configures (creating a pentest finding, an automation or remediation rule, a Jira or ServiceNow ticket, changing an issue's status). If the user wants one, say it is out of scope for this skill and point them to the Wiz portal.

