security

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package security loads security risk pattern annotations from a YAML file and converts them into NodeSecurityPattern + EdgeHasSecurityPattern rows that fold into the main CKG graph.

Where pkg/policy answers "why does this code exist?" (governance, fork blocks, gas schedules), pkg/security answers "what could go wrong with this code?" — the curated list of reentrancy candidates, access-control gaps, Byzantine attack surfaces, integer overflow hotspots that domain experts have flagged. An LLM modifying a listed symbol sees the risk surface as part of the retrieval envelope instead of having to run a separate static analyser (slither / mythril / semgrep) and reconcile its findings.

See docs/PROJECT-BLUEPRINT-ALIGNMENT.md §4.2 P1 #5 for the design intent. The MVP is purely YAML-driven (operators curate the matches[] list); automated pattern detection (slither-style flow rules) is deferred to a follow-up — the data model here is the same either way.

Schema

The YAML envelope:

security_patterns:
  - id: "reentrancy.external_call_after_state_change"
    name: "Reentrancy: external call after state change"
    category: "reentrancy"        # reentrancy | access-control | byzantine | overflow | …
    severity: "high"              # info | low | medium | high | critical
    description: "..."
    remediation: "..."            # optional fix guidance
    matches:                      # qnames of code symbols this pattern applies to
      - "Vault.withdraw"
      - "Token.transfer"

Every SecurityPattern node carries id → QualifiedName, name → Name, category → SubKind, description + remediation → DocComment. severity rides in the Signature field as "severity=<level>" so search snippets and post-filter ordering can use it without touching the attrs JSON blob.

Index

Constants

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

Severity levels. Mirror the conventional ranking used by Slither, Semgrep, CodeQL et al. so consumers familiar with those tools can map findings directly without an enum translation layer.

Variables

This section is empty.

Functions

This section is empty.

Types

type Entry

type Entry struct {
	ID          string   `yaml:"id" json:"id"`
	Name        string   `yaml:"name" json:"name"`
	Category    string   `yaml:"category,omitempty" json:"category,omitempty"`
	Severity    string   `yaml:"severity,omitempty" json:"severity,omitempty"`
	Description string   `yaml:"description,omitempty" json:"description,omitempty"`
	Remediation string   `yaml:"remediation,omitempty" json:"remediation,omitempty"`
	Matches     []string `yaml:"matches,omitempty" json:"matches,omitempty"`
}

Entry is one security pattern row from the YAML file.

type File

type File struct {
	SecurityPatterns []Entry `yaml:"security_patterns"`
}

File is the top-level YAML envelope. The single-key envelope mirrors pkg/policy.File — explicit, editor-friendly, room to grow envelope- level metadata (source-of-truth URL, last-reviewed date) without breaking existing consumers.

func LoadFromFile

func LoadFromFile(path string) (*File, error)

LoadFromFile reads, parses, and validates a security pattern YAML. Hard errors:

  • I/O / parse failure (wrapped underlying error)
  • Empty id (would collide on the SecurityPattern node PK)
  • Duplicate id (same collision)
  • Severity outside the closed enum (loose strings would let typos past the boundary and surface as silent under/over-counts in downstream "severity ≥ high" filters)

Empty / absent security_patterns key is NOT an error; the result has zero entries — useful when an operator wants to land the file before populating it.

type ResolveResult

type ResolveResult struct {
	Nodes    []types.Node
	Edges    []types.Edge
	Warnings []ResolveWarning
}

ResolveResult bundles the rows Resolve produced and any matching warnings (matches[] qnames that found no code node).

func Resolve

func Resolve(f *File, codeNodes []types.Node, yamlPath string) ResolveResult

Resolve builds NodeSecurityPattern nodes + EdgeHasSecurityPattern edges to fold into the main graph.

  • One NodeSecurityPattern per entry. QualifiedName = ID, Name = Name, SubKind = Category. DocComment merges Description and Remediation (blank line between them when both are present).
  • One EdgeHasSecurityPattern per (matched qname, pattern) pair. Direction = at-risk code symbol → pattern node so the natural query "what risks does X exhibit?" is a single FK lookup.

O(P + N) overall: a single qname → id index built from codeNodes drives the matches[] hot loop. Missing references emit a ResolveWarning rather than failing — security annotation is strictly additive metadata.

type ResolveWarning

type ResolveWarning struct {
	PatternID string
	TargetRef string
	Reason    string
}

ResolveWarning records a matches[] entry that didn't find a target in the parsed graph. Surfaced verbatim so editors of the YAML can spot stale references (renamed functions, moved fields).

Jump to

Keyboard shortcuts

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