Safeguard
Product•

Keep a Maintenance-Mode Product Patched With a Skeleton Team

Write down the support promise, keep an SBOM per supported version, fix by exploitation and reachability, take safe upgrades and publish VEX for the rest.

Safeguard Security Team
38 min read

You keep an old product secure with two engineers by narrowing the job until two people can actually do it. Write down exactly which versions you support and until when, keep a bill of materials for each of those versions, spend engineering time only on findings that are exploited or likely to be exploited and that the old code can actually reach, take conservative upgrades, and tell customers in writing, in a machine readable form, when a listed CVE does not affect them.

That rarely happens by default, because a maintenance-mode product has no roadmap meeting and nobody whose job title says "owner". This post is the operating model for a product that stays on sale with a small team and a steady patch stream.

Key takeaways

  • "Maintenance mode" only works as a promise if it is written down: which versions, which kinds of fixes, and the end-of-sale, end-of-support and end-of-life dates for each.
  • CISA's Product Security Bad Practices (version 2.0, January 2025) asks on-premises software makers to state the support period at the time of sale and ship security updates for the whole of it. It also asks for a no-cost patch when a KEV-listed vulnerability is exploitable in the product, and public documentation, ideally VEX, when it is not.
  • NIST SP 800-218 (SSDF) RV.1.2 gives as an example running automated analysis "for all supported releases", not just the current one.
  • Keep an SBOM per supported version, built from the released artifact, so new advisories can be matched without a rebuild.
  • Spend scarce time on KEV listings first, then high EPSS scores, then reachable and exposed code. Everything else waits for the next planned maintenance release.
  • Take patch-level upgrades on old branches. When the only fix is a major version the old code cannot take, mitigate, backport or announce, and say which in writing.
  • Safeguard capabilities covered, with maturity labels: SBOM generation and analysis (GA); SCA and vulnerability management with EPSS and CISA KEV enrichment (GA); reachability analysis (GA); policies and gates (GA); AI Remediate fix pull requests and autonomous remediation (GA, ships switched off with every category set to Manual); CSAF and VEX upload (GA); Portal, meaning the SBOM publish and share product (GA); the CLI and the MCP server (GA); Gold Open Source (GA); fork and patch (GA).

Why maintenance-mode products drift out of date

A product enters maintenance mode for good reasons. The successor is on sale, and the old line keeps customers who cannot migrate yet, often banks, health systems and public agencies where a migration has its own budget cycle. They pay for support, and support usually includes security fixes.

What changes is the staffing. The original team moved on. Two engineers, sometimes one, inherit the old line alongside other work. Builds become rare, maybe one or two maintenance releases a year.

Meanwhile every open source component inside the old product keeps receiving advisories, and some reach end of life upstream. The gap between "what we shipped" and "what is safe" grows each month, and nobody notices because nobody is scanning a codebase that is not changing.

The fix is not heroics. It is a narrower, written scope, and tooling that does the watching so the two engineers only do the deciding and the fixing.

What does "maintenance mode" mean in a support contract?

"Maintenance mode" has no standard legal meaning. In practice it describes a product line that receives fixes but no new features. The contract needs to say what kind of fixes, for which versions, and for how long. If it does not, every customer reads it differently, and the skeleton team inherits every reading at once.

The three dates and what each one commits you to

Most vendors use three lifecycle dates; our explainer on end-of-sale, end-of-support and end-of-life dates covers them in depth.

DateWhat stopsWhat the team still owes
End of saleNew licences for the lineSecurity and defect fixes for supported versions, as the contract states
End of support (sometimes split into end of full support and end of security support)Defect fixes, sometimes all fixesWhatever the contract says survives: often security fixes only, sometimes nothing
End of lifeEverythingNothing beyond a final advisory, though customers will still ask

The trap for a small team is ambiguity in the middle row. "Supported" can mean "we answer the phone" or "we ship patches within a stated window". Write it as the second, with a scope you can deliver.

Write the support promise as a short policy

