sast

package
v3.92.10 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: AGPL-3.0 Imports: 31 Imported by: 0

Documentation

Index

Constants

View Source
const (
	KindSAST    = "sast"
	KindSecrets = "secrets"
	KindOCI     = "oci"
	KindIAC     = "iac"
)

Rule kinds. Every embedded rule declares one in its metadata block; a module that declares none is treated as sast.

The distribution across the ~1,900 embedded rules is lopsided and that shape drives the language server's scheduling: roughly 1,092 secrets, 791 sast, 7 oci and 7 iac. Secrets rules declare no languages, so the language filter can never drop them, and each one iterates every file. Measured on a Go repository, evaluating a single file costs 231 ms against all kinds but 10.4 ms against sast+iac+oci alone, so the editor's keystroke path runs without secrets and picks them up on save. See session_bench_test.go.

View Source
const DefaultRegistry = "https://github.com"

DefaultRegistry is the base URL used when --rule-registry is not set.

Variables

AllKinds is every kind the embedded corpus declares.

View Source
var DefaultRulesFS embed.FS

DefaultRulesFS holds the built-in .rego rule files compiled into the binary. The rules/ directory is relative to this file (internal/sast/rules/).

View Source
var InteractiveKinds = []string{KindSAST, KindIAC, KindOCI}

InteractiveKinds are the kinds cheap enough to evaluate on every keystroke.

View Source
var SeverityLabel = map[string]string{
	"critical": "Dangerous",
	"high":     "Risky",
	"medium":   "Quality",
	"low":      "Style",
	"info":     "Tentative",
}

SeverityLabel maps severity to the human-readable semantic label.

View Source
var SeverityToLevel = map[string]string{
	"critical": "error",
	"high":     "error",
	"medium":   "warning",
	"low":      "note",
	"info":     "note",
}

SeverityToLevel maps severity to the default SARIF level when a rule doesn't explicitly set "level" in its metadata.

Functions

func ApplyNosec added in v3.67.0

func ApplyNosec(findings []Finding, rootPath string) ([]Finding, []NosecHit)

ApplyNosec filters findings against nosec source comments and returns the kept findings plus one NosecHit per dropped finding. rootPath anchors the (possibly relative) ArtifactURI values to disk. len(hits) is the number dropped.

func CacheDir

func CacheDir(ref RuleRef) (string, error)

CacheDir returns the OS-native cache directory for a rule repository.

Linux:   ~/.cache/vulnetix/rules/<org>/<repo>/
macOS:   ~/Library/Caches/vulnetix/rules/<org>/<repo>/
Windows: %LOCALAPPDATA%\vulnetix\rules\<org>\<repo>\

func CanonicalLanguage added in v3.35.0

func CanonicalLanguage(label string) string

CanonicalLanguage exposes the alias-collapse used by the language pre-filter (e.g. "node"/"ts" -> "javascript") so callers can normalise catalog labels.

func CountByKind added in v3.87.0

func CountByKind(modules map[string]string) map[string]int

CountByKind reports how many rule modules declare each kind. Libraries are not counted.

func ExtractRegoID added in v3.87.0

func ExtractRegoID(src string) string

ExtractRegoID returns the "id" field from a Rego module's metadata block, or "" when none is declared.

A string scan rather than a parse: this runs over every module on every load, including the ~1,900 embedded ones, and parsing them twice (once here, once in the compiler) would be the more expensive way to learn one field.

func ExtractRegoKind added in v3.87.0

func ExtractRegoKind(src string) string

ExtractRegoKind returns the "kind" field from a Rego module's metadata block. Modules that declare no kind default to sast, which is the historical behaviour every rule was written against.

func FetchRuleRepo

func FetchRuleRepo(registry string, ref RuleRef, w io.Writer) (string, error)

FetchRuleRepo clones or pulls a rule repository into the system cache. Returns the local cache path. Prints progress to w.

func FilterModulesByID added in v3.87.0

func FilterModulesByID(modules map[string]string, ruleID string) map[string]string

