Safeguard
Supply Chain Security•

eMudhra and Java: Check and Fix cacerts and Custom Trust Stores

Java got no fix for eMudhra by 21 Oct. Find every cacerts and custom trust store, check with keytool, remove both trust paths with care, test, then rebuild.

Safeguard Security Team
27 min read

Java had no confirmed eMudhra fix on 21 October 2026: the community tracker listed it as pending. Any JVM, app server, Android app or container image with its own trust store may still accept certificates from the eight weak-key intermediates. Find every cacerts and custom trust store, check them with keytool, remove both trust paths with care, test, then rebuild.

This is the Java follow-up to our eMudhra CA key compromise explainer, which covers what happened and how browsers reacted. Here we stay inside the JVM: where its trust lives, how to change it without breaking production, and how to prove the change worked.

Where Java stands on 21 October

Browsers were patched within hours. Java was not: a JDK trust store change usually ships with a JDK update, and every vendor builds its own.

ItemStatus as of 21 Oct 2026Source
Community tracker entry for Java"Pending"Tracking site run by Mozilla's Dennis Jackson
OpenJDK bug to remove or distrust emSign ECC Root CA - G3None found in our searchOpenJDK bug tracker, web search
emsigneccrootcag3 in OpenJDK's cacerts sourceStill present on the master branchOpenJDK GitHub repository
comodoaaaca (AAA Certificate Services) in OpenJDK's cacerts sourceStill present on the master branchOpenJDK GitHub repository
Oracle, Eclipse Temurin, Amazon Corretto, Azul statementsNone found in our searchWeb search on 21 Oct
Red HatBulletin RHSB-2026-012 open; no fixed ca-certificates errata listed at its 06:32 update on 21 OctRed Hat
Android devicesBlock delivered through Google Play Services around 22:00 UTC on 19 OctGoogle

The tracker's Java entry links to a page at ops.java, which returned an access error when we tried to fetch it. Check it, and your JDK vendor's release notes, before assuming nothing has shipped.

Red Hat says downstream projects assigned CVE-2026-111943 to track trust store updates; The Hacker News reports Go uses it for its fix. Red Hat lists three conditions for real risk: a trust store that still trusts the intermediates, an attacker holding a recovered key, and a position in the middle of the network path.

Why Java needs its own work

The JVM ignores the browser fixes

Chrome blocked the intermediates through CRLSet, Firefox through OneCRL, Android through Play Services. None of that reaches a JVM. Scott Helme lists Java with curl, Python, Node and Go as clients that, by default, trust a CA bundle on disk and do not check revocation or Certificate Transparency.

Oracle's JSSE reference guide confirms the revocation part. The com.sun.net.ssl.checkRevocation system property defaults to false, and the default trust manager disables revocation checking unless you turn it on. So eMudhra's revocation of all eight intermediates on 18 October, recorded on Mozilla's Bugzilla entry, and Sectigo's revocation of its cross-signs change nothing for a default JVM.

There are two trust paths, not one

Each of the eight weak-key intermediates exists twice, according to Mozilla's Bugzilla entry and the tracker's list of impacted certificates:

  1. An eMudhra-issued copy, with an issuer of emSign Root TLS CA - G3 or emSign Root CS CA - G3, which chains up to emSign ECC Root CA - G3. Google and Mozilla named that root as the one being removed.
  2. A Sectigo cross-signed copy, issued in May 2025 according to Helme, whose issuer is AAA Certificate Services, an old Comodo root.

A server holding a recovered key can send either chain. Removing emsigneccrootcag3 blocks only the first. If your trust store holds AAA Certificate Services, the second can still validate.

This matters for Java in particular. Sectigo says Mozilla and Chrome dropped TLS trust from AAA Certificate Services in releases after 15 April 2025, so many Mozilla-derived bundles no longer trust it for websites. The OpenJDK cacerts source still ships it as comodoaaaca, as of the master branch we checked on 21 October. The Red Hat bulletin and the tracker's Linux workarounds both name AAA Certificate Services alongside the eMudhra root for the same reason.

