Template repository for building Bomly plugins in Go.
It ships a complete, working matcher plugin — the simplest role to run end to end — that annotates every package in the scan registry with a configurable greeting. Keep the structure, replace the logic, and you have a production-shaped plugin: typed config with a generated JSON schema, the package-updates delta protocol, unit tests, the SDK conformance suite, CI, and a release workflow that packages platform archives Bomly can install.
- Click Use this template on GitHub (or
gh repo create my-plugin --template bomly-dev/bomly-plugin-template). - Work through the rename checklist below.
- Replace the matcher logic in
plugin/plugin.gowith your own.
- Module path — change
module github.com/bomly-dev/bomly-plugin-templateingo.modto your repo path, and update the import incmd/bomly-plugin-template/main.go. - Plugin id — change
Nameinplugin/plugin.go(e.g.com.example.my-matcher) and theidfield inbomly-plugin.json. They must be identical: Bomly refuses to load a plugin whose manifest id and runtime descriptor name disagree. - Binary name — rename
cmd/bomly-plugin-template/tocmd/<your-binary>/, update thePLUGIN_NAMEenv in.github/workflows/release.yml, and update everyentrypointvalue inbomly-plugin.json. - Manifest metadata — update
name,version,description,homepage, andlicenseinbomly-plugin.json. - Role — this template is a matcher. For a detector, auditor, or analyzer, change the module kind and descriptor accordingly; the how-to guides below walk through each role.
plugin/ The component: descriptor, typed Config, Match, Module()
cmd/bomly-plugin-template/ Binary entrypoint: sdk.ServeModule(plugin.Module())
bomly-plugin.json Package manifest Bomly reads at install time
testdata/ Fixture registry used by the unit tests
.github/workflows/ CI (test/vet/fmt/tidy) and dispatch-driven release# Build the plugin binary
go build -o bin/bomly-plugin-template ./cmd/bomly-plugin-template
# Install it into Bomly as a dev plugin, enable it, and scan
bomly plugin install ./bin/bomly-plugin-template --dev
bomly plugin enable bomly.template.matcher
bomly scan --enrichbomly plugin list / bomly plugin info bomly.template.matcher show the registration, including the config schema generated from the Config struct.
The matcher's config block lives under plugins.matchers.<id> in your Bomly config file:
plugins:
matchers:
bomly.template.matcher:
greeting: "hi from my config"The Config struct in plugin/plugin.go is the single source of truth: its json/doc/default tags produce the JSON Schema advertised in the descriptor (sdk.MustConfigSchemaFor), and HostContext.DecodeConfig fills it at runtime in both embedded and managed execution.
go test ./...The tests cover the matcher's baseline (full registry) and delta (PackageUpdates) paths, plus TestConformance, which runs the SDK's conformance suite: module and descriptor validity, JSON round-trip stability, construction via HostContext, the Ready/Applicable contract (including prompt return on a cancelled context), the package-updates merge, and the manifest identity cross-check against bomly-plugin.json.
To probe a built binary over the real managed transport, add:
conformance.ProbeBinary(t, "bin/bomly-plugin-template",
conformance.WithModule(plugin.Module()))- Bump
versioninbomly-plugin.jsonand commit. - Run the Release workflow (workflow_dispatch) with the same version.
The workflow builds linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, and windows/amd64, packages each as <name>_<version>_<os>_<arch>.tar.gz (.zip for windows) containing the binary, bomly-plugin.json, README.md, and LICENSE, generates SHA256SUMS, and publishes a GitHub release. Users then install with:
bomly plugin install github.com/<owner>/<repo>@v<version>- Pin a released version of
github.com/bomly-dev/bomly-sdkingo.modand bump it deliberately. - The plugin wire protocol (
bomly.plugin.v1) is additive within v1: hosts and plugins negotiate optional features via descriptorCapabilities(e.g.sdk.CapabilityPackageUpdates), so older hosts and newer plugins keep working on the baseline behavior. - Version your plugin with semver; keep
bomly-plugin.jsonversionand the release tag in lockstep.
- No secrets in logs, ever. Use the
HostContext.Logger(); never log tokens, credentials, or PII. - Explicit network. Make outbound calls through
HostContext.HTTPClient()(backed bysdk.NewHTTPClientProviderFromEnvin managed execution) so the host's proxy, TLS, and timeout policy applies. Document every endpoint your plugin talks to. - Degrade gracefully: report unavailability through
Readyinstead of failing scans.
- How to implement a matcher
- How to implement a detector
- How to implement an auditor
- Bomly plugin development guide
Apache-2.0. See LICENSE.