Scanner Plugins
Motivation
By default, copa
uses Trivy to scan container images for vulnerabilities. However, we understand that different organizations have different requirements and may want to use different vulnerability scanners.
Starting with v0.5.0 and later, copa
offers extensibility to support different vulnerability scanners. Plugin architecture allows users to use the vulnerability scanner of their choice to patch container images without having to modify copa
's core codebase.
Usage
Scanner plugin binaries must be in $PATH
, and should be prefixed with copa-
and have executable permissions. Copa will automatically detect and use the scanner plugin if it is in $PATH
.
For example, if you have a scanner plugin binary called copa-foo
in $PATH
, you can run copa
with the following command:
copa patch --scanner foo --image $IMAGE ...
You can also a submit scan report in native v1alpha1
format (interface mentioned below) by using --scanner native
flag along with -r <report>
flag.
Scanner Plugins from the Community
If you have built a scanner plugin and would like to add it to this list, please submit a PR to update this section with your plugin.
If you have any issues with a specific plugin, please open an issue in the applicable plugin's repository.
Writing a Scanner Plugin
Please see instructions at Scanner Plugin Template for a template to get started with writing a scanner plugin.
Scanner Plugin Interface
alpha
versions of the API are not guarenteed to be backwards compatible. Once the API graduates to beta
and stable
, it will be backwards compatible.
API Versions:
- v1alpha1: Original format with single
updates
field - existing plugins continue to work - v1alpha2: New format with separate
osupdates
andlangupdates
fields that supports app-level patching
Scanner plugins support two API versions for backwards compatibility:
v1alpha1
type UpdateManifest struct {
// API version (v1alpha1)
APIVersion string `json:"apiVersion"`
// Metadata contains information about the OS and config
Metadata Metadata `json:"metadata"`
// Updates contains all package updates (OS packages only)
Updates UpdatePackages `json:"updates"`
}
type UpdatePackage struct {
// Package name
Name string `json:"name"`
// Installed version
InstalledVersion string `json:"installedVersion"`
// Fixed version
FixedVersion string `json:"fixedVersion"`
// Vulnerability ID
VulnerabilityID string `json:"vulnerabilityID"`
}
type Metadata struct {
OS OS `json:"os"`
Config Config `json:"config"`
}
type Config struct {
// OS Architecture (e.g. amd64, arm64)
Arch string `json:"arch"`
}
v1alpha2
type UpdateManifest struct {
// API version (v1alpha2)
APIVersion string `json:"apiVersion"`
// Metadata contains information about the OS and config
Metadata Metadata `json:"metadata"`
// OSUpdates is a list of OS package updates
OSUpdates UpdatePackages `json:"osupdates"`
// LangUpdates is a list of language/library package updates
LangUpdates LangUpdatePackages `json:"langupdates"`
}
type UpdatePackage struct {
// Package name
Name string `json:"name"`
// Installed version
InstalledVersion string `json:"installedVersion"`
// Fixed version
FixedVersion string `json:"fixedVersion"`
// Vulnerability ID
VulnerabilityID string `json:"vulnerabilityID"`
// Package type (python-pkg)
Type string `json:"type"`
// Package class (os-pkgs, lang-pkgs)
Class string `json:"class"`
}
type Config struct {
// OS Architecture (e.g. amd64, arm64)
Arch string `json:"arch"`
// Architecture variant (e.g. v8)
Variant string `json:"variant,omitempty"`
}
Format Examples
From the above, we can see that the plugin must return a JSON object via standard out with the following fields.
v1alpha1
{
"apiVersion": "v1alpha1",
"metadata": {
"os": {
"type": "debian",
"version": "11.3"
},
"config": {
"arch": "amd64"
}
},
"updates": [
{
"name": "libcurl4",
"installedVersion": "7.74.0-1.3+deb11u1",
"fixedVersion": "7.74.0-1.3+deb11u2",
"vulnerabilityID": "CVE-2021-22945"
}
]
}
v1alpha2
{
"apiVersion": "v1alpha2",
"metadata": {
"os": {
"type": "debian",
"version": "11.3"
},
"config": {
"arch": "amd64",
"variant": "v8"
}
},
"osupdates": [
{
"name": "libcurl4",
"installedVersion": "7.74.0-1.3+deb11u1",
"fixedVersion": "7.74.0-1.3+deb11u2",
"vulnerabilityID": "CVE-2021-22945",
"type": "debian",
"class": "os-pkgs"
}
],
"langupdates": [
{
"name": "requests",
"installedVersion": "2.25.1",
"fixedVersion": "2.31.0",
"vulnerabilityID": "CVE-2023-32681",
"type": "python-pkg",
"class": "lang-pkgs"
}
]
}