FilterModulesByID retains only the module whose metadata id matches ruleID, case-insensitively. An empty ruleID returns modules unchanged.

func FilterModulesByKind added in v3.87.0

func FilterModulesByKind(modules map[string]string, noSAST, noSecrets, noContainers, noIAC bool) map[string]string

FilterModulesByKind removes embedded modules whose kind matches a disabled feature. Externally imported rules (anything not under the embedded "rules/" prefix) bypass the filter: the user asked for them explicitly.

func FilterModulesToKinds added in v3.87.0

func FilterModulesToKinds(modules map[string]string, kinds []string) map[string]string

FilterModulesToKinds keeps only the modules whose declared kind is in the allowed set. Unlike FilterModulesByKind it does NOT exempt externally imported (--rule) packs: a locked specialized subcommand applies its kind scope to every rule regardless of origin, so `containers --rule <pack>` never bleeds into that pack's secrets or iac rules.

Shared libraries are always retained. OPA compiles every module together, so dropping a dependency of a kept rule fails the whole evaluation; libraries produce no findings, so a few extra cost nothing.

An empty kinds slice means "no lock" and returns modules unchanged.

func Fingerprint

func Fingerprint(ruleID, artifactURI string, startLine int) string

Fingerprint produces a stable hash identifying a finding by rule + location. Used as the dedup key in memory.yaml and the SARIF fingerprints map. Returns the first 16 hex characters of SHA-256("<RuleID>\x00<ArtifactURI>\x00<StartLine>").

func IsRuleModule added in v3.87.0

func IsRuleModule(src string) bool

IsRuleModule reports whether src is a rule rather than a shared library. Libraries declare no metadata id and produce no findings.

func LanguagesForPath added in v3.35.0

func LanguagesForPath(path string) map[string]bool

LanguagesForPath returns the set of canonical ecosystem keys that a single file path maps to, by extension suffix, basename substring, or special filename. Exported so other packages (e.g. the AIBOM detector) can scope per-file content rules to the languages they target, reusing the same extension table as the SAST language pre-filter.

func LoadAllModules

func LoadAllModules(
	defaultFS embed.FS,
	disableDefault bool,
	ruleRefs []RuleRef,
	registry string,
	w io.Writer,
) (map[string]string, error)

LoadAllModules loads default embedded rules and any external --rule repos. If disableDefault is true, embedded rules are skipped. Returns map[filename]source for all loaded .rego files.

func LoadFileContents

func LoadFileContents(input *ScanInput, maxSize int64)

LoadFileContents populates input.FileContents for files matching the given language extensions. Files over maxSize bytes and binary files are skipped.

When LoadOptions is provided the caller can opt into binary inspection (strings + EXIF) and the synthetic content is folded into the same map.

func LoadFileContentsWithOptions added in v3.29.0

func LoadFileContentsWithOptions(input *ScanInput, opts LoadOptions)

LoadFileContentsWithOptions is the full-control variant used by the secrets subcommand.

func MarkConfidenceGap added in v3.65.0

func MarkConfidenceGap(res *SARIFResult, reason string)

MarkConfidenceGap flags a result whose evidence could not be fully verified, with a reason stating exactly what was unverifiable and why.

func MergeGitHistoryEntries added in v3.29.0

func MergeGitHistoryEntries(input *ScanInput, entries []secretscan.GitHistoryEntry) int

MergeGitHistoryEntries injects the file versions returned by secretscan.ScanGitHistory into input.FileContents. Returns the number of entries injected. Duplicate keys (same commit, same path) are silently ignored.

func ModulesDigest added in v3.87.0

func ModulesDigest(modules map[string]string) string

ModulesDigest is a content hash over a module set: sha256 over the sorted (name, sha256(source)) pairs.

Hashing content rather than tracking mtimes means an externally cloned rule pack that changed on disk produces a different key without anything having to observe the change.

func PrintHeadline added in v3.12.1

func PrintHeadline(report *SASTReport)

PrintHeadline prints a bold SAST headline (finding count + severity breakdown) above the analysis table. Used as the top-of-output summary when SCA did not run (so the SCA "X packages | Y vulnerabilities" line is absent).