A support policy that two engineers can keep has five parts:

  1. Supported versions. Name them. "The latest 4.x and 5.x maintenance releases" beats "the two most recent versions", because "recent" moves.
  2. Fix scope. Security fixes above a stated severity or with known exploitation; defect fixes only for data loss or outage.
  3. Delivery form. Cumulative maintenance releases, not per-customer hotfixes. One branch per supported line.
  4. Response window. What you promise once a vulnerability is confirmed to affect a supported version. A promise you miss is worse than a slower one you keep.
  5. Dates. End of sale, end of support and end of life for each line, published where customers can find them.

Make the dates machine readable

The OASIS OpenEoX technical committee aims to standardise a machine readable way to share end-of-life and end-of-support information for software and hardware. On 25 October 2026 its page said it had not yet produced technical work. Publish the dates in plain text on a stable URL now, and adopt OpenEoX once it exists.

What does CISA expect of vendors with older products still in use?

Two CISA documents speak to this directly. Neither binds private vendors, but federal and critical infrastructure customers bring them into contracts and questionnaires.

Secure by Design: ownership does not end at the last feature release

CISA and its U.S. and international partners published "Shifting the Balance of Cybersecurity Risk: Principles and Approaches for Secure by Design Software" in April 2023 and revised it on 25 October 2023. It sets out three principles: take ownership of customer security outcomes, embrace radical transparency and accountability, and lead from the top.

For an old product, the first two matter most: the customer should not have to find out on their own which of your components are vulnerable, and you should tell them what is and is not affected. CISA's Secure by Design page says every technology provider "must take ownership at the executive level". A line with no named owner fails that test before a single CVE lands.

Product Security Bad Practices: three items that land on old products

CISA's Product Security Bad Practices guidance, version 2.0, carries a revision date of 17 January 2025. Its change record says version 2.0 added three new bad practices, one of which covers product support periods, and clarified the timelines for patching known exploited vulnerabilities. The guidance is voluntary and is aimed at manufacturers of software used in critical infrastructure or national critical functions. Three items matter here.

Item 13, support periods. For on-premises products, CISA treats failing to clearly communicate the period of support as a bad practice. The recommended actions are to communicate the support period at the time of sale and to provide security updates through the entire support period. That is the written support promise above, stated by a federal agency.

Item 5, known exploited vulnerabilities. Shipping a product that, at release, includes a component with an exploitable vulnerability on CISA's KEV catalog is listed as a bad practice. If a new KEV entry affects the product and is exploitable in it, CISA says the manufacturer should issue a patch at no cost to users in a timely manner. If it is not exploitable in the product, the manufacturer should publicly document the presence of the vulnerability. A footnote adds that this documentation should ideally be published as VEX, and another sets a 30 day patch window for KEV entries published within 30 days before a planned release, counted from when a patch for the affected component becomes available.

Item 6, open source components. Releasing a product with open source components that carry critical vulnerabilities is listed as a bad practice, as is failing to patch at no cost in a timely manner when exploitable vulnerabilities are later disclosed. The footnotes define critical as CVSS 9.0 or above and high impact as 7.0 or above. The recommended actions include routinely monitoring all open source dependencies for CVEs and for end-of-life status, and including the cost of updating to new major versions of open source dependencies in business planning so those dependencies keep receiving security fixes for the expected product life.

That last sentence is the one most maintenance-mode products miss. The day a framework your old product depends on reaches end of life upstream, your support promise starts costing more. Budget for it, or shorten the promise.

NIST SSDF: "all supported releases"

NIST SP 800-218, the Secure Software Development Framework version 1.1, groups vulnerability response practices under RV. Three tasks map to a maintenance-mode line:

  • RV.1.1 asks producers to gather information from acquirers, users and public sources on potential vulnerabilities in the software and its third-party components, and investigate all credible reports. One of its examples is to automatically review provenance and software composition data for all components to identify new vulnerabilities.
  • RV.1.2 asks producers to review, analyse or test the software to find previously undetected vulnerabilities. Its first example is to run automated code analysis and testing on a regular or continuous basis "for all supported releases".
  • RV.2.1 and RV.2.2 ask producers to analyse each vulnerability for risk and plan a response. RV.2.2's examples include making a risk-based decision to remediate or to address risk another way, applying a temporary mitigation when no permanent one exists, and publishing advisories that tell acquirers how to find and fix the vulnerable software.

PW.4.4, on verifying that acquired open source components stay well secured through their life cycles, rounds this out. A product that is still sold and supported is still inside the SSDF's scope, even if no feature work happens.

Federal patch timelines: what changed in 2026

On 10 June 2026 CISA issued Binding Operational Directive 26-04, "Prioritizing Security Updates Based on Risk". It revokes BOD 22-01 and BOD 19-02. It binds federal civilian agencies, not vendors, and sets remediation urgency from four variables: whether the asset is publicly exposed, whether the CVE is on the KEV catalog, whether exploitation can be automated, and whether the attacker gains partial or total control. Its Table 1 sets the timelines.

For a vendor, two things follow. BOD 22-01's KEV deadlines are history and should not appear in new contracts as if current. And federal customers now triage by exposure, KEV status, automation and impact, so patch notes and VEX statements that speak to those factors answer the question they are asking.

NIST SP 800-40: patching as preventive maintenance

NIST SP 800-40 Revision 4 (April 2022) is written for organisations that apply patches, but its framing helps here: patching is preventive maintenance and a cost of doing business. That is the argument to make when finance asks why a product with no new revenue still needs engineering time.

Who does what on a skeleton team?

The roles do not need headcount; they need names. Here is a worked example for a two-engineer team. It is illustrative, not a benchmark.

RoleWhoWhat they decide
Line ownerA director or VPThe support policy, the end-of-life date, and budget for major upgrades
Maintainer AEngineerWeekly triage, fix pull requests, maintenance release builds
Maintainer BEngineer, part timeReview, test, VEX statements, customer advisories
Product security contactShared with the successor teamWhether a finding is exploitable in the old product; advisory wording
Customer support leadSupport teamWhich customers run which versions; who to notify

And a rhythm that fits around other work:

  • Weekly, about an hour. Review new findings across supported versions. Anything on KEV or with a high EPSS score gets a decision that week: fix, mitigate, or document as not affected.
  • Monthly. Confirm scheduled scans ran, refresh accepted risks near expiry, and check for dependencies that reached end of life upstream.
  • Each maintenance release. Regenerate the SBOM from the release artifact and publish it with VEX for open findings that do not affect the release.
  • Twice a year. The line owner weighs the support policy against its cost. End-of-life decisions start here.

Our post on whether a small product team needs a PSIRT covers the incident side of this: who answers a researcher's report on a product nobody is building.

How do you keep an accurate SBOM for every supported version when builds are rare?

An SBOM is the only way a two-person team can answer "are we affected?" in minutes instead of days. For a maintenance-mode line it has to be per version, because 4.2 and 4.3 can carry different dependency trees, and customers run both.

What the SBOM must contain

CISA, the NSA, the FBI and international partners published "2026 Minimum Elements for a Software Bill of Materials (SBOM)" on 29 July 2026. It replaces the 2021 NTIA minimum elements, which should now be cited only as history. The CISA page says the new guidance reflects current SBOM tools and stakeholder feedback from a 2025 comment period while preserving the core principles of the NTIA original. Use it as the checklist your customers' procurement teams will use.

Generate it from what you shipped

For an old product, three rules keep the SBOM honest:

  1. Build it from the release artifact or the release tag's lockfiles, not from the default branch. The default branch has moved on. The customer runs the tag.
  2. Store one SBOM per released version and keep it. When a new advisory lands, you match it against stored SBOMs without rebuilding anything. A rebuild of a five-year-old product is exactly the work a skeleton team cannot afford on short notice.
  3. Regenerate on every maintenance release. Patch upgrades change the tree, and a stale SBOM is worse than none because it gives confident wrong answers.

Where the old build only runs on an old machine, run the SBOM tool there; the lockfiles and manifests in the checkout are all it needs.

Scan old versions on a schedule, not just at build time

Build-time scanning says little about a product built eight months ago. What matters is re-matching the stored inventory against new advisories on a schedule: weekly at a minimum, plus a manual re-check the day a high-profile advisory lands. Our post on scanning release branches and old versions on a schedule covers the mechanics.

