Safeguard
Compliance•

Executive Order 14412: What Federal Software Vendors Need Ready for Post-Quantum Questions

EO 14412 and OMB M-26-15 set PQC deadlines and two FAR rules. What federal vendors will be asked, and a Go tool to test TLS for ML-KEM hybrid key exchange.

Safeguard Security Team
Security Research
13 min read

Every federal civilian agency has to send OMB its post-quantum cryptography migration plan by 22 October 2026. OMB Memorandum M-26-15, which implements Executive Order 14412, requires each plan to include a third-party coordination plan, and it gives program offices the job of making sure vendor requirements include PQC readiness and cryptographic agility. So the next round of questions about your product's cryptography is already being written, before any contract clause requires an answer.

This guide is for software and SaaS vendors that sell to US federal agencies, and the engineers who'll answer for the product's cryptography. It sets out what EO 14412 and M-26-15 require and when, where CISA's product list puts your category, what agencies are likely to ask, and a Go tool that checks whether your TLS endpoints accept a post-quantum key exchange today.

The short answer

Executive Order 14412, signed on 22 June 2026, sets 31 December 2030 for federal high value assets and high impact systems to use post-quantum cryptography for key establishment, and 31 December 2031 for digital signatures. It also orders two FAR rules for contractors: a proposed rule, due about 19 December 2026, requiring compliance with NIST's FIPS, including the post-quantum standards, by 31 December 2030; and one, due about 19 March 2027, requiring vulnerability disclosure programs that accept reports of cryptographic weaknesses. Neither rule exists yet. What exists now is M-26-15, which tells agencies to inventory their cryptography, prioritize systems, buy PQC-capable products where they're widely available, and coordinate with vendors. A vendor that can show a cryptographic inventory, hybrid post-quantum key exchange on its TLS endpoints, and a plan for signatures will have the answers ready.

What EO 14412 orders, and when

The order runs on fixed day counts from 22 June 2026:

DeadlineSectionWhoWhat
22 Jul 2026 (30 days)4(a)Each agencyName a PQC migration lead
20 Sep 2026 (90 days)4(b)OMBIssue migration guidance (done early, as M-26-15 on 24 June)
19 Dec 2026 (180 days)6(c)FAR CouncilProposed rule: covered contractors comply with NIST FIPS, including PQC, by 31 Dec 2030
19 Dec 2026 (180 days)6(b)NISTRevise the Cryptographic Module Validation Program to speed up validations
19 Mar 2027 (270 days)6(d)FAR CouncilProposed rule: contractor vulnerability disclosure policies that cover cryptographic vulnerabilities, "including testing for lack of encryption and the use of non-FIPS approved algorithms"
19 Mar 2027 (270 days)5(d)CISA with NISTPublic guidance on minimum elements for a cryptographic bill of materials
31 Dec 20304(b)(ii)AgenciesHigh value assets and high impact systems use PQC for key establishment
31 Dec 20314(b)(iii)AgenciesThe same systems use PQC for digital signatures

The FAR dates are for proposed rules. A final rule, its exact scope and the clause text will come later, after public comment. National security systems are handled separately, through the NSA.

What M-26-15 asks of agencies

M-26-15 turns the order into a plan. Agencies must aim to mitigate "as much quantum risk as feasible" by the end of 2030, in phases:

PhaseYearsFocus
12026 to 2027Strategy, planning and discovery, including the cryptographic inventory
22027 to 2028Pilots and early migration
32028 to 2030PQC key establishment for prioritized systems
42031PQC digital signatures for the same systems
52035Remaining systems

Priority goes to high impact systems, high value assets, logical access control built on asymmetric cryptography such as PKI, and data expected to stay mission-sensitive in 2030. Appendix A lists the quantum-vulnerable algorithms: ECDH, MQV, ECDSA, finite-field Diffie-Hellman, RSA for signatures and key establishment, DSA, and any other asymmetric algorithm "not definitively known to be quantum-resistant". The replacements are ML-KEM (FIPS 203) for key establishment and ML-DSA (FIPS 204) or SLH-DSA (FIPS 205) for signatures.

