fix(bitdefender): all-clients sweep, quarantine path, EDR controls, self-test

Several bugs found and fixed during live testing against the ACG GravityZone
tenant:
- security_sweep_all_clients: iterate each company (the companies container is
  not a valid endpoint parent; passing it 400'd the whole sweep)
- list_quarantine: use service-scoped path quarantine/computers with companyId
  (bare quarantine module 404'd; param is companyId not parentId)
- rename GZEndpointSummary.detection_active -> threat_detected with corrected
  semantics (True = active threat, tracks with infected; not an engine-on flag)
- status: readable sectioned table renderer for the nested apiKey/license dict
- portable CLAUDETOOLS_ROOT resolution (derive from file path, not a Windows
  literal) so it works on the Mac/Linux fleet

Adds scripts/selftest.py: a 29-check read-only harness (all passing) covering
every read command, --json, error exit codes, and destructive-action gating.
EDR/incident commands (blocklist, isolate/unisolate, blocklist-add/remove) and
raw destructive-method gating are included from this session's work.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 07:28:02 -07:00
parent 446d25c66b
commit db6aa3683f
6 changed files with 495 additions and 12 deletions

View File

@@ -85,6 +85,10 @@ 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
@@ -93,7 +97,8 @@ 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) unless `--confirm` is passed. Note that `raw` prints the upstream
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.
@@ -132,6 +137,15 @@ $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}'