Documentation
¶
Overview ¶
Copyright (C) 2026 l3montree GmbH
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Index ¶
- Constants
- Variables
- func CompileRules(ctx context.Context, rules []models.UpstreamVEXRule) (map[string]cel.Program, error)
- func EvalCompiledRules(ctx context.Context, compiled map[string]cel.Program, ...) (map[string][]string, error)
- func IdentityOfRule(rule models.UpstreamVEXRule) (string, error)
- func PrepareVulnsForEval(ctx context.Context, vulns []models.DependencyVuln) ([]map[string]any, error)
- func PurlVersionMatches(patternPurl, pathPurl packageurl.PackageURL) (bool, error)
- func ToCELExpression(cveID string, pattern PathPattern) string
- func VexRuleTitle(cveID string, pattern PathPattern) string
- type PathPattern
Constants ¶
const (
// PathPatternWildcard matches any path element at that position
PathPatternWildcard = "*"
)
PathPattern wildcard for VEX rules
Variables ¶
var CelEnv = sync.OnceValues(func() (*cel.Env, error) { return cel.NewEnv( cel.Variable("vuln", cel.AnyType), cel.Function("matchesPattern", cel.Overload( "matchesPattern_vuln_list", []*cel.Type{cel.DynType, cel.ListType(cel.StringType)}, cel.BoolType, cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val { path, err := stringListField(lhs, "vulnerabilityPath") if err != nil { return types.NewErr("matchesPattern: invalid vuln.vulnerabilityPath: %v", err) } artifactPurls, err := stringListField(lhs, "artifactPurls") if err != nil { return types.NewErr("matchesPattern: invalid vuln.artifactPurls: %v", err) } pattern, err := toStringList(rhs) if err != nil { return types.NewErr("matchesPattern: invalid pattern argument: %v", err) } matches := PathPattern(pattern).Matches(path, artifactPurls) return types.Bool(matches) }), ), ), cel.Function("matchesPurl", cel.Overload("matchesPurl_string_string", []*cel.Type{cel.StringType, cel.StringType}, cel.BoolType, cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val { purl, ok := lhs.Value().(string) if !ok { return types.NewErr("matchesPurl: invalid purl argument: %v", lhs) } pattern, ok := rhs.Value().(string) if !ok { return types.NewErr("matchesPurl: invalid pattern argument: %v", rhs) } purlObj, err := packageurl.FromString(purl) if err != nil { return types.NewErr("matchesPurl: invalid purl: %v", err) } patternObj, err := packageurl.FromString(pattern) if err != nil { return types.NewErr("matchesPurl: invalid pattern purl: %v", err) } matches, err := PurlVersionMatches(patternObj, purlObj) if err != nil { return types.NewErr("matchesPurl: %v", err) } return types.Bool(matches) }), ), ), ) })
Functions ¶
func CompileRules ¶
func EvalCompiledRules ¶
func EvalCompiledRules(ctx context.Context, compiled map[string]cel.Program, vulnMaps []map[string]any) (map[string][]string, error)
returns map keyed by vulnID and value is a list of ruleIDs that match that vuln
func IdentityOfRule ¶
func IdentityOfRule(rule models.UpstreamVEXRule) (string, error)
func PrepareVulnsForEval ¶
func PurlVersionMatches ¶
func PurlVersionMatches(patternPurl, pathPurl packageurl.PackageURL) (bool, error)
func ToCELExpression ¶
func ToCELExpression(cveID string, pattern PathPattern) string
func VexRuleTitle ¶
func VexRuleTitle(cveID string, pattern PathPattern) string
Types ¶
type PathPattern ¶
type PathPattern []string
PathPattern represents a path pattern with wildcards. Patterns use suffix matching where "*" can match any number of path elements. A wildcard "*" can appear at any position to match zero or more path elements. Examples:
- ["pkg:golang/lib@v1.0"] matches paths ending with exactly this element
- ["*", "pkg:golang/lib@v1.0"] matches paths ending with any elements followed by this element
- ["*"] matches any path suffix
func (PathPattern) Matches ¶
func (p PathPattern) Matches(path []string, artifactPurls []string) bool
Matches is like matchesSuffix, but first strips a leading pattern element that identifies one of the vulnerability's own artifacts.
VulnerabilityPath is always component-only and never includes the artifact's own identity, but devguard's own exports (CSAF, CycloneDX VEX) always include the artifact as the path's root. A pattern reconstructed from such an export - e.g. a downloaded VEX document being re-uploaded - would otherwise carry that artifact element as its first path segment and never match any real vulnerability path.
Once stripped, the remainder is matched exactly from the start of path (like the ROOT stop-marker case in matchesSuffix), not as a generic suffix: the artifact anchors the pattern to the absolute root of the dependency graph, so a shorter pattern must not match as a mere suffix of a longer, distinct path through a shared component - that per-path distinction is exactly what CSAF's product tree encodes.