func PrintHeadlineWithLabel added in v3.27.0

func PrintHeadlineWithLabel(report *SASTReport, label string)

PrintHeadlineWithLabel prints a bold findings headline using the scan family label supplied by the caller.

func PrintPrettySummary

func PrintPrettySummary(report *SASTReport, resultsOnly bool)

PrintPrettySummary prints a styled SAST findings table to stdout. If resultsOnly is true, stays silent when there are no findings.

func PrintPrettySummaryWithTitle added in v3.27.0

func PrintPrettySummaryWithTitle(report *SASTReport, resultsOnly bool, title string)

PrintPrettySummaryWithTitle prints a styled findings table with a caller supplied heading. Container/IaC/Secrets subcommands share the SAST engine but should not call their output "SAST".

func ResolveURL

func ResolveURL(registry string, ref RuleRef) string

ResolveURL builds the git clone URL from a registry base URL and rule reference.

func ResolvedFingerprints

func ResolvedFingerprints(oldLog *SARIFLog, newFindings []Finding) []string

ResolvedFingerprints returns fingerprints present in the old SARIF log but absent from the new findings. These represent resolved findings.

func WriteSARIF

func WriteSARIF(log *SARIFLog, path string) error

WriteSARIF serializes a SARIF log to the given file path.

Types

type BuildOptions added in v3.29.0

type BuildOptions struct {
	MaxDepth int
	Excludes []string

	// IgnoreGit, when true, skips the .git directory entirely. The default
	// is false: the secrets subcommand walks .git to surface credentials
	// that exist only in past commits.
	IgnoreGit bool

	// IgnoreGlobs is an additional set of glob patterns to exclude. The
	// patterns are matched against the relative path and the base name
	// (mirroring --exclude). The CLI's --ignore flag is wired into this
	// slice so that a single --ignore "fixtures/**" is enough.
	IgnoreGlobs []string

	// IgnoreBinaries, when true, skips binary files entirely. When false
	// (the default for the secrets subcommand), binary files are inspected
	// with strings + EXIF and the result is added to FileContents.
	IgnoreBinaries bool

	// GitHistory, when true, walks the git history at rootPath and adds
	// each file version to FileContents under the __git_history__/ prefix.
	// Requires that IgnoreGit be false; if both are set, IgnoreGit wins.
	GitHistory bool

	// GitHistoryMaxCommits caps the number of commits walked.
	GitHistoryMaxCommits int
	// GitHistoryMaxFiles caps the number of file versions emitted.
	GitHistoryMaxFiles int

	// RespectGitignore, when true, prunes files and directories matched by
	// .gitignore files. Defaults false for backwards compatibility; the
	// sast/secrets/containers/iac/cbom/aibom commands set it true unless the
	// user passes their --*-include-ignored override.
	RespectGitignore bool
}

BuildOptions controls how the filesystem is walked and how binary/git content is folded into the scan input. Zero-value options produce the legacy behaviour: text files only, no git history.

type CompileKey added in v3.87.0

type CompileKey struct {
	// ModulesDigest is a content hash over the module set, so an edited rule
	// pack on disk produces a different key without anyone having to notice
	// that it changed.
	ModulesDigest string
	// ShardCount is part of the key because the shard split determines which
	// modules compile together.
	ShardCount int
	// Kinds is the sorted, comma-joined kind filter, or "" for no filter.
	Kinds string
}

CompileKey identifies a compiled rule set. Any change to it is a different entry, which is what makes invalidation a lookup rather than a signal: changing --rule packs, toggling default rules or narrowing kinds all produce a different key, so the old entry is simply not found.

func (CompileKey) String added in v3.87.0

func (k CompileKey) String() string

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine compiles Rego modules and evaluates them against a filesystem scan.

func NewEngine

func NewEngine(modules map[string]string, scanRoot string) *Engine

NewEngine constructs an Engine with the given Rego modules.

func (*Engine) Evaluate

