risk

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package risk provides a rule-based engine for detecting dangerous SQL patterns by inspecting the AST produced by the CockroachDB parser.

The engine is organized around three concepts:

  • Rule: a named check that inspects a single parsed statement and returns zero or more findings. Each rule has a severity, reason code, and category.
  • Registry: an ordered collection of rules. Its Analyze method parses a SQL string and runs every rule against every statement.
  • Finding: a single risk detected in a SQL statement, carrying a machine-readable reason code, human-readable message, position within the input, and a fix hint.

Callers that want the built-in rule set can use the package-level Analyze function, which delegates to DefaultRules().

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CheckInput

type CheckInput struct {
	AST      tree.Statement
	StmtSQL  string
	Position Position
}

CheckInput is the context passed to a rule's check function for a single parsed statement.

type Finding

type Finding struct {
	ReasonCode string    `json:"reason_code"`
	Severity   Severity  `json:"severity"`
	Message    string    `json:"message"`
	Position   *Position `json:"position,omitempty"`
	FixHint    string    `json:"fix_hint"`
}

Finding is a single risk detected by a rule. The struct is the JSON-serializable shape embedded in both the CLI envelope's Data field and the MCP tool result.

func Analyze

func Analyze(sql string) ([]Finding, error)

Analyze is a convenience function that runs the default rule set against sql. It is equivalent to NewRegistry(DefaultRules(), DefaultMultiRules()).Analyze(sql).

func AnalyzeParsed

func AnalyzeParsed(stmts statements.Statements, sql string) []Finding

AnalyzeParsed is a convenience function that runs the default rule set against already-parsed statements. It is equivalent to NewRegistry(DefaultRules(), DefaultMultiRules()).AnalyzeParsed(stmts, sql).

type MultiCheckInput

type MultiCheckInput struct {
	Stmts     statements.Statements
	Positions []Position
}

MultiCheckInput is the context passed to a multi-statement rule's check function. Stmts is the full parsed statement list for the SQL passed to Analyze; Positions[i] is the location of Stmts[i] within the original SQL. The two slices have the same length and are indexed in parallel.

type MultiRule

type MultiRule struct {
	ReasonCode string
	Severity   Severity
	Category   string
	Check      func(input MultiCheckInput) []Finding
}

MultiRule defines a risk detection rule that needs to look across more than one parsed statement at a time (e.g. spotting multiple DDL statements inside a single explicit BEGIN..COMMIT block). The Check function is invoked once per Analyze call with the full statement list and returns any findings; it is expected to return nil when the input does not contain anything relevant.

func DefaultMultiRules

func DefaultMultiRules() []MultiRule

DefaultMultiRules returns the built-in set of AST-only risk rules that need to look across more than one parsed statement at a time.

type Position

type Position struct {
	Line       int `json:"line"`
	Column     int `json:"column"`
	ByteOffset int `json:"byte_offset"`
}

Position identifies a location within the original SQL input. Line and Column are 1-based; ByteOffset is 0-based.

type Registry

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

Registry holds an ordered set of per-statement rules and an ordered set of multi-statement rules, and runs them against parsed SQL. Built by NewRegistry and immutable afterward; rule evaluation order matches the order provided to the constructor (per-statement rules run first, in registration order, for each statement; multi-rules run afterward, in registration order, once per Analyze call).

func NewRegistry

func NewRegistry(rules []Rule, multiRules []MultiRule) *Registry

NewRegistry creates a registry from the given per-statement rules and multi-statement rules. Either slice may be nil. Rules are evaluated in the order provided: per-statement rules in registration order for each statement, then multi-statement rules in registration order once per Analyze call. It panics if any rule has a nil Check function, an empty ReasonCode, or a ReasonCode that duplicates any other registered rule (across both slices).

func (*Registry) Analyze

func (r *Registry) Analyze(sql string) ([]Finding, error)

Analyze parses sql and applies every registered rule. Per-statement rules run first, in statement order, with rules evaluated in registration order within each statement; multi-statement rules run afterward, in registration order, each invoked once over the full statement list. Findings are returned in production order, so all per-statement findings precede all multi-statement findings. The registry stamps each finding's ReasonCode and Severity from the rule that produced it, so individual rules only need to set Message, Position, and FixHint.

func (*Registry) AnalyzeParsed

func (r *Registry) AnalyzeParsed(stmts statements.Statements, sql string) []Finding

AnalyzeParsed runs every registered rule against already-parsed statements. sql is the original source text — required for positionFromSQL to locate each statement's line/column. Exposed so callers that already invoked parser.Parse (e.g. to also run version.Inspect on the same AST) can reuse the parsed output rather than reparsing. Returns no error: parsing happened upstream.

type Rule

type Rule struct {
	ReasonCode string
	Severity   Severity
	Category   string
	Check      func(input CheckInput) []Finding
}

Rule defines an AST-only risk detection rule. The Check function inspects a single parsed statement and returns any findings. Rules are expected to return nil when the statement is not relevant (e.g. a DELETE rule receiving a SELECT AST).

func DefaultRules

func DefaultRules() []Rule

DefaultRules returns the built-in set of AST-only risk rules that inspect a single statement at a time.

type Severity

type Severity string

Severity classifies the urgency of a finding. Values are ordered from most to least urgent and are part of the wire format — renaming or reordering them is a breaking change.

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

Severity constants, ordered from most to least urgent.

Jump to

Keyboard shortcuts

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