aquasecurity/trivy
Plugin system
Active contributors: knqyf263, simar7
Purpose
The plugin system lets external developers extend Trivy without forking the codebase. A plugin is an external binary (or shell script) that Trivy launches as a top-level subcommand. Plugins are distributed through a public index (trivy-plugin-index) or installed directly from a Git URL or local path.
Directory layout
pkg/plugin/
├── plugin.go # Plugin metadata + Run
├── manager.go # Install, list, run, uninstall, update
├── manager_unix_test.go
├── index.go # Plugin index (downloader + cache)
└── testdata/Key abstractions
| Symbol | File | Purpose |
|---|---|---|
plugin.Plugin |
pkg/plugin/plugin.go |
Plugin descriptor (name, summary, platforms, install path, hooks). |
plugin.Manager |
pkg/plugin/manager.go |
Install/list/run/uninstall/update. Loaded by cmd/trivy/main.go and pkg/commands/app.go. |
plugin.NewManager |
pkg/plugin/manager.go |
Factory; defaults to ~/.trivy/plugins. |
plugin.Run |
pkg/plugin/plugin.go |
Entrypoint when running as a plugin. |
plugin.Index |
pkg/plugin/index.go |
Pulls and caches the plugin index. |
Lifecycle
graph LR
Install[trivy plugin install <name>] --> Manager
Manager --> IndexCheck{In index?}
IndexCheck -->|yes| FromIndex[download from URL in index]
IndexCheck -->|no| FromURL[download from explicit URL]
FromIndex --> Extract
FromURL --> Extract
Extract --> Cache[~/.trivy/plugins/<name>/]
Cache --> ManifestCheck[plugin.yaml]
Run[trivy <name>] --> ResolveCmd[loadPluginCommands]
ResolveCmd --> ExecBinary[exec or fork as plugin]When the Trivy CLI starts:
loadPluginCommandsinpkg/commands/app.gocallsplugin.NewManager().LoadAll(ctx)and gets aPluginfor each installed entry.- For each plugin, a synthetic Cobra command is added to the root with
DisableFlagParsing: true(the plugin handles its own flags). - When the user runs
trivy <plugin>, the synthetic command'sRunEcallsplugin.Run, which forks the plugin binary (or calls back into the same binary withTRIVY_RUN_AS_PLUGIN=<name>).
plugin.yaml declares per-platform install URLs, the binary path inside the archive, and metadata used in trivy plugin list and search.
Plugin index
The plugin index is itself an OCI artifact distributed via ghcr.io/aquasecurity/trivy-plugin-index. pkg/plugin/index.go downloads, caches, and parses it. The index lists official plugins with their repo URL, summary, and supported platforms.
Self-as-plugin
cmd/trivy/main.go checks for TRIVY_RUN_AS_PLUGIN:
if runAsPlugin := os.Getenv("TRIVY_RUN_AS_PLUGIN"); runAsPlugin != "" {
log.InitLogger(false, false)
if err := plugin.Run(context.Background(), runAsPlugin, plugin.Options{Args: os.Args[1:]}); err != nil {
return xerrors.Errorf("plugin error: %w", err)
}
return nil
}This lets a user write a plugin that is a Trivy command (e.g., one that calls trivy image and post-processes the output) without recompiling.
Plugin types
The most common plugin shapes are:
- Wrapper plugins — call
trivythemselves (usingTRIVY_RUN_AS_PLUGIN=...to avoid recursion) and reformat or post-process the output. - Output processors — read a Trivy JSON report from stdin and emit a new format. Used for pipe chains like
trivy image -f json | trivy <my-plugin>. - Side commands — provide entirely new functionality that is too niche for core (e.g., a corporate-internal report uploader).
Integration points
- CLI —
loadPluginCommandsadds plugins as subcommands. - Module system — sibling extension mechanism using WASM. Plugins are unsandboxed; modules are sandboxed.
Entry points for modification
- Change install behavior —
pkg/plugin/manager.go. The download supports OCI, Git, and direct URLs. - Change index format —
pkg/plugin/index.go. The schema is documented in the trivy-plugin-index repo. - Add plugin metadata — extend
plugin.Pluginand theplugin.yamlschema.
Key source files
| File | Purpose |
|---|---|
pkg/plugin/plugin.go |
Plugin descriptor and Run. |
pkg/plugin/manager.go |
Install, list, run, uninstall, update. |
pkg/plugin/index.go |
Plugin index downloader. |
cmd/trivy/main.go |
TRIVY_RUN_AS_PLUGIN dispatch. |
pkg/commands/app.go |
loadPluginCommands registers plugins as subcommands. |
See also
- CLI — how plugins appear at the user level.
- Module system — sandboxed alternative.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.