sarif

package
v0.40.1 Latest Latest
Warning

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

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

Documentation

Overview

Package sarif provides Draugr's result currency: a pragmatic model of SARIF 2.1.0 findings, plus merge and deduplication. Every scanner normalizes its output to a Report; the engine merges reports and the result can be serialized to standard SARIF JSON for GitHub / Azure DevOps / GitLab.

Index

Constants

View Source
const Version = "2.1.0"

Version is the SARIF specification version Draugr emits.

Variables

This section is empty.

Functions

func DerivedHelpURI added in v0.35.0

func DerivedHelpURI(ruleID string) string

DerivedHelpURI maps identifiers with a stable, publicly resolvable home to their advisory. It's the fallback for scanners that publish no rule metadata; anything unrecognized gets "".

Types

type Counts

type Counts struct {
	Error   int
	Warning int
	Note    int
	None    int
}

Counts tallies results by severity.

func (Counts) Total

func (c Counts) Total() int

Total returns the sum of all counts.

type Level

type Level string

Level is the severity of a result, mirroring SARIF's result.level.

const (
	LevelError   Level = "error"
	LevelWarning Level = "warning"
	LevelNote    Level = "note"
	LevelNone    Level = "none"
)

The SARIF result levels.

func (Level) AtLeast

func (l Level) AtLeast(other Level) bool

AtLeast reports whether l is at least as severe as other.

func (Level) Rank added in v0.5.0

func (l Level) Rank() int

Rank orders levels from most to least severe (higher is worse): error=3, warning=2, note=1, none/unknown=0.

type Location

type Location struct {
	URI       string `json:"uri,omitempty"`
	StartLine int    `json:"startLine,omitempty"`
}

Location points at where a finding was observed.

type MarshalOptions added in v0.35.0

type MarshalOptions struct {
	// Compact drops what only a human reads — indentation, and the rule prose relayed from
	// the scanner — while keeping the report valid SARIF.
	//
	// It exists for a consumer that is going to *act* on the report rather than read it,
	// typically an agent paying for every byte of context. Rule descriptions and remediation
	// text are the bulk of a Draugr report (61% of it, measured on this repo), and a reader
	// that can follow a link doesn't need them inlined. So helpUri survives compaction and the
	// prose doesn't: keep the pointer, drop the paragraphs.
	Compact bool
}

MarshalOptions tunes how a report is serialized. The zero value is the default: indented, with everything a person or an editor might want.

type Report

type Report struct {
	Tool    string   `json:"tool,omitempty"`
	Results []Result `json:"results"`
	// Rules is the metadata the scanner published about the rules it applied, keyed by rule id.
	// A result names its rule; the rule is what explains it. Carrying this through is what lets
	// a reader — in a terminal, an editor, or a pull request — find out what "DS-0002" means.
	// Not every scanner publishes it, so entries may be missing.
	Rules map[string]Rule `json:"rules,omitempty"`
}

Report is a set of findings, normalized to SARIF semantics. Tool names the primary scanner; when a report carries results from several tools (after Merge), each Result keeps its own Tool.

func FromSARIF

func FromSARIF(data []byte) (Report, error)

FromSARIF parses standard SARIF 2.1.0 JSON into a Report, flattening all runs and setting each result's Tool from its run's driver name.

func Merge

func Merge(reports ...Report) Report

Merge combines reports into one, deduplicating results by fingerprint and preserving first-seen order. Each result's Tool is backfilled from its source report when unset.

func (Report) Counts

func (r Report) Counts() Counts

Counts tallies the report's results by severity.

func (Report) Dedup

func (r Report) Dedup() Report

Dedup returns a copy with exact-duplicate results removed, preserving first-seen order.

func (Report) HelpURI added in v0.35.0

func (r Report) HelpURI(ruleID string) string

HelpURI returns where a reader can look up ruleID: what the scanner published, or a URL derived from a well-known identifier scheme when it published nothing. Empty when we can't say — a wrong link is worse than none.