func (e *Engine) Evaluate(opts EvalOptions) (*SASTReport, error)

Evaluate runs all loaded Rego policies against the filesystem at scanRoot.

func (*Engine) ListRules

func (e *Engine) ListRules() ([]RuleMetadata, error)

ListRules extracts metadata from all loaded rule packages without running detection. Used for --list-default-rules.

type EvalOptions

type EvalOptions struct {
	MaxDepth int
	Excludes []string

	// IgnoreGit, IgnoreGlobs, IgnoreBinaries, GitHistory, etc. are
	// forwarded to BuildScanInputWithOptions / LoadFileContentsWithOptions
	// so the secrets subcommand can enable binary and history scanning
	// without affecting the generic scan command's behaviour.
	IgnoreGit            bool
	IgnoreGlobs          []string
	IgnoreBinaries       bool
	GitHistory           bool
	GitHistoryMaxCommits int
	GitHistoryMaxFiles   int
	MinStringLength      int

	// RespectGitignore prunes files/dirs matched by .gitignore. The
	// sast/secrets/containers/iac commands set it true by default; the
	// user opts out with --<mode>-include-ignored.
	RespectGitignore bool
}

EvalOptions configures the SAST evaluation.

type Finding

type Finding struct {
	RuleID      string        `json:"rule_id"`
	Message     string        `json:"message"`
	ArtifactURI string        `json:"artifact_uri"`
	Severity    string        `json:"severity"`
	Level       string        `json:"level"`
	StartLine   int           `json:"start_line"`
	EndLine     int           `json:"end_line,omitempty"`
	Snippet     string        `json:"snippet"`
	Fingerprint string        `json:"-"`
	Metadata    *RuleMetadata `json:"-"`

	// Test-suite attribution, set post-evaluation by internal/testsuite when the
	// finding's file belongs to the project's test suite. IsTestSuite drives the
	// SARIF `vulnetix/test-*` result properties and the typed wire fields.
	IsTestSuite        bool     `json:"-"`
	TestFramework      string   `json:"-"`
	TestLanguage       string   `json:"-"`
	TestConfidence     string   `json:"-"`
	TestMatchedPattern string   `json:"-"`
	TestEvidence       []string `json:"-"`
}

Finding is unmarshaled from each element of the Rego "findings" set. Detection fields (ArtifactURI, StartLine, Snippet) are set by Rego logic. Fingerprint and Metadata are set by the engine after evaluation.

type LoadContentsResult added in v3.88.0

type LoadContentsResult struct {
	// Loaded is the number of files whose content was read.
	Loaded int
	// SkippedTooLarge is the number of files over the per-file cap.
	SkippedTooLarge int
	// SkippedBinary is the number of binary files skipped entirely.
	SkippedBinary int
	// SkippedUnreadable is the number of files that could not be read.
	SkippedUnreadable int
	// TruncatedAtBudget is true when the aggregate byte budget was exhausted
	// and files were left unread as a result.
	TruncatedAtBudget bool
	// TotalBytes is how much file content was held.
	TotalBytes int64
}

LoadContentsResult reports what a content load actually managed to read.

"No findings" and "did not look" must never be indistinguishable, so a load that stopped early says so rather than leaving the caller to infer it from a suspiciously small map.

func LoadFileContentsBudgeted added in v3.88.0

func LoadFileContentsBudgeted(ctx context.Context, input *ScanInput, opts LoadOptions, maxTotalBytes int64) (LoadContentsResult, error)

LoadFileContentsBudgeted is LoadFileContentsWithOptions with an aggregate byte ceiling and cancellation.

LoadFileContentsWithOptions caps each file at MaxFileSize but nothing caps the total, so a repository with enough files below the per-file cap can allocate several gigabytes. A CLI process exits afterwards and nobody notices; a long-lived language server holding that is a memory leak with a filesystem as its source.

Files are loaded in sorted order so that the same repository truncates at the same point on every run, which keeps a truncated scan reproducible rather than dependent on map iteration order.

func (LoadContentsResult) Degradations added in v3.88.0