Which findings deserve scarce engineering time?

Two engineers cannot fix everything, and they should not try. The SSDF's RV.2.1 asks you to analyse each vulnerability for risk; RV.2.2 lets you decide whether to remediate or respond another way. That is permission, from the framework itself, to triage hard.

Four signals, in order

  1. CISA KEV listing. The KEV catalog lists CVEs with reliable evidence of exploitation. Each entry carries a date added and a due date written for federal agencies, and since BOD 26-04 entries also note whether forensic triage is required. If a component in a supported version matches a KEV entry, it goes to the top of the list. This is also the item CISA's Bad Practices guidance names directly.
  2. EPSS probability. FIRST's Exploit Prediction Scoring System is a data-driven model that estimates the probability that a published CVE will be exploited in the next 30 days. It publishes a score between 0 and 1, with percentiles, every day for every CVE. Use it for what is not yet on KEV. A rising EPSS score on a component in your old product is an early warning.
  3. Reachability. A vulnerable function that the old code never calls is a much lower risk than one on a request path. Reachability analysis is imperfect, especially with reflection and dynamic dispatch, but for a team that must choose, it is the difference between a fix this week and a note in the next release.
  4. Exposure. Where does the old product run? An internet-facing portal module is different from a batch job behind a firewall. BOD 26-04 uses asset exposure as one of its four factors for exactly this reason. You do not know every customer's deployment, but you know which components face the network by design.

A decision table the team can apply in a weekly hour

KEV listedEPSSReachable in old codeNetwork facingDecision
YesAnyYes or unknownAnyFix or mitigate now; out of band release if the policy promises it
YesAnyNo, with evidenceAnyPublish a not affected statement with justification; fix in the next maintenance release anyway
NoHighYesYesFix in the next maintenance release, or sooner if the score keeps rising
NoHighNoAnyDocument; fix opportunistically
NoLowAnyAnyNext maintenance release if a safe upgrade exists; otherwise record and move on

"High" and "low" are your thresholds to set. Write them into the support policy so customers see the same rule the team applies. Our post on keeping a contract promise of no known exploited vulnerabilities covers how to word a KEV commitment so a small team can meet it.

When is a patch-only upgrade enough, and what if the only fix is a major version?

Old code was written against APIs that have since changed. A patch release of a dependency usually keeps the API; a major release usually does not. Upgrade size is the main risk control on a maintenance branch.

Prefer the smallest upgrade that fixes the issue

Popular components often publish fixes on more than one release line. When a fix exists on the line you already use, take it; a patch-level change should need little more than the existing tests and a smoke test.

Check the lockfile, not just the manifest. A fix in a transitive dependency often needs an override or resolution entry, because the direct dependency that pulls it in has not released a new version for the old line.

When the only fix is a major version

This is the hard case, and it is where many maintenance-mode lines quietly fail. The options, from cheapest to most expensive:

  1. Prove it does not affect you. If the vulnerable code is not present, not reachable or not controllable by an attacker in your product, publish a VEX not affected statement with the justification. This is not a dodge; it is what CISA's Bad Practices guidance asks for when a KEV is not exploitable in the product.
  2. Mitigate in your own code. Validate the input before it reaches the vulnerable function, disable the feature that exposes it, or change a default. SSDF RV.2.2's second example covers exactly this: a temporary mitigation until the permanent fix is available.
  3. Backport the fix. Take the upstream patch and apply it to the version you use, in a fork or a vendored copy. This works when the patch is small. It also means you now maintain that fork, so record it in the SBOM and in the support policy.
  4. Take the major upgrade. Sometimes there is no alternative. Budget it as the project it is. This is the cost CISA's Bad Practices item 6 asks manufacturers to plan for.
  5. Announce end of support for the affected version. If none of the above is affordable, the honest move is to tell customers that version will not receive the fix and give them a migration path.

Whichever you choose, say it in writing. Silence is the one option that fails every framework above. Our post on why dependency upgrade pull requests sit unmerged covers the review side: on an old branch, a large upgrade pull request with no owner tends to sit forever.

How do you tell customers a listed CVE does not affect the old version?

