Files
claudetools/.claude/skills/bitdefender/SKILL.md
Mike Swanson b66843096a sync: auto-sync from GURU-5070 at 2026-06-19 08:40:35
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-19 08:40:35
2026-06-19 08:41:57 -07:00

6.6 KiB

name, description
name description
bitdefender Manage the ACG Bitdefender GravityZone Cloud MSP tenant (Public JSON-RPC API): inventory/audit endpoints, live security sweeps (infected / outdated-signature / outdated-product), client companies, install packages, custom groups, scans, move/delete endpoints (gated), policies (read-only), quarantine. Live production partner tenant — treat destructive actions conservatively. Triggers: bitdefender, gravityzone, install bitdefender on, list endpoints, infected machines, av coverage, security sweep, endpoint protection, quarantine.

Bitdefender GravityZone Skill

Standalone CLI client for the GravityZone Cloud Public API (JSON-RPC). Talks to the live ACG partner tenant. Read-only by default; destructive operations are gated behind --confirm.

Running the CLI

This machine's Python launcher is py (per identity.json). The scripts also work with python/python3.

# from the scripts dir, or pass full paths
bash "$CLAUDETOOLS_ROOT/.claude/scripts/py.sh" "C:/claudetools/.claude/skills/bitdefender/scripts/gz.py" status
bash "$CLAUDETOOLS_ROOT/.claude/scripts/py.sh" "C:/claudetools/.claude/skills/bitdefender/scripts/gz.py" companies
bash "$CLAUDETOOLS_ROOT/.claude/scripts/py.sh" "C:/claudetools/.claude/skills/bitdefender/scripts/gz.py" sweep --company <id> --json

Transport auto-selects: uses httpx if installed, otherwise stdlib urllib (no third-party dependency required).

Credentials

The API key is NEVER hardcoded. At runtime the client loads it from the SOPS vault:

bash "$CLAUDETOOLS_ROOT/.claude/scripts/vault.sh" \
     get-field msp-tools/gravityzone.sops.yaml credentials.api_key

CLAUDETOOLS_ROOT resolves from the env var, else claudetools_root in C:/claudetools/.claude/identity.json, else C:/claudetools. For testing you can override with GRAVITYZONE_API_KEY. Auth is HTTP Basic (key as username, empty password).

Cache model (important)

The CLI keeps a local cache at .claude/skills/bitdefender/.cache/inventory.json (gitignored — no secrets, no PII).

  • Cached (identity / structure tier): company id<->name map, endpoint id<->name/company/fqdn map, policy id<->name map, package list, and custom groups created via this tool. TTL = 86400s (24h).
  • NEVER cached (volatile): infected status, last-seen, online/offline, signature/product freshness. Those are ALWAYS pulled live — sweep and endpoint always hit the API.
  • Refresh: inventory --refresh forces a full re-pull. get_inventory() auto-refreshes when the cache is stale.
  • Write-through: a successful create-package or make-group updates the cache with the new id immediately, so you don't need a full refresh to reference it.

Policy API limitation

The Public API exposes policies only shallowly. You CAN list policies, read their id/name, audit which endpoints carry which policy (via endpoint detail), and — via the UNVERIFIED assignPolicy — assign an existing policy. You CANNOT read the granular module configuration of a policy, and there is NO create / edit / clone policy method in the Public API. For policy authoring, use the GravityZone console.

Safety gating

Destructive subcommands refuse to run without --confirm; without it they print what they would do and exit non-zero:

  • delete-endpoint <id> --confirm
  • delete-package --package <name> --confirm
  • delete-group --group <id> --confirm
  • isolate --endpoints <id> ... --confirm (cuts the endpoint off the network; reversible via unisolate)
  • unisolate --endpoints <id> ... --confirm
  • blocklist-add --company <id> --hashes <h> ... --confirm
  • blocklist-remove --id <hashItemId> --confirm

Never run destructive calls casually against this tenant. UNVERIFIED methods (assignPolicy, uninstall/reconfigure tasks, quarantine remove/restore, set label) are intentionally NOT exposed as dedicated subcommands — reach them only through raw after confirming the correct params against references/api-reference.md and the official Bitdefender docs.

raw itself refuses destructive method names (delete/uninstall/remove/ reconfigure, plus the EDR verbs isolat*/addToBlocklist/removeFromBlocklist) unless --confirm is passed. Note that raw prints the upstream response verbatim — it can carry data from the called method, so do not paste raw output into tickets/logs without review.

Common commands

GZ="bash "$CLAUDETOOLS_ROOT/.claude/scripts/py.sh" C:/claudetools/.claude/skills/bitdefender/scripts/gz.py"

# Status / inventory
$GZ status
$GZ companies
$GZ inventory --refresh
$GZ endpoints --company <companyId>
$GZ endpoint <endpointId>

# Live security posture
$GZ sweep --company <companyId>          # readable table
$GZ sweep --company <companyId> --json   # machine output

# Policies (read-only, shallow)
$GZ policies
$GZ policy <policyId>

# Quarantine
$GZ quarantine --company <companyId>

# Deployment
$GZ packages
$GZ create-package --name "Win Default" --company <companyId>
$GZ install-links --package "Win Default" --company <companyId>

# Org structure
$GZ make-group --name "New Site" --parent <parentId>
$GZ move --endpoints <id1> <id2> --group <groupId>

# Scans
$GZ scan --targets <id1> <id2> --type 2 --name "Full scan"

# EDR / incident response
$GZ blocklist                                  # list blocklisted hashes (whole tenant)
$GZ blocklist --company <companyId>            # scope to one company
$GZ incidents --company <companyId>            # list incidents (parentId required; method UNVERIFIED on this tenant - may return "Method not found")
$GZ isolate --endpoints <id1> <id2> --confirm  # cut endpoint(s) off the network (reversible via unisolate)
$GZ unisolate --endpoints <id1> <id2> --confirm   # restore endpoint(s) from isolation
$GZ blocklist-add --company <companyId> --hashes <h1> <h2> --hash-type 1 --source-info "..." --confirm
$GZ blocklist-remove --id <hashItemId> --confirm  # id comes from `blocklist` output

# Power use — call any method directly
$GZ raw --module network --method getEndpointsList --params '{"page":1,"perPage":50}'

# Destructive (gated)
$GZ delete-endpoint <id> --confirm

Phase-2 hooks (not yet implemented)

  • GuruRMM push-deploy: use install-links to fetch the platform installer URL, then push the installer to a target via the GuruRMM agent fleet (/rmm) for one-step Bitdefender rollout from RMM.
  • Push webhook: subscribe to GravityZone Push events (new malware / endpoint state changes) and surface them through the coord API / RMM alerts instead of polling sweep.

Reference

Full verified vs unverified method spec, JSON-RPC envelope, auth, and the policy/deployment caveats: references/api-reference.md.