Put anything that changes what the scanner reports or blocks in version control: policies, thresholds, exclusions with reasons and expiry dates, scanner and rule versions, and schedules. Keep credentials, tokens and tenant specific secrets out, and load them from a secrets manager at run time.
Why bother
If scanner settings live only in a web console, nobody can answer "who turned that rule off, and when?" Changes are hard to review, hard to roll back and hard to reproduce. Auditors and incident responders ask exactly those questions.
Configuration as code gives you pull request review, history, rollback and the ability to test a change before it reaches everyone. For a platform team, it also lets you ship a sane default to every repository and let teams override within limits.
What goes in, what stays out
| Belongs in version control | Stays out |
|---|---|
| Policy definitions and severity thresholds | API tokens and keys |
| Which scan types run, and on which events | Per-user credentials |
| Exclusion paths, each with owner, reason and expiry | Customer or tenant secrets |
| Scanner, rule and database versions | Anything that changes per run |
| Schedules and priority lane assignments | Raw scan output with sensitive data |
| Required check names and branch rules |
A layered model
Most platform teams end up with three layers.
- Organisation defaults: the baseline every repository inherits, owned by the platform or security team.
- Team overrides: allowed within bounds, such as adding an exclusion with an expiry but not lowering the blocking severity.
- Repository file: a small file in the repository for local exclusions and ownership metadata.
Merge them in a defined order, and make the effective configuration viewable. A team debugging a failed gate should be able to see the merged result and which layer set each value.
Rules for exclusions
Exclusions are where configuration quietly rots. Require each one to carry an owner, a reason and an expiry date, and fail the check when an exclusion has expired. An exclusion without an end date is a permanent hole.
Review and testing
- Require code owner review on organisation defaults.
- Validate the file against a schema in CI so typos fail early.
- Provide a dry run that shows what a change would block across a sample of repositories before merging.
- Log the effective configuration hash in every scan result so you can tie findings to settings.
Rollout
Treat configuration changes like code releases. A threshold change from high to medium blocking can fail a thousand builds. Use the same ring approach as for scanner upgrades, and announce changes with a date.
Try it yourself
Click through it at your own pace, or open it full screen. Notice which conditions decide whether a pull request is blocked, since those are the settings worth versioning.
Safeguard provides policies, gates and guardrails for pull requests and builds. You can try the free scan at https://gold.safeguard.sh/scan.
Quick check
Should the scanner token be in the config file?
No. Reference a secret by name and fetch it from your secrets manager at run time.
Can teams edit their own exclusions?
Usually yes, with an owner, reason and expiry, reviewed by a code owner, and with limits on what they can override.
Last reviewed: 19 October 2026.