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.
| Approach | Where it breaks |
|---|---|
| The spreadsheet sprint: export scanner output, sort by CVSS, assign rows | CVSS 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 release | One incompatible major version blocks everything, testing balloons, and the next audit finds the same problem |
| Ask the integrator | The integrator is gone, the quote takes weeks, or one library sits in five services from three firms |
| Leave it, it is behind the firewall | DMZ 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.
| Field | Example value | Why it matters |
|---|---|---|
| Service name | erp-connector | The unit you will patch and test |
| Repository | git server path, or "none, binary only" | No repository means a different remediation path |
| Owner | name and backup | Someone has to approve the change |
| Language and package manager | Java, Maven | Decides the upgrade mechanics |
| Runs on and talks to | plant, network zone; ERP, PLC gateway | Drives exposure and impact ranking |
| Parses data from outside the plant | yes or no | External parsers rank higher |
| Validation impact | none, quality sign-off, regulated | Decides the test and approval path |
| Test assets | unit tests, test cell, none | Decides 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.
| Rank | Conditions | Target action |
|---|---|---|
| P0 | On 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 DMZ | Fix in the next available window; apply a temporary mitigation now if the window is far away |
| P1 | On KEV or high EPSS, and reachable or unknown, on an internal plant network | Fix in the next planned monthly window |
| P2 | High CVSS but low EPSS, not on KEV, reachable or unknown | Batch into the quarterly maintenance release |
| P3 | Not reachable, or in a build or test-only dependency | Record, recheck when data changes, fix opportunistically |
| Accept | No fix exists, or the fix needs a vendor release | Formal 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:
- Patch version bump. Same major and minor version, backward compatible. Usually the safest.
- Minor version bump. New features, rare breaking changes. Needs a regression run.
- Major version bump. Expect API changes. Needs code changes and real testing, often a test cell run.
- Replace the component. The library is abandoned. Swap to a maintained alternative.
- 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) | Language | Runs in | Notes |
|---|---|---|---|
| erp-connector | Java, Maven | Corporate DMZ | Receives work orders, posts confirmations |
| opcua-gateway | Python, pip | Plant network | Reads tags from cell PLCs |
| historian-forwarder | Go modules | Plant network | Buffers and forwards time series |
| label-service | .NET, NuGet | Plant network | Prints lot labels; quality-validated |
| quality-bridge | Java, Maven | Plant network | Moves inspection holds to the MES |
| andon-dashboard | JavaScript, npm | Plant network | OEE and downtime screens |
| edi-intake | Python, pip | Corporate DMZ | Parses 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:
| Action | What a failed policy does to the gate |
|---|---|
| Block | The gate fails |
| Warn | The gate passes, with a warning naming the policy |
| Notify | The 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 step | What Safeguard does (GA) | What you still own |
|---|---|---|
| Inventory software (CSF ID.AM-02) | Builds SBOMs per repository, image or SBOM file; shows transitive paths | Listing 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 finding | Feeding in services it cannot reach, such as vendor appliances |
| Prioritise by risk (SSDF RV.2.1) | Reachability classes and a priority score with exposure context | Agreeing 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 results | Reviewing, merging, test cell runs, deployment in the window |
| Prevent recurrence | Policies and gates with Block, Warn and Notify in CI | Choosing when to move from Warn to Block |
| Accept risk formally | Exception requests with justification, expiry and an audit trail | Approving exceptions and the compensating controls |
| Evidence | Pull requests, gate outcomes, exception history | Change records and validation sign-offs |
| Isolated networks | Local runner, on-prem and air-gapped deployment, Zero AI mode | Your 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.
- 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.
- 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.
- 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.
- It cannot test what has no tests. Add at least a smoke test before you rely on fix pull requests for a service.
- 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.
- 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 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 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
- NIST SP 800-82 Rev. 3, Guide to Operational Technology (OT) Security
- NIST SP 800-40 Rev. 4, Guide to Enterprise Patch Management Planning
- NIST SP 800-218, Secure Software Development Framework Version 1.1
- NIST SP 800-218 full text (PDF)
- NIST Cybersecurity Framework 2.0 (PDF)
- ISA/IEC 62443 series of standards
- ISA-95 standard
- CISA Known Exploited Vulnerabilities catalog
- CISA BOD 26-04, Prioritizing Security Updates Based on Risk
- FIRST Exploit Prediction Scoring System (EPSS)
- Safeguard docs: AI Remediate
- Safeguard docs: Policies and Gates
- Safeguard docs: Policy outcomes and actions
- Safeguard docs: Vulnerabilities
- Safeguard docs: Vulnerability Prioritization (Reachability Analysis)
- Safeguard docs: Deep Dependency Scanning
- Safeguard docs: CLI Usage
- Safeguard docs: Local Runner
- Safeguard docs: GitHub Actions
- Safeguard docs: Jenkins
- Safeguard docs: Air-Gapped Deployment
- Safeguard use case: Auto-fix vulnerabilities
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.