func (r LoadContentsResult) Degradations() []string

Degradations renders the result as human-readable notices, empty when the load was complete.

type LoadOptions added in v3.29.0

type LoadOptions struct {
	// MaxFileSize is the upper bound for any single file's text content
	// (raw or extracted). Files larger than this are skipped entirely.
	MaxFileSize int64
	// IgnoreBinaries, when true, skips binary files. When false (the
	// default for the secrets subcommand), binary files are inspected:
	// printable strings are extracted with the secretscan package and any
	// EXIF/IPTC/XMP metadata is added under __exif__/.
	IgnoreBinaries bool
	// MinStringLength is the minimum run length to surface when extracting
	// strings from binaries. Defaults to secretscan.StringMin (4).
	MinStringLength int
}

LoadOptions configures LoadFileContents. The MaxFileSize and IgnoreBinaries fields correspond directly to the CLI flags of the same name; MaxDepth and Excludes are not relevant here (the walker has already determined the set of files to consider).

type NosecHit added in v3.68.0

type NosecHit struct {
	File      string
	StartLine int
	EndLine   int
	RuleID    string
	Kind      string
	WholeFile bool
	Snippet   string
}

NosecHit records one finding that a nosec directive suppressed. It carries enough to mint/track an org suppression rule: the file + line span of the suppressed code, the rule id that was silenced, the rule Kind (so the caller can map it to a scanner category), whether a whole-file (line-1) directive did the suppressing, and the code snippet for drift tracking.

type PreparedSet added in v3.87.0

type PreparedSet struct {
	Key CompileKey

	// RuleCount is how many rule modules survived filtering. Reported so a
	// caller can tell "evaluated 140 rules" from "evaluated 1,232".
	RuleCount int
	// contains filtered or unexported fields
}

PreparedSet is a compiled and prepared rule set, ready to evaluate.

type RuleMetadata

type RuleMetadata struct {
	ID          string   `json:"id"`
	Name        string   `json:"name"`
	Description string   `json:"description"`
	HelpURI     string   `json:"help_uri"`
	Languages   []string `json:"languages"`
	Severity    string   `json:"severity"`
	Level       string   `json:"level"`
	Kind        string   `json:"kind"`
	CWE         []int    `json:"cwe"`
	CAPEC       []string `json:"capec"`
	ATTACKTech  []string `json:"attack_technique"`
	CVSSv4      string   `json:"cvssv4"`
	CWSS        string   `json:"cwss"`
	Tags        []string `json:"tags"`
}

RuleMetadata is unmarshaled from the Rego "metadata" constant object. Every field maps directly to the JSON keys used in the Rego policy.

func (*RuleMetadata) EffectiveLevel

func (m *RuleMetadata) EffectiveLevel() string

EffectiveLevel returns the SARIF level for a rule — the explicit level if set, otherwise derived from severity.

type RuleRef

type RuleRef struct {
	Org  string
	Repo string
}

RuleRef identifies an external rule repository by org and repo name.

func ParseRuleRef

func ParseRuleRef(arg string) (RuleRef, error)

ParseRuleRef parses a "org/repo" string from a --rule flag value.

type SARIFArtifact

type SARIFArtifact = sarif.Artifact

type SARIFArtifactLocation

type SARIFArtifactLocation = sarif.ArtifactLocation

type SARIFInvocation added in v3.65.0

type SARIFInvocation = sarif.Invocation

type SARIFLocation

type SARIFLocation = sarif.Location

type SARIFLog

type SARIFLog = sarif.Log

func BuildSARIF

func BuildSARIF(findings []Finding, rules []RuleMetadata, toolVersion string) *SARIFLog

BuildSARIF converts findings and rules into a SARIF 2.1.0 log.

func LoadExistingSARIF

func LoadExistingSARIF(path string) (*SARIFLog, error)

LoadExistingSARIF reads a SARIF log from disk. Returns nil if the file does not exist.

type SARIFMessage

type SARIFMessage = sarif.Message

type SARIFNotification added in v3.65.0

