A machine readable suppression record should carry the advisory ID and aliases, the package and version, the project, a reason from a closed list, evidence, an owner, an approver, a created date and an end date. Stored as YAML or JSON in the repository, it can be reviewed, diffed and enforced in CI.
The fields and why each exists
| Field | Purpose |
|---|---|
| advisory and aliases | Match the finding even if its primary ID changes |
| package and version | Tie evidence to the code reviewed |
| project | Keep scope narrow |
| reason | One value from a fixed list so reports can group them |
| evidence | A link or short note a stranger can follow |
| owner | Who renews or removes it |
| approver | Who agreed, other than the author |
| created | When it began |
| expires | When it lapses and the finding returns |
Keep free text short. A closed reason list lets you count and audit. The OpenVEX justification values, such as component not present or vulnerable code not in execute path, make a good starting vocabulary.
An example
suppressions:
- advisory: EXAMPLE-2026-0001
aliases: [EXAMPLE-ALIAS-0001]
package: example-lib
version: 2.3.1
project: billing-service
reason: vulnerable_code_not_in_execute_path
evidence: "Search of repo found no call to parseLegacy; see PR 482"
owner: team-billing
approver: security-reviewer
created: 2026-10-19
expires: 2027-01-17
The IDs and names above are placeholders for illustration.
A CI check that keeps it honest
Write a short job that loads the file and fails the build when:
- A required field is missing.
- The reason is not on the allowed list.
- The expiry is missing, in the past, or beyond the policy maximum.
- The package and version no longer appear in the current dependency list, which flags dead entries.
- Author and approver are the same person.
Run it on every pull request that touches the file, and on a schedule, since entries expire without a commit.
Design choices to settle early
- Where to store. One file per repository is simple. A central file helps when many repositories share a rule, but it needs strong access control.
- Format. Pick one that supports comments and is easy to diff.
- History. Do not edit entries in place to renew them. Add a new dated entry or use version control history, so an auditor can replay decisions. See exception audit trails.
Keep it portable
If you ever change scanners, a clean record in your own format converts easily to the new tool's rules, or to VEX statements for customers. Our post on portable triage decisions covers the exit paths.
Start with the minimum
If this feels heavy, begin with four fields: advisory, package, reason and expiry. Add owner and approver once the habit holds. A small record that people fill in beats a rich schema they bypass.
Quick check
Should evidence be a link or free text?
Both. A short sentence for context and a link for proof. Links can rot, so name the file or commit too.
Is YAML required?
No. Any structured format works if it supports comments, diffs and automated checks.
Sources
Last reviewed: 19 October 2026.