Three parts of the memo reach vendors directly:

  • TLS 1.3. Agencies must support TLS 1.3 or a successor by 2 January 2030, the date EO 14306 set. The memo calls TLS 1.3 foundational for PQC because hybrid key exchange runs on its handshake.
  • Automation. It says the inventory should be built with automated tools where possible, naming software composition analysis of SBOMs, SAST and DAST to find cryptographic functions in code, and network scanners for protocols and cipher suites, feeding a central cryptographic bill of materials.
  • Products. Agencies should use CISA's list of PQC product categories and require PQC integration for products in them. CISA and the Department of War, with GSA, will lead the work with FedRAMP-authorized cloud providers and with SaaS, PaaS and IaaS offerings used by more than one agency.

Where CISA's list puts your product

CISA published its "Product Categories for Technologies That Use Post-Quantum Cryptography Standards" on 23 January 2026, under EO 14306. It has two tables.

Widely available, so agencies "should plan acquisitions to procure only PQC-capable products": cloud services (PaaS and IaaS), chat and messaging, web browsers and web servers, and data-at-rest encryption. CISA notes that most of these have PQC for key establishment but not yet for signatures.

Transitioning, where manufacturers are encouraged to implement and test PQC: SaaS, networking hardware and software, operating systems, hypervisors and containers, identity and access management including certificate authorities and HSMs, email and conferencing, databases, and security tools such as SIEM and intrusion detection. CISA asks that products here use PQC for secondary functions too, "such as for software updates".

If you sell a web-facing service on PaaS or IaaS, or a web server, you're in the first table, and a buyer following the guidance can treat missing PQC key exchange as a reason not to buy. If you sell SaaS, you're in the second. That isn't a pass. It's where CISA expects movement, and products move to the first table as the category matures.

What agencies will likely ask

M-26-15 doesn't publish a vendor questionnaire, so treat this as a reading of the memo, not a list of official questions. Expect some version of:

  1. What cryptography does the product use, and where? Libraries and versions, algorithms in code, protocols on the wire, certificate and key types.
  2. Do your endpoints negotiate hybrid post-quantum key exchange? For TLS, that means a group such as X25519MLKEM768.
  3. Do you support TLS 1.3?
  4. Is the cryptography configurable? The memo's agility section says algorithm choices "must be specified in external configuration files, not compiled into the application binary".
  5. What's your plan for signatures? Code signing, update signing, JWT and API token signing, certificates.
  6. Are your cryptographic modules FIPS 140-3 validated?
  7. Does your vulnerability disclosure policy accept cryptographic findings?

Our guide to what crypto agility means in practice covers question 4 in depth.

Check your TLS endpoints

The fastest question to answer is the second one. This Go program connects to each endpoint three times with only one hybrid group offered, X25519MLKEM768, SecP256r1MLKEM768 or SecP384r1MLKEM1024, and records which the server accepts. It also reports the default negotiation and the certificate's key, which stays quantum-vulnerable until certificates move to ML-DSA. It needs Go 1.26 or later, uses only the standard library, and does nothing but TLS handshakes. Use -cafile for internal endpoints with a private CA.

// pqtls checks whether TLS endpoints accept a post-quantum hybrid key exchange
// and reports the quantum-vulnerable parts of each handshake (certificate key
// and signature). It needs Go 1.26 or later and only performs TLS handshakes.
//
//	go run . example.com api.example.com:8443
//	go run . -cafile internal-ca.pem portal.internal:8443
package main

import (
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"flag"
	"fmt"
	"net"
	"os"
	"strings"
	"time"
)

var hybrids = []tls.CurveID{tls.X25519MLKEM768, tls.SecP256r1MLKEM768, tls.SecP384r1MLKEM1024}

var roots *x509.CertPool // nil means the system trust store

func dial(addr string, curves []tls.CurveID) (tls.ConnectionState, error) {
	host, _, _ := net.SplitHostPort(addr)
	d := &net.Dialer{Timeout: 10 * time.Second}
	conn, err := tls.DialWithDialer(d, "tcp", addr, &tls.Config{
		ServerName:       host,
		MinVersion:       tls.VersionTLS12,
		CurvePreferences: curves,
		RootCAs:          roots,
	})
	if err != nil {
		return tls.ConnectionState{}, err
	}
	defer conn.Close()
	return conn.ConnectionState(), nil
}