Customers scan what you ship, and their scanners flag every CVE in every component whether or not your product is affected. A machine readable "not affected" statement answers those questions once, for every customer.

What a VEX statement must say

CISA's "Minimum Requirements for Vulnerability Exploitability eXchange (VEX)", published 21 April 2023, sets the minimum content. Each statement links a vulnerability to a product and gives one of four statuses: not affected, affected, fixed or under investigation.

For "not affected", the document says a statement should give a justification, and if it does not, it must give an impact statement explaining why. The justification must be one of five values: component not present, vulnerable code not present, vulnerable code not in execute path, vulnerable code cannot be controlled by adversary, and inline mitigations already exist. For "affected", a statement must include an action statement that should describe how to remediate or mitigate.

Pick a format your customers' tools read

VEX is a set of minimum elements, not a single file format. The common carriers are CSAF 2.0 with its VEX profile (an OASIS standard), CycloneDX VEX and OpenVEX. Ask your largest customers which their tools ingest. Publish per version, because a statement that 4.3 is not affected says nothing about 4.2.

Rules that keep VEX honest

Use "under investigation" freely; it beats silence. Revisit statements on every maintenance release, because a code change can make a not affected statement false. And keep the evidence behind each justification, so you can defend it when a customer's auditor asks.

When is it time to announce end of life instead of carrying the product?

Every maintenance-mode line ends. The question is whether it ends on a date you chose or on the day a critical fix turns out to be impossible. Signals that the date should come sooner:

  • A key dependency reached end of life upstream and no fixed release line remains for the version you use.
  • The only fix for an exploited vulnerability is a major upgrade the team cannot carry, and mitigation is not credible.
  • The build itself is rotting. The toolchain, base image or build server needed to cut a release is itself unsupported.
  • The customer base has shrunk to a few accounts that could be migrated for less than the cost of carrying the line.
  • The team is down to one person with no backup.

When you announce, give a long notice period, publish the final dates in the same place as the support policy, and keep the SBOM and VEX for the last release available after end of life. Customers will still be running it. Our security checklist for sunsetting a product covers the retirement itself; this post is about the years before that.

How Safeguard does this job

Everything above can be done with open source tools and discipline. Safeguard puts the per-version inventory, exploitation and reachability signals, fix pull requests and not affected statements in one place, so the weekly hour goes on deciding. The steps follow Safeguard's documentation; where the docs do not show something, the step says so.

Step by step

  1. Model the product line (GA). Safeguard's organisation docs describe a hierarchy of Tenant, Organization, Project and Version. Create an organisation for the maintenance-mode line under Settings, Organizations, so its access, default policy and notification settings stay separate from the successor product. Projects are the scanning units, and the CI docs say each push becomes a new version named after its branch and commit, so scans of each maintenance branch show up as their own versions. Invite the maintainers and the line owner under Settings, Members.

  2. Scan each supported branch from CI (SCA and SBOM generation, GA; CLI, GA). The CI docs say one step in the pipeline runs safeguard ci scan, and each push becomes a new version of its project, named after the branch and commit. Create a secret key under Settings, Developer with the scopes scans:trigger and scans:read, and store it as SAFEGUARD_API_KEY. Templates scan pushes to main and pull requests into it; the docs say you can change the branches and that wildcards work, for example release/*, which covers maintenance branches. For any CI that runs a shell step, the docs show:

    curl -fsSL https://cli.safeguard.sh/install | bash
    SAFEGUARD_API_KEY=... safeguard ci scan --wait --fail-on critical \
      --repository-url "$REPO_URL" --branch "$BRANCH" --commit "$COMMIT"
    

    The docs also suggest pinning the CLI version with SAFEGUARD_VERSION=<version> on the install line, so a CLI release does not change a build under you. On a maintenance line that sees two builds a year, pin it.

  3. Scan on the old build server if that is where the build lives (GA). If the old product builds on a self-hosted or firewalled Git server, the docs show safeguard ci scan --local, which reads dependencies from lockfiles and manifests in the checkout on the runner and sends only the results. For a machine where you only want local files, the docs show safeguard scan --dir . --output out/, which writes results you can keep as build artifacts; it needs two open source scanning tools on the PATH, which the docs name, and it reports without failing the build.

  4. Re-check old versions between builds (GA). Because maintenance releases are rare, do not rely on build-time scans alone. Safeguard scans run on a schedule you set, on a manual Rescan, and from CI. Set a schedule for every supported release line, and run a manual Rescan when a high-profile advisory lands. This is the scanner doing RV.1.1's "automatically review software composition data" for you.

  5. Triage on the Vulnerabilities tab (vulnerability management with EPSS and KEV, GA; reachability analysis, GA). The Vulnerabilities docs list CISA KEV among the data sources alongside NVD, GitHub Security Advisories, OSV and vendor bulletins. Findings fall into Critical, High, Medium, Low and Exploitable, where Exploitable means known active exploitation in the wild. Each finding shows CVE ID, CVSS, EPSS, exploited status, affected component and version, fixed version and reachability. Filter by exploitable status, EPSS score range, fix availability and reachability status, which turns the decision table above into a saved filter. Treat "unreachable" in dynamic languages such as Ruby and PHP with extra care; Safeguard's docs say reachability filtering typically removes 60 to 80% of findings from the urgent queue, which is their stated figure, not a guarantee for your codebase.

  6. Put a floor under every maintenance release (policies and gates, GA). The simplest floor is the severity flag from step 2: with --wait, --fail-on <severity> fails the step on a dependency vulnerability at or above the level you choose. For a policy-based gate, the docs show --fail-on-gate <gate>, which fails unless the gate is Passed or Warning. Policies take one of three actions: Block, Warn or Notify, with approvals handled through exceptions. Two cautions from the docs. Policy outcomes are off until Safeguard turns them on for your workspace. And KEV and reachability are filters on the Vulnerabilities tab, not documented gate conditions, so confirm with Safeguard how to express "KEV listed" before a contract depends on that gate. SAST findings are not part of --fail-on yet; SAST is generally available.

  7. Open the fix as a pull request (AI Remediate, GA; autonomous remediation, GA, ships off). From a finding, the AI Remediate docs describe a flow: analyse the vulnerability, choose an upgrade path, assess breaking changes, open a pull request and run tests if configured. Click AI Remediate, review the proposed change and click Create Pull Request. Bulk AI Remediate opens one pull request per repository. Breaking change detection labels each change Safe, Minor, Major or Critical, which maps directly to the "smallest upgrade" rule above. Safeguard's offering describes a Safest strategy that applies backward-compatible fixes only. Autonomous remediation ships switched off, with every category set to Manual, and nothing is applied until your team turns it on. The docs do not say whether fix pull requests can target an old release branch rather than the default branch, so confirm that with Safeguard before you plan around it; if they cannot, the maintainer applies the proposed change to the maintenance branch by hand.

  8. Record decisions that are not fixes (GA). On the Vulnerabilities tab, Mark False Positive takes a justification and can require approval by policy, and Accept Risk takes an expiration date and a business justification. Use expiry dates that match your monthly review, so accepted risks resurface instead of aging silently.

  9. Upload VEX for each supported version (CSAF and VEX upload, GA). Go to Integrations, filter by Upload, and click Connect on the Upload CSAF/VEX card. Enter a name, drop in the file, which is validated automatically, then set the project name and version and click Upload. Supported formats are CSAF 2.0, CycloneDX VEX, OpenVEX and the CSAF VEX profile. The docs say uploads can mark vulnerabilities as not affected for your products and document mitigation status. Setting the version on upload is what keeps a statement about 4.3 from leaking onto 4.2.

  10. Publish SBOMs per version to customers (Portal, GA). Portal here means Safeguard's SBOM publish and share product, not the free entry tier of the same name. In its SBOM Repository, you create a Product with name, SKU and description and associate SBOMs with it, track versions from git tags or manual assignment, and compare two versions to see added and removed components, version changes, and new and resolved vulnerabilities. That comparison is a ready answer to "what changed in this maintenance release?" Existing SBOMs can be imported with Import SBOM. Use the in-app flow; the API shown on that docs page is not available yet.

  11. Triage from an assistant on the days you have ten minutes (MCP server, GA). The Claude docs say you can add Safeguard from Claude's connector directory, where it is listed as a community connector, or as a custom connector at https://mcp.safeguard.sh/mcp/anthropic, signing in with OAuth. A new workspace starts with a small read-only set of tools, and an administrator turns on more per tool. For a part-time maintainer, asking which supported version carries a newly listed CVE is quicker than opening three projects.

Requirement, Safeguard, and what you still own

RequirementSourceWhat Safeguard doesWhat you still own
State the support period at sale; patch through itCISA Bad Practices item 13Nothing; this is policyThe written support policy and the dates
Find new vulnerabilities in all supported releasesSSDF RV.1.1, RV.1.2Versions per branch and commit; CI scans on maintenance branches; scheduled scans and manual Rescan (SCA, GA)Setting a schedule for every supported line; scanning artifacts built outside CI
SBOM per release that meets current minimum elementsCISA 2026 Minimum ElementsSBOM generation in SPDX and CycloneDX (GA); Portal versioning and comparison (GA)Generating from the release artifact; keeping old SBOMs
Prioritise by exploitation and riskSSDF RV.2.1; BOD 26-04 factors (for agency customers)KEV and EPSS enrichment, Exploitable category (GA); reachability (GA)Exposure judgement; thresholds
Patch exploitable KEVs at no cost, in a timely mannerCISA Bad Practices item 5AI Remediate pull requests; autonomous remediation (GA, ships off, every category Manual)Reviewing, testing on the old branch, cutting the release
Document KEVs that are not exploitable, ideally as VEXCISA Bad Practices item 5 and footnoteCSAF and VEX upload per project version (GA)Writing accurate statements with justifications
Release gateSSDF RV.2.2 risk response--fail-on and --fail-on-gate (GA); policy outcomes off until enabledConfirming the gate covers what the contract promises
Budget major upgrades for open source dependenciesCISA Bad Practices item 6Shows which components need a major version to fixThe budget and the decision

What Safeguard does not do

  • It does not set your support policy or your end-of-life date. Those are business decisions with contract consequences. Safeguard can show the cost of carrying a line in findings and fixes; it cannot decide whether that cost is worth paying.
  • It does not make an incompatible major upgrade safe on old code. Breaking change detection flags risk and the Safest strategy keeps to backward-compatible changes, but when the only fix is a major version, someone still has to adapt the code or choose another response.
  • It does not confirm, in its docs, that fix pull requests can target an old release branch. Check with Safeguard before relying on it; plan for a maintainer to apply the change to the maintenance branch if not.
  • It does not write your VEX statements. Uploads record your statements; the justification is your assertion and needs your evidence behind it.
  • It does not see what it was never shown. Artifacts built outside the scanned branch, vendored copies without manifests, and binaries added at packaging time need their own scan or SBOM upload.
  • It does not publish lifecycle dates in a machine readable format. OpenEoX is not final yet, and Safeguard's docs do not describe publishing support dates.
  • Fork and patch is generally available. It is not part of this flow, so do not plan a maintenance commitment around it without asking which packages it covers.
  • Autonomous remediation is off until you turn it on. Every category starts as Manual. That is deliberate, and on an old branch it is the right default.

Common mistakes

  • Scanning only the default branch. The main branch says nothing about the 4.x line customers run. Scan every supported branch.
  • Rebuilding to find out what shipped. If you have to rebuild a five-year-old release to answer a customer, you have no per-version SBOM. Generate and keep one on every release.
  • Triaging by CVSS alone. It fills the queue with unreachable criticals and buries exploited highs.
  • Taking a major upgrade on a maintenance branch to clear a scanner finding. A broken release on an old line costs more trust than the CVE it fixed. Mitigate or document instead, and say so.
  • Answering customer scanner reports one email at a time. Publish VEX per version and point every customer to it.
  • Blanket not affected statements. "The 4.x line is not affected" is rarely true for every 4.x release. Be specific.
  • Letting accepted risks never expire. Set expiry dates and review them monthly.
  • Announcing end of life after the crisis. An end-of-life date chosen on the day a fix proves impossible looks like abandonment. Choose it early, publish it, and keep it.
  • No named owner. A line with no owner has no one to make the calls above.

FAQ

How do we keep legacy software secure with a small team?

Narrow the scope in writing, keep a per-version SBOM, re-scan supported versions on a schedule, fix what is exploited or likely to be and reachable, take patch-level upgrades, and publish VEX for the rest.

What does CISA say about end-of-support dates for software?

CISA's Product Security Bad Practices, version 2.0 (January 2025), says manufacturers of on-premises products should clearly communicate the support period at the time of sale and provide security updates through the entire support period. It is voluntary guidance aimed at products used in critical infrastructure.

Do we have to patch old versions when a new CVE comes out?

Only the versions your support policy covers, and only to the extent the policy promises. For KEV-listed vulnerabilities that are exploitable in the product, CISA's guidance asks for a timely patch at no cost; for those that are not exploitable, it asks for public documentation, ideally VEX.

Is BOD 22-01 still in force for KEV patch deadlines?

No. CISA's BOD 26-04, issued 10 June 2026, revokes BOD 22-01 and sets risk-based timelines for federal agencies from four factors: exposure, KEV status, exploit automation and technical impact. It binds agencies, not vendors, unless a contract carries it through.

What should we do when the fix requires a major version upgrade?

In order of cost: prove the vulnerability does not affect you and publish VEX, mitigate in your own code, backport the upstream patch, take the major upgrade as a planned project, or announce end of support for that version. Whatever you choose, tell customers in writing.

What is a VEX not affected justification?

CISA's VEX minimum requirements list five: component not present, vulnerable code not present, vulnerable code not in execute path, vulnerable code cannot be controlled by adversary, and inline mitigations already exist. If you give no justification, you must give an impact statement explaining why.

Does NIST SSDF apply to products in maintenance mode?

SP 800-218 does not exempt them. RV.1.2's first example is automated analysis and testing "for all supported releases", and RV.2.2 covers risk responses including temporary mitigations and advisories.

When should we end-of-life an old product?

When a key dependency has no fixed release line left for your version, when exploited vulnerabilities need major upgrades the team cannot carry, when the build toolchain itself is unsupported, or when the team is down to one person. Announce early and keep the final SBOM and VEX available afterwards.

When the old line cannot take the fix

For a maintenance-mode product, the hardest weeks are the ones where a fixed version exists only on a release line the old code cannot take, or where no fix exists at all. The options below are Safeguard's general remediation paths for open source components; on an old branch, read them alongside the smallest-upgrade rule above, and note which parts are early access.

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 categories include dependencies, licenses, security posture and findings, and each one is set separately. 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.

3. Gold Registry: start from components that are already fixed

Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) 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. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull 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. It installs the CLI, opens the interactive terminal with safeguard, and asks it to "fix the lodash CVE in this repo". The CLI 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 approval, prints a summary and pushes nothing. It then shows /permissions, /model and /scan .. On a maintenance branch, this is the shape of a patch-level fix a part-time maintainer can review step by step.

Click through it at your own pace, or open it full screen.

The second demo connects Claude to the Safeguard MCP server with OAuth and chooses which tools Claude can use. For a skeleton team, that is the low-effort triage path: ask which supported version carries a CVE, with the assistant limited to the tools you allow.

Click through it at your own pace, or open it full screen.

To try it on your own maintenance branches, download Safeguard at safeguard.sh/download and read the setup guides at docs.safeguard.sh.

Quick check

A KEV-listed CVE affects a component in version 4.2 of your maintenance-mode product, but the vulnerable function is never called. What does CISA's Bad Practices guidance ask for?

If the KEV is not exploitable in the product, CISA asks the manufacturer to publicly document the presence of the vulnerability, ideally as VEX. A not affected statement with the "vulnerable code not in execute path" justification, scoped to version 4.2, does that.

Why keep a separate SBOM for each supported version instead of one for the product line?

Because different maintenance releases carry different dependency trees, and customers run specific versions. Stored per-version SBOMs let you match new advisories without rebuilding old releases, and keep not affected statements from applying to versions they do not cover.

Sources

Last reviewed: 24 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.