# Zscaler Discover

> Use when you need a full inventory of the Zscaler tenant, when starting work on a new tenant, or when memory/zscaler-tenant.md is missing or outdated.

- **Type:** Skill
- **Install:** `agentstack add skill-secsilab-zscaler-claude-skills-zscaler-discover`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [secsilab](https://agentstack.voostack.com/s/secsilab)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [secsilab](https://github.com/secsilab)
- **Source:** https://github.com/secsilab/zscaler-claude-skills/tree/main/skills/zscaler-discover

## Install

```sh
agentstack add skill-secsilab-zscaler-claude-skills-zscaler-discover
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Zscaler Tenant Discovery

Scan the entire Zscaler tenant and generate a structured inventory in project memory.

## Prerequisites

1. Verify `.mcp.json` exists at project root
2. Run `zscaler_check_connectivity` — abort if it fails
3. Run `zscaler_get_available_services` — note which services are available

## Scan Plan

Use **subagents** to scan ZIA, ZPA, and ZTB in parallel. ZIdentity/ZCC/ZDX run in a third subagent.

### ZIA (MCP tools)

| Resource | Tool |
|----------|------|
| Locations | `zia_list_locations` |
| Cloud firewall rules | `zia_list_cloud_firewall_rules` (no search param) |
| URL filtering rules | `zia_list_url_filtering_rules` |
| URL categories (custom) | `zia_list_url_categories` |
| SSL inspection rules | `zia_list_ssl_inspection_rules` |
| DLP rules | `zia_list_web_dlp_rules_lite` |
| IP source groups | `zia_list_ip_source_groups` |
| IP destination groups | `zia_list_ip_destination_groups` |
| GRE tunnels | `zia_list_gre_tunnels` |
| Static IPs | `zia_list_static_ips` |
| VPN credentials | `zia_list_vpn_credentials` |

### ZPA (MCP tools)

| Resource | Tool |
|----------|------|
| App segments | `zpa_list_application_segments` |
| Segment groups | `zpa_list_segment_groups` |
| Server groups | `zpa_list_server_groups` |
| Access policy rules | `zpa_list_access_policy_rules` |
| App connector groups | `zpa_list_app_connector_groups` |
| Service edge groups | `zpa_list_service_edge_groups` |
| PRA portals | `zpa_list_pra_portals` |
| PRA credentials | `zpa_list_pra_credentials` |
| BA certificates | `zpa_list_ba_certificates` |
| SCIM groups | `get_zpa_scim_group` |

### ZIdentity / ZCC / ZDX (MCP tools)

| Resource | Tool |
|----------|------|
| Users | `zidentity_list_users` |
| Groups | `zidentity_list_groups` |
| Devices (ZCC) | `zcc_list_devices` |
| Applications (ZDX) | `zdx_list_applications` |
| Alerts (ZDX) | `zdx_list_alerts` |

### ZTB (AirGap API — OPTIONAL)

**Skip if** `ZSCALER_AIRGAP_SITE` is not set in `.env`.

Use Python urllib to call the AirGap API. Read `.env` for credentials and site name.

```python
import urllib.request, urllib.parse, json, ssl, os

env = {}
with open(".env") as f:
    for line in f:
        line = line.strip()
        if "=" in line and not line.startswith("#"):
            k, v = line.split("=", 1)
            env[k] = v

site = env.get("ZSCALER_AIRGAP_SITE")
if not site:
    print("SKIP: No ZSCALER_AIRGAP_SITE in .env")
    exit(0)

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

# OAuth2 token
vanity = env.get("ZSCALER_VANITY_DOMAIN", env.get("ZSCALER_CLIENT_ID", "").split("@")[0])
token_data = urllib.parse.urlencode({
    "client_id": env["ZSCALER_CLIENT_ID"],
    "client_secret": env["ZSCALER_CLIENT_SECRET"],
    "grant_type": "client_credentials"
}).encode()
req = urllib.request.Request(f"https://{vanity}.zslogin.net/oauth2/v1/token", data=token_data)
req.add_header("Content-Type", "application/x-www-form-urlencoded")
token = json.loads(urllib.request.urlopen(req, context=ctx).read())["access_token"]

BASE = f"https://{site}-api.goairgap.com"
def api_get(path):
    r = urllib.request.Request(f"{BASE}{path}")
    r.add_header("Authorization", f"Bearer {token}")
    return json.loads(urllib.request.urlopen(r, context=ctx).read())

# Collect ZTB data
sites = api_get("/api/v2/Site/")
gateways = api_get("/api/v3/Gateway/")
networks = api_get("/api/v2/Network/")
ipsec = api_get("/api/v2/cluster/ipsec-status")

# PBR and VRRP require IDs from gateways/clusters
# Iterate gateways for PBR policies
# Iterate clusters for VRRP status
```

Collect: sites, gateways, networks/VLANs, PBR policies (per gateway), IPsec status, VRRP status (per cluster).

## Output

### Memory File

Write to `memory/zscaler-tenant.md` in the project's auto-memory directory (`.claude/projects//memory/`).

```markdown
---
name: zscaler-tenant-inventory
description: Auto-discovered Zscaler tenant inventory — locations, segments, rules, gateways, users. Generated by /zscaler-discover.
type: reference
---

# Zscaler Tenant Inventory

Generated: 
Vanity: 
Customer ID: 

## ZIA

### Locations
| Name | ID | Profile | IP/GRE | State |
...

### Cloud Firewall Rules
| Order | Name | ID | Action | State | Protocols |
...

(repeat for each ZIA resource)

## ZPA

### App Segments
| Name | ID | Domain(s) | Segment Group | Enabled |
...

(repeat for each ZPA resource)

## ZIdentity
### Users
| Name | Email | Status |
...

### Groups
| Name | ID | Member Count |
...

## ZTB (if scanned)
### Sites / Gateways / Networks / PBR / IPsec / VRRP
...

## ZCC / ZDX
...
```

For each table: include **name, ID, key attributes, and state/enabled**. Keep rows concise.

### Update MEMORY.md

Add a pointer line if not already present:
```
## Zscaler Tenant Inventory
- See `memory/zscaler-tenant.md` for full auto-discovered inventory (generated by /zscaler-discover)
```

### Print Summary

After writing the file, print:
- Count per resource type (e.g., "ZIA: 3 locations, 12 firewall rules, ...")
- Anomalies: disabled rules, empty segment groups, orphaned segments, services with zero resources
- Total scan time

## Error Handling

- If a service is unavailable (from `get_available_services`), skip it and note in output
- If an MCP tool call fails, log the error and continue with remaining resources
- If ZTB API fails, skip ZTB section and note the error

## Related API Reference

For detailed endpoint documentation used by discovery:
- ZIA resources (locations, rules, policies) → See @zscaler-zia skill
- ZPA resources (segments, groups, connectors) → See @zscaler-zpa skill
- ZTB resources (sites, gateways, networks) → See @zscaler-ztb skill
- ZCC devices → See @zscaler-zcc skill
- ZDX applications and devices → See @zscaler-zdx skill
- ZIdentity users and groups → See @zscaler-zid skill

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [secsilab](https://github.com/secsilab)
- **Source:** [secsilab/zscaler-claude-skills](https://github.com/secsilab/zscaler-claude-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-secsilab-zscaler-claude-skills-zscaler-discover
- Seller: https://agentstack.voostack.com/s/secsilab
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