Older JDKs are not automatically safe

OpenJDK added three eMudhra roots (emSign Root CA - G1, emSign Root CA - G2 and emSign ECC Root CA - G3) in JDK 22, under JDK-8319187. The backports landed in 21.0.2, 17.0.10, 11.0.22, openjdk8u402 and Oracle's 8u401. An older JDK has no emsigneccrootcag3 entry, so the first path fails, but it very likely has comodoaaaca, so the second may work. Check.

A keystore cannot say "distrust"

A Java keystore used as a trust store is a list of trust anchors. It has no slot for "this intermediate is bad." A default JVM can stop trusting it in three ways: remove every anchor it chains to, turn on revocation checking, or move to a JDK build whose vendor adds its own block. Until vendors ship, the first two are the levers you hold.

Where Java trust stores live

Oracle's JSSE guide gives the lookup order the default trust manager uses:

  1. The file named by the javax.net.ssl.trustStore system property, if set. If that file does not exist, the JVM uses an empty trust store.
  2. Otherwise lib/security/jssecacerts under the Java home, if it exists.
  3. Otherwise lib/security/cacerts under the Java home.

That second step catches people out. A jssecacerts file sitting next to cacerts silently wins, and fixing cacerts does nothing.

Where Java runsTrust store you are probably usingWhat updates it
Vendor JDK from a tarball or installerJAVA_HOME/lib/security/cacertsA new JDK build, or your own keytool edits
Debian or Ubuntu openjdk packages/etc/ssl/certs/java/cacerts, kept by ca-certificates-javaThe ca-certificates package hooks; update-ca-certificates -f forces a full re-import, per the Debian README
RHEL, Fedora and relativesCommonly /etc/pki/java/cacerts, generated by update-ca-trustThe ca-certificates package and blocklist entries; confirm the path with ls -l
Eclipse Temurin container images/opt/java/openjdk/lib/security/cacerts; USE_SYSTEM_CA_CERTS can merge certificates mounted at /certificatesRebuilding on a newer image
jlink custom runtimesA copy of cacerts frozen into the runtime image at build timeRebuilding the runtime from a fixed JDK
App servers and clients with explicit settingsWhatever file the configuration namesYou
Android appsSystem store plus anything in the app's network security config or bundled keystoresPlay Services for the system store; an app release for anything bundled

On Debian, keystore aliases are file names with a debian: prefix, so do not grep only for the JDK-style alias. Temurin's USE_SYSTEM_CA_CERTS adds certificates and removes none, so it does not help here.

Step by step: find, check, fix, prove

1. Inventory every trust store on a host

# Every cacerts and jssecacerts file, with symlinks shown
find / -xdev \( -name cacerts -o -name jssecacerts \) 2>/dev/null | xargs -r ls -l

# Every running JVM, and any trust store it was told to use
jcmd -l
for pid in $(jcmd -l | awk '$2 !~ /JCmd/ {print $1}'); do
  echo "== $pid"; jcmd "$pid" VM.system_properties 2>/dev/null \
    | grep -E 'java.home|javax.net.ssl.trustStore'
done

# Trust stores named in configuration files
grep -rniE 'truststore|jssecacerts' /etc /opt /srv \
  --include='*.xml' --include='*.properties' --include='*.yml' \
  --include='*.yaml' --include='*.conf' 2>/dev/null

Write down each file, which JVMs read it and who owns its updates.

2. Check each store by name

The default keytool -list output shows aliases and fingerprints. The verbose form shows the owner of each entry, which works whatever the alias is.

# JDK-style aliases (for example "emsigneccrootcag3 [jdk]" and "comodoaaaca [jdk]")
keytool -list -cacerts -storepass changeit | grep -iE 'emsign|comodoaaa'

# Any store, any alias style: print the alias above each matching owner
keytool -list -v -keystore /etc/ssl/certs/java/cacerts -storepass changeit \
  | grep -E '^(Alias name|Owner):' \
  | grep -B1 -E 'emSign|AAA Certificate Services'

changeit is the initial cacerts password, per Oracle's keytool documentation; yours may differ. For your own stores, pass the password with -storepass:env VAR to keep it out of shell history.

Other emSign roots, such as emSign Root CA - G1, are not part of this removal. eMudhra says it is moving G3 customers to its G1 chain, and Mozilla left G1 trusted. Match names exactly.

3. Check each store by fingerprint

Custom trust stores sometimes contain intermediates because someone imported a whole chain, and name checks can miss that. Compare fingerprints against the sixteen affected certificates. These values come from the tracker's list of impacted intermediates and match Mozilla's Bugzilla entry; check them against those pages before you rely on them.

cat > emudhra-bad.txt <<'EOF'
E7568FE6E12331F4FD7DE61DA4C7559D0F8EB192A218D4741A3BA75184333838
98B896625C0C230ADEEC3EB2CF6AAD5001ECF9156A68644E82374CE5833BC25B
42C4ACCD12C4F59597925E1A08A7A90102608543809308D50EC427E118BA1493
432EC25F0D28DE9006D97BF752F17BBB2CD41F669933FCB072D9A1148D0261F3
CB6E15165AC802E9B3F993F16C25D41F4E81C21EBDE71AE1B012AC00BF9C7C3F
0164D7CEAE5BB909C272AF151FF44B1177AE9B47D9424B94F1D9558C30934D19
9E39DE2881273ACC225A149C72BA3E0F51424963669AB633EE1DC7DF5DB067B4
4B2460A466F95FD40113BCDCCA2CEB29B3B093921DE45474DA7DF48874C630B1
579480AEA166290BD3C643589E795FC0D0E54E86505D180F1DFF99EFD3199512
5F1DED4DD590AF74631290CF073B122A2AAC6A1FA479778A0BD43579BD832699
45A883F349AEDFD5F3A649B5498FFB121712BA8B448F3F2A91DBC5A766FCDDBE
FD9D5C2DBBD4995AB69B8D50C439D9527B00529199C2FD01B2174EB58F07021F
7485B51C0ED192878FA1D2F948FB529AE1842CC5086C4B67F7BE5B2039DE9489
62B7F9868263F72F6911FC78CEAF72C1979158B7368BF648683BB2AA39B02E72
A496E23AC0CAB8155FC9B117B97EAE368EFCBB9041AEC8804D5A308D2D01C2D8
84112972B8E59D14560AE7E7119654474AAD119990CF3722BFC1E3B91615E1FD
EOF

keytool -list -keystore /path/to/truststore.p12 -storepass:env TRUSTSTORE_PASS \
  | grep -o 'SHA-256): [0-9A-F:]*' | cut -d' ' -f2 | tr -d ':' \
  | grep -F -f emudhra-bad.txt && echo "AFFECTED ENTRY FOUND"

The first eight are the eMudhra-issued intermediates; the last eight are the Sectigo cross-signs.

4. Test the real JVM before you change anything

The tracker runs two test hosts: dv-g3b-emudhra and dv-g3b-aaa-emudhra. The second is named for the AAA cross-signed path; the tracker's chains.zip holds the exact chains each one serves. A certificate error is the result you want from both. A small single-file program, run with the same JDK and trust settings as your service, gives a real answer:

// TlsCheck.java  (run with: java TlsCheck.java URL)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class TlsCheck {
  public static void main(String[] args) throws Exception {
    var client = HttpClient.newHttpClient();
    var req = HttpRequest.newBuilder(URI.create(args[0])).build();
    var res = client.send(req, HttpResponse.BodyHandlers.discarding());
    System.out.println("ACCEPTED (bad): HTTP " + res.statusCode());
  }
}
java TlsCheck.java https://dv-g3b-emudhra.we-have-a-problem.com/
java TlsCheck.java https://dv-g3b-aaa-emudhra.we-have-a-problem.com/

# Same check against an app's own trust store
java -Djavax.net.ssl.trustStore=/path/to/truststore.p12 \
     -Djavax.net.ssl.trustStorePassword="$TRUSTSTORE_PASS" \
     TlsCheck.java https://dv-g3b-aaa-emudhra.we-have-a-problem.com/

You want an SSLHandshakeException with "PKIX path building failed." ACCEPTED (bad) means that trust store still trusts that path. Cloudflare's advice applies: a pass from curl or a browser says nothing about a JVM, and one JVM says nothing about another with a different trust store.

5. Check what your own endpoints depend on

Before removing an anchor, find out who you would cut off. Look at the chain of each host your Java services call and each partner that connects with client certificates:

openssl s_client -connect partner.example.com:443 -servername partner.example.com \
  -showcerts </dev/null 2>/dev/null | grep -E ' s:| i:'

If anything ends at emSign ECC Root CA - G3, it breaks when you remove that root, and it breaks in Chrome after Google's root removal, expected on 27 October. Ask the owner to move to another hierarchy. If anything still ends at AAA Certificate Services, plan that removal more carefully or keep the anchor and use the revocation stopgap in step 7.

6. Remove the anchors safely

Back up first. Then pick the method that matches who owns the file.

A JDK's own cacerts (tarball, installer or image):

CACERTS="$JAVA_HOME/lib/security/cacerts"
sudo cp -p "$CACERTS" "$CACERTS.bak-$(date +%F)"
keytool -list -cacerts -storepass changeit | grep -iE 'emsign|comodoaaa'   # copy exact aliases
sudo "$JAVA_HOME/bin/keytool" -delete -cacerts -storepass changeit -alias "emsigneccrootcag3 [jdk]"
# Only after step 5 says nothing you need chains to it:
sudo "$JAVA_HOME/bin/keytool" -delete -cacerts -storepass changeit -alias "comodoaaaca [jdk]"

Oracle's keytool documentation describes -delete as the way to remove an untrusted CA from cacerts. Use the keytool from the same JDK, and note that -cacerts cannot be combined with -keystore.

Debian and Ubuntu system Java keystore: do not edit /etc/ssl/certs/java/cacerts by hand; the package hooks rewrite it. Install the fixed ca-certificates package from your distribution (the tracker lists versions such as 20260816ubuntu0.24.04.1 and 20250419+deb13u1), then rebuild the Java keystore and check it:

sudo apt-get update && sudo apt-get install --only-upgrade ca-certificates ca-certificates-java
sudo update-ca-certificates -f
keytool -list -v -keystore /etc/ssl/certs/java/cacerts -storepass changeit \
  | grep -E '^Owner:' | grep -E 'emSign ECC Root CA - G3|AAA Certificate Services'

If the fixed package leaves a root you still want gone, the tracker's expert-only workaround is to mark the root with a ! in /etc/ca-certificates.conf and rerun update-ca-certificates. The tracker labels these workarounds as not recommended for ordinary users.

RHEL family: Red Hat's bulletin had no fixed package listed at its last update, and it points to knowledge base solution 7149312 for disabling the AAA roots. The standard mechanism is to place a PEM copy of the root you want distrusted in /etc/pki/ca-trust/source/blocklist/ and run update-ca-trust extract, which regenerates the extracted bundles, including the Java one. Follow Red Hat's article for the exact files, and recheck /etc/pki/java/cacerts afterwards.

Your own trust stores: the same keytool -delete -keystore FILE -alias ALIAS command works. For a store that holds only your partners' CAs, an affected entry is a red flag in itself: find out who added it and why.

7. Consider revocation checking as a stopgap

eMudhra revoked its eight intermediates on 18 October with the reason caCompromise, and Sectigo says on the same Bugzilla entry that it has revoked its cross-signs. A JVM that checks revocation can see that. Oracle documents the switches:

# Turn on revocation checking for the default trust manager, with CRL distribution points
export JAVA_TOOL_OPTIONS="-Dcom.sun.net.ssl.checkRevocation=true -Dcom.sun.security.enableCRLDP=true"

OCSP is controlled by the ocsp.enable security property, set in a java.security override file rather than as a plain system property. Oracle's PKI guide notes that OCSP only applies when revocation checking is on, and falls back to CRLs only if an OCSP problem occurs.

This stopgap has sharp edges. Handshakes may now need a network fetch, so locked-down egress can cause outages, and Oracle's default fetch timeouts are 15 seconds. Try it in staging, rerun step 4 and your integration tests, then decide.

8. Rebuild images and redeploy

A fixed host does nothing for a container. Each image froze its trust store when it was built.

# Pull fresh bases and rebuild without cache
docker build --pull --no-cache -t your-java-app:trustfix .

# Pull the trust store out of the image and check it with the host keytool
cid=$(docker create your-java-app:trustfix)
docker cp -L "$cid":/opt/java/openjdk/lib/security/cacerts ./cacerts-from-image
docker rm "$cid"
keytool -list -keystore ./cacerts-from-image -storepass changeit | grep -iE 'emsign|comodoaaa'

If the base image has no fixed JDK yet, delete the aliases inside your Dockerfile so the change is repeatable and reviewed, instead of patching running containers:

FROM eclipse-temurin:21-jre
# Temporary: remove eMudhra G3 trust until the JDK vendor ships a fix (see ticket SEC-1234)
RUN keytool -delete -cacerts -storepass changeit -alias "emsigneccrootcag3 [jdk]" \
 && ! keytool -list -cacerts -storepass changeit | grep -qi emsigneccrootcag3

Add the comodoaaaca deletion only if step 5 cleared it. For jlink runtimes, apply the same change to the JDK you link from, or to the cacerts inside the output runtime, then rebuild. Restart every JVM after a change: trust stores load at startup. Then roll the new images out and rerun the step 4 check from inside a running container.

Our notes on container image supply chain incidents explain why base images need scheduled rebuilds.

App servers and frameworks

Java servers often keep two trust settings: one for outbound calls and one for client certificates (mTLS).

  • Outbound calls from your code usually use the JVM default trust store, unless a client library was given its own. Search configuration for truststore as in step 1.
  • Inbound client certificates use a separate setting. Apache Tomcat's truststoreFile, for example, is "the trust store file to use to validate client certificates," and it falls back to the javax.net.ssl.trustStore system property when unset. If that property points at a full public bundle, any public CA, including a forged intermediate, could vouch for a client.

For mTLS, the fix is better than removing two roots: trust only the private CA that issues your clients' certificates. Cloudflare's guidance to mTLS users is to review and update the CAs they trust for client authentication.

Messaging, search and database clients often take their own trust store path too. Treat each as a separate store and run the same checks.

Android apps

The device side is mostly handled. Google says Android devices got the block through Google Play Services around 22:00 UTC on 19 October; a restart applies it at once. Google adds that apps targeting the latest SDK or opting in to Certificate Transparency enforcement were not exposed, since nothing from these intermediates was logged in CT before the block.

The app side is yours. Android's network security configuration lets an app add trust anchors from a raw resource, and the Android documentation notes that CT verification is turned off for a domain whose trust anchors include user or inline certificates. So an app that bundles its own CA file can skip both the Play Services block and CT. Check:

# Which configs add their own anchors?
grep -rn -A3 '<trust-anchors>' app/src/main/res/xml/

