To plan end-of-support upgrades across a legacy Java and .NET estate, first build an inventory of the runtime, framework and key libraries behind every application, then map each one to the vendor's published support dates. Score every application on risk and on migration effort, decide renew or migrate one application at a time, and run the moves in waves with a build gate that stops new end-of-life components from entering behind you.
That is the whole method. The hard part is doing it across several hundred applications, many of them written by people who left years ago, with a support renewal quote sitting in your inbox that went up again. This guide is written for the VP or Director of Engineering who has to answer one question for the CIO this quarter: do we pay for another year of extended support, or do we finally move, and what does the move really cost? It works with the tools you already have. Safeguard comes in near the end, with its limits stated plainly. Nothing here is legal or regulatory advice; your counsel and your examiners decide what applies to your company.
Key takeaways
- Treat the renewal as an estate decision, not a contract decision.
- The dates that drive 2026 and 2027 planning, from the vendors' own lifecycle pages as of this week: .NET 8 and .NET 9 both reach end of support on November 10, 2026; .NET Framework 4.6.2 ends in January 2027; Oracle lists Java SE 17 Premier Support through September 2026 "or later", with Extended Support to September 2029; Java SE 8 Extended Support runs to December 2030 and Java SE 11 to January 2032.
- New York's cybersecurity regulation (23 NYCRR 500.13) now asks for an asset inventory that tracks each asset's support expiration date. The NAIC Insurance Data Security Model Law asks for a risk-based program and an annual written report to the board.
- NIST SP 800-40 Rev. 4 gives you the vocabulary for the risk committee: accept, mitigate, transfer or avoid, plus a separate plan for assets that can never be patched.
- Decide per application with a simple matrix: business criticality and data sensitivity on one axis, migration effort on the other. Renew only where the move is genuinely expensive and the risk is contained, and always with an end date.
- Run upgrades in waves of similar applications, and turn on a gate in CI so no new project starts on a runtime or library you have already scheduled for retirement.
- Safeguard supports the inventory, the watching and the gating: SBOM generation and SCA across ecosystems (GA), vulnerability management (GA), policies, gates and guardrails (GA), products that group projects into business applications (GA), and autonomous remediation (GA, ships off with every category set to Manual) for library upgrades. It does not migrate code, test business logic or negotiate your support contract.
The situation
The renewal notice arrives about ninety days out. It covers extended support for an old runtime, perhaps a commercial JDK subscription that keeps Java 8 patched. The price is higher than last year, and procurement wants a yes or no by month end.
You cannot answer it from the contract. The contract says how many processors or employees are licensed. It does not say which of your four hundred applications run on that runtime, which handle policyholder data, which are being retired anyway, and which would take two engineers a fortnight to move versus two teams a year.
A bad week looks like this. Finance asks why the support line grew. The CIO asks how many applications are affected, and three teams give three different numbers. Someone in claims mentions a batch job nobody has rebuilt since 2019. Risk asks whether any of this is in the regulator's asset inventory. The default answer, because there is no time to do better, is to renew for another year. That is how a one-year bridge becomes a five-year habit.
The way out is a repeatable inventory you can rerun every quarter, a small set of rules for deciding per application, and a gate that stops the problem regrowing while you work it down.
How regulators view unsupported software
Insurance engineering leaders do not need the full regulatory text, but you need to know which sentences your CISO and risk team will hold you to, because they change what "renew for another year" has to come with.
New York: support expiration dates belong in the asset inventory
If your company is licensed in New York, 23 NYCRR Part 500 applies. Section 500.13(a) requires written policies and procedures for a complete, accurate and documented asset inventory of your information systems. At a minimum those procedures must track key information for each asset, and the list in 500.13(a)(1) includes owner, location, classification or sensitivity, recovery time objectives and, at item (iv), the "support expiration date". The procedures must also set how often the inventory is updated and validated.
Timing matters. The transitional section, 500.22, gave covered entities two years from the effective date of the second amendment to comply with 500.13(a). The second amendment took effect on November 1, 2023, so the inventory requirement has applied since November 1, 2025. If your inventory does not carry support dates for the runtimes and frameworks your applications depend on, that is a gap your CISO already knows about.
Section 500.5 adds vulnerability management: automated scans plus manual review of what scans miss, a monitoring process for new vulnerabilities, and timely remediation prioritised by risk. An unsupported runtime makes that last clause hard to meet, because for some new vulnerabilities there will be no fix to apply.
The NAIC Insurance Data Security Model Law
Most states regulate insurer cybersecurity through laws based on the NAIC Insurance Data Security Model Law (#668), adopted in 2017. Its drafting note says a licensee that complies with New York's Part 500 is intended to comply with the model law as well. Three parts are worth knowing:
- Section 4C (risk assessment) asks you to identify reasonably foreseeable threats, assess the sufficiency of your safeguards in areas that explicitly include "network and software design", and assess the effectiveness of key controls at least annually.
- Section 4D (risk management) asks you to design the program to mitigate the risks you found, to identify and manage the systems that support the business in line with their importance, to adopt secure development practices for in-house applications and procedures for evaluating externally developed ones, and to include cybersecurity risk in enterprise risk management.
- Section 4E (board oversight) asks executive management to report in writing at least annually on the program, including material matters such as risk management and control decisions.
Your state's version may differ in wording and dates, so check it with counsel. The practical point is simple: a decision to keep running unsupported software is a risk management decision, it should be recorded as one, and it will appear in the annual report to the board whether you plan for it or not.
CISA's Product Security Bad Practices
CISA's Product Security Bad Practices guidance is voluntary and aimed at software manufacturers, not buyers. The January 2025 version added a bad practice about support periods: for on-premises products, not clearly communicating the period of support is called out, and the recommended action is to state the support period at the time of sale and provide security updates throughout it.
The same document asks manufacturers to monitor open source dependencies for vulnerabilities "or other security-relevant alerts, such as end-of-life", and to budget for moving to new major versions. For an insurer it describes what good looks like for software you build for agents and policyholders, and gives you a fair question for every vendor you buy from.
NIST SP 800-40 Rev. 4: the language for the risk committee
NIST SP 800-40 Rev. 4 (April 2022) frames patching as preventive maintenance, "a cost of doing business", and names four risk responses for vulnerable software: accept, mitigate, transfer and avoid. It notes that upgrading to a version without the vulnerability is one of the only responses that removes the problem without removing functionality, and it lists end-of-life as a reason that is sometimes not possible: the vendor no longer supports the software, so a patch will never come.
Section 3.5.4 covers unpatchable assets. It asks organisations to plan several long-term mitigations besides patching, such as isolation and segmentation, and to periodically re-evaluate them with both a risk assessment and a cost-benefit analysis that compares the value of the asset with the extra cost of mitigating, transferring or accepting its risk. That cost-benefit analysis is your renew-or-migrate decision, written in the language your risk committee already uses.
Which end-of-support dates matter for Java and .NET in 2026 and 2027
Start with the vendors' own pages, not a summary. The dates below were read from Oracle's Java SE Support Roadmap (updated October 20, 2026), Microsoft's .NET and .NET Core support policy (updated October 13, 2026) and Microsoft's .NET Framework lifecycle page. Check them again before you put them in a board paper; vendors adjust these pages.
| Runtime | What the vendor page says | Why it matters now |
|---|---|---|
| .NET 8 (LTS) | End of support November 10, 2026 | Weeks away. Anything still on .NET 8 needs a plan now |
| .NET 9 (STS) | End of support November 10, 2026 | Same day as .NET 8. Teams that moved to 9 to get ahead are not ahead |
| .NET 10 (LTS) | End of support November 14, 2028 | The current landing zone for .NET migrations |
| .NET Framework 4.6.2 | Support ends in January 2027 (listed as 13 January 2027, 06:59 UTC, which is the evening of 12 January in US time zones) | Move to 4.8 or 4.8.1 at minimum |
| .NET Framework 3.5 SP1 | Support ends in January 2029 (listed as 10 January 2029 UTC) on the systems where it is a standalone product | Older line-of-business code often still targets it |
| .NET Framework 4.7 to 4.8.1 | Follow the Component Lifecycle Policy, tied to the Windows version they run on | No fixed date, but tied to your Windows server plans |
| Java SE 8 (LTS) | Premier Support ended March 2022; Extended Support until December 2030 | Paid support is available for years; the question is whether paying is wise |
| Java SE 11 (LTS) | Premier Support ended September 2023; Extended Support until January 2032 | Same shape as Java 8 |
| Java SE 17 (LTS) | Premier Support until September 2026 "or later"; Extended Support until September 2029 | Just moved into Extended Support |
| Java SE 21 (LTS) | Premier Support until September 2028; Extended Support until September 2031 | A sound target for most Java moves |
| Java SE 25 (LTS) | Premier Support until September 2030; Extended Support until September 2033 | The newest LTS; the next is planned as Java 29 in September 2027 |
A few details from those pages change the decision:
- Oracle has waived some Extended Support fees. The roadmap says the Extended Support fee for Java SE 17 is waived from October 2026 to September 2029, and the uplift fee for Java SE 11 and Java SE 8 is waived for periods ending January 2032 and December 2030. Check how that applies to your contract; it can change the renewal arithmetic more than any engineering estimate.
- Oracle's dates are examples of its policy. The footnote points customers to the Oracle Lifetime Support Policy, and products that embed Java can have different timelines.
- Licensing moved too. Oracle says JDK 21 updates released from October 20, 2026 are offered under the Java SE OTN license. That is part of what the move really costs.
- Microsoft supports the latest patch only. The .NET policy says you need the latest patch installed to qualify for support, and the final six months of a release are a maintenance period.
- Not everything is Oracle JDK. Many estates run OpenJDK builds from other distributors, each with its own schedule. Map each application to the distribution it actually runs.
For the vendor-specific detail, we have covered several of these dates on their own: see runtime end-of-support dates to watch before the end of 2026, Java 8 Premier and Extended dates and .NET Framework 4.6.2 ending in January 2027. If the terms themselves get muddled in meetings, what end of sale, end of support and end of life each mean is a useful one-page share.
Runtimes are only the top layer. Application servers, web frameworks and ORMs have their own schedules, and a runtime upgrade often forces a framework upgrade, which forces library upgrades. Give every widely used framework a row in your lifecycle table: version, support end, paid support end if any, and the source page.
Step by step, with or without Safeguard
The six steps below work with any tooling. Each has an output you can show someone.
Step 1. Build the estate inventory
You need one row per application per runtime, with enough detail to decide. The minimum columns:
| Column | Example | Where it comes from |
|---|---|---|
| Application and business owner | Commercial lines rating, VP Commercial Underwriting | CMDB or application portfolio list |
| Repositories and deployables | Three services, one batch job, one UI | Source control, build system |
| Runtime and exact version | Java 8u-something, .NET Framework 4.6.2 | Build files, container images, servers |
| Runtime distribution | Oracle JDK, another OpenJDK build, Microsoft .NET | Images and server packages |
| Key frameworks and versions | Application server, web framework, ORM | Build manifests and lockfiles |
| Data class | Policyholder PII, claims health data, internal only | Data classification register |
| Exposure | Internet facing, partner facing, internal | Network and architecture records |
| Support end date and source | December 2030, Oracle roadmap | Your lifecycle table |
| Planned retirement, if any | Replaced by new platform in 2027 | Portfolio plan |
Survey teams only for owner, data class and retirement plans. Versions should come from the code and the artefacts; surveys about versions are where the three different numbers come from.
How do you inventory runtimes, frameworks and libraries across hundreds of applications?
There are four sources of truth, and you need at least two of them per application.
- Build manifests and lockfiles. Maven and Gradle files for Java, project and lock files for .NET. They give the target framework and every declared library, and cover most of the estate quickly.
- Container images. The base image and its layers show which runtime actually runs in production, which is not always what the build file targets.
- Built artefacts. For applications whose source is lost or no longer builds, the JAR, WAR or EAR file, or the DLLs on the server, are the only evidence.
- Servers. This is where you find the shared JRE that seven applications use and nobody owns.
Generate a software bill of materials (SBOM) for each deployable from the first three sources, in SPDX or CycloneDX, and keep them. Once you have them, "which applications use this framework below version X" becomes a query, not a project. Expect a long tail of applications that do not build, repositories nobody can find, and vendor products where you must ask the vendor.
Before anyone uses the inventory for a decision, pick twenty applications at random and have an engineer confirm the runtime on the running host. If more than a couple are wrong, fix the method, not the rows.
Step 2. Map every row to a support date
Join the inventory to your lifecycle table. Each runtime and framework row gets three dates: when free or standard support ends, when paid extended support ends (if available), and when the vendor stops all fixes. Add a status column with four values:
- Supported: inside standard support with the latest patches.
- Approaching: standard support ends within twelve months.
- Paid support: outside standard support, covered by a contract you are paying for.
- Unsupported: no vendor fixes at any price.
Now you can answer the CIO's first question with numbers: how many applications are in each status, how many of the "paid support" ones depend on the contract up for renewal, and how many are "unsupported" already.
Step 3. Score risk and effort per application
Two scores, each from 1 to 5, kept deliberately simple so teams can score their own applications in an afternoon and you can challenge the outliers.
Risk score (higher is worse):
| Factor | 1 | 3 | 5 |
|---|---|---|---|
| Data handled | Internal only | Business confidential | Policyholder PII, health or payment data |
| Exposure | Internal network only | Partner or agent facing | Internet facing |
| Support status | Supported | Paid support | Unsupported |
| Known exploited vulnerabilities in its components | None | Present but mitigated | Present and reachable from outside |
Take the highest factor, not the average. A rating engine that only talks to internal systems but carries health data is a 5 for data, and averaging would hide that.
Effort score (higher is harder):
| Factor | 1 | 3 | 5 |
|---|---|---|---|
| Jump size | Patch or minor version | One major version | Several major versions, or Framework to modern .NET |
| Framework coupling | Libraries upgrade cleanly | One framework needs a major upgrade | Application server or framework is itself end of life |
| Test coverage | Good automated tests | Partial, some manual regression | None, regression is a manual business test cycle |
| People | Active team that owns it | Team exists, knowledge thin | No owner; original authors gone |
| Build health | Builds and deploys from CI | Builds with effort | Does not build from source |
Use the average for effort, then sanity-check the 5s by asking the team for a rough engineer-week range. The aim is relative ordering, not a precise estimate.
Step 4. Decide renew or migrate per application
This is the step most programmes skip, and it is the one that controls cost.
How do you decide renew versus migrate per application?
Put every application on a two-by-two of risk against effort, then apply the rule for its quadrant.
| Low effort (1 to 2.5) | High effort (above 2.5) | |
|---|---|---|
| High risk (4 to 5) | Migrate first. Cheap and urgent; these are your first wave | Migrate, but fund it as a project. Bridge with paid support and compensating controls, with a hard end date |
| Low risk (1 to 3) | Migrate in the normal course of work. Fold into feature releases | Candidate to renew support, retire or replace. Do not spend migration money here first |
Then apply four overrides before you sign anything:
- If the application is scheduled for retirement before the support period ends, renew or accept. Do not migrate something you are about to switch off. Write the retirement date into the decision and check it is real.
- If a vendor product embeds the runtime, the vendor decides. You cannot upgrade the JDK inside a vendor's application server. Ask the vendor for their support period and roadmap (the CISA guidance gives you a fair way to ask) and treat it as third-party risk.
- If the jump forces a framework rewrite, split the decision. Sometimes the honest answer is a two-step move: runtime first to buy time, framework next year.
- If paid support costs less than one year of migration effort for that application, and its risk is contained, renewing is rational. Record it as risk acceptance with an end date, the compensating controls, and the trigger that would reopen the decision (for example, a known exploited vulnerability in that runtime with no fix in your support tier).
A worked example, illustrative and with round invented numbers: an estate of 400 applications, of which 120 depend on the runtime under renewal. Scoring puts 20 in high risk and low effort, 25 in high risk and high effort, 50 in low risk and low effort, and 25 in low risk and high effort. Ten of the last group are scheduled for retirement next year. A defensible decision: migrate the 20 this quarter, fund the 25 hard cases as an eighteen-month project with paid support as their bridge, fold the 50 into normal release work, retire the 10 and renew the remaining 15 with an end date. If the contract can be scoped, the renewal covers 40 applications instead of 120, each with an exit date. Redo the arithmetic with your own counts and pricing.
Step 5. Sequence waves and prevent backsliding
How do you sequence waves and prevent backsliding?
Group applications into waves by what they share, not by org chart. Applications on the same runtime, the same application server and the same build pattern should move together, so the second team reuses what the first team learned. A typical order:
- Wave 0, the path finders. Two or three representative applications from different groups. Their job is the upgrade runbook: build, framework, test and deployment changes, and the problems you hit.
- Wave 1, high risk and low effort. These go quickly and retire the most risk per engineer-week.
- Wave 2, shared platforms. Base images, shared libraries, internal frameworks and the batch platform, which unblock many applications at once.
- Wave 3 onward, the long tail by family. All the claims services, then all the agent portal services, and so on.
- The hard cases, as funded projects. Each with its own plan and its own bridge of paid support.
Each wave needs an entry and exit gate. Entry: the application has an owner, a test approach and a target version. Exit: the application runs on the target in production, the old runtime is removed from the host or image, and the inventory shows the new version.
Backsliding is the quiet failure. While you migrate a hundred applications, a new service is started from an old template, a team copies a Dockerfile from a 2019 repository, or a library pulls an old transitive dependency back in. Three controls stop it:
- A sunset list. A short published list of runtime and framework versions that are no longer allowed for new work, with dates. Keep it next to your lifecycle table.
- A gate in CI. Every build checks its components against the sunset list. New projects fail outright. Existing projects get a warning first, then a block on a published date. The gate is what turns the list into a habit.
- Golden templates. New service templates and base images on the target runtime only, maintained by the platform team. Make the right path the easy path.
Exceptions will be needed. Give them an owner, a reason and an expiry date, and review expired exceptions in the same meeting that reviews the waves.
Step 6. Report progress in the same shape every month
Pick five numbers and keep their definitions fixed: applications by support status, applications by wave, open exceptions and those expiring this month, known exploited vulnerabilities in unsupported components, and builds blocked by the gate. If the trend is flat for two months, the programme has stalled.
What do you tell the CIO and the risk committee?
The CIO wants a decision and a cost. The risk committee wants to know the risk is understood, owned and time-bound. One page can serve both if it is built from the steps above.
A template you can adapt:
| Section | What to put in it |
|---|---|
| The decision | Renew support for these applications, for this period; migrate these, in these waves |
| The estate in numbers | Applications by support status; how many depend on this contract; how many are already unsupported |
| Why not renew everything | The count that would stay on paid support indefinitely, and the trend if nothing changes |
| Why not migrate everything now | Effort scores for the hard cases; what migrating them this year would displace |
| Risk accepted, and its limits | Applications staying on paid or no support, the compensating controls, the end date and the reopen trigger for each |
| Regulatory position | How the inventory meets your support date tracking obligations; how accepted risk will appear in the annual board report |
| What we need | Funding for the hard cases, the platform team's time for templates and base images, the gate turned on by a date |
| How you will know | The five monthly numbers and their targets |
Use NIST's four words: for each group, say whether you are accepting, mitigating, transferring or avoiding the risk, and why. And separate the contract decision from the engineering plan, because the contract can often be shortened or scoped once the plan exists. Our post on questions to ask about extended support after end of support covers what to ask the vendor before you sign.
How Safeguard does this
Safeguard does not make the renew-or-migrate decision and does not move code between runtimes. What it does is produce and keep the component inventory per application, watch it for new vulnerabilities, let you ask estate-wide questions in plain language, and enforce the sunset list in CI. Each step below names the screen or command only where Safeguard's docs show it.
1. Mirror your portfolio in organizations
Safeguard's hierarchy is tenant, then organization, then project, then version. Create an organization per portfolio (for example personal lines, commercial lines, claims and shared platforms) under Settings → Organizations with + New Organization. Each organization can carry a default policy. Group engineers into teams under Settings → Teams, and give risk and audit colleagues the read-only Viewer role.
2. Connect repositories and images to generate SBOMs
SBOM generation and SCA across ecosystems are GA. From Integrations in the sidebar, click Connect on the GitHub, GitLab, Bitbucket or generic Git card. For private repositories you enter credentials and verify them, then choose the workspace and repositories, set the branch or tag, the project name and the version, and click Connect. Container images connect the same way from Amazon ECR, Docker Hub, Google Cloud or any OCI registry, and you can upload a package manifest file when that is all you have.
Each connected repository becomes a project with its own SBOM, listed under Projects with findings and vulnerability counts. The docs say Safeguard scans every project daily for newly disclosed vulnerabilities, and you can add scanning on push, on a schedule or on release. SBOMs export as SPDX or CycloneDX, as well as CSV, Excel and PDF.
3. Reach the applications that live outside source control
For applications that do not build, sit on isolated hosts or exist only as artefacts, use the Safeguard CLI (GA). The docs show:
# Install the CLI
curl -fsSL https://cli.safeguard.sh/install | bash
# Scan a local directory, writing results under ./output
safeguard scan --dir .
# Scan a container image
safeguard scan --image myregistry.azurecr.io/myapp:v1 \
--registry-username "$REGISTRY_USER" \
--registry-password "$REGISTRY_PASSWORD"
# Bring in an SBOM you already have (SPDX or CycloneDX)
safeguard scan --sbom sbom.json
The CLI support matrix lists Maven, Gradle and Scala SBT for the JVM, and NuGet project files, Paket and .NET Core deps.json files for .NET. It also lists binary file types, including Java archives (JAR, WAR and EAR) and Windows executables, installers and DLLs, which matters for the applications whose source is gone. A scan from the interactive terminal while signed in uploads the SBOM and findings to the platform; the docs say your source never leaves the machine. We have not run these commands for this post; they are copied from the docs.
4. Group projects into products that match your applications
Products are GA. A product groups several projects so you see combined risk for one business application. A policy administration system with three services, a batch job and a UI becomes one product, which is the unit your renew-or-migrate decision is made on.
5. Ask estate-wide questions in plain language
Search, powered by Safeguard's Griffin models, works across every SBOM you have access to. The docs show plain lookups by component name, or name and version, and plain-English questions; one example on the docs page is "Show outdated dependencies in the payments service". Component results list the projects where each component is used. For an end-of-support programme, the useful questions are the ones you would otherwise ask twenty teams: which projects use a given framework version, which projects in the claims organization carry critical vulnerabilities, which components are outdated in a product. You can star searches you rerun every month and export results as CSV, JSON or PDF for the board pack.
6. Read each application's detail
Open a project to see its Project Overview. The Dependencies tab shows the full tree and a table with each component's version, license, vulnerability count and last updated date. The Vulnerabilities tab shows severity, affected components and fix recommendations. Vulnerability management is GA, with detection from public databases including CISA's Known Exploited Vulnerabilities catalog. The Mitigations tab records risk acceptances with expiration dates, which is where a "renew with an end date" decision can live next to the code it applies to.
7. Turn the sunset list into policies and gates
Policies, gates and guardrails are GA. Under Settings → Policies, click Create Policy, define conditions with the visual builder or YAML, set severity and the action, then save and enable. The documented conditions include vulnerability severity, CVSS and EPSS scores, license, component age (the example is no components older than two years) and maintenance (no abandoned packages), and there is a No Abandoned Packages template.
Safeguard's policy outcomes page says each policy runs its starred search whenever it is evaluated on a gate. In practice that means the search you wrote in step 5 for the versions on your sunset list is the natural basis for the policy that enforces it.
Each policy has one action, and the docs define three:
| Action | What happens when the policy fails |
|---|---|
| Block | The gate fails |
| Warn | The gate passes, with a warning naming the policy |
| Notify | The gate passes, and Safeguard sends a notification to your configured channels |
That maps directly to the backsliding plan: Block for new projects, Warn for existing projects during the migration window, Notify for the platform team when something new matches. Approval for a genuine exception runs through Safeguard's exception workflow: a developer clicks Request Exception, picks the policy and finding, gives a business justification and an expiration date, and approvers decide, with an audit trail recorded. The docs note that policy outcomes are switched on per workspace by Safeguard, so check that the Outcome column appears on your Gates and Policies tables.
8. Enforce the gate in CI
The CI integration page shows one shell step. Create a secret key under Settings → Developer with the scopes scans:trigger and scans:read, store it in CI as SAFEGUARD_API_KEY, and add the step:
curl -fsSL https://cli.safeguard.sh/install | bash
SAFEGUARD_API_KEY=... safeguard ci scan --wait --fail-on-gate <gate>
Per the policy outcomes page, the step exits 0 when the gate is Passed or Warning, and non-zero when it is Failed (printing the Block policies that failed), Error or Not evaluated. With the --local flag the scan runs on the runner and only results leave it, which suits self-hosted Git servers. We have not run this snippet for this post.
9. Upgrade libraries with fix pull requests
For library upgrades, Safeguard's Griffin models can open fix pull requests from the Vulnerabilities tab (the AI Remediate button). Autonomous remediation is GA and ships switched off, with every category set to Manual. Its dependencies category covers outdated or deeply nested dependencies. This clears the library debt that blocks a runtime move; it does not perform the runtime move.
10. Watch progress and report
The dashboard shows top risks, fix rate and a component health trend that includes outdated components over time, with PDF export and scheduled weekly or monthly reports. Policies add exception history and violation trends, and Settings → Audit Log records who changed what.
What each step of the programme maps to
| Programme step | What Safeguard does | What you still own |
|---|---|---|
| Inventory | SBOM per project from repositories, images, manifests and binaries; products group projects into applications | Owner, data class, exposure and retirement plans |
| Map to support dates | Component and version per project; plain-language search across the estate | The lifecycle table of vendor dates and its sources |
| Score risk | Vulnerabilities by severity, EPSS and KEV per project | Data sensitivity and business criticality scores |
| Score effort | Dependency tree and outdated components per project | Test coverage, team capacity, framework rewrite estimates |
| Decide | Risk acceptance with expiry in Mitigations; exceptions with expiry | The decision, the contract and the signature |
| Waves | Fix pull requests for library upgrades (ships off by default) | Runtime and framework migration, testing, release |
| Prevent backsliding | Policies with Block, Warn or Notify; CI gate step | The sunset list and template images |
| Report | Dashboard trends, exports, scheduled reports, audit log | The board narrative and regulatory filings |
What Safeguard does not do
- It does not migrate code. Moving from .NET Framework to modern .NET or from Java 8 to Java 21 involves API changes, framework replacements and build changes. Safeguard's fix pull requests suit library version upgrades much better than runtime migrations; plan engineering time for the migrations.
- It does not test your business logic. A rating engine that compiles on a new runtime can still produce a different premium. Regression testing against real business cases stays with your teams and your business owners.
- It does not publish a vendor support calendar for you. Safeguard's documented policy conditions include component age and maintenance, which are related to support status but not the same thing. Your lifecycle table of vendor dates, and the sunset list built from it, remain yours to maintain from the vendors' own pages.
- End-of-support visibility depends on recognised components. Safeguard can only report a runtime or framework version if it appears in what is scanned: a manifest, a lockfile, an image layer or a recognisable binary. A JRE installed by hand on a server that never ships in an image may not show up; cover those hosts with your own server inventory.
- It does not negotiate or interpret your support contract. Fee waivers, scoping a renewal to fewer applications and licensing terms are between you, procurement and the vendor.
- It does not decide your risk acceptance. Safeguard records exceptions and acceptances with expiry dates and approvers. Who may accept which risk, and how it reaches the board, is your governance.
Common mistakes
- Answering the renewal before the inventory. Renewing everything for a year feels safe and buys nothing. Renew for the applications that need it, once you know which ones they are.
- Inventory by survey. Teams report the version they believe they run. Read it from build files, images and artefacts, and check a sample on real hosts.
- Treating the runtime as the whole problem. The application server or web framework that has to move with it is usually where the effort is.
- Averaging risk. One severe factor, such as health data or internet exposure, should set the score.
- Moving to the release that ends next. Teams that moved to .NET 9 now share .NET 8's end date. Pick targets by support end date.
- No gate. Without a CI gate, new work starts on old templates and the estate refills while you drain it.
- Exceptions without expiry. An exception with no end date is a permanent acceptance nobody signed.
- Leaving vendor products out. Embedded runtimes in bought software are still part of your estate and your regulator's inventory.
FAQ
How do I find which applications still run Java 8 or .NET Framework 4.6.2?
Generate an SBOM per deployable from build manifests, container images and, where source is missing, the built artefacts. Then query the SBOMs for the runtime or target framework version. Confirm a random sample on running hosts before you use the count in a decision.
Is it worth paying for Java 8 extended support in 2026?
Sometimes. Oracle lists Java SE 8 Extended Support until December 2030 and has waived the uplift fee for a period. Paying is reasonable for low-risk applications that are expensive to move or due for retirement. For high-risk applications, treat it as a time-limited bridge with an end date.
When does .NET 8 support end?
Microsoft's .NET support policy lists November 10, 2026 for both .NET 8 (LTS) and .NET 9 (STS). .NET 10 (LTS) is supported until November 14, 2028.
When does .NET Framework 4.6.2 support end?
Microsoft's lifecycle page lists January 2027 (13 January 2027 at 06:59 UTC, the evening of 12 January in US time zones). Versions 4.7 through 4.8.1 follow the lifecycle of the Windows version they are installed on.
Does NYDFS require tracking end-of-support dates?
Section 500.13(a) of 23 NYCRR Part 500 requires an asset inventory whose procedures track key information for each asset, including its support expiration date, and has applied since November 1, 2025. Confirm with counsel how it applies to your company.
What does the NAIC Insurance Data Security Model Law say about legacy software?
It does not name legacy software. It asks for a risk assessment that covers software design, risk management that identifies and manages systems by importance, secure development and evaluation of external applications, and an annual written report to the board on material risk decisions.
How do I stop teams from starting new projects on end-of-life runtimes?
Publish a sunset list, make new service templates and base images use only the target runtime, and add a CI gate that blocks new projects whose components match the list and warns existing ones during the migration window.
Can Safeguard tell me which projects use an end-of-life framework?
Safeguard keeps an SBOM per project and its search lists the projects where a component and version are used, so you can query for the versions on your sunset list. You supply the list of which versions are end of life, from the vendors' pages.
Most of the cost in an end-of-support programme sits in the library and framework upgrades that a runtime move drags along, and in the vulnerabilities that keep arriving in old components while you work. The block below is how Safeguard handles that dependency layer; it does not replace the engineering work of the runtime migration itself.
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 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 | Safeguard policies and gates in CI |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch |
| 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 local runner demo shows how to set up the runner on your own machine, approve it with its device code, and then scan from the terminal. For an insurer's legacy estate, that is the route for the applications that only exist on isolated hosts or as built artefacts: run the scan where the code lives and send the SBOM and findings to the platform.
Click through it at your own pace, or open it full screen.
The CLI demo is a real session: asked to fix a lodash CVE, the assistant reads the finding and advisory, asks before any command that changes something, edits the manifest, runs install and tests with approval and pushes nothing. The same pattern fits the library upgrades in front of a runtime move.
Click through it at your own pace, or open it full screen.
To try it on your own estate, download Safeguard at https://safeguard.sh/download and read the setup guides at https://docs.safeguard.sh/docs .
Quick check
Which item in 23 NYCRR 500.13(a)(1) makes support dates part of the asset inventory, and since when has it applied?
Item (iv), the support expiration date. Under section 500.22, 500.13(a) applied two years after the second amendment took effect on November 1, 2023, so from November 1, 2025.
A low-risk internal application is expensive to migrate and due for retirement in 2027. What is a defensible decision?
Renew paid support or accept the risk for that application only, recorded with an end date, compensating controls and a trigger that reopens the decision. Spend migration effort on high-risk applications first.
Sources
- Oracle Java SE Support Roadmap
- Microsoft: .NET and .NET Core official support policy
- Microsoft Learn: .NET Framework lifecycle
- CISA: Product Security Bad Practices
- NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning
- NIST SP 800-40 Rev. 4, full text (PDF)
- 23 NYCRR 500.13, Asset management and data retention requirements (LII)
- 23 NYCRR 500.5, Vulnerability management (LII)
- 23 NYCRR 500.22, Transitional periods (LII)
- NAIC Insurance Data Security Model Law (#668), PDF
- Safeguard docs: Generate SBOM
- Safeguard docs: Explore SBOM
- Safeguard docs: Policies and Gates
- Safeguard docs: Policy outcomes and actions
- Safeguard docs: Organization and User Management
- Safeguard docs: Search
- Safeguard docs: Dashboard
- Safeguard docs: CLI support matrix
- Safeguard docs: CLI usage
- Safeguard docs: CI/CD integration
- Safeguard Gold Open Source
Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.