func keyDesc(c *x509.Certificate) string {
	switch k := c.PublicKey.(type) {
	case *rsa.PublicKey:
		return fmt.Sprintf("RSA-%d (quantum-vulnerable)", k.N.BitLen())
	case *ecdsa.PublicKey:
		return fmt.Sprintf("ECDSA %s (quantum-vulnerable)", k.Curve.Params().Name)
	case ed25519.PublicKey:
		return "Ed25519 (quantum-vulnerable)"
	default:
		return c.PublicKeyAlgorithm.String()
	}
}

func main() {
	cafile := flag.String("cafile", "", "PEM file of extra CA certificates, for internal endpoints")
	flag.Parse()
	if flag.NArg() == 0 {
		fmt.Fprintln(os.Stderr, "usage: pqtls [-cafile ca.pem] host[:port] ...")
		os.Exit(2)
	}
	if *cafile != "" {
		pem, err := os.ReadFile(*cafile)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(2)
		}
		roots, _ = x509.SystemCertPool()
		if roots == nil {
			roots = x509.NewCertPool()
		}
		roots.AppendCertsFromPEM(pem)
	}
	missing := 0
	for _, arg := range flag.Args() {
		addr := arg
		if !strings.Contains(addr, ":") {
			addr += ":443"
		}
		def, err := dial(addr, nil)
		if err != nil {
			fmt.Printf("%s\n  error: %v\n", addr, err)
			missing++
			continue
		}
		var accepted []string
		for _, h := range hybrids {
			if st, err := dial(addr, []tls.CurveID{h}); err == nil && st.CurveID == h {
				accepted = append(accepted, h.String())
			}
		}
		leaf := def.PeerCertificates[0]
		fmt.Printf("%s\n", addr)
		fmt.Printf("  default handshake: %s, key exchange %s\n", tls.VersionName(def.Version), def.CurveID)
		if len(accepted) > 0 {
			fmt.Printf("  hybrid PQC key exchange accepted: %s\n", strings.Join(accepted, ", "))
		} else {
			fmt.Printf("  hybrid PQC key exchange accepted: none\n")
			missing++
		}
		fmt.Printf("  certificate key: %s, signed with %s\n", keyDesc(leaf), leaf.SignatureAlgorithm)
	}
	if missing > 0 {
		os.Exit(1)
	}
}

Save it as main.go beside a go.mod containing module pqtls and go 1.26. We ran it on 16 October against three federal sites:

$ go run . www.cisa.gov login.gov sam.gov
www.cisa.gov:443
  default handshake: TLS 1.3, key exchange X25519MLKEM768
  hybrid PQC key exchange accepted: X25519MLKEM768
  certificate key: ECDSA P-256 (quantum-vulnerable), signed with ECDSA-SHA384
login.gov:443
  default handshake: TLS 1.3, key exchange X25519MLKEM768
  hybrid PQC key exchange accepted: X25519MLKEM768, SecP256r1MLKEM768
  certificate key: RSA-2048 (quantum-vulnerable), signed with SHA256-RSA
sam.gov:443
  default handshake: TLS 1.3, key exchange X25519MLKEM768
  hybrid PQC key exchange accepted: X25519MLKEM768, SecP256r1MLKEM768
  certificate key: RSA-2048 (quantum-vulnerable), signed with SHA256-RSA

All three already negotiate a hybrid key exchange by default, and all three still present RSA or ECDSA certificates. That's the state CISA's footnote describes: key establishment first, signatures later. For the failing case, we started two local OpenSSL 4.0.3 test servers, one limited to classical groups with -groups X25519:P-256:

$ go run . -cafile c.pem localhost:8443 localhost:8444
localhost:8443
  default handshake: TLS 1.3, key exchange X25519
  hybrid PQC key exchange accepted: none
  certificate key: ECDSA P-256 (quantum-vulnerable), signed with ECDSA-SHA256
