Migration to LightHouse 0.23.X¶
This page covers the migration of ML-DSA signing keys to the new interoperable key encoding introduced in LightHouse 0.23.0.
Info
You must be at least on version 0.22.0 to migrate to 0.23.X.
What Changed¶
LightHouse 0.23.0 upgrades github.com/go-oidfed/lib to 0.12.0, which changed
how ML-DSA (post-quantum, MLDSA44/MLDSA65/MLDSA87) private keys are
encoded in PEM files:
| Encoding | |
|---|---|
| Old (lib < 0.12.0) | PKCS#8 with the raw seed wrapped in a nested OCTET STRING (04 20 ...) — a non-standard encoding written by earlier versions of the library |
| New (lib >= 0.12.0) | RFC 9935 seed-only PKCS#8, the encoding used by crypto/x509 and OpenSSL: the seed is an IMPLICIT [0] OCTET STRING (80 20 ...) |
Keys in the old encoding still load in 0.23.0, but new keys are written in the new encoding, and the new encoding is what external tools (e.g. OpenSSL) expect. Existing ML-DSA keys should be re-encoded once with the migration described below. The parsed key is identical — only the encoding changes, so key IDs, JWKS, and signatures are unaffected.
Only ML-DSA keys are affected
EC, RSA, EdDSA, and other key types are not affected. Non-ML-DSA keys are detected and skipped by the migration.
Backup Before Migration
Before starting the migration process, create backups of:
- Your key directory (filesystem KMS), e.g.
/var/lib/lighthouse/keys - Your database, if you store private keys with
signing.kms: db
Migration Steps¶
Use lhmigrate keys mldsa. Depending on where your private keys live
(signing.kms in your config file), pick the matching mode.
Filesystem KMS (signing.kms: filesystem)¶
./lhmigrate keys mldsa --source /var/lib/lighthouse/keys
The command scans all *.pem files in the directory (this covers both the
current <kid>.pem layout and the legacy <type>_<alg>.pem layout,
e.g. federation_MLDSA65.pem), re-encodes every legacy ML-DSA key in place,
and skips everything else. Files are written atomically; a converted key that
was already in the new format is left untouched, so running the command twice
is safe.
Add -n -v to preview the conversion without writing:
./lhmigrate keys mldsa --source /var/lib/lighthouse/keys --dry-run -v
Database KMS (signing.kms: db)¶
# SQLite
./lhmigrate keys mldsa --db-type sqlite --db-dir /var/lib/lighthouse
# MySQL
./lhmigrate keys mldsa --db-type mysql \
--db-dsn 'user:pass@tcp(127.0.0.1:3306)/lighthouse?charset=utf8mb4&parseTime=True'
# PostgreSQL
./lhmigrate keys mldsa --db-type postgres \
--db-dsn 'host=localhost user=lighthouse password=secret dbname=lighthouse port=5432'
For SQLite, --db-dir points at the directory (or pass the database file via
--db-dsn). The command re-encodes ML-DSA keys in the private_keys_<type>
table (default type: federation) and skips non-ML-DSA keys.
Using Docker
The lhmigrate tool is included in the Docker image.
To run it, override the image entrypoint with --entrypoint /lhmigrate,
and mount your key directory or data directory:
# Filesystem KMS
docker run --rm \
-v /var/lib/lighthouse:/data \
--entrypoint /lhmigrate \
oidfed/lighthouse:0.23 \
keys mldsa --source /data/keys
# Database KMS (SQLite)
docker run --rm \
-v /var/lib/lighthouse:/data \
--entrypoint /lhmigrate \
oidfed/lighthouse:0.23 \
keys mldsa --db-type sqlite --db-dir /data
Verify the migration¶
Re-run with -v and check the summary: converted counts re-encoded keys,
skipped counts keys of other algorithms. A second run must report no
converted keys (the conversion is idempotent).
If you use the filesystem KMS, you can also verify a converted ML-DSA key with OpenSSL, which only understands the new encoding:
openssl asn1parse -in /var/lib/lighthouse/keys/<kid>.pem
# the private key payload must start with 80 (IMPLICIT [0] OCTET STRING),
# not 04 (OCTET STRING)
Then start LightHouse and confirm signing works, e.g. fetch the entity configuration:
curl https://localhost:8080/.well-known/openid-federation