![ci]()
A hands-off supply-chain watchdog for your de. honey runs
best-in-class security scanners on a schedule, unifies their results into one
, and (optionally) has Claude DM you a triage write-up each day.
honey doesn't detect anything itself — it orchestrates scanners, each a
"lens" on a different risk:
| Lens | Answers | Upstream |
|---|---|---|
| bumblebee *(core)* | "Do I have a known-compromised package/extension?" | Perplexity |
| os | "Do my dependencies ha CVEs?" (all ecosystems) | Google/OSV |
| go | "Do I actually *call* a Go function?" | Go team |
| skillspector | "Is an installed AI agent skill behaving maliciously?" | NVIDIA |
| smuggle | "Is something *hidden* from the scanners — in Unicode, a bidi trick, a remote include?" | honey-native |
| mcp | "Did an MCP server's definition change since I approved it?" (rug pulls) | honey-native |
| ocr | "Are there instructions *hidden in an image* bundled with a skill?" | honey-native |
Two further lenses — mcp-scan (cloud) and garak (li probing) — are
off by default and wrap external tools; see Lenses.
On top of the raw scanners, honey adds a
suppression baseline (acknowledge a
re finding once, get told if it later changes) and a
policy (tune what
escalates the daily alarm).
bumblebee (the only required scanner) is a read-only in collector that
flags on-disk package/extension/ metadata matching a known-compromised
entry in a threat-intelligence catalog. The lenses are opt-in and inert
until you install their tool. honey adds the update→scan→report loop,
worst-wins , scheduling, and reporting — **all detection capability and
threat data are the upstreams'**, above all Perplexity's
bumblebee. See Acknowledgements.
Use honey three ways, smallest footprint first:
./daily-cycle.sh, read the . No Claude, no> The is report.sh's O: line, not manifest.json —
> that file is bumblebee *alone* and reads clean even when a lens found
> something. daily-cycle.sh's exit code (0 clean / 1 needs attention)
> reflects the same worst-wins .
setup.sh is idempotent and ends by running ./doctor.sh, which prints a
✓/✗ line for every dependency with exact fix-it commands for anything
missing. If a scan e, run ./doctor.sh first.
By default setup.sh also offers to install the two Go-based
lenses (os, go) —
you already have Go. The Python-based skillspector lens is pointed to, not
auto-installed. Pass HONEY_SETUP_INSTALL_LENSES=0 ./setup.sh to skip lenses.
Core: bash, git, jq, and Go
1.25+ (bumblebee needs 1.25+). macOS or Linux. setup.sh checks all of
these and tells you the install command for anything you're missing — it won't
guess your package manager. These also cover the two Go-based vuln lenses
(os, go), which install via go install.
Per optional lens: only the skillspector lens adds a requirement —
Python 3.12+ (install it per
SkillSpector's README). The vuln
lenses need nothing beyond the core toolchain. ./doctor.sh shows which
lenses are active and how to enable inactive ones.
> Why a bumblebee *checkout* and not just the binary? The threat-intel
> catalogs live in the repo's threat_intel/ directory, not inside the
> installed binary. honey needs both: the binary to scan, and a git checkout
> for the catalogs (which it git pulls each run to stay current).
> setup.sh handles both.
daily-cycle.sh runs one cycle: bumblebee first, then every active lens,
folded into one worst-wins .
1. git pull --ff-only the bumblebee checkout — fresh threat_intel/
catalogs (they're updated upstream via PR).
2. go install github.com/perplexityai/bumblebee/cmd/bumblebee — fresh
binary.
3. bumblebee scan --profile deep --root $HOME --exposure-catalog <repo>/threat_intel → writes a timestamped run dir +
--findings-onlymanifest.json.
4. Each active lens runs and writes its
own lens-<name>.json into the same run dir.
5. daily-cycle.sh exits 0 only when the o (worst across
bumblebee + every lens, after the baseline and policy) is clean, 1
otherwise — so a scheduler or routine can branch on it.
A clean machine produces no findings — that's the "all clear". Results live
outside the bumblebee checkout and ~/go, so neither the git pull nor
the go install can delete them. The manifest.json status below
describe bumblebee's result specifically; a lens can still escalate the
o even when bumblebee is clean.
status clean — scan completed, no matches.exposed — one or more catalog matches (see findings.ndjson).incomplete — hit --max-duration; co partial, NOT all-clear.scan_error — scan failed; see cycle.log / diagnostics.ndjson.bumblebee is honey's canonical lens (known-bad catalog matching). honey can
run additional lenses alongside it — independent scanners that cover a
different surface — and fold their results into one report. Each lens lives inlenses/ as a small script; if its underlying tool isn't installed,
the lens is inert (a clean machine with no lens tools beha as
bumblebee-only). The cycle's o is the worst across bumblebee
and every active lens — a lens can escalate concern, never mask a bumblebee
finding.
Every lens is opt-in: honey ne a lens's tool for you, and an
uninstalled lens is fully inert. Install the tool, and the lens activates on
the next run. ./doctor.sh shows which lenses are active.
What runs, and what phones out. Install a lens's tool and it activates on
the next run — *except two*, which never join the default cycle unless you set
an explicit flag, because they send data off your machine:
mcp-scan calls a cloud API (and shares tool names/descriptions with theHONEY_ENABLE_MCP_SCAN=1. honey's native mcp lensgarak probes a li over the network — enable withHONEY_ENABLE_GARAK=1 plus a target.E else runs locally, with one nuance worth stating plainly:os and go look up public databases
(OSV.dev, vuln.go.dev) by package *coordinates* — your code and file contents
ne the machine, and HONEY_OS=1 switches to local DBs.bumblebee, skillspector, smuggle, mcp, and ocr touch no network at all.
| Lens | Tool | Covers | Install |
|---|---|---|---|
| skillspector | NVIDIA SkillSpector | AI agent skills (SKILL.md + scripts): prompt injection, data exfil, excessi, tool poisoning | per its README (Python 3.12+) |
| smuggle | honey-native | Scanner-e in agent-skill/instruction files: in (tag chars), bidi o (Trojan Source), zero-width chars, and remote-include instructions — the tricks static pattern scanners miss | none (uses perl; PowerShell uses native .NET) |
| mcp | honey-native | MCP servers (.mcp.json + host configs — in to skillspector): in every server and hash-diffs its definition across runs to catch rug pulls (a server that changes after you approve it); flags fetch-and-exec launch commands | none (jq / native .NET) |
| ocr | honey-native | Image-payload / SkillCamo: OCRs images bundled in skills and flags hidden instructions — the multimodal blind spot text scanners can't see | tesseract (brew install tesseract) |
| mcp-scan | In / Snyk Agent Scan | Hybrid rules+model analysis of MCP servers & skills (tool poisoning/shadowing, toxic flows) — opt-in; cloud | pip install mcp-scan; enable with HONEY_ENABLE_MCP_SCAN=1 |
| garak | NVIDIA garak | Probes a li for jailbreaks/injection/leakage — opt-in; not offline | pip install garak; enable with HONEY_ENABLE_GARAK=1 + a target |
| os | Google/OS | Known vulns in lockfiles/manifests across all ecosystems (npm, pypi, cargo, go, …) | go install github.com/google/os/cmd/os |
| go | Go vuln team go | Go vulns that your code actually calls (reachability-aware → far less noise) | go install golang.org/x/vuln/cmd/go |
How they complement each other. bumblebee matches *known-compromised*
packages (reacti). os/go cover *known CVEs* — broad
across ecosystems, then deep and reachability-aware for Go. skillspector reads
agent-skill *content* for malicious behavior; smuggle catches what's *hidden*
from that content scan (in Unicode, bidi, remote includes); ocr catches
instructions hidden in *images*; and mcp watches MCP manifests for *change*
(rug pulls). Reacti, breadth, depth, anti-e, and drift — one
.
Where the vuln lenses scan. os and go scan your *project*
directories, not all of $HOME. Set HONEY_PROJECT_ROOTS (colon-separated;
default ~/git:~/code:~/De:~/src) to control this. The agent-skill
lenses (skillspector, smuggle, ocr) scan skill dirs under ~/.claude (o
with HONEY_SKILL_ROOTS).
Declared deps, not copies. os walks into node_modules,/, .pnpm, and every nested .claude/worktrees/* — flagging the same
transiti dozens of times across installed copies (one real run
produced 2,954 findings, 81% of them duplicated packages; after
filtering, 402 real ones). By default honey **excludes those paths and dedupes
identical package@+ad across lockfiles**, so you see each real
dependency once. Tune via HONEY_OS (set empty to
scan e) and HONEY_OS=1.
Go di of labor. os and go o on Go. By
default os defers Go stdlib ad to go — otherwise
it flags every stdlib CVE for your go directi dozens, unreachable,
no CVSS). go reports only the stdlib vulns you actually call. SetHONEY_OS=1 to keep them in os anyway.
Both vuln lenses run static DB lookups (os → OSV.dev withHONEY_OS=1 for local DBs; go → vuln.go.de
runs static (--no-llm) by default — honey's Claude routine is the semantic
layer; set HONEY_SKILLSPECTOR_LLM=1 to use SkillSpector's own LLM stage.
Two things can go stale — the vuln data and the scanner binaries —
and honey treats them differently:
go installHONEY_UPDATE_LENSES=0 to disable. The update is non-fatal: if it failsscan_error (), never a falseStatic scanners are noisy. A daily run o, first-party agent skills
can emit dozens of findings that are false positi reference or
documentation material — enough to drag O to EXPOSED every day and
bury a *real* finding. honey lets you acknowledge a re finding
once so it stops contributing to the daily — without going blind to
the thing honey exists to catch.
The mechanism is pin, not mute. A suppression entry doesn't say "ignore this
skill" (trust-by-location is blindness-by-location — a first-party plugin that
ships a malicious update keeps its path). It says *"I re this exact content
and judged this finding benign — tell me the instant the content changes."* Each
entry records a sha256 of the referenced file, so:
Every suppressed finding is therefore also a change-detector on the content it
for. Suppression is a report-layer re-rank, never a deletion — raw
run records are untouched — and a suppressed run never reads as a bare
all-clear: the always carries the tallies, e.g.O: CLEAN (12 suppressed) or O: EXPOSED — … (12 suppressed, 2 mutated).
Design details and the threat model are in docs/BASELINE.plan.md.
Manage it with honey-baseline.sh (Windows:win/honey-baseline.ps1) — it only editshoney.baseline.json, never your system:
add filters are combinable (AND): --all (excludes bumblebee), --scanner,--se, --rule, --location. Pinning a bumblebee (known-compromised)
match is opt-in and loud — --all excludes it; you must name --scanner explicitly.
bumblebeehoney.baseline.json is committed and re on
purpose: baseline edits show up in git diff / PR review, which is itself an
anti-gaming control.
What it does and does not defend. The content hash is the right defense
against silent post-review mutation (manifest-alteration rug pulls, source
swaps). It is structurally blind to payloads that were ne in the
first place — sleeper/trigger-activated code, instructions fetched from a remote
URL at runtime, or content hidden in bundled images. The baseline can only
suppress what a lens surfaced; widening the scanned surface is separate work.
Where the baseline pins *specific* findings, the policy is the *broad*
dial for the daily marketplace noise. Two settings, applied after suppression
(docs/.plan.md):
HONEY_TRUSTED_PATTERNSclaude-plugins-official) is tagged first-party; the report shows[1st-party] marker.O only at/above the floor forHONEY_ for third-party, HONEY_O: … (65 review)), but non-blocking.Safe by default: floors default to none — every finding blocks, exactly as
before. Pro labeling is on (informational). bumblebee always blocks
(known-compromised catalog), and a MUTATED pin always blocks (rug-pull
tripwire) — the floor is a lens-noise dial, never a mute for genuine danger.
If you use Claude Code and have the Slack
connector enabled, you can have the whole thing run daily and DM you the
analysis — no extra credentials, because a *Local* routine reuses your own
Claude auth and connectors.
1. In the Routines hub: New routine → Local.
2. Paste the prompt from routine-prompt.md (it runs
daily-cycle.sh to scan, report.sh for the factual baseline, then DMs
you an enriched write-up). Set HONEY_DIR in it to your checkout path.
3. Set the schedule (e.g. daily at noon).
On a clean run you get a one-line all-clear; on an exposed run you get
per-finding triage with drafted remediation, layering Claude's tailored
judgment on top of report.sh's deterministic facts. Because it's *Local*,
it can see your real filesystem (so the scan is meaningful) — a *Remote* cloud
routine cannot, and would always report clean.
Lenses in the routine — already handled. The prompt runs report.sh,
which covers bumblebee *and every active lens*, so the routine picks up
os / go / skillspector automatically once their tools are
installed — no prompt change needed. Two things make this work without manual
config:
daily-cycle.sh sets its own PATH (including ~/go/bin and ~/.local/bin),~/git:~/code:~/De:~/src. A Localhoney.conf (addexport HONEY_PROJECT_ROOTS="${HONEY_PROJECT_ROOTS:-/my/projects:/other}") —Set
HONEY_PROJECT_ROOTS=… before running the scripts. line to the prompt.)BUMBLEBEE_REPO, which setup.sh persists forTo triage by hand in a chat instead ("triage the latest honey run"), seetriage-guide.md.
Don't use Claude or Slack? Schedule the scan with your OS and get a native
desktop notification when something needs attention — no accounts, no
connectors.
com.honey.bumblebee.notify)osascript (built in) or terminal-notifier if installed.notify-sendIt runs notify-cycle.sh, which scans and — only when the
is exposed / incomplete / scan_error — pops a notification
pointing at runs/latest/report.txt. Clean runs are silent.
You still get analysis without Claude. report.sh renders a
readable triage report straight from the structured findings — ,
co, and each match grouped by se with its location, confidence,
and standard per-ecosystem remediation steps (npm/pip/go/bundler/composer/
brew/extension). The notify path writes it to runs/latest/report.txt
automatically; you can also run it anytime:
The Claude routine produces richer, tailored prose and reasons about your
specific project layout, but the facts and standard fixes are all inreport.sh deterministically — so the no-Claude path is genuinely
actionable, not just a "something matched" ping.
> macOS permissions: a scheduled job scanning all of $HOME may need
> *Full Disk Access* (System Settings → Privacy & Security) to read protected
> directories, and notifications must be allowed for the running process. If a
> scheduled run sees fewer files than a manual one, Full Disk Access is why.
After any run, runs/latest/manifest.json has the andruns/latest/findings.ndjson has any matches.
All settings are en with working defaults — a default
install needs none of them. Set them inline (HONEY_PROJECT_ROOTS=… ./daily-cycle.sh)
or export them in your shell.
Persisting a setting (honey.conf). Env vars don't survi shells,
and a Claude *Local* routine / cron job starts with a bare en that
won't see them. For settings that must stick — most often a non-defaultBUMBLEBEE_REPO — setup.sh writes a gitignored honey.conf at the repo
root that every script sources. If setup.sh finds an existing bumblebee
checkout at a non-default path, it offers to use it and persists the choice
there (rather than cloning a duplicate). Precedence is **env var > honey.conf
> built-in default**, so an explicit env o the file for a
one-off run. You can also hand-edit honey.conf — one export VAR=… per line.
| Var | Default | Purpose |
|---|---|---|
| HONEY | the scripts' own directory | where runs are written |
| BUMBLEBEE_REPO | $HOME/git/bumblebee | bumblebee checkout (for catalogs) |
| BUMBLEBEE_SCAN_ROOT | $HOME | what bumblebee scans |
| BUMBLEBEE_MAX_DURATION | 30m | bumblebee scan time cap |
| HONEY_PROJECT_ROOTS | ~/git:~/code:~/De:~/src | where the vuln lenses (os, go) look for projects |
| HONEY_SKILL_ROOTS | skill dirs under ~/.claude | where the agent-skill lenses (skillspector, smuggle, ocr) look for skills |
| HONEY_SMUGGLE_EXCLUDE | node_modules/.git//.pnpm | smuggle lens: skip files whose path matches (ERE) |
| HONEY_MCP_CONFIGS | Claude/Cursor/VS Code/Windsurf host configs | mcp lens: colon-separated MCP config files to in (plus every .mcp.json under the project roots) |
| HONEY_MCP_STATE | <repo>/.mcp-state.json | mcp lens: where the per-run manifest hashes are stored for rug-pull diffing (gitignored) |
| HONEY_OCR_MAX | 300 | ocr lens: cap on images OCR-scanned per run |
| HONEY_ENABLE_MCP_SCAN | 0 | set 1 to enable the opt-in mcp-scan lens (cloud/phones home; also needs SNYK_TOKEN/OPENAI_API_KEY) |
| HONEY_ENABLE_GARAK | 0 | set 1 to enable the opt-in garak lens (probes a li; also needs HONEY_GARAK_TARGET) |
| HONEY_UPDATE_LENSES | 1 | go install the Go lens binaries (os, go) before scanning; 0 to skip |
| HONEY_OS | 0 | os: use local vuln DBs instead of OSV.dev |
| HONEY_OS | 0 | os: keep Go stdlib ad (default defers them to go) |
| HONEY_OS | node_modules//.pnpm/testdata/fixtures/.claude/worktrees (ERE) | os: skip findings whose source path matches — keeps the scan on *declared* manifests, not installed/ copies. Set empty to scan e. |
| HONEY_OS | 0 | os: 1 keeps one finding per path; default collapses identical package@+ad across paths into one (+N more) |
| HONEY_SKILLSPECTOR_LLM | 0 | skillspector: enable its own LLM stage (default static --no-llm) |
| HONEY_BASELINE | <repo>/honey.baseline.json | path to the suppression baseline (pin-and-diff); see Suppression baseline |
| HONEY_TRUSTED_PATTERNS | claude-plugins-official | ERE; a finding whose location matches is first-party (else third-party). Empty ⇒ nothing trusted. See policy |
| HONEY_ | none | min se (none\|low\|medium\|high\|critical) at which a third-party finding escalates O; below it → non-blocking "review" tier (still reported) |
| HONEY_ | = HONEY_ | same, for first-party findings. Set high (or critical) to demote trusted-marketplace low/medium noise to review |
runs/, latest, and *.log are gitignored — they contain an in
of your machine and should never be published. honey.baseline.json is
deliberately not gitignored: suppression pins are meant to be re in
control.
| Symptom | Fix |
|---|---|
| Anything unexpected | ./doctor.sh — it pinpoints the cause |
| command not found: bumblebee | Go's bin dir isn't on PATH; doctor.sh prints the export PATH=… line to add |
| Scan finds nothing even when it should | Usually a missing/stale catalog checkout — ./setup.sh re-clones/updates it |
| jq not found | brew install jq (macOS) / sudo apt-get install jq (Debian/Ubuntu) |
| go build fails | Need Go 1.25+; upgrade from < |
| Status incomplete | Scan hit the time cap; raise BUMBLEBEE_MAX_DURATION or narrow BUMBLEBEE_SCAN_ROOT |
honey is a thin wrapper. The actual scanning engine and all threat
intelligence are the work of Perplexity:
Both are published by Perplexity under the Apache License 2.0. honey adds only
the update→scan→report loop, scheduling, and reporting around them. If honey
is useful to you, the credit for the hard part belongs upstream — please star
and follow bumblebee.
The optional lenses wrap further
upstream tools — honey installs none of them automatically and redistributes
no code; each lens is inert unless you install its tool yourself:
skillspector lens.os lens.go lens.All detection capability and data are the work of these upstream
projects. See NOTICE for full attribution.
honey is licensed under Apache 2.0. It depends on, but does not
include, bumblebee and its
threat_intel catalogs, which are independently licensed by Perplexity under
Apache 2.0. See NOTICE for attribution.
开发语言:Shell
Star 数:42
该项目属于安全软件方向的开源资源,代码结构清晰,适合安全研究人员学习参考。项目围绕Hands-off supply-chain watchdog for dev machines: orchestrates multiple security scanners (Perplexity bumblebee + osv-scanner, govulncheck, NVIDIA SkillSpector) into one daily verdict — via Claude/Slack, desktop notification, or plain CLI.展开,提供了可运行的实现,对理解相关安全机制、工具原理与攻防技术具有较高的研究价值。
从技术实现角度看,此类项目的核心在于对底层原理的深入理解与工程化落地。开发者在研究过程中可以结合官方文档与社区讨论,梳理项目的初始化流程、核心模块职责与数据流转,逐步掌握其中的技术细节与设计思路。
1. 下载源码压缩包,解压到本地环境。
2. 根据项目类型准备对应的运行环境与依赖。
3. 按照 README 中的步骤完成配置与部署。
4. 在隔离的测试环境中运行验证,避免影响生产系统。
本资源来源于开源社区,仅供安全研究、技术学习与合法授权范围内的攻防演练使用,请勿用于任何非法或侵害他人权益的用途。使用本项目产生的一切后果由使用者自行承担。
| 资源标题 | honey - Hands-off supply-chain watchdog for dev machines: |
| 所属分类 | 安全软件 |
| 发布作者 | admin |
| 发布时间 | 2026-10-05 22:47:14 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 83 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |