Skip to content

Threat-model pipeline: extend entry-point queries to Go CLIs (cobra) and other non-HTTP shapes #262

Description

@mlieberman85

Summary

The tree-sitter discovery pipeline currently produces empty threat models for projects that aren't web services. The Go query set in particular only matches HTTP routing patterns (net/http, chi, gorilla) plus sql.Open, so any Go CLI tool — even sizable ones — comes back with zero entry points discovered.

Motivating example: gittuf/gittuf

Cold audit (2026-05-17, gittuf @ main):

  • 284 in-scope Go files scanned across 267 .go sources
  • 0 entry points discovered — pipeline emits "0 classes, 0 findings"
  • gittuf is a cobra-based CLI: 42 func New() *cobra.Command constructors, 83 files with &cobra.Command{...} literals, 0 HTTP routes
  • darnit's existing Go query (go.entry.selector_string_arg) requires the call-object to be http or to come from a known HTTP routing import — neither holds for cobra command construction

The resulting THREAT_MODEL.md is structurally complete but content-empty, which is misleading.

Why this matters

  • darnit-baseline control OSPS-SA-03.02 (Threat model documentation) is one of our flagship auto-remediations. For non-web-service projects it produces an empty file.
  • Go is one of two languages we list as supported in tree-sitter coverage.
  • The "demo gap" is real: any conference/customer demo against a Go CLI today underdelivers.

Suggested approach

Phase 1 — cobra (the most common Go CLI framework):

  • Add EntryPointKind.CLI_COMMAND to discovery_models.py
  • New tree-sitter query: cobra command construction — match &cobra.Command{Use: "...", RunE/Run: ...} composite literals
  • New tree-sitter query: func New() *cobra.Command declarations as a coarse fallback
  • Wire into _extract_go_entry_points in ts_discovery.py alongside the existing HTTP path
  • Coalesce sibling subcommands in grouping.py (gittuf has 42 commands; without coalescing the output is noisy)
  • Update threat-rendering wording in ts_generators.py so STRIDE narratives read sensibly for CLI threats (the current text is HTTP-centric)
  • Tests: extend test_ts_discovery.py and test_ts_generators.py with cobra fixtures

Phase 2 — broaden to other CLI frameworks (urfave/cli, kingpin) and other non-HTTP Go shapes (gRPC servers, message handlers).

Effort estimate

  • Phase 1: ~3.5–5 engineering days incl. tests. The Go AST is more verbose than Python's, and ranking/grouping has web-app assumptions baked in that need to be unwound.
  • Phase 2: ~2–3 additional days.

Acceptance

  • gittuf cold-audit produces a non-empty docs/threatmodel/SUMMARY.md with at least one finding per major command family (cache, attest, rsl, verify, etc.).
  • No regression on existing Python or Go-HTTP test fixtures.
  • Output is presentation-quality on stage (no "0 findings" for any recognized shape).

Related

  • Coverage gap is documented in README.md ("Threat-model coverage scope" section) — see PR for that addition.
  • Tracks alongside any broader Go threat-model query expansion needed for projects in similar shapes (cosign, slsa-verifier, etc.).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions