‹ Blogs

Post-Quantum Cryptography in OpenBao

Featured Image
Published on October 20, 2026
Author Fabian Kammel

The Migration So Far

The ongoing post-quantum cryptography (PQC) migration has mostly focused on securing the key exchange of protocols like TLS and SSH. TLS, for example, uses a hybrid scheme that combines the ECC-based X25519 curve and ML-KEM (FIPS 203) into a single mechanism called X25519MLKEM768.

Focusing on the key exchange first makes sense because messages exchanged today can be recorded and decrypted years later, once quantum computers (or other advances) break today’s cryptographic algorithms. This attack is known as harvest now, decrypt later (HNDL). Authentication, on the other hand, only needs to hold at the moment of the handshake because a signature verification cannot be altered retroactively, so it was safe to tackle it second.

The window to tackle the PQC migration is closing, with governments bringing their deadlines forward to around the end of the decade. For example, the US now requires PQC key establishment by 2030 and PQC digital signatures by 2031.

In this post, we walk through the new PQC features in OpenBao 2.7, enabled by ML-DSA (FIPS 204) support in Go 1.27, to get you started on your PQC authentication journey!

A PQC OpenBao Quick-Start

We’ve prepared a PQC quick-start configuration for OpenBao that allows you to test the new features in minutes. We’ll repeat relevant configuration snippets and commands in this post, but make sure to check out the repository for the full working example!

PQC TLS Configuration

OpenBao uses TLS to protect communication with its clients, such as the OpenBao CLI and applications that consume secrets. Upgrading our current TLS configuration to PQC requires changes in two areas: the certificate and the TLS protocol settings.

First, we need to reference a PQC TLS server certificate and key. We can generate one with OpenSSL 3.5+ or with our favourite PKI (more on that in the next section):

openssl genpkey -algorithm ML-DSA-65 \
  -provparam ml-dsa.output_formats=seed-only \
  -out tls/server-key.pem
openssl req -x509 -key tls/server-key.pem -out tls/server.pem -days 3650 \
  -subj "/CN=OpenBao PQC Demo Bootstrap" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1" \
  -addext "authorityKeyIdentifier=keyid"

Note the seed-only output format. Go only accepts ML-DSA private keys in their compact seed-only representation (RFC 9881), so a key in OpenSSL’s default format will be rejected by OpenBao.

Second, we need to require TLS 1.3, because the new PQC algorithms are only supported in that version. Additionally, we want to restrict the key exchange mechanisms our OpenBao server supports to quantum-safe ones only.

This listener configuration contains both changes:

listener "tcp" {
  # ... other config, for example address ...

  tls_cert_file = "tls/server.pem"
  tls_key_file  = "tls/server-key.pem"

  tls_min_version = "tls13"
  tls_key_exchange_preferences = [
    "X25519MLKEM768",
    "SecP384r1MLKEM1024",
    "MLKEM1024",
  ]
}

For more information, check out the official OpenBao documentation on PQC key exchange mechanisms.

A word for early adopters: with this configuration, every client needs to support TLS 1.3, a PQC key exchange, and ML-DSA certificates. Clients built with Go 1.27+, such as the bao CLI, are ready today, but ML-DSA support across the wider ecosystem is still rolling out. Make sure all clients talking to your OpenBao server are on board before making the switch.

PQC PKI

Using OpenSSL to create ad-hoc certificates is good enough for a development environment, but it will fall short in production. OpenBao 2.7 now supports PQC PKI, so let’s use OpenBao to manage its own TLS certificate.

We configure the PKI secrets engine using OpenBao’s declarative self-initialisation, which runs the request blocks below in order on the first server start. The same requests can, of course, also be sent via the CLI or API.

First, we initialise the PKI secrets engine, as we would today:

