Policies exist so that "we accept this risk" is a written decision with a date on it, rather than a flag someone passed once.
Minimal policy#
# ztvs.policy.yaml
version: 1
suppress:
- where:
advisory: ZTVS-2026-0044
reason: "Not reachable — the vulnerable codec path is never constructed"
review_by: 2026-11-30
ztvs scan ./my-project --policy ztvs.policy.yaml
reason and review_by are required. A suppression without a reason is
rejected at parse time, and one whose review_by has passed becomes a finding
again.
Matching more than one advisory#
suppress:
- where:
package: { name: openssl, version: { below: 0.10.66 } }
severity: { at_most: medium }
reason: "Tracked in PLATFORM-812, scheduled for the 0.5 release"
review_by: 2026-10-15
Available matchers:
| Matcher | Accepts |
|---|---|
advisory |
id, or a list of ids |
package.name |
exact name |
package.version |
below, at_least, exactly |
severity |
at_most, at_least |
layer_index |
below, exactly |
path |
glob against the evidence path |
Failing the build on purpose#
enforce:
fail_on:
severity: { at_least: high }
unsuppressed_only: true
$ ztvs scan ./my-project --policy ztvs.policy.yaml
matched 7 advisories · 2 suppressed by policy
1 unsuppressed finding at or above high
$ echo $?
1
Checking a policy without scanning#
ztvs policy lint ztvs.policy.yaml
Catches expired suppressions and matchers that no longer match anything — the second is the useful one, because a suppression that stopped matching is a decision quietly doing nothing.