Fleet visibility dashboard and ingest server for Bumblebee scans.
Run the Hive server, point developer endpoints at it with --output http,
and browse fleet inventory, exposure findings, and per-endpoint scan history
in a React dashboard — no log shipper or custom receiver required.
This project is a fork of perplexityai/bumblebee.
Bumblebee (upstream) is a read-only supply-chain inventory scanner for
macOS and Linux developer endpoints, built by the
Perplexity AI team. It walks lockfiles,
package-manager metadata, extension manifests, and MCP configs on disk and
emits structured NDJSON — packages, optional exposure findings, and a
trailing scan_summary per run.
Bumblebee Hive (this fork) adds the missing fleet layer: a central ingest server, SQLite-backed storage, a REST read API, and a web UI so security and platform teams can see what is installed across developer machines without building their own receiver or querying raw NDJSON files.
| Addition | Description |
|---|---|
Hive server (cmd/hive) |
Go HTTP receiver: POST /v1/ingest for NDJSON batches, SQLite persistence, run promotion to current inventory per endpoint/profile. Ingest auth: bearer token, HMAC-SHA256, or none. |
REST read API (internal/api/) |
GET /v1/health, /v1/stats, /v1/endpoints, /v1/runs, /v1/findings, and per-run package/finding queries for the dashboard. |
React dashboard (web/) |
Fleet overview, endpoint list and detail (profile breakdown, ecosystem charts), fleet findings with severity filter, per-run drill-down, and offline Demo mode for local .jsonl files. React 19, React Router 7, Vite 6, Tailwind 4, TypeScript. |
| Docker deployment | Multi-stage Dockerfile.hive (Node UI build + Go server + Alpine runtime), docker-compose.yml with persistent volume, docker-compose.dev.yml for auth-free local dev. |
| Makefile | make hive (UI + server), make bumblebee, make test. |
| Documentation | docs/getting-started.md (end-to-end guide with screenshots), docs/receiver.md (Hive reference), docs/images/ (dashboard screenshots). |
| CI | .github/workflows/ci.yml builds both cmd/bumblebee and cmd/hive. |
Supporting packages: internal/ingest/ (auth + NDJSON handler),
internal/store/ (SQLite store), internal/hivemodel/ (endpoint identity).
The upstream scanner (cmd/bumblebee) remains stdlib-only. Hive adds
modernc.org/sqlite as the only external Go dependency.
docker compose up --build
# Dashboard: http://localhost:8080
# Ingest: POST http://localhost:8080/v1/ingest
# Token: dev-token-change-meNo local Go or Node required. For native builds, dev mode, and custom tokens, see docs/receiver.md.
Step-by-step guide (Linux/WSL endpoints, profiles, UI tour): docs/getting-started.md.
Requires Go 1.25+ on the endpoint (or build elsewhere and copy the binary).
go install github.com/perplexityai/bumblebee/cmd/bumblebee@latest
# or from this checkout:
go build -o bumblebee ./cmd/bumblebee
bumblebee selftest # smoke test before fleet rolloutexport BUMBLEBEE_TOKEN=dev-token-change-me
bumblebee scan --profile baseline \
--output http \
--http-url http://127.0.0.1:8080/v1/ingest \
--http-auth bearer \
--http-token-env BUMBLEBEE_TOKEN \
--http-allow-insecureOpen http://localhost:8080 — the endpoint appears under Endpoints with inventory broken down by ecosystem and profile.
For recurring scans (cron, systemd) and macOS launchd deployment, see docs/getting-started.md and docs/deployment-macos.md.
| View | What it shows |
|---|---|
| Overview | Fleet counts: endpoints, complete runs, findings, current packages; ecosystem and severity breakdowns. |
| Endpoints | Every device that reported scans — OS, active profiles, finding count, last seen. |
| Endpoint detail | Per-host inventory with profile tabs (baseline, project, deep), ecosystem charts, scan history. |
| Findings | Fleet-wide exposure catalog matches, filterable by severity. |
| Run detail | Single scan: profile, status, duration, findings vs packages, scanned roots. |
| Demo | Load a local .jsonl file without running the server. |
Findings appear only when scans include --exposure-catalog.
The scanner is provided by the upstream Bumblebee project. Key reference below; see the upstream README for full detail.
Bumblebee answers a narrow supply-chain response question: when an advisory names a package, extension, or version, which developer machines show a match in their on-disk metadata right now?
- Single static binary, Go 1.25+, zero non-stdlib dependencies.
- Three scan profiles (
baseline,project,deep) for different populations and cadences. - Reads only the lockfiles, package-manager install metadata,
extension manifests, and supported MCP JSON configs listed in
docs/inventory-sources.md. No package
manager execution (
npm ls,pip show,go list, ...) and no source-file reads.
| Family | Emitted ecosystem |
Sources |
|---|---|---|
| npm | npm |
package-lock.json, npm-shrinkwrap.json, node_modules/.package-lock.json, node_modules/<pkg>/package.json |
| pnpm | npm |
pnpm-lock.yaml, .pnpm/.../package.json |
| Yarn | npm |
yarn.lock (Classic + Berry) |
| Bun | npm |
bun.lock; bun.lockb presence as diagnostic |
| PyPI | pypi |
*.dist-info/METADATA, INSTALLER, direct_url.json, *.egg-info/PKG-INFO |
| Go modules | go |
go.sum, go.mod |
| RubyGems | rubygems |
Gemfile.lock, installed *.gemspec |
| Composer | packagist |
composer.lock, vendor/composer/installed.json |
| MCP | mcp |
JSON host configs: mcp.json, .mcp.json, claude_desktop_config.json, mcp_config.json, mcp_settings.json, cline_mcp_settings.json, plus ~/.gemini/settings.json (Gemini CLI / Code Assist) and ~/.claude.json (Claude Code user- and project-scoped mcpServers). Non-JSON configs (Codex config.toml, Continue YAML) are not parsed in v0.1. |
| Agent skills | agent-skill |
skills.sh / vercel-labs/skills lock files: global ~/.agents/.skill-lock.json (or $XDG_STATE_HOME/skills/.skill-lock.json) and project-local skills-lock.json. Loose SKILL.md directories without a lock file are not enumerated. |
| Editor extensions | editor-extension |
VS Code, Cursor, Windsurf, VSCodium manifests |
| Browser extensions | browser-extension |
Chromium-family (manifest.json) and Firefox (extensions.json) per profile |
| Homebrew | homebrew |
Formula INSTALL_RECEIPT.json files and cask .metadata install markers |
Bumblebee is a one-shot scanner: each invocation performs a single scan and exits. Cadence is the runner's responsibility (cron, launchd, systemd, MDM, etc.).
| Profile | Scans | Use for |
|---|---|---|
baseline |
Common global/user package roots, language toolchains, editor extensions, browser extensions, and MCP configs. | Recurring lightweight inventory via an external runner. |
project |
Configured development directories, such as ~/code, ~/src, or ~/work. |
Recurring inventory for known project workspaces. |
deep |
Explicit --root paths, including broad roots like $HOME. |
On-demand incident or campaign checks, usually with --exposure-catalog and --findings-only. |
baseline and project refuse bare-home roots; only deep walks them.
# Baseline global inventory.
bumblebee scan --profile baseline > inventory.ndjson
# Daily project sweep with explicit roots.
bumblebee scan --profile project \
--root "$HOME/code" \
--root "$HOME/Developer"
# On-demand exposure scan against a published advisory.
bumblebee scan --profile deep \
--root "$HOME" \
--exposure-catalog ./catalog.json \
--max-duration 10m
# Preview resolved roots without scanning.
bumblebee roots --profile baselinebumblebee scan --help lists every flag.
Records are NDJSON, one per line. Diagnostics go to stderr as NDJSON. Each
run ends with a scan_summary record; Hive uses it to promote a run to
current state. See docs/transport.md for the HTTP/file
wire contract and docs/state-model.md for the
promotion model.
Example package record
{
"record_type": "package",
"schema_version": "0.1.0",
"scanner_name": "bumblebee",
"run_id": "9b1f0c2e4d5a6b7c8d9e0f1a2b3c4d5e",
"endpoint": {
"hostname": "alex-mbp",
"os": "darwin",
"device_id": "MDM-7F4A2B"
},
"profile": "project",
"ecosystem": "npm",
"package_name": "@tanstack/query-core",
"version": "5.59.20",
"confidence": "high"
}Example finding record
{
"record_type": "finding",
"profile": "deep",
"finding_type": "package_exposure",
"severity": "critical",
"catalog_id": "advisory-2026-0042",
"ecosystem": "npm",
"package_name": "example-pkg",
"version": "1.2.3",
"confidence": "high"
}Minimal JSON, exact (ecosystem, name, version) matching only:
{
"schema_version": "0.1.0",
"entries": [
{
"id": "advisory-2026-0042",
"name": "example-pkg 1.2.3 (compromised release)",
"ecosystem": "npm",
"package": "example-pkg",
"versions": ["1.2.3"],
"severity": "critical"
}
]
}Sample catalogs maintained upstream: threat_intel/.
| Doc | Contents |
|---|---|
| docs/getting-started.md | End-to-end: start Hive, install scanner, run scans, schedule, UI tour |
| docs/receiver.md | Hive server reference: auth, API, Docker, promotion rules |
| docs/deployment-macos.md | macOS launchd / MDM fleet deployment |
| docs/transport.md | NDJSON wire format and HTTP ingest contract |
| docs/state-model.md | Current-state promotion and record identity |
| web/README.md | Dashboard development (Vite + API proxy) |
Apache License 2.0. See LICENSE.
The upstream perplexityai/bumblebee project is also licensed under Apache 2.0.