# What is in each bundled PEM?
for f in app/src/main/res/raw/*.pem; do
  echo "== $f"
  awk -v cmd='openssl x509 -noout -subject -fingerprint -sha256' \
    '/BEGIN CERT/{close(cmd)};{print | cmd}' < "$f"
done

Also search the code for custom TrustManager classes and bundled keystores (.bks, .jks, .p12). Pins on your own servers' keys need no change. Ship an app update for any bundled store holding the affected roots or intermediates. Google's post does not cover devices without Play Services, so ask their vendors.

Common mistakes

  • Deleting only emsigneccrootcag3. The AAA cross-sign path survives. Test both test hosts.
  • Fixing cacerts while jssecacerts exists. The JVM reads jssecacerts first.
  • Editing the Debian keystore by hand. The next ca-certificates update rewrites it. Fix the source, then regenerate.
  • Assuming an old JDK is safe because it lacks the G3 root. It may still trust AAA Certificate Services.
  • Forgetting the restart. A running JVM keeps the trust store it loaded at startup.
  • Patching a live container. The next deploy brings the old store back. Change the Dockerfile.
  • Clearing new errors by disabling verification. Cloudflare's line is clear: "It's important to not resolve these errors by disabling verification." A broken partner needs a new certificate.

What would have helped

Practices any team can use

Treat every trust store as a dependency with an owner. The step 1 inventory should exist before an incident: each cacerts, jssecacerts, custom store and Android bundle, which services read it and who updates it.

Keep trust stores small. A partner integration or an mTLS listener rarely needs the whole public web PKI. Trust one private CA or a few named roots, and a public CA incident often passes you by.

Rebuild on a schedule. Weekly base image rebuilds and JDK patch updates make "rebuild everything" routine.

Test the trust store you ship. A small check like TlsCheck.java in CI, pointed at known-bad hosts when an incident provides them, proves what a build really trusts.

Background: certificate authority compromise risks.

Zero-Day Discovery and Gold

Safeguard's Zero-Day Discovery looks for previously unknown flaws before a CVE exists, in an agentic mode and a deterministic scanner mode, across seven package ecosystems, and issues findings as SGZ advisories before they reach public CVE databases. It hunts code flaws in packages. Weak keys from a CA's key ceremony are not a package code flaw, and JDK trust stores are not what it inspects.

Gold Open Source at gold.safeguard.sh is free with no login: searchable CVE intelligence with CVSS, EPSS, KEV status, affected and fixed versions and a recommended safe version, plus a free read API and a GitHub Action for CI gates. Gold Registry at registry.safeguard.sh is the paid side: hardened drop-in components and container images held to zero exploitable critical or high CVEs, built to SLSA L3+, signed with Sigstore and published with evidence pages. An artifact loses its badge if it regresses.

We are not saying Gold carried a Java image with a fixed trust store before JDK vendors shipped one. The habit that helps is pulling patched, signed base images from a curated source and rebuilding fast when upstream moves.

Where Safeguard fits

  • Finding the images and services. SBOM and dependency scanning covers repos, container images and SBOM files: safeguard scan --dir ., safeguard scan --image IMAGE or safeguard scan --sbom FILE, with JSON results under ./output. The platform shows which projects contain a given component and version, so "which images still carry an old ca-certificates or ca-certificates-java package" or "which services run on a given JDK base" becomes a lookup.
  • Matching advisories. Vulnerability matching against vulnerability databases can flag packages once a published identifier, such as CVE-2026-111943, appears in the sources it matches against. A trust store change with no advisory will not show as a vulnerability, so use the component and version view as well.
  • Holding the line. Policies and gates evaluated in the platform can block builds that still carry an outdated trust store package.
  • Making the change. The Safeguard CLI assistant can edit a Dockerfile, bump a base image tag, add the temporary keytool step and run the rebuild and tests with your approval of each command. safeguard exec runs one non-interactive turn for CI. Autonomous remediation can open fix PRs for dependency bumps; it ships off by default.

Where it does not help: a package scan reports packages and versions, not the entries inside a keystore file, so keep the keytool checks. A JDK unpacked from a tarball may not show up as a package at all. Safeguard cannot see a CA's key ceremony, cannot tell you whether anyone used a recovered key against you, and will not reach devices or hosts you never scan. No scanner would have prevented this incident; the keys were weak at the source. For the whole month in one place, see October 2026 security incidents and what would have helped.

FAQ

Has any JDK vendor shipped an eMudhra fix?

Not that we could confirm on 21 October. The tracker listed Java as pending, and we found no OpenJDK removal bug and no statement from Oracle, Eclipse Temurin, Amazon Corretto or Azul. Look for an emSign entry in your vendor's release notes.

Is deleting emsigneccrootcag3 enough?

No. Each affected intermediate also has a Sectigo cross-signed copy that chains to AAA Certificate Services, which OpenJDK's cacerts still includes as comodoaaaca. Check both, test against both tracker hosts, and remove comodoaaaca only after confirming nothing you need still chains to it.

Will removing these roots break anything?

Anything that chains to emSign ECC Root CA - G3 will fail, but Chrome is removing that root around 27 October anyway, and eMudhra is moving customers to its G1 chain. Removing AAA Certificate Services can break older Sectigo chains that still end there. Step 5 shows how to check first.

Should I just turn on revocation checking?

As a stopgap, yes, since eMudhra and Sectigo revoked the certificates. It adds network fetches to handshakes and can fail hard without egress to CRL or OCSP servers. Test in staging; removing anchors stays the main fix.

Does this affect Java code signing?

Two of the eight intermediates are for code signing. OpenJDK's bug for adding the eMudhra roots describes emSign ECC Root CA - G3 as covering both TLS and code signing, and a cacerts file does not separate the two. Treat any JAR signed under the two code-signing intermediates with suspicion, and remove the anchors as above.

Are Android users protected?

Devices with Google Play Services received a block around 22:00 UTC on 19 October, and a restart applies it. Apps that bundle their own CA files or keystores are not covered by that block. Developers need to check and ship updates.

Fix it without waiting for upstream

In incidents like this one, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

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

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your 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 shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
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 have helped

The CLI demo shows the assistant fixing a lodash CVE: it reads the finding and the advisory, asks before each command, edits package.json, then runs install and tests with your approval and pushes nothing. For eMudhra you would ask the same assistant to add the temporary keytool -delete step to your Java Dockerfile, rebuild with a fresh base, and rerun TlsCheck.java against both test hosts. It asks before every command.

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

The desktop app demo shows a real session: the CLI session appears in the conversation list, you ask for work on your computer, pick the folder, then approve or deny each command and file edit until the upgrade is done and tests pass. Here the same flow could take a Java service through a base image bump and a trust store test, one approval at a time.

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

The local runner demo shows setting up the runner on your own machine, approving it with its device code, then scanning from the terminal. After this incident you would scan each rebuilt Java image to confirm the ca-certificates packages and JDK base it now contains, then pair that with the keytool check.

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

To find every Java image that still ships an old trust store, download Safeguard and follow the CLI docs.

Quick check

You deleted emsigneccrootcag3 from cacerts and restarted the JVM. The aaa test host still connects. Why?

The cross-signed copy of the intermediate chains to AAA Certificate Services, which the JDK still trusts as comodoaaaca. Check whether anything you need chains to that root, then remove it or turn on revocation checking as a stopgap, and test again.

You fixed cacerts on the host, but the service in Kubernetes still accepts the test host. What did you miss?

The container carries its own JDK and trust store, frozen at build time. Change the Dockerfile, rebuild with a fresh base, redeploy, and rerun the check from inside a running pod. Also check for a jssecacerts file or a javax.net.ssl.trustStore setting.

Sources

Last reviewed: 21 October 2026. This is a developing story; check the linked advisories for the latest status.

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.