type SARIFNotification = sarif.Notification

type SARIFPhysicalLocation

type SARIFPhysicalLocation = sarif.PhysicalLocation

type SARIFPropertyBag

type SARIFPropertyBag = sarif.PropertyBag

type SARIFRegion

type SARIFRegion = sarif.Region

type SARIFReportingDescriptor

type SARIFReportingDescriptor = sarif.ReportingDescriptor

type SARIFResult

type SARIFResult = sarif.Result

type SARIFRun

type SARIFRun = sarif.Run

type SARIFSnippet

type SARIFSnippet = sarif.Snippet

type SARIFTool

type SARIFTool = sarif.Tool

type SARIFToolDriver

type SARIFToolDriver = sarif.ToolComponent

type SASTReport

type SASTReport struct {
	Findings    []Finding
	Rules       []RuleMetadata
	RulesLoaded int // rules after filtering (kind/id) that were evaluated
	RulesTotal  int // rules loaded pre-filter (builtin + --rule repos)
	// Degradations lists capabilities that ran reduced or not at all during
	// this evaluation ("couldn't verify X because Y"). They are surfaced as
	// SARIF toolExecutionNotifications so a report consumer can distinguish
	// "scanned clean" from "not fully scanned".
	Degradations []string
}

SASTReport holds the results of a SAST evaluation run.

type ScanInput

type ScanInput struct {
	// FileSet maps each relative file path to true for O(1) existence checks in Rego.
	FileSet map[string]bool `json:"file_set"`
	// DirsByLanguage maps language name to directories containing that language's indicator files.
	DirsByLanguage map[string][]string `json:"dirs_by_language"`
	// FileContents maps relative path to file text. Populated lazily for small files
	// when content-level rules are present. Files over MaxFileSize and binary files are
	// skipped unless binary inspection is enabled (see FileScanOptions).
	FileContents map[string]string `json:"file_contents,omitempty"`
	// ScanRoot is the absolute path being scanned (for display; rules use relative paths).
	ScanRoot string `json:"scan_root"`
}

ScanInput is serialized to JSON and passed as the OPA input document.

func BuildScanInput

func BuildScanInput(rootPath string, maxDepth int, excludes []string) (*ScanInput, error)

BuildScanInput walks the filesystem at rootPath and builds the OPA input document.

func BuildScanInputContext added in v3.88.0

func BuildScanInputContext(ctx context.Context, rootPath string, opts BuildOptions) (*ScanInput, error)

BuildScanInputContext is BuildScanInputWithOptions with cancellation.

filepath.WalkDir does not honour a context, so a workspace scan of a large repository cannot be interrupted: the walk runs to completion regardless of whether anyone still wants the answer. In a CLI that is invisible. In a language server it means a cancelled scan keeps a core busy, and a shutdown waits for a traversal nobody is reading.

Returns ctx.Err() when cancelled, so a caller can distinguish "cancelled" from "failed".

func BuildScanInputWithOptions added in v3.29.0

func BuildScanInputWithOptions(rootPath string, opts BuildOptions) (*ScanInput, error)

BuildScanInputWithOptions is the full-control entry point. It replaces BuildScanInput when the caller needs to enable binary or git-history inspection (the secrets subcommand does, the generic scan does not).

func Overlay added in v3.88.0

func Overlay(base *ScanInput, docs map[string]string) *ScanInput

Overlay returns a shallow copy of base whose FileContents holds exactly the documents in docs.

This is the keystroke path. A full BuildScanInput walk plus content load costs a filesystem traversal and a read of every file; on an edit only one file changed, and the editor already has its text, including the parts not yet written to disk.

FileSet and DirsByLanguage are shared with base rather than copied. Rules that ask whether a path exists, or which languages a directory contains, still see the whole repository, so a rule keyed on "there is a Dockerfile here" behaves the same as in a full scan. Both maps are treated as read-only by evaluation, and a prepared query evaluates concurrently against them.