initialize "pki" {
  request "mount" {
    operation = "create"
    path      = "sys/mounts/pki"
    data = {
      type          = "pki"
      max_lease_ttl = "87600h"
    }
  }

  request "urls" {
    operation = "create"
    path      = "pki/config/urls"
    data = {
      issuing_certificates    = "http://127.0.0.1:8080/v1/pki/ca"
      crl_distribution_points = "http://127.0.0.1:8080/v1/pki/crl"
    }
  }
}

Minting PQC X.509 certificates is as easy as setting mldsa as the key_type and selecting one of the supported key_bits values: 44, 65, or 87.

Here, we create a root certificate using ML-DSA-65 with a 10-year lifetime. Then, we also create a role that specifies the shape of our TLS server (leaf) certificates; here, we allow the localhost domain with a 30-day lifetime:

initialize "pki" {
  request "root" {
    operation = "create"
    path      = "pki/root/generate/internal"
    data = {
      common_name = "OpenBao PQC Demo Root CA"
      issuer_name = "pqc-root"
      key_type    = "mldsa"
      key_bits    = 65
      ttl         = "87600h"
    }
  }

  request "role" {
    operation = "create"
    path      = "pki/roles/openbao-server"
    data = {
      key_type           = "mldsa"
      key_bits           = 65
      allowed_domains    = "localhost"
      allow_bare_domains = true
      allow_ip_sans      = true
      ttl                = "720h"
      max_ttl            = "720h"
    }
  }
}

To configure our OpenBao server, we need to download the root CA: bao read -field=certificate pki/cert/ca, and issue a server certificate: bao write -format=json pki/issue/openbao-server common_name=localhost ip_sans=127.0.0.1. After replacing the bootstrap certificate and key with the newly issued ones, we reload the server (for example, by sending SIGHUP) to pick up the new certificate.

We can use the same approach to start issuing PQC certificates for all our TLS infrastructure.

PQC Signing With Transit

TLS certificates are not the only signatures we need to migrate. Software artifacts and SBOMs are often verified many years after they were signed, which is why they’re among the first use cases that need to migrate to PQC.

One way to achieve this is to use OpenBao’s Transit secrets engine, which now supports ML-DSA keys. Access to the key is governed by OpenBao policies, and every signing operation shows up in the audit log.

First, we enable Transit and create an ML-DSA-65 signing key:

bao secrets enable transit
bao write -f transit/keys/release-signing type=mldsa-65

Next, we sign our release artifact. Transit expects base64-encoded input:

openssl base64 -A -in release.tar.gz -out release.b64
bao write -field=signature transit/sign/release-signing \
  input=@release.b64 > release.sig

Anyone with access to OpenBao can check the signature:

bao write transit/verify/release-signing \
  input=@release.b64 signature=@release.sig

The consumers of our release should not need access to our OpenBao server, though. We can export the public key and verify the signature with any FIPS 204 implementation, for example, OpenSSL 3.5+. We do need to strip the vault:v1: prefix, which tells OpenBao which key version was used, from the signature:

bao read -field=keys -format=json \
  transit/export/public-key/release-signing format=pem \
  | jq -r '."1"' > release-signing.pem
cut -d: -f3 release.sig | openssl base64 -d -A -out release.sig.bin

openssl pkeyutl -verify -pubin -inkey release-signing.pem \
  -rawin -in release.tar.gz -sigfile release.sig.bin

This concludes our round-up of the new PQC features in OpenBao. Namely, the PQC TLS listener, PQC PKI and PKI transit engine.

What’s Next

Next up on OpenBao’s roadmap is enabling ML-KEM support in the Transit Secrets Engine, PQC-secure JWTs, and PQC algorithm support in auto-unseal mechanisms. Note that the latter already supports symmetric algorithms in many places and is thus natively quantum-secure.

Start Your PQC Journey With the People Who Build It

If you’re an early adopter planning your post-quantum migration, or want to roll out PQC certificates across your infrastructure, that’s exactly the work we do. We contributed these PQC features to OpenBao and helped organisations put them into production. Explore Enterprise for OpenBao, or get in touch to talk through what a quantum-safe secrets management and PKI setup looks like for your environment.

Related blogs