func (Report) Highest

func (r Report) Highest() Level

Highest returns the most severe level present, or LevelNone when there are no results.

func (Report) MarshalSARIF

func (r Report) MarshalSARIF() ([]byte, error)

MarshalSARIF serializes the report to standard SARIF 2.1.0 JSON as a single "Draugr" run, with each result's originating scanner recorded in its property bag ("tool").

func (Report) MarshalSARIFWith added in v0.35.0

func (r Report) MarshalSARIFWith(opts MarshalOptions) ([]byte, error)

MarshalSARIFWith is MarshalSARIF with explicit options.

type Result

type Result struct {
	// Tool is the scanner that produced the finding.
	Tool     string   `json:"tool,omitempty"`
	RuleID   string   `json:"ruleId"`
	Level    Level    `json:"level"`
	Message  string   `json:"message"`
	Location Location `json:"location,omitempty"`
	// Score is the finding's numeric CVSS-style severity (0–10), sourced from the SARIF
	// "security-severity" property. HasScore reports whether a score was present; without
	// one, normalized Severity falls back to Level.
	Score    float64 `json:"score,omitempty"`
	HasScore bool    `json:"-"`
	// Priority is the computed action band (P1–P4) for this finding, stamped by the engine
	// from the component's risk classification. Empty when prioritization is not configured.
	Priority string `json:"priority,omitempty"`
}

Result is a single finding.

func (Result) Fingerprint

func (r Result) Fingerprint() string

Fingerprint is a stable identifier for deduplication: two results with the same fingerprint are considered the same finding.

func (Result) Severity added in v0.5.0

func (r Result) Severity(floor Severity) Severity

Severity resolves a finding's normalized severity, in the order the SARIF/prioritization design prescribes:

  1. the finding's numeric score (CVSS / SARIF security-severity), if present;
  2. otherwise its SARIF level;
  3. then raised to floor if floor is more severe (a control-default floor, e.g. a leaked secret is never "low"). Pass an empty floor for no floor.

type Rule added in v0.35.0

type Rule struct {
	// Name is a human-readable identifier (SARIF reportingDescriptor.name), where the id
	// itself is opaque.
	Name string `json:"name,omitempty"`
	// ShortDescription is a single sentence; FullDescription is a paragraph.
	ShortDescription string `json:"shortDescription,omitempty"`
	FullDescription  string `json:"fullDescription,omitempty"`
	// Help is remediation guidance, often Markdown.
	Help string `json:"help,omitempty"`
	// HelpURI points at the rule's documentation or advisory.
	HelpURI string `json:"helpUri,omitempty"`
}

Rule is what a scanner says about one of its rules, beyond the bare id. Every field is optional: scanners vary widely in how much they publish, and an absent field is normal.

type Severity added in v0.5.0

type Severity string

Severity is Draugr's normalized, cross-control severity ladder. Unlike Level (the SARIF wire values error/warning/note), Severity is what prioritization ranks on: it splits a numeric CVSS-style score into four bands so a dependency CVE, a leaked secret, and an IaC misconfiguration can share one ordered list. See docs/concepts.md (prioritization).

const (
	SeverityCritical Severity = "critical"
	SeverityHigh     Severity = "high"
	SeverityMedium   Severity = "medium"
	SeverityLow      Severity = "low"
)

Severity bands, from most to least severe.

func (Severity) AtLeast added in v0.5.0

func (s Severity) AtLeast(other Severity) bool

AtLeast reports whether s is at least as severe as other.

func (Severity) Escalate added in v0.7.0

func (s Severity) Escalate() Severity

Escalate returns the next-higher severity band; critical is already the maximum. Used by exploitability enrichment to bump a finding one band.

func (Severity) Rank added in v0.5.0

func (s Severity) Rank() int

Rank orders severities (higher is worse): critical=4, high=3, medium=2, low=1, empty/unknown=0.

Jump to

Keyboard shortcuts

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