Known limitation, and the reason this is not used on every trigger: a rule that correlates the contents of two files sees only the overlaid ones, so it can under-report. The corpus is per-file today (rules iterate input.file_contents and examine one entry at a time), but nothing structurally enforces that. Save and workspace scans therefore evaluate real content, and overlay is confined to the path where latency actually matters.

func OverlayOnto added in v3.88.0

func OverlayOnto(base *ScanInput, docs map[string]string) *ScanInput

OverlayOnto returns a copy of base with docs merged over its existing contents, rather than replacing them.

Used on save, where the point is to evaluate the whole repository with the editor's version of the dirty buffers in place of what is on disk.

type Session added in v3.87.0

type Session struct {
	// contains filtered or unexported fields
}

Session holds compiled, prepared rule sets across evaluations.

Engine.Evaluate compiles fresh on every call: evalModules calls compileModules per shard, per invocation, so Engine.compileOnce is dead on the sharded path. For a process that runs once and exits that is fine. For the language server, which evaluates on every keystroke, it is the difference between usable and not.

Two changes carry it, and both were measured before being built (see session_bench_test.go):

  • Cache the compiled shards, keyed by CompileKey. Compiling all 1,899 embedded modules costs 1.72s in one compiler, 0.30s across 16 shards. Note that this is roughly 50x cheaper than the ~85s the comment at the top of engine.go claims; that comment is stale.
  • Prepare each shard's query once with rego.PrepareForEval rather than building a fresh rego.New(...).Eval per call. Preparation costs 7.5ms and a prepared query is safe to Eval concurrently from many goroutines against different inputs, which TestPreparedQueryConcurrentEvalParity proves under -race.

The larger lever is not caching at all, it is what you choose to evaluate. Warm evaluation costs ~59ms per file across the whole corpus, and 92% of that is the 1,092 secrets rules, which declare no languages and so survive every language filter while each iterating every file. Against sast+iac+oci alone a single file costs 10.4ms rather than 231ms. Callers express that with Kinds; the language server passes InteractiveKinds on keystroke and all kinds on save.

A Session is safe for concurrent use. The zero value is ready.

func (*Session) CachedSets added in v3.87.0

func (s *Session) CachedSets() int

CachedSets reports how many distinct rule sets are held. Each one retains a compiled OPA program, so this is the number that matters for memory.

func (*Session) Compiles added in v3.87.0

func (s *Session) Compiles() int64

Compiles reports how many times this session actually compiled rather than serving a cached set. Test instrumentation.

func (*Session) Eval added in v3.87.0

func (s *Session) Eval(ctx context.Context, set *PreparedSet, input *ScanInput) (*SASTReport, error)

Eval runs a prepared set against an input and returns the union of findings.

The input is not copied and is only read, so the same *ScanInput may be evaluated by several sessions or shards at once.

func (*Session) Evict added in v3.87.0

func (s *Session) Evict()

Evict drops every cached set. The language server calls this when the rule configuration changes in a way that is not captured by the digest, and when memory needs reclaiming.

func (*Session) Prepare added in v3.87.0

func (s *Session) Prepare(ctx context.Context, modules map[string]string, kinds []string) (*PreparedSet, error)

Prepare compiles and prepares `modules`, restricted to `kinds`, or returns the cached result of having done so.

kinds is a rule-kind filter; nil or empty means every kind. Shared library modules are always retained regardless of the filter, because OPA compiles every module together and dropping a dependency of a kept rule fails the whole evaluation.

Concurrent callers asking for the same key block on the first rather than each compiling their own copy: on a cold start with several open documents that is the difference between one compile and one per document.

func (*Session) Run added in v3.87.0

func (s *Session) Run(ctx context.Context, modules map[string]string, kinds []string, input *ScanInput) (*SASTReport, error)

Run prepares and evaluates in one call, which is what most callers want.

Directories

Path Synopsis
Command secretsgen renders the high-fidelity secret-detection rule set and its documentation from a single source of truth: catalog.json.
Command secretsgen renders the high-fidelity secret-detection rule set and its documentation from a single source of truth: catalog.json.

Jump to

Keyboard shortcuts

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