localhost:8444
  default handshake: TLS 1.3, key exchange X25519MLKEM768
  hybrid PQC key exchange accepted: X25519MLKEM768, SecP256r1MLKEM768
  certificate key: ECDSA P-256 (quantum-vulnerable), signed with ECDSA-SHA256

The program exits with status 1 when any endpoint accepts no hybrid group, so it can run in CI against staging. Without Go, OpenSSL 3.5 or later answers the same question for one group:

openssl s_client -connect www.cisa.gov:443 -groups X25519MLKEM768 </dev/null 2>&1 | grep "Negotiated TLS1.3 group:"

It prints Negotiated TLS1.3 group: X25519MLKEM768 when the server accepts the group. When it doesn't, the handshake fails with a handshake_failure alert and the command prints nothing.

Most fixes are an upgrade

If your endpoints fail, the cause is usually the TLS library or the load balancer in front of the service, not your code. The baselines we confirmed:

  • OpenSSL 3.5.0 (8 April 2025) added ML-KEM, ML-DSA and SLH-DSA, and changed the default TLS key shares to offer X25519MLKEM768 and X25519.
  • Go 1.24 added crypto/mlkem and enabled X25519MLKEM768 by default in crypto/tls. Go 1.26 added SecP256r1MLKEM768 and SecP384r1MLKEM1024 to the default, and Go 1.27 added crypto/mldsa. Setting CurvePreferences explicitly, or GODEBUG=tlsmlkem=0, turns the hybrids off, so check your config.
  • Java: JDK 24 added ML-KEM (JEP 496) and ML-DSA (JEP 497) as APIs.

Then look in front of the service. A load balancer, CDN or API gateway terminates TLS and decides the key exchange, which is why the memo lists "cloud gateways" and "API proxies" among the network devices that must support PQC key exchange.

Build the inventory you'll be asked for

A first-pass cryptographic inventory takes four sources, the same ones M-26-15 names:

  1. Dependencies. From your SBOM, list every cryptographic library and its version: OpenSSL, BoringSSL, Go's standard library, Bouncy Castle, libsodium, language bindings.
  2. Code. Search first-party code for direct use of RSA, ECDSA, ECDH, DH and DSA, for hardcoded algorithm names, and for key sizes. These are the places configuration can't change.
  3. Network. Run the checker above against every public and internal TLS endpoint, including the ones behind gateways.
  4. Keys and signatures. Certificates, code-signing and update-signing keys, JWT signing keys, and what your KMS or HSM can generate.

Record it in a format a buyer can read. CycloneDX supports cryptographic assets today, and CISA's minimum elements for a CBOM are due by March 2027. Our explainer on what a cryptographic bill of materials is covers the format.

What to do

  1. Run the TLS check against production and staging. Fix failures by upgrading the TLS library or the terminating proxy.
  2. Support TLS 1.3 everywhere. It's a prerequisite for hybrid key exchange, and agencies have to support it by January 2030.
  3. Write the inventory down from the four sources above, and keep it current with automation.
  4. Move algorithm choices into configuration wherever code hardcodes them.
  5. Publish a signature plan with dates for code signing, update signing and tokens, even if they depend on your vendors.
  6. Update your vulnerability disclosure policy to accept cryptographic findings, before the FAR rule requires it.

The fair view

None of this is a contract requirement yet. The FAR rules are proposals due this winter and next spring, the 2030 and 2031 dates apply to agency systems rather than vendors, and M-26-15 is guidance to agencies. A vendor could wait for the final rule and lose nothing on paper.

The memo is also candid about the costs. It calls hybrid architecture "an intricate and resource-intensive stopgap" and asks agencies to weigh the trade-offs. PQC signatures are larger: 2,420 bytes for ML-DSA-44 and 3,309 for ML-DSA-65, against 64 bytes for an ECDSA P-256 signature. Signature migration will be harder than key exchange because it touches certificates, firmware and every verifier.

But key exchange is mostly an upgrade, it protects data recorded now from decryption later, and federal sites already do it. A buyer comparing two vendors in a widely available category has an official reason to prefer the one that negotiates X25519MLKEM768. For most vendors, the cheapest time to be that one is before the plans due on 22 October turn into requirements.

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.