plugin

package
v0.31.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 26, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package plugin is the Draugr plugin SDK. It defines the three extension kinds — Scanner, Controller, and Surveyor — the shared value types (Target, Config), and the transports (in-process built-ins, gRPC out-of-process plugins, and declarative tool adapters).

See docs/plugin-api.md.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ValidateConfig added in v0.29.0

func ValidateConfig(schema json.RawMessage, cfg Config) error

ValidateConfig checks cfg against a scanner's declared JSON Schema (ScannerInfo.ConfigSchema). An empty schema accepts any config. Validation is fail-fast: the first violation is returned as a human-readable error naming the offending option, so a mistyped Saga key or wrong value type is reported before any scan runs.

It supports the subset of JSON Schema Draugr emits for scanner config: object schemas with "properties", "required", and "additionalProperties"; and scalar/array leaves with "type" (string, boolean, integer, number, array, object) and "enum". This is deliberately narrow — scanner schemas are authored in-repo (a typed allowlist of options), not accepted from users — while remaining valid JSON Schema that external tooling and the config wizard can consume.

Types

type CacheKey

type CacheKey string

CacheKey uniquely identifies the inputs of a scan, so an unchanged target is never re-scanned. See ComputeCacheKey.

func ComputeCacheKey

func ComputeCacheKey(scanner, version string, t Target, cfg Config) CacheKey

ComputeCacheKey derives a stable cache key from the scan inputs: the scanner name and version, the target kind and identity, and the effective config. It is deterministic and independent of config map ordering.

type CacheVersioner added in v0.10.0

type CacheVersioner interface {
	CacheVersion(ctx context.Context) string
}

CacheVersioner is an optional interface a Scanner may implement to contribute a tool/data version to its cache key — so that an update to the underlying tool or its data (e.g. a vulnerability database) invalidates cached results, not just the TTL. The engine calls CacheVersion only when caching is enabled, and folds a non-empty return into the cache key. It is resolved lazily; implementations should memoize any probe and return "" when the version can't be determined (the key then falls back to Info().Version). Unlike Info(), CacheVersion may perform I/O.

type Config

type Config map[string]any

Config is scanner/plugin configuration. It is validated against the plugin's declared JSON Schema (ScannerInfo.ConfigSchema) before use.

type ControlResult

type ControlResult struct {
	Control string
	Report  sarif.Report
	Summary Summary
}

ControlResult is a control's outcome after aggregation.

type Controller

type Controller interface {
	Info() ControllerInfo
	// Plan expands a component (or the project, when comp is nil) into scan jobs.
	Plan(model saga.Model, comp *saga.Component) ([]ScanJob, error)
	// Aggregate merges and deduplicates this control's scanner outputs into one result.
	Aggregate(results []sarif.Report) (ControlResult, error)
}

Controller orchestrates one or more scanners for a single security control. It plans the work for a component (or the project) and aggregates the scanners' results.

type ControllerInfo

type ControllerInfo struct {
	// Name is the control name, e.g. "images", "sast", "opensource".
	Name  string
	Scope Scope
	// Summary is a one-line description of what the control does, for `draugr controls`.
	Summary string
	// DefaultScanners lists the scanner(s) the control runs by default. Some controls accept
	// additional opt-in scanners (see controllers.<name>.scanners); those are discovered from
	// the registry rather than listed here.
	DefaultScanners []string
}

ControllerInfo describes a controller.

type HostTarget

type HostTarget struct {
	Name string
	URL  string
	Type string
}

HostTarget is a running endpoint. Type is "browser" or "api".

func (HostTarget) Identity

func (t HostTarget) Identity() string

Identity returns the host URL.

func (HostTarget) Kind

func (HostTarget) Kind() TargetKind

Kind returns TargetHost.

type ImageTarget

type ImageTarget struct {
	Ref    string
	Digest string
}

ImageTarget is a container image. Identity prefers the immutable digest.

func (ImageTarget) Identity

func (t ImageTarget) Identity() string

Identity returns the digest when set, otherwise the ref. Keying on the immutable digest makes the cache content-addressed: a rebuilt image under the same tag has a new digest and so a new key, while an unchanged image reuses its result.

func (ImageTarget) Kind

func (ImageTarget) Kind() TargetKind

Kind returns TargetImage.

func (ImageTarget) PinnedRef added in v0.11.0

func (t ImageTarget) PinnedRef() string

PinnedRef returns the reference a scanner should actually pull: the ref pinned to the digest (e.g. "repo:tag@sha256:…") when a digest is known, so the bytes scanned match the digest the result is cached under. The tag is kept for readable scanner output. Falls back to the ref alone (or a repo-less digest) when either part is missing or the ref is already digest-pinned.

