Plugins
Install, enable, verify, and build external detectors, matchers, and auditors.
Bomly plugins let you extend scans without changing the Bomly binary. Today, managed external plugins can add:
- detectors that turn project files into dependency graphs
- matchers that enrich packages with vulnerabilities, licenses, lifecycle data, or other package metadata
- auditors that turn graph and registry data into findings or risk scores
External analyzer plugins are not supported yet. bomly plugin list --analyzers can show built-in reachability analyzers, but the external plugin runtime currently serves only detectors, matchers, and auditors through sdk.ServeDetector, sdk.ServeMatcher, and sdk.ServeAuditor.
Start Here
Use this page when you want to install, trust, configure, package, or troubleshoot a managed plugin.
Use the implementation guides when you are writing one:
- How To Implement A Detector Plugin
- How To Implement A Matcher Plugin
- How To Implement An Auditor Plugin
Example plugin repositories live outside this repo so each plugin type can show a realistic package, release, and README:
- Bun Lock Detector — detector example using
PackageManagerOther - ClearlyDefined License Matcher — matcher example for license enrichment
- EOL Lifecycle Matcher — matcher example for lifecycle metadata
- Meme Dependency Auditor — auditor example that emits warning findings
How Plugins Run
Managed plugins are Go binaries that use Bomly's public sdk package. Bomly starts each enabled external plugin as a separate native OS subprocess through HashiCorp go-plugin in gRPC mode.
Plugin identity is split into three clear places:
- Manifest = package.
bomly-plugin.jsonrecords install and package fields: ID, name, version, description, homepage, license, source, Bomly version constraint, runtime, plugin API version, and entrypoint. - Descriptor = component. The plugin binary returns one role descriptor: detector, matcher, or auditor. The descriptor owns the component name, display name, aliases, tags, supported ecosystems, supported package managers, and role-specific behavior.
- Installed DB = trust and state. Bomly records checksum, enabled/disabled state, install path, and an internal descriptor snapshot when a plugin is installed. Plugin authors do not write that snapshot.
There is no Metadata() hook. For packaged plugins, Bomly reads id, kind, and pluginApiVersion from bomly-plugin.json, launches the binary, fetches the matching descriptor, and requires descriptor.name == manifest.id. For dev-binary installs without a manifest, Bomly probes detector, matcher, and auditor descriptors and accepts the binary only when exactly one role responds.
Bomly owns:
- installing plugin packages
- validating
bomly-plugin.json - checking recorded checksums
- storing plugins under
~/.bomly/plugins - enabling and disabling plugins
- loading enabled plugins during scan runtime preparation
Plugins do not get install hooks, post-install scripts, or automatic execution from repository checkouts.
Trust And Enablement
Installed external plugins are disabled by default. They do not participate in scans until you enable them:
bomly plugin enable <plugin-id>
Treat bomly plugin enable as the trust decision. When enabled, a plugin runs with the same user-level privileges as the Bomly process. It can read and write files, make network connections, spawn child processes, and access environment variables available to that user.
Repository-declared plugins are never executed automatically. The host must explicitly install and enable the plugin before it can run.
Try The Example Plugins
Each example repo has a bomly-plugin.json, a small Go implementation, tests, and packaging notes.
git clone git@github.com:bomly-dev/bomly-plugin-bun-lock-detector.git
cd bomly-plugin-bun-lock-detector
go test ./...
go build -o ./bin/bomly-plugin-bun-lock-detector .
bomly plugin install ./bin/bomly-plugin-bun-lock-detector --dev
bomly plugin enable bomly.examples.detector.bun-lock
bomly scan --path ./my-bun-project --detectors bomly.examples.detector.bun-lock
The matcher and auditor examples use the same workflow:
bomly plugin enable clearlydefined-license-matcher
bomly scan --enrich --matchers +clearlydefined-license-matcher
bomly plugin enable bomly.examples.auditor.meme-deps
bomly scan --audit --auditors +bomly.examples.auditor.meme-deps
Check that Bomly can see any installed plugin:
bomly plugin list --external
bomly plugin info <plugin-id>
bomly plugin verify <plugin-id>
bomly plugin test <plugin-id>
bomly plugin doctor <plugin-id>
Disable or uninstall it later:
bomly plugin disable <plugin-id>
bomly plugin uninstall <plugin-id>
Common Commands
List plugins:
bomly plugin list
bomly plugin list --external
bomly plugin list --detectors
bomly plugin list --matchers --json
bomly plugin list --auditors
Show one plugin:
bomly plugin info <plugin-id>
bomly plugin info <plugin-id> --json
Install a plugin:
bomly plugin install ./dist/bomly-plugin-example.tar.gz
bomly plugin install ./bin/bomly-plugin-example --dev
bomly plugin install https://example.com/bomly-plugin-example.tar.gz --checksum sha256:...
bomly plugin install https://example.com/bomly-plugin-example.tar.gz --insecure-skip-checksum
bomly plugin install github:bomly-dev/bomly-plugin-bun-lock-detector@v0.1.0
Check a plugin:
bomly plugin verify <plugin-id> # manifest, checksum, binary, runtime descriptor
bomly plugin test <plugin-id> # runtime readiness
bomly plugin doctor <plugin-id> # verify + test
Enable, disable, or remove a plugin:
bomly plugin enable <plugin-id>
bomly plugin disable <plugin-id>
bomly plugin uninstall <plugin-id>
Select Plugins During A Scan
Plugin selectors use the same +/- grammar as built-in components:
# Use only this detector.
bomly scan --detectors bomly.examples.detector.bun-lock
# Add an external matcher to the default matcher set.
bomly scan --enrich --matchers +clearlydefined-license-matcher
# Use one auditor explicitly.
bomly scan --audit --auditors bomly.examples.auditor.meme-deps
Detector plugins can participate in subproject discovery. Their runtime descriptor and PackageManagerSupport response record package-manager support and evidence patterns such as go.mod. Bomly stores that verified descriptor snapshot during install so external detectors can join the same scan-planning flow as built-ins.
Configuration And Proxy Support
Bomly passes the active plugin API version, the explicit BOMLY_CONFIG path when one was provided, proxy settings, and the enabled plugin's own config to managed plugin subprocesses.
Per-plugin configuration lives under plugins.<plugin-id>:
plugins:
clearlydefined-license-matcher:
api_base: https://api.clearlydefined.io
External plugins can read only their own config through the SDK:
type config struct {
APIBase string `json:"api_base"`
}
var cfg config
if err := sdk.DecodePluginConfigFromEnv(&cfg); err != nil {
return err
}
Proxy settings can be configured with a direct proxy URL:
network:
proxy:
url: http://proxy.example:8080
no_proxy: localhost,127.0.0.1,.corp.example
Bomly also accepts decomposed proxy settings:
network:
proxy:
type: http # http, https, or socks5
host: proxy.example
port: 8080
username: my-user
password: my-password
no_proxy: localhost,127.0.0.1,.corp.example
ca_cert_file: /path/to/proxy-ca-chain.pem
Equivalent environment variables are BOMLY_HTTP_PROXY, BOMLY_HTTP_NO_PROXY, BOMLY_HTTP_PROXY_TYPE, BOMLY_HTTP_PROXY_HOST, BOMLY_HTTP_PROXY_PORT, BOMLY_HTTP_PROXY_USERNAME, BOMLY_HTTP_PROXY_PASSWORD, and BOMLY_HTTP_CA_CERT_FILE.
When Bomly proxy fields are not set, Bomly's SDK HTTP client still honors standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables. For compatibility with non-SDK plugin code, Bomly also forwards the effective proxy values using the standard proxy environment variable names.
Plugins that make outbound HTTP calls should create one process-local provider with sdk.NewHTTPClientProviderFromEnv() and reuse it for timeout-specific clients:
provider, err := sdk.NewHTTPClientProviderFromEnv()
if err != nil {
return err
}
client := provider.Client(20 * time.Second)
Package Layout
An external plugin package includes a bomly-plugin.json manifest and one or more platform entrypoint binaries:
bomly-plugin.json
bin/
bomly-plugin-example
README.md
Installed plugins are stored under:
~/.bomly/plugins/
installed.json
store/
<plugin-id>/
<version>/
The manifest identity must match the runtime descriptor returned by the plugin binary. A detector plugin must also return package-manager support so Bomly can plan when the detector should run.
Supported Install Sources
Current supported sources are:
- local archive
- local binary with
--dev - direct URL with checksum
- GitHub Release via
github:owner/repo@tag
For GitHub Release installs, Bomly resolves release metadata, selects the asset matching the current OS and architecture, and uses a SHA256SUMS asset when present to verify the archive automatically.
For private GitHub Releases, set one of these environment variables before installing:
export BOMLY_GITHUB_TOKEN=<token-with-release-access>
# Also accepted: GITHUB_TOKEN, GH_TOKEN, GITHUB_AUTH_TOKEN
bomly plugin install github:bomly-dev/bomly-plugin-bun-lock-detector@v0.1.0
Bomly attaches the token only to github:owner/repo@tag metadata, checksum, and asset downloads. Direct URL installs do not receive GitHub auth headers.
Security Model
External plugins are native OS subprocesses. They are not sandboxed, not containerized, and not restricted by Bomly beyond the operating system's standard user-level privilege boundary.
What Bomly validates before executing a plugin:
- Manifest schema and required fields: ID, version, kind, runtime, API version
- Plugin API version compatibility with the running core version
- Entrypoint binary exists at the recorded path
- SHA256 checksum matches the installed record, when a checksum was recorded
- Runtime descriptor matches the manifest identity, kind, API version, and installed descriptor snapshot
What Bomly cannot enforce:
- Restricting the plugin's filesystem or network access
- Preventing the plugin from reading environment variables or credentials on the host
- Preventing the plugin from spawning additional child processes
- Guaranteeing that the installed binary matches the declared source if no checksum was recorded
Installation mode risk:
| Source | Integrity guarantee |
|---|---|
Local archive with --checksum sha256:... | Strongest: checksum ties the installed binary to the declared archive |
GitHub Release with SHA256SUMS | Release asset is verified automatically when checksums are present |
Direct URL with --checksum | Checksum ties the download to the declared identity |
Direct URL with --insecure-skip-checksum | None: the downloaded binary may differ from the declared source |
Local binary with --dev | None: appropriate only for binaries you built locally |
Recommended practices:
- Always supply
--checksumfor direct URL installs. - Run
bomly plugin verify <id>before enabling any plugin installed from an external source. - Treat
bomly plugin enableas the explicit trust decision for granting execution privileges. - Prefer
github:owner/repo@taginstalls when releases publishSHA256SUMS. - Do not enable plugins you did not build or obtain from a source you control.