Architecture Overview¶
ts-sast is a small command line utility in Python that drives static analysis engines, called backends, and assembles their findings into one SARIF log with a TrustSource header. It does not contain an analysis engine of its own; the value is in the rule packs, the conventions and the integration.
System Components¶
- CLI (
ts_sast.cli): the click based command set, config and profile handling. Modelled on ts-scan's CLI so that the tools behave alike. - Backends (
ts_sast.backend,ts_sast.devskim): a backend wraps one analysis engine. It contributes--<name>:executable,--<name>:forwardand--<name>:ignoreoptions exactly like a package manager scanner in ts-scan, runs its executable, and returns one SARIFrun. The first backend is DevSkim. - Rule packs (
ts_sast/rules/devskim/): DevSkim's language and comment definitions extended with VB6, and the rule files. They are package data and travel with the wheel, so a scan needs no checkout of this repository. - SARIF assembly (
ts_sast.sarif,ts_sast.SastScan): concatenates the runs, stamps the ts-scan compatible header into each run's property bag and renders the text summary.
What the scan can and cannot see¶
DevSkim matches regular expressions against code, with comments stripped and with conditions that look at surrounding lines. That is enough to find dangerous API usage, hard-coded secrets, disabled security controls and references to retired components, and it runs in seconds on any code base. It cannot tell whether the string passed to Shell came from a text box or from a constant. The rule descriptions are written so that a reviewer knows what to check at each finding.
The semantic analyser planned as the second backend closes exactly that gap for VB6: it parses the code into a semantic graph and follows data from sources to sinks, so that a finding carries the path that makes it exploitable. When it arrives, ts-sast scan will run both backends and the SARIF will contain two runs per module, one per backend.
Architecture Decision Records¶
ADR-001 - ts-sast is a separate tool, not a ts-scan option (2026-09-06, 0.1.0)¶
Context. The DevSkim rule pack and the demo application were first drafted inside ts-scan next to the VB6 project scanner. The ts-scan maintainer had just rejected the OBOM extraction on the grounds that it is not software composition analysis and would confuse customers; the same reasoning applies to static analysis, and it adds a .NET dependency that an SBOM pipeline must not be burdened with.
Decision. Move the static analysis assets into their own repository and package, ts-sast, following ts-scan's CLI conventions, packaging and site structure. ts-scan keeps only what improves the SBOM (the VB6 component catalogue and the implicit runtime).
Consequences. Three tools with one set of conventions: ts-scan for SBOM, ts-obom for access rights, ts-sast for code findings. Each installs only what it needs. The price is a third repository and a third pipeline step.
ADR-002 - DevSkim as the first backend, rule packs as package data (2026-09-06, 0.1.0)¶
Context. No open source static analyser supports classic VB6. DevSkim's language list and rules are plain JSON, it produces SARIF, and it runs wherever the .NET SDK runs. A semantic analyser is months away; something useful is needed now.
Decision. Wrap DevSkim as a backend and ship the VB6 language definition and rule pack inside the Python package. Keep DevSkim's default rules active; where a ts-sast rule overlaps, declare overrides. Every rule carries self-tests that CI verifies.
Consequences. A working VB6 scan today with no engine to maintain. The dependency on the .NET SDK is accepted and hidden in the Docker image. Two DevSkim details constrain rule authoring and are documented in the rules guide: the spelling of severities and the behaviour of rules with conditions.
ADR-003 - SARIF is the result format; the TrustSource header lives in the run's property bag (2026-09-06, 0.1.0)¶
Context. Findings have an established interchange format that the platform, code hosting services and IDEs read. ts-scan's results carry a module header that the platform uses for correlation.
Decision. Emit SARIF 2.1 unchanged from the backend and add the ts-scan style header (module, moduleId, source, tag, branch, backend, tool) under properties["ts-sast"] of each run, plus an automationDetails.id. Offer text only as a convenience rendering of the same log.
Consequences. Every SARIF consumer works without adapters; the platform can join findings to SBOM modules by moduleId. No second result format to maintain.
ADR-004 - Environment variable prefix TS_SAST_ instead of ts-scan's TS_ (2026-09-06, 0.1.0)¶
Context. click derives environment variable names from the command and option names. With ts-scan's prefix, ts-sast scan --output and ts-scan scan --output would both read TS_SCAN_OUTPUT_PATH.
Decision. Use TS_SAST_ as the prefix, as ts-obom uses TS_OBOM_.
Consequences. All three tools can be configured in the same CI job without interference, at the cost of one small deviation from ts-scan's conventions.
ADR-005 - Backends are processes, not libraries (2026-09-06, 0.1.0)¶
Context. DevSkim is a .NET program; the planned semantic analyser will be a Java program built on an MIT licensed parser. Neither can be imported into Python, and linking would tie the licence of ts-sast to theirs.
Decision. A backend is an executable that ts-sast starts, feeds paths and rule locations, and reads SARIF from. The Python side stays Apache-2.0 and thin.
Consequences. Backends can be written in whatever language suits them and released on their own cadence. The Docker image is where the executables are bundled and is therefore the recommended way to run ts-sast; a bare pip install needs the backend installed separately, which the setup guide explains.
Further development¶
Backlog, in rough order:
- Semantic VB6 backend. The analyser described in the ProLeap concept paper: parser based, data-flow aware, SARIF with code flows. Enters as a second backend behind
--vb6analyzer:...options. - Upload to the TrustSource platform once the platform accepts SARIF; the header in the run property bag is prepared for it.
- Rule packs for VBA (Office macros share VB6's language and runtime library) and for classic ASP / VBScript.
- SARIF fingerprints (
partialFingerprints) so that findings keep their identity across scans and suppressions survive line shifts.