type InfraTarget

type InfraTarget struct {
	Platform string
	Ref      string
}

InfraTarget is an infrastructure surface (e.g. a Kubernetes cluster). Platform is the kind of infrastructure (e.g. "kubernetes"); Ref names the concrete instance.

func (InfraTarget) Identity

func (t InfraTarget) Identity() string

Identity returns the platform and ref, e.g. "kubernetes/prod".

func (InfraTarget) Kind

func (InfraTarget) Kind() TargetKind

Kind returns TargetInfra.

type Prewarmer added in v0.11.0

type Prewarmer interface {
	Prewarm(ctx context.Context) error
}

Prewarmer is an optional interface a Scanner may implement to warm shared, expensive state once before a run's concurrent fan-out — e.g. downloading a vulnerability database — so that many parallel scans don't each cold-start it (a thundering herd). The engine calls Prewarm once per distinct scanner, before scans start; a returned error is best-effort (logged, not fatal — the scan will surface any real problem). Implementations should memoize.

type RepositoryTarget

type RepositoryTarget struct {
	URL      string
	Revision string
	Paths    []string
}

RepositoryTarget is a source repository at a revision, optionally scoped to paths.

func (RepositoryTarget) Identity

func (t RepositoryTarget) Identity() string

Identity returns the URL and revision, e.g. "https://git/x@1.0".

func (RepositoryTarget) Kind

Kind returns TargetRepository.

type ScanJob

type ScanJob struct {
	Scanner  string
	Target   Target
	Config   Config
	CacheKey CacheKey
}

ScanJob is a unit of scan work produced by a controller's Plan.

type Scanner

type Scanner interface {
	Info() ScannerInfo
	Scan(ctx context.Context, target Target, cfg Config) (sarif.Report, error)
}

Scanner wraps a single security tool and runs one kind of scan. It is the atomic unit of work. Implementations must be side-effect-free with respect to the target and must honor ctx cancellation. Output is normalized to SARIF.

type ScannerInfo

type ScannerInfo struct {
	// Name is the scanner identifier, e.g. "trivy".
	Name string
	// Binary is the external executable the scanner shells out to, e.g. "trivy". Empty for
	// scanners that need no external tool. Used by `draugr doctor` to check availability.
	Binary string
	// Version is the scanner/plugin version; it participates in the cache key.
	Version string
	// Controls are the security controls this scanner can serve, e.g. ["images"].
	Controls []string
	// TargetKinds are the target kinds this scanner accepts.
	TargetKinds []TargetKind
	// ConfigSchema is a JSON Schema for Config; it drives validation and the config wizard.
	ConfigSchema json.RawMessage
}

ScannerInfo describes a scanner and its capabilities.

type Scope

type Scope string

Scope declares whether a controller operates on the whole project or per component.

const (
	ScopeProject   Scope = "project"
	ScopeComponent Scope = "component"
)

The scopes a controller may declare.

type Summary

type Summary struct {
	Errors   int
	Warnings int
	Notes    int
}

Summary counts findings by severity, for the Norn (policy/gate).

type SurveyScope

type SurveyScope struct {
	Kind   string
	Ref    string
	Config Config
}

SurveyScope tells a surveyor where to look, e.g. a kube context + namespace, a GitHub org, or an ADO project.

type Surveyor

type Surveyor interface {
	Info() SurveyorInfo
	Survey(ctx context.Context, scope SurveyScope) (saga.Fragment, error)
}

Surveyor (one of "the Ravens") discovers an application's surface and returns a Saga fragment, so the descriptor can write itself. Implementations must honor ctx cancellation.

type SurveyorInfo

type SurveyorInfo struct {
	// Name is the surveyor identifier, e.g. "k8s-images", "github-org-repos".
	Name string
	// Provides are the target kinds this surveyor can discover.
	Provides []TargetKind
	// ConfigSchema is a JSON Schema for the scope Config.
	ConfigSchema json.RawMessage
}

SurveyorInfo describes a surveyor.

type Target

type Target interface {
	Kind() TargetKind
	Identity() string
}

Target is something a scanner can act on. Identity returns a stable string that uniquely identifies the target for cache keying (a commit, an image digest, a normalized endpoint) — two targets with the same Identity are considered the same scan input.

type TargetKind

type TargetKind string

TargetKind identifies the sort of surface a scanner acts on.

const (
	TargetRepository TargetKind = "repository"
	TargetImage      TargetKind = "image"
	TargetHost       TargetKind = "host"
	TargetInfra      TargetKind = "infrastructure"
)

The kinds of target a scanner may accept.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL