Safeguard
Product•

Use case: fixing stale libraries in MES integrations after an audit

An audit flagged stale libraries in your MES integrations. How a plant IT lead finds them, ranks risk and ships tested upgrades without stopping the line.

Safeguard Security Team
38 min read

An audit found stale open source libraries in the code that connects your MES to the ERP, the historian, the label printers and the line. The fix is a loop you can run every month: inventory every integration's dependencies, rank them by exploitation and exposure, upgrade the risky ones through pull requests that are tested before they reach a change window, and gate new builds so the backlog does not grow back. This post walks that loop for a plant IT lead, first with any tools, then with Safeguard.

Key takeaways

  • The stale libraries usually sit in the custom glue around the MES (ERP connectors, OPC UA gateways, historian collectors, label services, dashboards), not in the vendor core.
  • Treat patching as preventive maintenance (NIST SP 800-40 Rev. 4) that respects OT performance, reliability and safety (NIST SP 800-82 Rev. 3).
  • Rank by KEV status, then EPSS, then whether the service calls the vulnerable code, then network exposure.
  • Ship small, tested pull requests into planned windows, never one big upgrade weekend.
  • Safeguard capabilities used in this post, all GA: software composition analysis with deep transitive dependency scanning (GA), SBOM generation (GA), vulnerability management with EPSS and KEV enrichment (GA), reachability analysis and prioritisation (GA), autonomous remediation with Griffin fix pull requests, single and bulk (GA, ships switched off with every category set to Manual), policies and gates with Block, Warn and Notify actions (GA), the Safeguard CLI and local runner (GA), and on-prem and air-gapped deployment with Zero AI mode (GA).
  • What stays yours: deciding the change window, validating on a test cell, signing off the release, and anything inside a vendor appliance or a vendor's own MES binaries.

The job and who owns it

Who this is for

You are the plant IT lead, or the IT and OT systems lead for a group of plants. You own the servers and applications that sit at ISA-95 Level 3: the manufacturing execution system, its database, and the integration services around it. You are not a full-time developer, but you own a handful of repositories that a former contractor, a systems integrator, or a now-departed colleague wrote. Some of those services are in Java, some in .NET, some in Python, and one dashboard is in Node.

The industry and its systems

A discrete or batch manufacturer runs a stack that looks roughly like this. Level 4 is the business layer: ERP, planning, finance. Level 3 is manufacturing operations management, where the MES schedules work orders, tracks genealogy, enforces recipes, records quality data and reports production back to the ERP. Levels 2 and below are the control layer: PLCs, DCS, SCADA, HMIs and the devices on the line.

The ISA-95 standard defines this hierarchy and says Level 3 covers manufacturing execution systems and similar systems that manage manufacturing operations. It also says the standard mainly deals with the interface between Levels 3 and 4. That interface, and the one between Level 3 and Level 2, is where your custom code lives.

Typical services there: an ERP connector that pulls work orders and posts confirmations, an OPC UA or machine data gateway that reads PLC tags, a historian collector, a label and print service, a quality or LIMS bridge, file drop and EDI handlers for supplier files, and an andon dashboard. Each was built once, validated once and left alone because it worked. That is exactly why the libraries inside them are stale.

The trigger

The trigger is an audit finding, from internal audit, a customer's supplier review, an insurer or an IEC 62443 assessment. The shape is familiar: "Third-party libraries in MES integration services are outdated and include components with known vulnerabilities. Management should establish a process to identify, prioritise and remediate them, with evidence."

This post does not interpret any specific audit finding or contract, and it is not legal, regulatory or audit advice. It describes the usual shape of the request and a defensible way to answer it.

What a bad week looks like

The finding arrives with a spreadsheet of a few hundred component versions and CVE identifiers. Production wants no downtime. The integrator who wrote the ERP connector has moved on. One service runs on a DMZ server with no internet access. Quality reminds you that the label service prints lot numbers and needs revalidation after any change. And the audit committee wants a dated plan by month end. The rest of this post turns that week into a routine.

The rules and guidance behind it

None of the documents below is a law that applies to every manufacturer. They are the references auditors, customers and insurers point to, and they describe a consistent expectation: know what software you run, find vulnerabilities in it continuously, fix them according to risk, and keep evidence.

NIST SP 800-82 Rev. 3: OT is different, so plan changes around it

NIST SP 800-82 Rev. 3, the Guide to Operational Technology Security, was published in September 2023 and supersedes Rev. 2. Its abstract describes how to secure OT while addressing OT's own performance, reliability and safety requirements, and it covers typical topologies, threats, vulnerabilities and countermeasures. For a plant IT lead, the practical point is that patching cannot be treated like an office laptop fleet. A change to the machine data gateway can stop data collection on the line, and a change to the label service can put a lot on hold.

NIST SP 800-40 Rev. 4: patching is preventive maintenance

NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning, was published in April 2022. It defines patch management as identifying, prioritising, acquiring, installing and verifying patches, updates and upgrades across the organisation. It frames patching as preventive maintenance and a normal cost of doing business, and it recommends an enterprise strategy that makes patching routine. That framing is useful when production asks why you need a recurring window: you are asking for the same thing maintenance asks for on the presses.

ISA/IEC 62443: patch management and secure development in the IACS world

The ISA/IEC 62443 series is the industrial automation and control systems security family. ISA lists, among others, ISA-TR62443-2-3-2015, Patch management in the IACS environment, ANSI/ISA-62443-3-3, System security requirements and security levels, ANSI/ISA-62443-4-1-2018, Secure product development lifecycle requirements, and ANSI/ISA-62443-2-4, Security program requirements for IACS service providers. If your auditor or your integrator works to 62443, expect questions about how patches are evaluated, tested and deployed in the IACS environment, and about how your own developed components handle third-party code. The standards are sold documents, so read the clauses in your licensed copies rather than relying on summaries, including this one.

For a deeper look at the newest part of the series, see our post on IEC 62443-2-2:2025 security protection schemes.

NIST CSF 2.0: the outcomes your board will recognise

The NIST Cybersecurity Framework 2.0 gives you outcome language that maps cleanly to this job:

  • ID.AM-02: inventories of software, services and systems managed by the organisation are maintained.
  • ID.RA-01: vulnerabilities in assets are identified, validated and recorded.
  • ID.RA-08: processes for receiving, analysing and responding to vulnerability disclosures are established.
  • PR.PS-01: configuration management practices are established and applied.
  • PR.PS-02: software is maintained, replaced and removed commensurate with risk.

PR.PS-02 is the one that matches an audit finding about stale libraries almost word for word.

NIST SP 800-218 SSDF: you are a software producer for your own integrations

NIST SP 800-218 (SSDF Version 1.1, February 2022) applies the moment you own an integration repository. Task PW.4.4 asks you to verify third-party components throughout their life cycles, starting with regular checks for publicly known vulnerabilities. RV.1.1 includes automatically reviewing software composition data for new vulnerabilities. RV.2.2 asks for a risk-based decision to remediate or accept each vulnerability, and temporary mitigation when no permanent fix exists. The SSDF's mapping column also references IEC 62443, so the frameworks line up.

CISA KEV, BOD 26-04 and EPSS: the signals for ranking

CISA maintains the Known Exploited Vulnerabilities catalog of vulnerabilities observed being exploited in the wild. CISA's BOD 26-04, Prioritizing Security Updates Based on Risk (10 June 2026), revokes and supersedes BOD 22-01 and BOD 19-02. It binds federal civilian agencies, not manufacturers, and its Table 1 timelines draw on the SSVC method, which weighs exploitation status, technical impact, safety impacts and prevalence. It is a useful model for a defensible ranking, not a rule you must follow.

FIRST's Exploit Prediction Scoring System (EPSS) is a data-driven model that estimates the probability that a published CVE will be exploited in the wild in the next 30 days. KEV tells you exploitation is happening; EPSS tells you how likely it is soon. Our post on KEV, EPSS and CVSS as patching signals goes deeper on combining them.

How teams do it today and where it breaks

Most plant teams answer this kind of finding in one of four ways, and each works for a while.

ApproachWhere it breaks
The spreadsheet sprint: export scanner output, sort by CVSS, assign rowsCVSS alone does not say which rows matter, the sheet is stale the next day, and a row does not say which service, server and plant it belongs to
The big upgrade weekend: bundle every bump into one releaseOne incompatible major version blocks everything, testing balloons, and the next audit finds the same problem
Ask the integratorThe integrator is gone, the quote takes weeks, or one library sits in five services from three firms
Leave it, it is behind the firewallDMZ connectors parse outside data by design, vendor remote access exists in nearly every plant, and informal acceptance is not evidence

All four treat remediation as a project rather than a loop. The steps below make it a loop.

Step by step: clearing the audit finding with any toolset

These steps work whether you use open source tools, a commercial platform, or Safeguard. Each one ends with something you can show an auditor.

Step 1. Build the integration inventory

List every service that touches the MES. Do not start from the scanner; start from the architecture. For each service, capture the fields below. A shared spreadsheet is fine for the first pass.

FieldExample valueWhy it matters
Service nameerp-connectorThe unit you will patch and test
Repositorygit server path, or "none, binary only"No repository means a different remediation path
Ownername and backupSomeone has to approve the change
Language and package managerJava, MavenDecides the upgrade mechanics
Runs on and talks toplant, network zone; ERP, PLC gatewayDrives exposure and impact ranking
Parses data from outside the plantyes or noExternal parsers rank higher
Validation impactnone, quality sign-off, regulatedDecides the test and approval path
Test assetsunit tests, test cell, noneDecides how fast you can ship fixes

Expect surprises: services nobody listed, services with no repository, and deployed versions that do not match the repository.

Step 2. Generate an SBOM for each service

An SBOM lists every component and version in a service. Generate one per service from the repository and lockfile, or from the built image where that is all you have, in SPDX or CycloneDX, and store it with its date. Integration code pulls in XML parsers, HTTP clients and logging libraries, each with its own tree, so the vulnerable component is often two or three levels down. Our post on dependency graph analysis and transitive risks explains why.

Step 3. Match against vulnerability data and enrich it

Match each SBOM against vulnerability databases and add three facts to every finding: whether the CVE is on the CISA KEV catalog, its current EPSS probability, and whether a fixed version exists. A finding with no fixed version needs a different plan from one with a one-line version bump.

Step 4. Rank with a decision table, not CVSS alone

Use a short table that production, quality and your auditor can all read. This one is a starting point; adjust the bands to your own risk appetite.

RankConditionsTarget action
P0On KEV, and the integration calls the vulnerable code or you cannot tell, and the service parses data from outside the plant or sits in the DMZFix in the next available window; apply a temporary mitigation now if the window is far away
P1On KEV or high EPSS, and reachable or unknown, on an internal plant networkFix in the next planned monthly window
P2High CVSS but low EPSS, not on KEV, reachable or unknownBatch into the quarterly maintenance release
P3Not reachable, or in a build or test-only dependencyRecord, recheck when data changes, fix opportunistically
AcceptNo fix exists, or the fix needs a vendor releaseFormal exception with owner, reason, compensating control and expiry

"Reachable" means your service actually calls the vulnerable function or code path. If you have no tool that answers that, treat every finding as reachable until someone has read the code. That is slower, but it is honest.

Step 5. Decide the upgrade path per finding

For each P0 and P1 finding, pick one of five paths:

  1. Patch version bump. Same major and minor version, backward compatible. Usually the safest.
  2. Minor version bump. New features, rare breaking changes. Needs a regression run.
  3. Major version bump. Expect API changes. Needs code changes and real testing, often a test cell run.
  4. Replace the component. The library is abandoned. Swap to a maintained alternative.
  5. Temporary mitigation. No fix exists yet, or the window is too far away. Restrict network access to the service, disable the vulnerable feature, or add input filtering, and record it as a temporary control with an expiry date.

Step 6. Make every fix a small pull request with tests

One finding, or one related group, per pull request, stating the CVE, the version change, what the lockfile pulled in and what tests ran. Small pull requests are easy to review, test and roll back, and the pull request becomes the audit record.

If a service has no tests, add one smoke test first: post one known confirmation to a test ERP client, or read a fixed set of tags from a simulator.

Step 7. Land fixes in planned windows

Agree a standing monthly window with production for integration services, separate from controller and HMI changes. Pre-stage tested builds before the window. Keep the previous build ready for rollback. Use this checklist for each window.

Change window checklist

  • Each change has a merged, reviewed pull request and a passing test run, plus a test cell run where validation requires it
  • Quality has signed off changes to services that touch lot, serial or recipe data
  • The rollback build is staged on the server
  • Monitoring confirms the service is processing transactions after the change
  • The change record links to the pull request and the finding it closes

Step 8. Gate new builds so the backlog stays down

Once the current backlog is moving, stop new risk from arriving. Add a check to the build pipeline of every integration repository that fails or warns when a build introduces a component with a known exploited or critical vulnerability. Start in warning mode for a few weeks, then move the most important rule to blocking.

Step 9. Keep the evidence

For each finding, the audit trail is: the SBOM that showed it, the ranking decision, the pull request that fixed it or the exception that accepted it, the test result, and the change record. Keep these in one place, linked by service name. Auditors do not need a perfect record; they need a consistent one.

Which MES integrations carry the most dependency risk?

Services that parse data from outside the plant rank highest: DMZ ERP connectors and EDI or file drop handlers. PLC gateways are high impact rather than high exposure, since a fault stops data collection and, where setpoints are written, can touch the process. Andon dashboards rank lower on impact but carry the largest dependency trees.

How do you upgrade without stopping the line?

Plan integration services apart from the control layer; they usually restart without stopping production. Confirm once that your ERP connector and historian collector queue data during a restart, then plan short restarts. Schedule services without buffering at shift change or in planned maintenance downtime.

What if the vulnerable library is inside a vendor's MES product?

The fix has to come from the vendor. Ask for an SBOM and their timeline for the specific CVEs, and record a formal exception with a compensating control until the release arrives. Do not patch inside vendor binaries yourself.

What about integration servers with no internet access?

Generate SBOMs and run scans in a place that has the tools and a current vulnerability database, then bring the results or the patched build into the plant through your normal transfer process. The tools you choose need an offline mode, or a way to receive vulnerability data updates without a live connection. Our post on software updates in air-gapped environments covers the transfer patterns.

Illustrative scenario: a castings plant clears an MES audit finding

This is a composite, illustrative example, not a customer. The company, its systems and every number below are invented example inputs, chosen to show the method. They are not results.

The company

"Example Castings" is a fictional manufacturer with three plants making aluminium housings. Each plant runs the same commercial MES. Around it, the company's small central IT team owns seven integration services, written over several years by two integrators and one internal developer:

Service (example)LanguageRuns inNotes
erp-connectorJava, MavenCorporate DMZReceives work orders, posts confirmations
opcua-gatewayPython, pipPlant networkReads tags from cell PLCs
historian-forwarderGo modulesPlant networkBuffers and forwards time series
label-service.NET, NuGetPlant networkPrints lot labels; quality-validated
quality-bridgeJava, MavenPlant networkMoves inspection holds to the MES
andon-dashboardJavaScript, npmPlant networkOEE and downtime screens
edi-intakePython, pipCorporate DMZParses supplier advance ship notices

The trigger

A customer's supplier security review flags outdated third-party components in the integration services and asks for a remediation plan within 30 days (an example deadline). The internal auditor adds the same item to the year's findings.

What they find, rank and fix

As example inputs, assume the first scan finds about 400 component versions across direct and transitive dependencies and about 120 findings, a handful on KEV. Most findings sit in the andon dashboard's large npm tree, but the two DMZ services hold the ones that matter.

Applying the Step 4 table, KEV-listed findings in the parsing code of edi-intake and erp-connector go to P0. Reachable high-EPSS findings in the gateway and quality bridge go to P1. Dashboard build tooling goes to P3. One label-service finding has no upstream fix, so it becomes a formal exception with a network restriction and an example 60-day expiry.

The team ships small pull requests, one per service per finding group, after adding a smoke test to the opcua-gateway against a tag simulator and a contract test to the erp-connector against the ERP test client. The label-service change waits for quality sign-off. Changes land in two monthly windows. A pipeline check on all seven repositories warns on new critical findings for four weeks, then blocks any build that adds a KEV-listed component.

For the auditor, they show per-service SBOMs, the ranking table, merged pull requests with test results, open exceptions with expiry dates and the pipeline rule. They do not claim the plant is "secure". They show a process that runs every month.

The next section shows how the same scenario runs in Safeguard.

How Safeguard does this

Everything below comes from Safeguard's offering documentation and docs.safeguard.sh. Commands and YAML are quoted as the docs show them; they were not run for this post. Every capability is GA.

1. Connect the integration repositories, or keep code on your machine

Connect your Git provider, or, where a repository cannot be shared with a cloud service, use the local runner (GA). The Local Runner is part of the Safeguard CLI. It runs scan jobs on your machine and uploads only the SBOM and findings, never source code, over outbound HTTPS it opens itself. The docs list the install as:

# macOS and Linux
curl -fsSL https://cli.safeguard.sh/install | bash

Then run safeguard, type /login and approve the session. On a server with no browser, the CLI usage page documents a no-browser login that prints a URL and code to enter elsewhere.

2. Generate the SBOM and find the vulnerable components

Software composition analysis with deep transitive dependency scanning (GA) and SBOM generation in SPDX and CycloneDX (GA) build the component inventory for each service. From the CLI, the docs show one target per scan:

# A local directory (your own or proprietary code)
safeguard scan --dir .

# A container image
safeguard scan --image myregistry.azurecr.io/myapp:v1 \
  --registry-username "$REGISTRY_USER" \
  --registry-password "$REGISTRY_PASSWORD"

# An SBOM you already have (SPDX or CycloneDX, detected automatically)
safeguard scan --sbom sbom.json

safeguard scan builds an SBOM, matches it against vulnerability databases, and writes JSON results under ./output. It exits 0 whatever it found; the docs say gating is done by policy gates in the platform. To see results in the platform, scan from the interactive terminal with /scan . while signed in.

The deep dependency scanning page lists the manifests and lockfiles it resolves for Maven, Gradle, Python, Go, NuGet and npm, which covers the scenario. Clicking a finding in the web app shows the full path from your service to the vulnerable package.

3. Keep the list current without rescanning by hand

Vulnerability management with EPSS and KEV enrichment (GA) keeps findings current. The Vulnerabilities page says Safeguard scans all projects daily and re-evaluates them when new CVEs are published. Each finding shows CVSS, EPSS, whether it is actively exploited, the affected and fixed versions, and reachability, and you can filter on each. That replaces the spreadsheet sprint.

4. Rank by reachability, exploitation and context

Reachability analysis and prioritisation (GA) answers the question from Step 4: does the service actually call the vulnerable code? The Vulnerability Prioritization page describes static reachability from your source, lockfile and bytecode, dynamic reachability from runtime data, and configuration reachability. Each finding is classified as reachable, conditionally reachable, unreachable or unknown, and unknown is treated conservatively as potentially reachable, which matches the honest default in Step 4.

The page combines reachability with EPSS, KEV, runtime and business context into a priority score, and lists filters such as:

reachable:true
kev:true
epss:>0.3
env:production reachable:true kev:true

Exposure labels (internet-facing, internal, air-gapped) and policy-declared critical assets are how the DMZ services rise above the andon dashboard without anyone re-sorting a spreadsheet. The page's /v1 REST examples are marked as not yet available, so use the web app, CLI or CI.

5. Turn the ranking rules into a gate

Policies, gates and guardrails, including plain English policy creation (GA), turn the decision table into rules that run on every scan. The Policies and Gates page describes policies as rules that evaluate SBOMs and generate findings, and gates as checkpoints that enforce them. You create a policy under Settings, then Policies, with conditions such as severity, CVSS, EPSS, license or component age.

Each policy has one Action, and the docs list exactly three:

ActionWhat a failed policy does to the gate
BlockThe gate fails
WarnThe gate passes, with a warning naming the policy
NotifyThe gate passes, and a notification is sent to the workspace's configured channels

Approval is handled through exceptions, not as a gate action. You click Request Exception, select the policy and finding, give a justification and an expiry date, and approvers decide, with an audit trail. That is the formal exception the label-service finding needed.

The Policy outcomes and actions page notes that policy outcomes are turned on per workspace by Safeguard, so ask your Safeguard contact if you see no Outcome column. Notify fires when a policy starts failing and again when new matching issues appear, not on every evaluation.

6. Put the gate in the integration pipelines

Both CI pages start the same way: create a secret key in Safeguard under Settings, then Developer, with the scans:trigger and scans:read scopes. The GitHub Actions page gives a ready workflow file. Many plant teams run Jenkins on premises, and the Jenkins page shows this stage, using a Secret text credential with the ID safeguard-api-key:

stage('Safeguard scan') {
  when {
    anyOf {
      branch pattern: '^(main)$', comparator: 'REGEXP'
      changeRequest target: '^(main)$', comparator: 'REGEXP'
    }
  }
  steps {
    withCredentials([string(credentialsId: 'safeguard-api-key', variable: 'SAFEGUARD_API_KEY')]) {
      sh '''
        set -eu
        export SAFEGUARD_INSTALL_DIR="$WORKSPACE/.safeguard-bin"
        curl -fsSL https://cli.safeguard.sh/install | bash
        "$SAFEGUARD_INSTALL_DIR/safeguard" ci scan --wait --fail-on critical
      '''
    }
  }
}

To fail on the policy gate rather than a severity threshold, the docs say to add the gate flag to the scan command:

safeguard ci scan --wait --fail-on-gate all

With policy outcomes on, it exits 0 when the gate is Passed or Warning and non-zero when it is Failed, Error or Not evaluated. For the scenario's rollout, set the KEV policy to Warn for a few weeks, then to Block. The Jenkins docs note that Windows agents are not supported, so a .NET service built on Windows needs a Linux agent for this stage, or the connected repository or local runner instead.

7. Open the fix pull requests

Autonomous remediation with Griffin fix pull requests (GA) does the work in Steps 5 and 6. The AI Remediate page describes the flow: analysis of the vulnerability and your codebase, solution generation that picks the safest upgrade path, an impact assessment for breaking changes and compatibility, pull request creation, and validation by running automated tests.

It upgrades vulnerable packages to fixed versions, handles transitive dependency conflicts and updates lock files. The docs list full support for npm, yarn and pnpm, pip, poetry and pipenv, Maven and Gradle, Go modules, Cargo, Bundler, NuGet and Composer, which covers every service in the scenario.

You can run it on a single vulnerability (click AI Remediate, review, click Create Pull Request), in bulk (select several, click AI Remediate Selected, and Griffin batches compatible fixes into one pull request per repository), or for the whole Vulnerabilities page. Each pull request carries the CVE reference, a summary of changes, breaking change warnings, test results if configured, and advisory links. That is the Step 9 evidence, written for you.

Breaking change detection labels each fix Safe, Minor, Major or Critical, with Critical meaning manual review required. In a plant, that maps onto Step 5: Safe and Minor fixes go into the monthly window, Major fixes go to a test cell first, Critical fixes go back to the owner. The docs advise never auto-merging breaking changes.

The offering documentation adds a strategy per remediation category: Safest (backward-compatible fixes only), Balanced, Aggressive and Smart. Autonomous remediation ships switched off, with every category set to Manual. For a plant, Manual plus Safest is the sensible start: Safeguard drafts pull requests, people review, test and merge them. It does not deploy to plant servers; building and installing in the change window stay with you.

8. Fix code locally with the assistant, with approval for every change

For a service that is not pushed anywhere yet, or where you want to work through a fix at your desk, the runner page documents the CLI assistant:

# Interactive, in this workspace
safeguard agent "fix the critical CVEs in this repository"

The assistant asks before any command that changes something, not before every command. For scripted use, the docs show safeguard exec, which runs one turn and defaults to strict permissions: nothing is asked, and anything the policy file has not pre-approved is denied.

9. Run it inside the plant perimeter if you must

On-prem and air-gapped deployment (GA) and Zero AI mode (GA) cover plants that cannot send code or findings out. The Air-Gapped Deployment page describes signed snapshot bundles, on a cadence from hourly to quarterly, carrying vulnerability feed deltas including CISA KEV and daily EPSS, delivered by one-way diode, removable media or a DMZ sync window. No component inside the perimeter calls outbound. Zero AI mode runs the platform with no LLM at all, configured per tenant.

How it maps: requirement, what Safeguard does, what you still own

Requirement or stepWhat Safeguard does (GA)What you still own
Inventory software (CSF ID.AM-02)Builds SBOMs per repository, image or SBOM file; shows transitive pathsListing every integration service, including binary-only ones
Identify vulnerabilities (CSF ID.RA-01, SSDF RV.1)Daily continuous scanning; EPSS, KEV and fixed versions per findingFeeding in services it cannot reach, such as vendor appliances
Prioritise by risk (SSDF RV.2.1)Reachability classes and a priority score with exposure contextAgreeing the ranking bands with production and quality
Remediate (CSF PR.PS-02, SSDF RV.2.2)Griffin fix pull requests, single, bulk or page level, with breaking change labels and test resultsReviewing, merging, test cell runs, deployment in the window
Prevent recurrencePolicies and gates with Block, Warn and Notify in CIChoosing when to move from Warn to Block
Accept risk formallyException requests with justification, expiry and an audit trailApproving exceptions and the compensating controls
EvidencePull requests, gate outcomes, exception historyChange records and validation sign-offs
Isolated networksLocal runner, on-prem and air-gapped deployment, Zero AI modeYour transfer process and plant network design

What to measure

These are checks you can run on your own programme. They are not outcomes Safeguard promises.

  • Every MES integration service has an owner, a repository or a documented "binary only" status, and an SBOM dated within the last 30 days
  • Number of open KEV-listed findings in integration services, tracked weekly, by service
  • Age of the oldest open P0 and P1 finding, against the target you set in the decision table
  • Share of P0 and P1 findings with a merged fix, a scheduled fix, or a formal exception: the goal is that every one has one of the three
  • Number of open exceptions, and how many are past their expiry date
  • Number of builds the gate warned on or blocked, by policy, so you can see whether new risk is still arriving
  • Share of fix pull requests that needed rework or failed tests, which tells you whether to stay conservative
  • Services with no tests: the count should only go down

What Safeguard does not do

Be clear about the edges before you plan around it.

  1. It does not patch your vendor's MES, controllers or appliances. When the library is inside a commercial MES binary, PLC firmware or a vendor appliance, the fix comes from that vendor. Safeguard can scan an SBOM or image they give you and track the finding.
  2. It does not deploy to plant servers or pick your window. It opens pull requests. Building, installing and rolling back stay with your change process.
  3. It does not replace validation. Breaking change labels and test runs feed your review; they do not replace a test cell run or quality sign-off.
  4. It cannot test what has no tests. Add at least a smoke test before you rely on fix pull requests for a service.
  5. It does not monitor the control layer. It works on software you build and the images and SBOMs you give it, not on PLCs or field devices on the wire.
  6. It does not decide your risk appetite. Ranking bands, exception approvals and what you tell an auditor are yours.

Common mistakes

  • Starting from the scanner, not the architecture. You miss services with no repository.
  • Ranking by CVSS alone. A critical score in a test-only dependency matters less than a KEV-listed high in the ERP connector's parser.
  • One big upgrade. A single incompatible major version will block every other fix in the bundle. Ship small pull requests.
  • Treating "behind the firewall" as a control. DMZ services parse outside data by design. If you accept risk, write it down with an owner and an expiry date.
  • Turning on automation before tests exist. Automatic pull request creation on a service with no tests just moves the risk to review.
  • Gating in Block mode on day one. Every build fails, teams route around the gate, and it loses credibility. Warn first, then Block.
  • Letting exceptions live forever. An exception without an expiry date is just the old informal acceptance with more paperwork.

FAQ

How do I find vulnerable libraries in MES integration code?

Generate an SBOM for each integration service from its repository and lockfile, or from the built image if you only have the deployed build, then match it against vulnerability databases. Add KEV status, EPSS and the fixed version to each finding. Safeguard's SCA and SBOM generation do this per repository, image or SBOM file, and its continuous scanning keeps the list current daily.

Is it safe to auto-fix dependencies in a manufacturing environment?

It is safe to auto-generate fixes as pull requests that people review and test. It is not wise to auto-deploy them to plant servers. Safeguard's autonomous remediation ships switched off with every category on Manual, and it opens pull requests rather than deploying, so your change window and validation still decide what reaches the plant.

What standards apply to patching MES and OT software?

Common references are NIST SP 800-82 Rev. 3 for OT security, NIST SP 800-40 Rev. 4 for patch management, the ISA/IEC 62443 series (including ISA-TR62443-2-3 on patch management in the IACS environment), NIST CSF 2.0 (notably PR.PS-02) and NIST SP 800-218 for software you develop. Which ones bind you depends on your contracts, customers and sector; this post is not legal advice.

How do I prioritise hundreds of findings from an audit?

Rank by KEV status first, then EPSS, then whether the service actually calls the vulnerable code, then network exposure and impact. A short decision table, like the one in Step 4, is easier to defend than a CVSS sort. Safeguard's reachability analysis and priority score apply the same signals automatically.

What do I do when no fixed version exists?

Record a formal exception with an owner, a justification, a compensating control and an expiry date, as NIST SSDF RV.2.2 describes. In Safeguard, exceptions are requested against a policy and finding and go to approvers with an audit trail.

Can Safeguard scan integration servers that have no internet access?

Yes, in two ways the docs describe. The local runner runs scans on your own machine and uploads only SBOMs and findings over outbound HTTPS, and the air-gapped deployment runs the full platform inside your perimeter with signed vulnerability feed updates delivered by diode, removable media or a DMZ sync window.

Does Safeguard send our integration code to an AI model?

Not if you choose otherwise. The local runner keeps source code on your machine and uploads only results. Zero AI mode runs the platform with no LLM in the loop, and you can also bring your own model or run Safeguard's models inside your environment. The setting is configurable per tenant.

How do I stop new vulnerable libraries from entering MES integrations?

Add a pipeline check to every integration repository. In Safeguard, link a policy to a gate, run the documented CI scan with the gate flag, and move the policy from Warn to Block once teams are used to it.

Most of this post is about fixes that already exist upstream and only need to reach your integration services through tested pull requests. The section below covers the harder cases too: finding the safe version quickly, and what to do when upstream has no fix yet.

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 CLI session. After install, safeguard opens the interactive terminal, and the user asks it to fix the lodash CVE in a repository. It reads the finding and the advisory, asks before any command that changes something, edits package.json to lodash 4.17.21, and runs npm install and npm test with approval. It prints a summary and pushes nothing, then shows /permissions, /model and /scan. The same flow applies to the andon dashboard in the scenario, or to any integration service you want to fix at your desk before it goes into a change window.

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, and then scans from the terminal. This is the path for integration repositories you cannot share with a cloud service: the scan runs on your machine and only the SBOM and findings leave it.

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

The third demo is a real Android session: sending work to a computer running the CLI, then approving the command on the phone with Allow once, Allow for turn or Deny. For a plant IT lead who is on the floor more than at a desk, it shows how a change on the integration workstation can wait for your approval from the phone.

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

Quick check

An ERP connector in the DMZ has a KEV-listed CVE in its XML library, and the reachability result is "unknown". How should you rank it?

Treat unknown as potentially reachable. KEV status plus DMZ exposure plus a parser of outside data puts it at P0: fix it in the next available window, and apply a temporary mitigation now if that window is far away.

Does turning on Safeguard mean fixes start deploying to plant servers on their own?

No. Autonomous remediation ships switched off with every category set to Manual, and even when enabled it opens pull requests. Merging, building and deploying in your change window stay with your team.

Sources

Related reading: software supply chain security for manufacturing OT, the case for autonomous remediation, and the matching use case page, auto-fix vulnerabilities.

To try the flow on one integration repository, download Safeguard and follow the docs.

Last reviewed: 25 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.