Baselines & incremental adoption

Onboard a legacy repo sanely.

Intermediate12 min · lesson 8 of 12

Turning a scanner on against a large existing repo produces hundreds of findings at once — and a wall of red that developers will route around or ignore. Baselines solve the adoption problem: you generate a baseline of the current findings, and Checkov then only fails on new issues introduced after that point, while the pre-existing ones are tracked for gradual remediation. This lets you gate immediately without blocking work on day one.

BASELINE, THEN RATCHET DOWN
1--create-baseline
capture current findings
2Commit .checkov.baseline
track existing debt
3--baseline: fail on new only
gate now, without blocking work
4Fix a batch, regenerate
burn the baseline down
Gate new code strictly while shrinking accepted debt over time — never baseline critical findings.
terminal
$ checkov -d . --create-baseline # writes .checkov.baseline of current findings
$ git add .checkov.baseline
# from now on, fail only on NEW findings:
$ checkov -d . --baseline .checkov.baseline

Ratchet down over time

A baseline is a starting point, not a permanent excuse. The healthy pattern is to gate new code strictly (no new findings) while burning down the baseline deliberately — fix a batch, regenerate the baseline smaller, repeat — so the accepted debt shrinks. Track the baseline count as a metric. Combined with severity gating (block criticals even if baselined, or exclude them from the baseline), this is how you adopt scanning on legacy infrastructure without a revolt.

A baseline that never shrinks is permanent debt
The risk of baselines is that they become a place findings go to be forgotten — the count only ever grows as new “accepted” issues are added. Treat the baseline as debt with a paydown plan: never baseline critical findings, review the baseline periodically, and drive the number down. A frozen, growing baseline means the scanner has quietly stopped protecting the old code entirely.