To stop vulnerable dependencies reaching production, check them at five points on the path to production, the editor, the pull request, the build, the release and the cluster admission step, and give each point a different job. Warn early where a fix is cheap, block late where the decision is final, and key the blocking rules on exploitation evidence (a CISA KEV listing, reachability, a fix being available) rather than on raw severity alone. Then record every decision, so the cluster can refuse anything that never passed.
No single gate catches everything. A pull request check never sees the base image. A build gate never sees a CVE published the week after the build. An admission check sees everything that ships, but it is the most expensive place to learn that a release needs a dependency bump. Layered checkpoints work because each covers a gap the others leave, and they fail when all five block the same finding five times.
The first two thirds of this guide apply whatever tools you run. Safeguard appears near the end, with a maturity label on every capability and a plain list of what it does not do.
Key takeaways
- Five checkpoints, five jobs. The editor informs, the pull request reviews the change, the build checks the whole artifact, the release decides, and admission refuses anything that skipped the decision.
- Block on exploitation evidence, warn on everything else. A KEV listed finding in reachable code with a fix available is a strong block signal. An unreachable medium with no fix is a ticket.
- Plan for outages and missing fixes. Decide which checkpoints fail open and which fail closed, and run time-boxed, approved exceptions for findings nobody can fix yet.
- Carry the decision forward with a signed attestation bound to the artifact digest, so the cluster verifies instead of rescanning.
- Measure escapes, overrides and time to fix.
- Safeguard labels in this post: IDE extensions (GA); Safeguard CLI and CI/CD integration (GA); SCA and deep dependency scanning (GA); policies, gates and guardrails (GA, with policy outcomes switched on per workspace by Safeguard); reachability analysis (GA, static analysis Preview for Ruby, PHP and Swift or Objective-C); attestation and signing (GA, but the Kubernetes admission controller is not yet published per the docs); Gold Open Source and its free gate (GA, GitHub Action not yet published, command line form available); autonomous remediation (GA, ships switched off with every category set to Manual); SAST (early access); Package Firewall (early access, outside this flow).
Where a vulnerable dependency gets into a release
Before choosing checkpoints, list the doors. Each one becomes visible at a different point in the pipeline.
A developer adds a new package. The version they pick has a published advisory. It shows up first in the editor and next in the pull request diff.
A version bump moves into an affected range. Upgrades can introduce vulnerabilities as well as remove them. The manifest and lockfile diff of the pull request shows it.
A transitive dependency changes underneath you. When a direct dependency declares a version range, a fresh resolution can pick a different transitive version without anyone editing a manifest. NIST SP 800-204D section 5.1.4 says dependency detection should cover transitive dependencies with "preferably no limit to the depth" analysed. You see the change in the pull request only if lockfiles are committed; otherwise only the build sees it.
The base image carries it. A clean lockfile can ship inside an image whose base layer carries a known exploited library. Nothing in the pull request diff shows this. Only a scan of the built image does.
Someone vendored or copied the code. Vendored directories, copied files and checked in binaries have no manifest entry, so manifest scanning misses them. This is the main reason the build should scan the produced artifact.
Nothing changed except what the world knows. The most common path is the quietest. A new CVE is published against a version you already ship. Every checkpoint that ran before the disclosure passed correctly, and production is now vulnerable. Only a recheck against deployed artifacts or a release gate that reads current data catches this.
| Entry path | First visible at | Checkpoint that should own it |
|---|---|---|
| New package | Editor, then pull request | Pull request (warn in editor) |
| Version bump into an affected range | Pull request | Pull request |
| Transitive change on fresh resolution | Pull request if lockfiles are committed, else build | Build |
| Base image | Build (image scan) | Build, then release |
| Vendored or copied code | Build (artifact scan), sometimes not at all | Build, plus code review |
| New CVE against unchanged code | After release | Release recheck, plus continuous monitoring |
The last row is why a dependency policy that ends at the pull request is not a policy. It is a filter on change, and much new exposure is not caused by change.
What the standards ask for
No standard names five checkpoints. Read together, several describe what each one is for.
NIST SSDF: define criteria, then check against them
NIST SP 800-218, the Secure Software Development Framework version 1.1 (February 2022), has two directly relevant practices.
PO.4, Define and Use Criteria for Software Security Checks. PO.4.1 asks you to define criteria for security checks and track them throughout the SDLC. Its examples include defining KPIs, KRIs and vulnerability severity scores, adding security criteria to existing checks such as the Definition of Done, and recording approvals, rejections and exception requests in the workflow. PO.4.2 asks for mechanisms that gather the information behind those criteria, with examples that include automating decisions that use the criteria and periodically reviewing those processes.
PW.4, Reuse Existing, Well-Secured Software. PW.4.4 asks you to verify that commercial, open source and other third-party components comply with your requirements throughout their life cycles. Its examples read like a checkpoint plan: regularly check for publicly known vulnerabilities, build automatic detection of known vulnerabilities into the toolchain, make sure components are still maintained, and confirm component integrity through digital signatures.
As a checkpoint design, PO.4 says the gate needs written criteria and a record of every decision, and PW.4.4 says the check has to keep running after the first pass.
NIST SP 800-204D: the CI/CD view
NIST SP 800-204D (February 2024) places dependency checks inside the pipeline. Section 5.1.4 says open source dependencies must be enumerated, understood and evaluated for policy, potentially using SCA tools. Section 5.2 frames delivery controls as verification policies for allowing or disallowing an artifact for deployment, with two requirements that map onto our checkpoints:
- DEPLOY-REQ-2: before merging pull requests, it should be possible to view details of any vulnerable versions through dependency review. That is the pull request checkpoint.
- DEPLOY-REQ-3: where a secure build process exists, it should be possible to require that the deployed artifact was generated by it. That is the admission checkpoint, keyed on provenance.
OWASP SCVS: what component analysis means
The OWASP Software Component Verification Standard, chapter V5 (Component Analysis), lists the automated checks a component analysis process should run. Requirement 5.4, identifying all publicly disclosed vulnerabilities in third-party and open source components, applies at all three levels. Requirement 5.5, identifying confirmed dataflow exploitability, appears only at level 3. Requirement 5.6 covers identifying unspecified component versions. In checkpoint terms, 5.4 is the floor for every gate, 5.5 is what reachability analysis tries to provide, and 5.6 is a reason to fail a build that resolves an unpinned version.
SLSA: proving which build produced the artifact
SLSA v1.0 defines three build levels: Build L1 (provenance exists), Build L2 (hosted build platform) and Build L3 (hardened builds). There is no level 4 in v1.0. SLSA's guidance on verifying artifacts tells consumers to check the provenance signature, confirm the builder identity is trusted for the claimed level, and compare provenance against expected values for at least the builder identity and the canonical source repository. That is the logic an admission check should run.
CISA KEV and BOD 26-04: exploitation as a deadline
CISA describes its Known Exploited Vulnerabilities catalog as the authoritative source of vulnerabilities exploited in the wild and says organisations should use it as an input to prioritisation. The current federal rule is Binding Operational Directive 26-04, "Prioritizing Security Updates Based on Risk," issued 10 June 2026. It revoked and superseded BOD 22-01, the 2021 directive that set fixed two-week KEV deadlines. BOD 26-04 sets remediation timelines from four factors: whether the vulnerable asset is publicly exposed, whether the CVE is in KEV, whether exploitation can be automated, and whether an attacker gains partial or total control. The clock starts when CISA adds the CVE to KEV or when the agency finds it on an asset and updates its CDM data, whichever is first, and the timeline is dynamic: taking a system off the internet can lengthen it, and a KEV addition shortens it. Our post on BOD 26-04's four factors walks through the model.
BOD 26-04 applies to federal agency information systems, and it does not reach contractors unless their contract says so. Private companies are not bound by it, but it is a useful benchmark, and the four factors map well onto checkpoints: exposure is a property of where the artifact will run, which the release gate and admission check know. A release gate that lets a KEV entry through to an internet-facing service needs a written reason.
FIRST EPSS: probability, not severity
FIRST's Exploit Prediction Scoring System estimates the probability that a published CVE will be exploited in the wild in the next 30 days, published daily as a score from 0 to 1 with a percentile. CVSS describes how bad exploitation would be; EPSS estimates how likely it is soon. Using both separates a severe but improbable finding from a moderate one under active attack.
The five checkpoints and what each should check
Each checkpoint has a job, inputs, an action on failure, and a cost when it is wrong. A false block in the editor costs a developer a minute; a false block at admission can stop a deploy during an incident.
Checkpoint 1: the editor
Job: tell the developer about a problem while changing the line is still free.
Checks: the manifest being edited, the version being added or bumped, and whether a fixed version exists, with an upgrade the developer can accept in place.
On failure: warn, never block. Developers try things on branches and revert. A checkpoint that refuses to save a file gets turned off.
Cannot do: it only sees developers who installed it and files they open. It does not see transitive resolution in CI, base images or automated commits. It speeds up the later checkpoints; it is not coverage.
Checkpoint 2: the pull request
Job: review the change, as NIST SP 800-204D DEPLOY-REQ-2 describes.
Checks: the dependency diff between the base branch and the pull request head, including lockfile changes. The useful question is what this change adds or makes worse. A check that reports every existing finding on every pull request becomes noise within a week.
On failure: block only on new findings that meet your strictest rule, for example a new KEV listed vulnerability with a fix available. Warn on the rest, attached to the pull request so the reviewer sees it.
Cannot do: it sees the declared graph, not the image the code will run in, and not transitive resolution if lockfiles are not committed.
Checkpoint 3: the build
Job: check the artifact that will actually ship, all of it.
Checks: the full resolved tree from lockfiles and manifests, and for containers, the built image including base layers. This is where vendored code inside an image and base image packages become visible, and where SCVS 5.6 applies: a build that resolves an unpinned version should fail on that alone.
On failure: block on the rule for the target environment. A development build can warn; a production build should block on the rule you would defend to an auditor.
Cannot do: it is a snapshot. A CVE published the next day makes the same artifact vulnerable, and the build checkpoint never runs on it again.
Checkpoint 4: the release
Job: decide. This artifact, at this digest, under this policy version, is approved for production or it is not.
Checks: the latest scan of the exact artifact being promoted against named policies, plus any open exceptions. If the build was days ago, re-evaluate against current data, because KEV and EPSS change daily.
On failure: block, with a documented exception path. Approvals belong here, recorded with the finding, approver, justification and expiry, as SSDF PO.4.1's example on recording approvals, rejections and exception requests suggests.
Cannot do: it cannot stop someone deploying an artifact that never went through the release pipeline, such as a hotfix pushed straight to a registry.
Checkpoint 5: cluster admission
Job: refuse anything that skipped the decision.
Checks: that the image is referenced by digest, carries a valid signature from a trusted signer, and carries an attestation that it passed the release gate or provenance from your trusted builder (SLSA verification, NIST SP 800-204D DEPLOY-REQ-3).
On failure: deny in production namespaces, warn or audit elsewhere. Kubernetes runs admission in two phases, mutating then validating, and if any controller rejects the request, the whole request is rejected. The built-in ValidatingAdmissionPolicy (stable since v1.30) uses CEL expressions and supports three validation actions, Deny, Warn and Audit, so you can roll a rule out in Warn or Audit before switching to Deny.
Cannot do: admission sees a pod spec and an image reference, not source. It should verify that someone authorised already checked the image, not rescan it.
Which checkpoint should block, which should warn, and why blocking everywhere fails
After an incident, the instinct is to block everywhere. It fails for four reasons.
The same finding fails five times. The developer fixes it once but reads about it in four places, and next time assumes any failure is the same old finding.
Blocking early blocks experiments. A library tried on a branch is not shipping. Blocking in the editor or on a draft pull request stops work that would never reach production.
Blocks without exceptions create bypasses. With no fast, recorded way through, people find unrecorded ones: a disabled required check, a direct registry push, a hotfix outside the pipeline. Every bypass is a release with no record.
Late blocks are expensive. An admission denial during an incident costs far more than a pull request warning, but a warning alone has no teeth.
The pattern that works is "warn early, decide once, verify late":
| Checkpoint | Default action | Blocks on | Why |
|---|---|---|---|
| Editor | Warn | Nothing | Cheapest point to fix; blocking gets it disabled |
| Pull request | Warn, block on new strict findings | New KEV listed or reachable critical findings with a fix | Only new findings count |
| Build | Block on the environment's rule | Production rule for production builds; unpinned versions | Sees the full artifact and base image |
| Release | Block, with exceptions | The release policy set on current data | The single recorded decision |
| Admission | Deny in production | Missing signature or gate attestation | Verifies the decision; does not re-decide it |
One rule keeps this sane: each finding class blocks at exactly one checkpoint and is merely visible at the others. If your production rule blocks at the release gate, the pull request warns on the same rule, and admission checks only that the release gate passed.
For rolling a rule from warn to block, see moving a security policy from warn mode to enforce mode and rolling out a pipeline security gate without blocking developers.
What a gate should key on
Severity alone is the most common key and the weakest. Five signals, combined, make a better rule.
Severity (CVSS)
CVSS describes how bad exploitation would be. It is a good tiebreaker and a poor primary key, because many high and critical findings in a dependency tree are never exploited and never reachable from your code.
KEV listing
A KEV listing means exploitation has been observed. It is the strongest single gate signal, and it is binary, which makes it easy to explain: this one is being used in attacks.
EPSS
EPSS adds a probability for everything not on KEV. A threshold such as "EPSS above 0.5" separates likely exploitation from the long tail. Because EPSS changes daily, a release gate on current data will sometimes fail a build that passed yesterday. That is the gate working; tell developers before it happens.
Reachability
Reachability asks whether your code can call the vulnerable function, which is what SCVS 5.5 calls confirmed dataflow exploitability. It cuts noise more than any other signal, with two cautions: quality differs by language, and "unknown" (reflection, dynamic dispatch, native code) must be treated as reachable.
Fix availability
Blocking a finding with no fixed version gives the developer nothing to do but request an exception. Block where there is an action (upgrade to version X); route no-fix findings to an exception with an expiry.
A worked rule set
This is an illustrative example, not a universal recommendation. Write your own thresholds down, because SSDF PO.4.1 asks for defined criteria.
| Condition | Pull request | Build (prod) | Release | Admission |
|---|---|---|---|---|
| KEV listed, reachable or unknown, fix available | Block | Block | Block | Verify gate attestation |
| KEV listed, no fix available | Warn | Warn | Exception required | Verify gate attestation |
| Critical, reachable, EPSS above 0.5, fix available | Warn | Block | Block | Verify gate attestation |
| Critical or high, unreachable | Warn | Warn | Pass, ticket | Verify gate attestation |
| Medium or low, any | Visible | Visible | Pass | Verify gate attestation |
| Unpinned or unresolvable version | Warn | Block | Block | Verify gate attestation |
The admission column never reads vulnerability data. It verifies that the release gate ran and passed for this digest. That is how you avoid five gates blocking the same thing.
What happens when the scanner is down or a fix does not exist yet
Scanner down: fail open or fail closed per checkpoint
Every gate depends on a scanner, a feed or a hosted API. When that is unavailable, the gate either passes (fails open) or blocks (fails closed). The right answer differs by checkpoint.
- Editor: fail open, silently.
- Pull request: fail open with a visible "not evaluated" status, so the reviewer knows the check did not run.
- Build: fail open for development builds; for production builds, fail closed or reuse the last result for the same lockfile hash.
- Release: fail closed. A decision that did not run is not a pass. Shipping during an outage is an exception with an approver, not a silent green.
- Admission: fail closed in production, keyed on the stored gate decision rather than a live scanner. A ValidatingAdmissionPolicy with failurePolicy Ignore lets requests through when the policy errors; with Fail, they are rejected. If admission only verifies a signature and an attestation, a scanner outage cannot block the cluster.
See CI security gate when the scanner is down: block or pass for more on this choice.
No fix yet: exceptions with an expiry, plus a compensating control
Blocking a no-fix finding forever does not make anyone safer; it makes them find a bypass. Write the exception into the process:
- Record the finding, the affected artifact and why no fix applies.
- Name a compensating control (a disabled feature, a configuration change, network isolation) or state there is none.
- Name an approver with authority to accept the risk.
- Set an expiry, after which the gate fails again and someone re-decides.
- When a fixed version ships, close the exception so the gate blocks again.
For KEV entries, set the exception's expiry from the same four factors BOD 26-04 uses, so an internet-facing, automatable, KEV listed finding gets the shortest window and a mitigation such as removing public exposure is what earns a longer one.
How signed attestations carry a "this was checked" decision into the cluster
The link between the release gate and admission is a signed statement about the artifact. The standard shape is an in-toto attestation: a predicate (the claim, such as SLSA provenance, an SBOM or a scan result), a subject (the artifact's SHA-256 digest) and a signature. Three properties make it work.
Bound to the digest, not the tag. A tag such as api:1.4.2 can be moved; a digest cannot. If the image changed after the gate, the attestation no longer applies.
Signed by a known signer. SLSA's verification guidance says to check the signature and confirm the builder identity is trusted. In admission terms, that is an allow-list of signers.
Checked against expected values. Compare at least the builder identity and the canonical source repository, as SLSA recommends. A gate attestation should also name the policy set and the time, so admission can refuse a release that passed an older, weaker policy.
Admission then becomes cheap: resolve digest, verify signature, read predicate, compare, admit or deny. It does not depend on a scanner, and it catches the laptop hotfix, because that image carries no gate attestation. See can Kubernetes admission control require an SBOM attestation and do you need both a CI image gate and admission control.
How to measure whether the checkpoints are working
SSDF PO.4.1 suggests analysing data on security successes and failures and using it to improve the SDLC. Six measures cover most of what you need.
| Measure | What it tells you | Warning sign |
|---|---|---|
| Escapes found in production | Findings present at release that were not blocked | Any escape matching a block rule means a bypass or misconfiguration |
| New CVEs against running releases | Exposure that arrived after release | Shows how much depends on continuous monitoring |
| Overrides and exceptions per release | How often people route around the gate | A rising trend means rules are too strict or fixes too slow |
| Expired exceptions still open | Exceptions nobody re-decided | Any non-zero count |
| Time from first warning to fix | Whether early checkpoints shorten the path | Fixes only after a release block mean early warnings are ignored |
| Duplicate failures per finding | Whether one finding blocks at several checkpoints | More than one block per finding |
Also watch gate duration; a release gate that adds a long wait gets routed around.
How Safeguard does this job, step by step
Safeguard covers four of the five checkpoints with generally available tools and is plain in its own docs about the fifth. Commands and settings below are as Safeguard's docs show them on 24 October 2026; where the docs show no command, the step describes the outcome.
Step 1: Put the extension in the editor (IDE extensions, GA)
Safeguard ships an extension for VS Code and Cursor and a separate JetBrains plugin. Both scan dependency manifests as you work and show vulnerabilities inline. In VS Code:
code --install-extension Safeguard-sh-Inc.SafeguardshIdeExtension
Cursor installs the same package from Open VSX; JetBrains IDEs install from Settings, Plugins. Run Safeguard: Login to sign in with an OAuth 2.0 device flow. Auto scan and scan on save are on by default, covering npm, Yarn, pnpm, pip, Poetry, Pipenv, Maven, Gradle, Go modules, Cargo and Bundler manifests. Hover a flagged dependency for a lightbulb fix; the safeguard.remediationStrategy setting picks Safe, Balanced (default) or Aggressive upgrades. This checkpoint warns and suggests; it blocks nothing.
Step 2: Create a CI secret key (CLI and CI/CD integration, GA)
Under Settings, Developer, create a secret key with the scopes scans:trigger and scans:read, optionally locked to one project. Store it in CI as SAFEGUARD_API_KEY. The docs give guides for GitHub Actions, GitLab CI/CD, Bitbucket Pipelines, Jenkins and Azure Pipelines, and say any CI with a shell step works. There is no plugin or Action to install; the CLI runs in a plain shell step.
Step 3: Scan every pull request and push (SCA and deep dependency scanning, GA)
This covers checkpoints 2 and 3 for code. The GitHub Actions guide gives this workflow:
name: Safeguard
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Safeguard scan
env:
SAFEGUARD_API_KEY: ${{ secrets.SAFEGUARD_API_KEY }}
SAFEGUARD_INSTALL_DIR: ${{ runner.temp }}/safeguard-bin
run: |
set -eu
curl -fsSL https://cli.safeguard.sh/install | bash
"$SAFEGUARD_INSTALL_DIR/safeguard" ci scan --wait --fail-on critical
Each push becomes a new project version named after the branch and commit; on a pull request the head branch is scanned. Safeguard clones the repository by default; add a checkout step and --local to scan on the runner so only results leave it. Per the docs, --wait fails the step if the scan fails or passes --timeout (default 30 minutes), and --fail-on fails on a dependency vulnerability at or above the chosen severity. Dropping --fail-on reports without failing.
For warn early, block later: run the pull request job without --fail-on, and the push job on main or release/* with --fail-on critical or high. Pin the CLI with SAFEGUARD_VERSION so a CLI release does not change a build under you. SAST findings appear in Safeguard but are not part of --fail-on yet; SAST is early access.
Step 4: Scan the built image per environment (CLI and CI/CD integration, GA)
This closes the base image gap. Add one step after the image build:
safeguard ci scan --image "ghcr.io/acme/api:$TAG" --environment prod --wait --fail-on critical
The image is scanned on the runner and recorded under its repository, one version per environment and tag, such as prod-1.4.2. The docs suggest one step per environment, for example --fail-on critical in production and no threshold in development.
Step 5: Write policies and link them to a release gate (policies, gates and guardrails, GA)
This is checkpoint 4. Policies evaluate scan data and produce findings; gates enforce linked policies. Per the docs:
- Go to Settings, Policies, and click Create Policy.
- Define conditions with the visual builder or YAML. Listed conditions include vulnerability severity, CVSS, EPSS, license, component age, maintenance and SLSA level.
- Set the policy's Action, save, enable, and link it to a gate.
Templates include No Critical Vulnerabilities, License Compliance, SLSA Level 2 and No Abandoned Packages. The docs list three actions:
| Action | When the policy fails |
|---|---|
| Block | The gate fails |
| Warn | The gate passes, with a warning naming the policy |
| Notify | The gate passes, and the workspace's configured channels are notified |
There is no separate "require approval" action; approvals go through the exception workflow in Step 7.
Policy outcomes are switched on per workspace by Safeguard. If the Gates and Policies tables show no Outcome column, ask your Safeguard contact. A gate's outcome follows a fixed order: no linked policies is Not evaluated; any failed Block policy is Failed; then any policy that errored is Error; then any not yet evaluated is Not evaluated; then any failed Warn policy is Warning; otherwise Passed. The docs say an Error is never counted as a pass, which is the fail closed behaviour a release gate needs.
KEV and reachability are not in the docs' condition table; they appear as Vulnerabilities tab filters (kev:true, reachable:true). Confirm how to express a rule on them before relying on it.
Step 6: Fail the release job on the gate (CLI and CI/CD integration, GA)
safeguard ci scan --wait --fail-on-gate <gate name or id | all>
Per the policy outcomes docs, this waits for the scan and the gate's evaluation on the new data, exits 0 on Passed or Warning, and exits non-zero on Failed (printing the failed Block policies), Error, Not evaluated, or a timeout before evaluation. It combines with --fail-on <severity>. That gives "decide once": the pull request reports, the production build fails on severity, and the release job fails on the named gate.
Step 7: Route exceptions through the documented workflow (policies, gates and guardrails, GA)
Click Request Exception, select the policy and finding, give a business justification, set an expiration date and submit. Approvers are notified and decide, and the audit trail records it. Compliance reporting shows status by policy, exception history and violation trends, which feeds the measures above.
Step 8: Triage what the gates report with reachability (reachability analysis, GA)
Safeguard combines reachability, EPSS and KEV, runtime context and business context into a 0 to 100 priority score. Safeguard's docs say this typically cuts the urgent queue by 60 to 80%; treat that as Safeguard's stated figure, not a guarantee. Unknown findings are marked potentially reachable, not suppressed. Static reachability is GA for JVM languages, Python, JavaScript and TypeScript, Go, Rust, C and C++ and .NET, and Preview for Ruby, PHP and Swift or Objective-C. Use the Vulnerabilities tab filters, such as env:production reachable:true kev:true; the docs page's /v1 endpoints are marked not available yet.
Step 9: Add the free Gold gate where you have no account (Gold Open Source, GA)
Gold Open Source is free and needs no login. The docs say the safeguard-sh/gold-scan-action GitHub Action is not on the Marketplace yet and the command line form is available now:
# .npmrc
@safeguard-sh:registry=https://registry.safeguard.sh/npm/
npx @safeguard-sh/gold-scan # scan the current directory (fail-on=kev)
npx @safeguard-sh/gold-scan . --fail-on vuln
It reads npm, PyPI, crates.io, Go, RubyGems and Packagist manifests and sends only dependency names to the public API. kev fails on actively exploited vulnerabilities, vuln on any known CVE, none reports only. It fails open if the API is unreachable, which suits the pull request or pre-commit checkpoint and makes it a poor sole release gate.
Step 10: The cluster checkpoint (attestation and signing, GA; admission controller not yet available)
Safeguard's attestation docs describe five in-toto v1 predicate types: SLSA Provenance v1, CycloneDX SBOM, SPDX SBOM, a build time vulnerability scan snapshot and a Griffin generated review. They are signed with Safeguard's own key held in a cloud key management service, not written to a public transparency log, and verified with cosign against Safeguard's published public key. Records appear on the Attestation tab in the app.
What is not available yet, per the docs: the Guardrails and Enforcement page says the Kubernetes admission controller is not published and warns against installing any chart claiming to be it; the attestation page says there is no CLI command for signing images or packages, none for verifying or listing attestations, and no public attestation API.
So for checkpoint 5 today, sign release images in your pipeline after the release gate passes, and require that signature and gate attestation by digest with a ValidatingAdmissionPolicy or admission webhook. Roll out in Warn or Audit, then switch production to Deny.
Where each Safeguard surface sits
| Checkpoint | Safeguard surface | Label | What you still own |
|---|---|---|---|
| Editor | IDE extension | GA | Getting developers to install it |
| Pull request | safeguard ci scan on pull_request, or the Gold gate CLI | GA | Report only vs fail |
| Build | safeguard ci scan, --image per environment | GA | Thresholds per environment, CLI pinning |
| Release | Policies on a gate, --fail-on-gate | GA (outcomes switched on per workspace) | Policy wording, exception approvers |
| Admission | Attestation tab; controller not yet published | GA for attestation | Your own signing and admission rule |
What Safeguard does not do
- No Kubernetes admission controller today. The docs say it is not published. Checkpoint 5 needs your own signing and admission rule until it ships.
- No CLI signing or verification yet. The docs list no CLI command for signing, verifying or listing attestations, and no public attestation API.
- No coverage where it is not wired in. A repository without the CI step, a registry push from a laptop or a cluster without an admission rule is outside every checkpoint.
- No control over local installs. The IDE extension warns developers who installed it; it does not intercept a terminal install or block anything. Package Firewall is early access and not part of this flow.
- No SAST in the CI threshold yet. SAST is early access, and
--fail-ondoes not count its findings. - Policy outcomes are not on by default.
--fail-on-gatedepends on Safeguard switching them on for your workspace. - Reachability is not equal across languages. Static analysis is Preview for Ruby, PHP and Swift or Objective-C.
- A gate is only as current as its data. A build that passed yesterday can be vulnerable today; re-evaluate at release.
- The free Gold GitHub Action is not published yet, and the command line form fails open by design.
Common mistakes
Blocking the same finding at every checkpoint. Pick one blocking checkpoint per rule; make the others informational.
Gating pull requests on the whole repository. A one line change fails on a two year old finding elsewhere. Gate on what the change adds.
Scanning manifests but not images. The base image never appears in a lockfile.
Treating "not evaluated" as a pass. A timeout or outage should never produce a green release.
Admission that rescans instead of verifying. It duplicates the build check and makes deploys wait on a vulnerability feed.
Checking tags instead of digests. A tag can move; bind attestations and admission checks to the digest.
Exceptions without an expiry. That is a permanent hole with a signature on it.
Using CVSS as the only key. It blocks unreachable, unexploited findings and still lets a medium severity KEV entry through.
FAQ
How do I stop vulnerable dependencies from reaching production?
Check at five points: the editor, the pull request, the build, the release and cluster admission. Warn in the editor and pull request, block at the build and release on a written rule keyed on KEV, reachability and fix availability, and have admission verify a signed record that the release gate passed for the image digest.
Should a CI security gate block or warn on vulnerable dependencies?
Both, at different points. Warn on pull requests for most findings and block new findings that match your strictest rule. Block at the production build and release gate. Blocking everywhere causes duplicate failures and bypasses.
What should a dependency security gate check besides CVSS severity?
A CISA KEV listing, the EPSS probability, whether the vulnerable code is reachable, and whether a fixed version exists. A reachable KEV entry with a fix is a far stronger block reason than an unreachable critical with no fix.
Is a pull request check enough to stop vulnerable dependencies?
No. It sees the declared dependency change, not the base image, vendored code or CVEs published after merge. It needs a build scan of the artifact and a release gate on current data.
What should happen when the vulnerability scanner is down during a release?
The release gate should fail closed, and shipping during the outage should go through a recorded exception with a named approver. Editor and pull request checks can fail open if they show the check did not run.
How do I handle a vulnerable dependency with no fix available?
Record an exception naming the finding, a compensating control, an approver and an expiry, and close it when a fix ships. For KEV entries, size the expiry with BOD 26-04's four factors (public exposure, KEV status, exploit automation and technical impact) rather than one fixed number; BOD 22-01's fixed deadlines were revoked in June 2026.
Do I need Kubernetes admission control if CI already scans images?
Yes. CI decides whether an image is acceptable; admission makes sure nothing reaches the cluster without that decision, including images built or pushed outside the pipeline.
Does NIST require dependency scanning in CI/CD pipelines?
NIST SP 800-218 PW.4.4 asks teams to verify third-party components throughout their life cycles, with automatic detection of known vulnerabilities in the toolchain as an example. NIST SP 800-204D section 5.1.4 says dependencies, including transitive ones, should be evaluated for policy, and DEPLOY-REQ-2 calls for dependency review before merging.
From a blocked build to a fixed one
Checkpoints only help if a blocked build turns into a fixed one quickly, and the fastest fix is usually an upgrade or a patched component. The block below describes how Safeguard helps close that gap, so a gate failure becomes a merged fix rather than a growing list of exceptions.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The first demo is a real Safeguard CLI session. You install the CLI, run safeguard to open the interactive terminal, and ask it to "fix the lodash CVE in this repo." It reads the finding and the advisory, asks before any command that changes something, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, prints a summary and pushes nothing, then shows /permissions, /model and /scan .. This is the developer side of a blocked pull request: the gate says what is wrong, and the fix lands before the build checkpoint runs.
Click through it at your own pace, or open it full screen.
The second demo sets up the local runner on your own machine, approves it with its device code, then scans from the terminal. It is the same CLI the CI steps above install, so it shows what a scan reports before you decide which checkpoint should fail on it.
Click through it at your own pace, or open it full screen.
To try the checkpoints on your own pipeline, download the CLI and apps at safeguard.sh/download and read the CI, policy and gate guides at docs.safeguard.sh/docs. For the evidence side of the release gate, see the companion post on proving every production release passed a security gate.
Quick check
Your pull request check, build gate, release gate and admission rule all block on "critical CVE present". What is wrong?
The same finding blocks four times, and admission depends on vulnerability data it should not need. Keep one blocking checkpoint per rule (usually the release gate), make the others informational or environment specific, and have admission verify a signed attestation that the release gate passed for the image digest.
An image passed its gate on Monday. On Wednesday a CVE in one of its libraries joins CISA's KEV catalog. Which checkpoint should catch it?
Not the build or pull request checks; they already ran. A release gate that re-evaluates on current data catches it before the next promotion, and continuous monitoring catches it for what is already running. Then patch or record a time-boxed exception, with the window sized by BOD 26-04's four factors, starting from the day the CVE joined KEV.
Sources
- NIST SP 800-218, Secure Software Development Framework (SSDF) Version 1.1 (PDF)
- NIST SP 800-204D, Strategies for the Integration of Software Supply Chain Security in DevSecOps CI/CD Pipelines
- NIST SP 800-204D full text (PDF)
- OWASP Software Component Verification Standard
- OWASP SCVS V5: Component Analysis Requirements
- SLSA v1.0: Security levels
- SLSA v1.0: Verifying artifacts
- Kubernetes: Admission Control in Kubernetes
- Kubernetes: Validating Admission Policy
- CISA: Known Exploited Vulnerabilities Catalog
- CISA: BOD 26-04, Prioritizing Security Updates Based on Risk
- CISA: BOD 22-01 (revoked)
- FIRST: Exploit Prediction Scoring System (EPSS)
- Safeguard docs: IDE Support
- Safeguard docs: CI/CD Integration
- Safeguard docs: GitHub Actions
- Safeguard docs: Container images
- Safeguard docs: Policies and Gates
- Safeguard docs: Policy outcomes and actions
- Safeguard docs: Guardrails and Enforcement
- Safeguard docs: Attestation and Signing
- Safeguard docs: Vulnerability Prioritization (Reachability Analysis)
- Safeguard docs: Gold Open Source
Last reviewed: 24 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.