valgen is a build-time code generator. This document describes its trust model so you can reason about supply-chain risk.
There are two separate binaries with separate import graphs:
- The generator (your
//go:generateprogram) runs at build/dev time. It imports the engine (.../valgen/gen,.../valgen/plugin) and the validator packages, parses your source, and writesvalgen_gen.go. - Your application imports only the runtime package (
.../valgenfor theErrorsaccumulator) and the generatedvalgen_gen.go. It never imports the generator (/gen) packages, so there is no generator code in your shipped binary — only the generated source it produced.
There is no global registry, no registration via init(), and no global mutators. Your generator main
feeds the exact set it trusts into the top-level gen.New builder and finishes with Run:
func main() { gen.New(validations.New().Generators()...).Add(acme.EvenGen{}).Run() }Because the engine only runs the generators you explicitly list — and its presence wrappers and error
builder are set only through the builder chain, never a global — a compromised transitive dependency
cannot silently register or override a generator, wrapper, or error builder to inject Go into your output.
The trusted configuration is exactly what appears in your main.
Importing any Go package runs its init(). So a compromised dependency in your generator's import graph
can execute arbitrary code at generation time on your build/CI machine — this is true of every Go build
tool and cannot be fixed by a library. It cannot reach your generated output (see above), but it can do
anything a process on your build machine can. Mitigate it the usual way:
- Pin and vendor your generator's dependencies; review upgrades.
- Run
go generatein a restricted/hermetic CI environment (no secrets, no network egress). - Review the
valgen_gen.godiff — generation is deterministic, so injected code shows up in review. - Add a CI guard that regenerates and fails on drift (
git diff --exit-code -- '*.go'aftergo generate).
Please report security issues privately via GitHub Security Advisories on this repository, rather than a public issue.