Spider CLI
The Spider CLI (spider) is a standalone command-line tool for querying Spider-captured network traffic data and managing capture lifecycle. It is designed for both humans and AI agents, and follows a kubectl-style verb-first command structure (spider <verb> <resource>).
Install
Binaries are published for Linux, macOS and Windows on both amd64 and arm64 architectures at https://repository.floocus.com/bin/spider-cli-<os>-<arch>/<version>/spider.xz (or spider.exe.xz on Windows). Use latest for the most recent version, or a specific tag like 1.0.0 to pin.
Linux / macOS
Auto-detects OS and architecture:
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m); [ "$ARCH" = "x86_64" ] && ARCH=amd64; [ "$ARCH" = "aarch64" ] && ARCH=arm64
curl -fL "https://repository.floocus.com/bin/spider-cli-${OS}-${ARCH}/latest/spider.xz" | unxz > /usr/local/bin/spider
chmod +x /usr/local/bin/spider
Requires xz-utils (Debian/Ubuntu: apt install xz-utils; macOS: brew install xz).
Windows
PowerShell, Windows 10+ (uses the bundled tar which handles .xz):
$arch = if ($Env:PROCESSOR_ARCHITECTURE -eq 'ARM64') { 'arm64' } else { 'amd64' }
Invoke-WebRequest "https://repository.floocus.com/bin/spider-cli-windows-$arch/latest/spider.exe.xz" -OutFile spider.exe.xz
tar -xf spider.exe.xz
# Then move spider.exe to a directory on your PATH.
Available platforms
| OS | amd64 | arm64 |
|---|---|---|
| Linux | spider-cli-linux-amd64/<v>/spider.xz | spider-cli-linux-arm64/<v>/spider.xz |
| macOS | spider-cli-darwin-amd64/<v>/spider.xz | spider-cli-darwin-arm64/<v>/spider.xz |
| Windows | spider-cli-windows-amd64/<v>/spider.exe.xz | spider-cli-windows-arm64/<v>/spider.exe.xz |
Binaries are statically linked (built with CGO_ENABLED=0) and have no runtime dependencies — the Linux builds run on glibc and musl (Alpine) alike.
Quick start
# Interactive setup (prompts for all fields; password/secret are hidden,
# arrow keys supported for line editing)
spider add profile prod
# Or non-interactive with a service account
spider add profile prod \
--api-url https://your-spider-instance \
--auth-type service_account \
--client-id <client_id> \
--client-secret <client_secret> \
--whisperer <whisperer_id> \
--controller <controller_id>
# Or with a human login
spider add profile prod \
--api-url https://your-spider-instance \
--auth-type human \
--email <email> \
--password <password> \
--whisperer <whisperer_id>
# Search last hour of HTTP errors
spider search http --query "stats.statusCode:[400 TO 599]" --pretty
# Get HTTP stats grouped by URL template
spider stats http --group-by template --pretty
# Detect duration outliers
spider outliers http --pretty
Authentication
Two auth types are supported:
| Auth type | Credentials | Use case |
|---|---|---|
service_account (default) | --client-id + --client-secret | Automation, CI, AI agents |
human | --email + --password | Interactive use |
Credentials are stored in ~/.spider/profiles.json (mode 0600). Tokens are cached in ~/.spider/tokens.json and refreshed automatically when they expire.
Command tree
Data search and retrieval
| Command | Description |
|---|---|
spider search http|psql|tcp|packets | Search captured communications |
spider get http|psql|tcp|packets <id> | Fetch a single communication by ID |
spider get http <id> req|res body | Fetch and decompress a request/response body (gzip, deflate, brotli handled client-side) |
spider stats http|psql|tcp|packets | Aggregated statistics with optional --group-by |
spider outliers http|psql | IQR-based duration/size outliers + z-score status anomalies |
spider aggs http|psql|tcp|packets | Run raw Elasticsearch aggregations |
Cluster-wide network usage
Per-minute aggregated traffic between Kubernetes actors, captured by Gocipher and enriched by the Controller. Two views share the same underlying records:
- Logical (
network-logical) — actors are namespace+kind+name (e.g.default:deployments:api). Best for "which workloads talk to which?". - Physical (
network-physical) — actors include the node and the pod instance (e.g.node-1:default:Pod:api-7c5f8). Best for "which pod on which node sends what?".
Both views are scoped to a single controller (taken from the active profile's controller_id or --controller); they accept --start, --stop, --query, --size, and --pretty like the other data commands.
The network-usage index stores no document
_source, sosearch network-logical/network-physicalreturns aggregated rows — one per (client × server) pair within the time window, with structured client / server actor (namespace / kind / name, plus node + instance for physical),ingress/egress/totalbytes & messages, and the list of serverportsobserved. This matches the Network-View grid output.--sizecaps the number of rows returned, sorted bytotal.bytesdesc.
| Command | Description |
|---|---|
spider search network-logical|network-physical | Search per-minute traffic records |
spider stats network-logical|network-physical | Bytes & message totals (ingress/egress/total), with optional --group-by |
spider outliers network-logical|network-physical | IQR outlier detection on bytes & messages |
spider aggs network-logical|network-physical | Run raw Elasticsearch aggregations on the network-usage index |
Group-by dimensions for stats / outliers:
- logical:
client,client_namespace,client_kind,client_name,client_ip,server,server_namespace,server_kind,server_name,server_ip,server_port - physical: above +
client_node,client_actor,client_instance_name,client_instance_kind,server_node,server_actor,server_instance_name,server_instance_kind
Management resources
| Command | Description |
|---|---|
spider search whisperers|controllers|gociphers|teams|users | Search management resources |
spider search attachments | Search ephemeral whisperer attachments for a controller |
spider show sidecars | List sidecar / statically-deployed whisperers (live) |
spider get whisperer|controller|gocipher|team|user <id> | Fetch a single resource by ID |
spider show whisperer|controller|team | Show the resource referenced by the active profile |
Coverage check — to know whether a workload already has a whisperer (attached on demand or deployed as a sidecar) before proposing a new attach:
# Ephemeral attachments currently bound to the workload
spider search attachments \
--query 'status:"ATTACHED" AND namespace:"<ns>" AND collection:"<kind>" AND item:"<name>"' \
--pretty
# Statically-deployed sidecars (filter by namespace/kind/name in the result)
spider show sidecars --prettyIf a whisperer is found, reuse its ID with
--whisperer <id>onsearch http|psql|tcp|packets. Only runspider attachif no coverage exists.
Capture control
| Command | Description |
|---|---|
spider show namespaces | List Kubernetes namespaces visible to the profile's controller |
spider show collection -n <ns> -c <type> | List workloads in a namespace (types: pods, statefulsets, deployments, daemonsets, cronjobs) |
spider attach -n <ns> -c <type> -t <name> | Attach a whisperer to a workload and drive it to RECORDING |
Sharing
| Command | Description |
|---|---|
spider add link | Create a private or public shareable link |
Profile management
| Command | Description |
|---|---|
spider add profile <name> | Create or update a profile (interactive if no flags) |
spider list profiles | List all saved profiles |
spider show profile [name] | Show a profile (secrets redacted) |
spider use profile <name> | Set the default profile |
spider delete profile <name> | Remove a profile |
Common flags
All data commands (search, stats, outliers, aggs) accept:
--start— start time (ISO 8601 or relative like-1h,-24h, ornow)--stop— stop time (default:now)--query/-q— Lucene query string--size— max results (default: 100)--pretty— human-readable JSON output
Scope (mutually exclusive depending on the command):
--whisperer/-w— whisperer IDs forhttp,psql,tcp,packets(overrides profile, repeatable)--controller— controller ID fornetwork-logicalandnetwork-physical(overrides profile)
Global:
--profile <name>— use a specific profile instead of the default
Fetching request/response bodies
spider get http <id> req|res body fetches the raw body from the server and decompresses it client-side based on the Content-Encoding header. Supported encodings: gzip, deflate, br (brotli).
spider get http <id> res body > response.json
Generating shareable links
Spider has two link types:
Private link — requires a Spider account to open. Created by default.
spider add link \
[--view http|psql|tcp|packets|network-logical|network-physical] \
[--query "<lucene>"] \
[--start <t>] [--stop <t>] \
[--whisperer <id>] [--controller <id>]
Public link — anyone can open; an OTP is emailed to the recipient (or fully open if no email/domain restriction is set).
spider add link --public --expiry 72h \
[--emails analyst@example.com] \
[--domains @example.com] \
[--view http] [--query "<lucene>"] \
[--start <t>] [--stop <t>]
Both link types open Network-View pre-loaded with the selected scope (whisperers for the data views, controller for the network-usage views), team, time window, view, and optional Lucene filter.
Public links also restrict visible data via accessFilters — the same --query limits what the recipient can see.
Attaching whisperers to Kubernetes workloads
Discover targets first (requires controller_id in profile), then attach:
# List namespaces visible to the controller
spider show namespaces
# List workloads in a namespace
spider show collection -n my-namespace -c deployments
# Attach a whisperer to a target workload
spider attach -n my-namespace -c deployments -t my-service
# Uses the profile's whisperer_id and controller_id by default.
# Waits up to 30s for the whisperer to reach RECORDING state.