Catch a File Your Build Added That Nobody Wrote
Your source is clean, every review passed, and the release carries a signature from your own build server. There is still a file in it that came from none of that.
Name what went into the build. Vigilance shows what came out that no input explains. It answers on the first run, with no earlier release to compare to.
The Attack That Leaves No Trace to Compare
An attacker does not touch your code. They get onto the machine that builds it, and they change the output after the compiler reads the source. Your repository stays clean. Every review passes. The release is signed, and the signature is genuine, because your own build server signed it.
SolarWinds worked this way in 2020, and the XcodeGhost compiler did in 2015. Ken Thompson described the same idea in 1984.
Why a Normal Check Cannot Answer It
Almost every tool compares a thing to an earlier copy of itself. That works well, and it is what Vigilance does the rest of the time.
A planted file has no earlier copy. It is in no commit, so a code review never sees it. It is in no previous release, so a version-to-version compare has nothing to hold it against.
A first run has no history. A tool that only compares gives no verdict at all on the day you first run it, which is the day you most want one.
The signature proves the wrong thing. A signature says the build server produced this file. That is exactly what the attacker wanted it to say.
Ask a Question That Needs No History
A build already knows what went in, which a folder on a laptop never does. So it can answer a better question than "has this changed": which file in the output does no input explain?
Record what goes in, record what comes out, then ask.
vigi record --step source --dir ./src --out source.json vigi record --step artifact --dir ./dist --out artifact.json vigi check --target artifact.json --cause source.json
On a build with a planted file, that prints:
HEADS UP 1 file can do things nothing upstream explains. 0 more arrived that can do nothing.
telemetry.js
Nothing upstream explains it.
It downloads from the internet and profiles this machine and its user.
note: no --previous given, so entry point changes were not reported
It exits 1, so the pipeline you already have stops the release. No earlier version was needed, and nothing had to be known about this attack in advance.
What It Compares
| Question | Code review and signing | Vigilance build check |
|---|---|---|
| Catches a bad change in your source | Yes | Yes |
| Catches a file added after the source was read | No | Yes |
| Works on the very first run | Not applicable | Yes |
| Needs an earlier release to compare against | Often | No |
| Needs the attack to be known first | Yes, for a scanner | No |
| Needs an agent on the build server | Sometimes | No, one file |
| Says what the planted file can do | No | Yes, it shows the capabilities |
A Build Makes Files on Purpose
Most builds produce files nobody typed: compiled output, generated code, vendored dependencies, assets. Vigilance does not guess about those. You record each step that makes files, and each one becomes a named cause.
vigi record --step source --dir ./src --out source.json vigi record --step generated --dir ./gen --out generated.json vigi record --step vendor --dir ./vendor --out vendor.json vigi record --step artifact --dir ./dist --out artifact.json vigi check --target artifact.json --cause source.json --cause generated.json --cause vendor.json
A file is reported only when no recorded step accounts for it. Record every step you run, and a quiet answer means something.
Known Risk versus New Risk
A bug or a bad package someone already reported, with a name and a number. Most tools work here.
A file your build produced that no input explains, on the day it ships, that no report covers yet. Vigilance works here.
Where This Sits
The build check answers one question at one moment. The rest of Vigilance watches what you install and what you already run. Same binary, no extra install.
See who runs it, attack case studies, or the file integrity check for the machines you already look after.
Common Questions
What Is a Build Server Attack?
An attacker gets onto the machine that compiles your software and changes the output after the compiler reads the source. The source stays clean, every review passes, and the signature on the release is genuine, because your own build server signed it. SolarWinds in 2020 worked this way.
Why Can a Normal Scan Not Catch It?
Almost every tool compares a thing to an earlier copy of itself. A payload planted during the build is in no commit and in no earlier release, so there is nothing to compare it against. On a first run there is no history, so most tools give no verdict at all.
How Does Vigilance Answer With No History?
A build already knows what went in. Vigilance records each input and the output, then reports which file in the output no input explains. That question needs no earlier release, so it answers on the very first run.
Does This Need an Agent on the Build Server?
No. Vigilance is one file with no service and no server. It runs as a step in the pipeline you already have and exits with a code your pipeline reads.
What If the Build Legitimately Generates Files?
Record every step that produces files, including the ones after the source. Generated code, vendored dependencies and assets each become a named cause. A file is only reported when no recorded step accounts for it.
Run It on Your Next Build
Free forever, every feature, up to 25 machines. One file, no agent.