Security·Cryptography

MCP server post-quantum security: ML-KEM, hybrid TLS, and quantum-safe authentication

NIST standardized the first post-quantum cryptography algorithms in 2024. For MCP servers handling long-lived data, the migration window has already opened: "harvest now, decrypt later" attacks mean traffic captured today can be decrypted once a cryptographically relevant quantum computer exists.

What's at risk in current MCP server deployments

A quantum computer running Shor's algorithm breaks RSA and elliptic curve cryptography (ECDSA, ECDH) in polynomial time. Current MCP server deployments typically use:

For most MCP servers today, the threat horizon is 10-15 years. But MCP servers that handle data with a confidentiality requirement beyond that horizon (healthcare records, legal documents, government data) need to start the migration now.

Pattern 1: Hybrid key exchange in TLS 1.3

NIST's ML-KEM (formerly Kyber) is the standardized post-quantum key encapsulation mechanism. The immediate migration path is a hybrid cipher suite that combines X25519 with ML-KEM — classically secure today and quantum-safe for the future. Both Chrome and Node.js 22+ support X25519Kyber768Draft00:

// Node.js 22+ with --experimental-network-inspection
// Set preferred cipher for outbound TLS connections
const https = require('https');
const tls = require('tls');

const agent = new https.Agent({
  // Prefer hybrid X25519+ML-KEM key exchange
  // Falls back to X25519 if server doesn't support PQC
  ciphers: [
    'TLS_AES_256_GCM_SHA384',     // TLS 1.3 (mandatory)
    'TLS_CHACHA20_POLY1305_SHA256' // TLS 1.3 (mandatory)
  ].join(':'),
  // Node.js 22 supports X25519Kyber768 via --enable-fips
  // or via openssl.cnf with provider = oqsprovider
  ecdhCurve: 'X25519Kyber768:X25519:P-256',
});

// For your server's inbound TLS (Caddy/nginx handles this automatically
// on modern versions — verify with: openssl s_client -connect host:443
// and look for "Server Temp Key: X25519Kyber768")

For Caddy (used in the SkillAudit factory deployment), post-quantum TLS is automatic from Caddy 2.9+ — no configuration needed. Check with:

curl -v --tlsv1.3 https://skillaudit.dev 2>&1 | grep "SSL connection"

Pattern 2: Post-quantum JWT signatures

NIST's ML-DSA (formerly CRYSTALS-Dilithium) is the standardized post-quantum digital signature algorithm. For JWT tokens, the jose library supports ML-DSA via the OQS provider in OpenSSL 3.x:

// Using node-oqs (OpenQuantumSafe bindings)
import { generateKeyPair, sign, verify } from 'node-oqs';

// Generate ML-DSA-65 key pair (NIST security level 3)
const { publicKey, privateKey } = await generateKeyPair('ML-DSA-65');

// Sign a JWT payload (custom JWT — jose doesn't yet support ML-DSA natively)
const header = Buffer.from(JSON.stringify({ alg: 'ML-DSA-65', typ: 'JWT' })).toString('base64url');
const payload = Buffer.from(JSON.stringify({ sub: userId, iat: Math.floor(Date.now() / 1000), exp: ... })).toString('base64url');
const signature = sign(`${header}.${payload}`, privateKey);
const token = `${header}.${payload}.${Buffer.from(signature).toString('base64url')}`;

// Verification
const [h, p, s] = token.split('.');
const valid = verify(`${h}.${p}`, Buffer.from(s, 'base64url'), publicKey);

This is a forward-looking pattern — most MCP server deployments should stay on RS256 today and plan the migration. The key preparatory step is crypto-agility: ensure your JWT library can be swapped without changing every token verification call site.

Pattern 3: Inventory and prioritize quantum-vulnerable usage

Before migrating, inventory all cryptographic operations in the MCP server codebase. A script to find RSA and EC key usage:

#!/bin/bash
echo "=== RSA key operations ==="
grep -rn "createSign\|RSA\|rsa\|RS256\|RS384\|RS512" src/ --include="*.js" --include="*.ts"

echo "=== EC key operations ==="
grep -rn "createECDH\|ECDH\|ECDSA\|ES256\|ES384\|ES512\|P-256\|P-384\|secp256k1" src/ --include="*.js"

echo "=== TLS configuration ==="
grep -rn "secureProtocol\|ciphers\|ecdhCurve\|createServer\|createSecureContext" src/ --include="*.js"

echo "=== Certificate loading ==="
grep -rn "readFileSync.*\\.pem\|readFileSync.*\\.crt\|readFileSync.*\\.key" src/ --include="*.js"

Prioritize migration based on data sensitivity and key lifetime:

SkillAudit and post-quantum readiness

SkillAudit's maintenance axis tracks cryptographic library versions and flags usage of deprecated algorithms. As the NIST PQC standards mature through 2026-2027, SkillAudit will add a dedicated post-quantum readiness check to the security axis — flagging RSA key sizes below 3072 bits and ECDH-only key exchanges without a PQC hybrid. Run an audit to see your current cryptographic posture.

Related: JWT algorithm confusion attacks · 50-question security checklist · OIDC security for MCP