Documentation
¶
Overview ¶
Package api is the public, library-shaped surface of Semantic Firewall. The CLI in cmd/sfw and the MCP server in the sibling semantic_firewall_mcp repo both consume it; everything in internal/cli is implementation glue that orchestrates flag parsing and process boundaries on top of the entry points defined here.
The entry points return the same JSON-serialisable types from pkg/models that the CLI prints, so callers can either marshal them directly or inspect the structured values in-process.
Index ¶
- func CalculateTopologyDelta(oldT, newT *topology.FunctionTopology) (string, int)
- func CompareFunctions(funcName string, oldResult, newResult diff.FingerprintResult) models.FunctionDiff
- func DepsDiff(oldDir, newDir string) (*models.DepsDiffOutput, error)
- func Diff(oldPath, newPath string) (*models.DiffOutput, error)
- func DiffBatch(pairs []DiffPair) []*models.DiffOutput
- func DiffBatchWithFS(fsys FileSystem, pairs []DiffPair) []*models.DiffOutput
- func DiffBatchWithOptions(fsys FileSystem, pairs []DiffPair, opts BatchOptions) []*models.DiffOutput
- func DiffWithFS(fsys FileSystem, oldPath, newPath string) (*models.DiffOutput, error)
- func FingerprintFiles(fsys FileSystem, paths []string, strict bool) map[string]FileFingerprints
- func ResultName(r diff.FingerprintResult) string
- func SSAFunctionName(fn *ssa.Function) string
- func ShortFunctionName(fullName string) string
- type BatchOptions
- type DiffPair
- type FileFingerprints
- type FileSystem
- type RealFileSystem
- func (RealFileSystem) Abs(path string) (string, error)
- func (RealFileSystem) Getwd() (string, error)
- func (RealFileSystem) Open(name string) (fs.File, error)
- func (RealFileSystem) ReadFile(name string) ([]byte, error)
- func (RealFileSystem) Stat(name string) (os.FileInfo, error)
- func (RealFileSystem) WalkDir(root string, fn fs.WalkDirFunc) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CalculateTopologyDelta ¶
func CalculateTopologyDelta(oldT, newT *topology.FunctionTopology) (string, int)
CalculateTopologyDelta diffs two function topologies and returns the topology_delta and risk_score Diff reports for the change. A nil oldT means the function was added, a nil newT that it was removed. Newly reached capabilities (process execution, raw syscalls, plugins, network, reflective invocation, filesystem mutation), new goroutines, obfuscation and the deletion signals each reach models.RiskScoreHigh on their own; ordinary call, loop and branch churn is capped below it. Removing structure is neutral, except a check.
func CompareFunctions ¶
func CompareFunctions(funcName string, oldResult, newResult diff.FingerprintResult) models.FunctionDiff
CompareFunctions reduces two FingerprintResult values to a FunctionDiff. A function is preserved only when its canonical IR is unchanged with every literal kept: the default fingerprint masks strings and larger integers, so on its own it would report a changed URL, command, size limit or permission mode as preserved. Any other function is modified; the Zipper only supplies the instruction-level evidence. Its alignment is driven by data flow, so it must not decide the status: a swapped branch or a call moved out of its guard aligns completely.
func DepsDiff ¶
func DepsDiff(oldDir, newDir string) (*models.DepsDiffOutput, error)
DepsDiff compares the third-party code compiled into the module rooted at oldDir with that compiled into the module rooted at newDir. Both trees are loaded with the hardened loader environment (GOPROXY=off), so every module either build needs must already be in the module cache.
A module is compared when its version or replacement differs between the trees, or when its code can change without either: replaced by a local directory, a module of the go.work that governs the tree (the go command builds with it; see diff.WorkspaceFile), or vendored (a tree with vendor/modules.txt is loaded from its vendor directory, as the go command builds it). For each such module the diff reports changed functions (paired and scored as in Diff), exported functions and package initializers that newly reach a capability class, and changes to files the analysis cannot see. Modules only in the new tree, and packages the new tree newly builds from an unchanged module, are reported with the capability classes their exported functions and initializers can reach.
func Diff ¶
func Diff(oldPath, newPath string) (*models.DiffOutput, error)
Diff is the convenience entry point: it computes a semantic diff between two on-disk Go source files using the real filesystem. Either path may be empty or non-existent to represent an added or removed file.
func DiffBatch ¶
func DiffBatch(pairs []DiffPair) []*models.DiffOutput
DiffBatch diffs every pair and returns one result per pair, in order. Each result is what Diff(pair.Old, pair.New) returns; a pair Diff would fail on has the error in its ErrorMessage and no functions.
The files of each side are loaded together: all files under one module root, governed by the same go.work, take one go/packages call, so a package and its import graph are loaded once however many of its files are diffed. A file outside any module, a file the module's default build leaves out, a file of a package that does not type-check, and every file of a group whose load or SSA build fails are loaded on their own, exactly as Diff loads them.
func DiffBatchWithFS ¶
func DiffBatchWithFS(fsys FileSystem, pairs []DiffPair) []*models.DiffOutput
DiffBatchWithFS is DiffBatch against the supplied FileSystem. With any FileSystem but RealFileSystem, each file is loaded on its own, so each result is what DiffWithFS returns for its pair.
func DiffBatchWithOptions ¶ added in v7.4.0
func DiffBatchWithOptions(fsys FileSystem, pairs []DiffPair, opts BatchOptions) []*models.DiffOutput
DiffBatchWithOptions is DiffBatchWithFS with opts.
func DiffWithFS ¶
func DiffWithFS(fsys FileSystem, oldPath, newPath string) (*models.DiffOutput, error)
DiffWithFS performs a semantic diff against the supplied FileSystem so tests can drive the pipeline without touching disk. Behaviour is identical to Diff otherwise.
func FingerprintFiles ¶
func FingerprintFiles(fsys FileSystem, paths []string, strict bool) map[string]FileFingerprints
FingerprintFiles fingerprints the functions declared in each file at paths. The result has one entry per distinct path, keyed by the path as given. Each entry is what a load of that file alone gives: its functions and its package's initializer, not its package siblings', or the error that load fails with. Unlike DiffBatch's inputs, every path must name a file: an empty path, a missing file, a file with only whitespace, a file over models.MaxSourceFileSize and a path that cannot be resolved are errors. Results is nil or empty when Err is set.
With RealFileSystem, files are loaded as DiffBatch loads them: all files under one module root and governed by the same go.work with one go/packages call, so a package is loaded and canonicalized once however many of its files are listed, and the results of one package share their SSA functions. Any other FileSystem, every file the grouped load cannot cover (outside a module, excluded by the default build, in an ill-typed package), and every file of a group whose load or fingerprinting fails, is loaded on its own.
With strict, an SSA instruction the canonicalizer does not handle fails the file ("panic while fingerprinting <path>: STRICT MODE: ...") instead of rendering as a placeholder. A panic in the FileSystem fails its file too.
func ResultName ¶
func ResultName(r diff.FingerprintResult) string
ResultName is the name reported for a fingerprinted function: its SSAFunctionName, or ShortFunctionName of its full name when the result carries no SSA function.
func SSAFunctionName ¶
SSAFunctionName returns fn's name relative to its own package: "F", "(*T).M", "F$1". Unlike ShortFunctionName it does not have to guess where the package path ends, so a package whose last path element contains a dot ("gopkg.in/yaml.v3", "example.com/lib.v2") is stripped completely.
func ShortFunctionName ¶
ShortFunctionName strips package paths and qualifying identifiers from a Go SSA function name so it is readable in diffs and reports. Given only the string, it takes the text up to the first dot after the last slash as the package name; prefer SSAFunctionName when the function is at hand.
It handles three shapes:
- "fmt.Println" -> "Println"
- "pkg.(*Type).Method" / "(*pkg.Type).Method" -> "(*Type).Method"
- Generics like "pkg.Func[a/b.T]" -> "Func[a/b.T]"
Brackets and parens are tracked so qualified types inside generic parameters or receiver positions are preserved verbatim.
Types ¶
type BatchOptions ¶ added in v7.4.0
type BatchOptions struct {
// NonGo has a pair with no Go file on either side reported by what the
// build makes of the file (see nonGoDiff), rather than loaded as Go.
NonGo bool
}
BatchOptions adjusts DiffBatchWithOptions.
type DiffPair ¶
DiffPair names the two versions of one file. An empty path, a missing or empty file, or /dev/null stands for the absent side of an added or removed file, as in Diff.
type FileFingerprints ¶
type FileFingerprints struct {
Results []diff.FingerprintResult
Err error
// contains filtered or unexported fields
}
FileFingerprints is one file's fingerprinted functions, or why there are none.
type FileSystem ¶
type FileSystem interface {
Stat(name string) (os.FileInfo, error)
Open(name string) (fs.File, error)
Getwd() (string, error)
Abs(path string) (string, error)
WalkDir(root string, fn fs.WalkDirFunc) error
ReadFile(name string) ([]byte, error)
}
FileSystem abstracts the OS file operations the analysis pipeline needs. Production code uses RealFileSystem; tests can substitute a mock to drive the pipeline without touching disk.
type RealFileSystem ¶
type RealFileSystem struct{}
RealFileSystem is the production FileSystem implementation backed by the os and filepath packages. ReadFile bounds the read at models.MaxSourceFileSize so a hostile/oversize input cannot exhaust memory.
func (RealFileSystem) Getwd ¶
func (RealFileSystem) Getwd() (string, error)
func (RealFileSystem) WalkDir ¶
func (RealFileSystem) WalkDir(root string, fn fs.WalkDirFunc) error